[PATCH] D95985: [ELF] Resolve defined symbols before undefined symbols
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 3 17:56:40 PST 2021
MaskRay updated this revision to Diff 321280.
MaskRay edited the summary of this revision.
MaskRay added a comment.
Herald added a subscriber: wenlei.
Add test
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D95985/new/
https://reviews.llvm.org/D95985
Files:
lld/ELF/InputFiles.cpp
lld/test/ELF/interconnected-lazy.s
Index: lld/test/ELF/interconnected-lazy.s
===================================================================
--- /dev/null
+++ lld/test/ELF/interconnected-lazy.s
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/main.s -o %t/main.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/b.s -o %t/b.o
+
+## foo and __foo are interconnected and defined in two lazy object files.
+## Test we resolve both to the same file.
+# RUN: ld.lld -y a -y foo -y __foo %t/main.o --start-lib %t/a.o %t/b.o --end-lib -o /dev/null | FileCheck %s
+
+# CHECK: a.o: lazy definition of __foo
+# CHECK-NEXT: a.o: lazy definition of a
+# CHECK-NEXT: a.o: lazy definition of foo
+# CHECK-NEXT: b.o: definition of __foo
+# CHECK-NEXT: b.o: definition of foo
+# CHECK-NEXT: b.o: reference to a
+# CHECK-NEXT: a.o: definition of a
+
+#--- main.s
+.globl _start
+_start:
+ call b
+
+#--- a.s
+.globl a
+.weak foo
+a:
+foo:
+
+.weak __foo
+__foo:
+
+#--- b.s
+.globl b
+.weak foo
+b:
+ call a
+foo:
+
+.weak __foo
+__foo:
Index: lld/ELF/InputFiles.cpp
===================================================================
--- lld/ELF/InputFiles.cpp
+++ lld/ELF/InputFiles.cpp
@@ -1134,6 +1134,7 @@
}
// Symbol resolution of non-local symbols.
+ SmallVector<size_t, 8> unds;
for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
const Elf_Sym &eSym = eSyms[i];
uint8_t binding = eSym.getBinding();
@@ -1150,8 +1151,7 @@
// Handle global undefined symbols.
if (eSym.st_shndx == SHN_UNDEF) {
- this->symbols[i]->resolve(Undefined{this, name, binding, stOther, type});
- this->symbols[i]->referenced = true;
+ unds.push_back(i);
continue;
}
@@ -1198,6 +1198,18 @@
fatal(toString(this) + ": unexpected binding: " + Twine((int)binding));
}
+
+ // Undefined symbols (not those defined relative to non-prevailing sections)
+ // can trigger recursive fetch. Process defined symbols first so that a set of
+ // interconnected symbols will all be resolved to same file, instead of being
+ // resolved to different files.
+ for (size_t i : unds) {
+ const Elf_Sym &eSym = eSyms[i];
+ StringRefZ name = this->stringTable.data() + eSym.st_name;
+ this->symbols[i]->resolve(Undefined{this, name, eSym.getBinding(),
+ eSym.st_other, eSym.getType()});
+ this->symbols[i]->referenced = true;
+ }
}
ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&file)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95985.321280.patch
Type: text/x-patch
Size: 2577 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210204/49978468/attachment.bin>
More information about the llvm-commits
mailing list