Skip to content

Commit 7223f67

Browse files
authored
[LLD][COFF] Don't resolve weak aliases when performing local import (#152000)
Fixes crashes reported in #151255. The alias may have already been stored for later resolution, which can lead to treating a resolved alias as if it were still undefined. Instead, use the alias target directly for the import. Also extended the test to make reproducing the problem more likely, and added an assert that catches the issue.
1 parent 771d9ab commit 7223f67

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

lld/COFF/Driver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2714,8 +2714,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
27142714
}
27152715

27162716
ctx.symtab.initializeSameAddressThunks();
2717-
for (auto alias : aliases)
2717+
for (auto alias : aliases) {
2718+
assert(alias->kind() == Symbol::UndefinedKind);
27182719
alias->resolveWeakAlias();
2720+
}
27192721

27202722
if (config->mingw) {
27212723
// Make sure the crtend.o object is the last object file. This object

lld/COFF/SymbolTable.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -478,17 +478,11 @@ void SymbolTable::resolveRemainingUndefines(std::vector<Undefined *> &aliases) {
478478
if (name.starts_with("__imp_")) {
479479
auto findLocalSym = [&](StringRef n) {
480480
Symbol *sym = find(n);
481-
if (auto undef = dyn_cast_or_null<Undefined>(sym)) {
482-
// The unprefixed symbol might come later in symMap, so handle it now
483-
// if needed.
484-
if (!undef->resolveWeakAlias())
485-
sym = nullptr;
486-
}
487-
return sym;
481+
return sym ? sym->getDefined() : nullptr;
488482
};
489483

490484
StringRef impName = name.substr(strlen("__imp_"));
491-
Symbol *imp = findLocalSym(impName);
485+
Defined *imp = findLocalSym(impName);
492486
if (!imp && isEC()) {
493487
// Try to use the mangled symbol on ARM64EC.
494488
std::optional<std::string> mangledName =
@@ -502,11 +496,10 @@ void SymbolTable::resolveRemainingUndefines(std::vector<Undefined *> &aliases) {
502496
imp = findLocalSym(*mangledName);
503497
}
504498
}
505-
if (imp && isa<Defined>(imp)) {
506-
auto *d = cast<Defined>(imp);
507-
replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
499+
if (imp) {
500+
replaceSymbol<DefinedLocalImport>(sym, ctx, name, imp);
508501
localImportChunks.push_back(cast<DefinedLocalImport>(sym)->getChunk());
509-
localImports[sym] = d;
502+
localImports[sym] = imp;
510503
continue;
511504
}
512505
}

lld/test/COFF/import_weak_alias.test

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@
44
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/foo.s -o %t.foo.obj
55
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/qux.s -o %t.qux.obj
66
# RUN: lld-link %t.qux.obj %t.foo.obj -out:%t.dll -dll
7+
# RUN: lld-link %t.foo.obj %t.qux.obj -out:%t.dll -dll
78
#
89
#--- foo.s
910
.text
1011
bar:
1112
ret
1213

13-
.weak foo
14-
.set foo, bar
14+
.weak a
15+
.weak b
16+
.weak c
17+
.set a, bar
18+
.set b, bar
19+
.set c, bar
1520
#--- qux.s
1621
.text
1722
.global _DllMainCRTStartup
1823
_DllMainCRTStartup:
19-
call *__imp_foo(%rip)
24+
call *__imp_a(%rip)
25+
call *__imp_b(%rip)
26+
call *__imp_c(%rip)
2027
ret

0 commit comments

Comments
 (0)