[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 15:50:12 PST 2021
MaskRay created this revision.
Herald added subscribers: arichardson, emaste.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
If both `a.a(a.o)` and `a.a(b.o)` define foo (in COMDAT group `foo`) and `__profd_foo` (in COMDAT group `__profd_foo`).
LLD may select `foo` from `a.a(a.o)` as the prevailing definition while `__profd_foo` from `b.a(b.o)` as the prevailing definition.
parse ArchiveFile a.a
entry fetches a.a(a.o)
parse ObjectFile a.o
define entry
define foo
reference b
b fetches a.a(b.o)
parse ObjectFile b.o
define prevailing __profd_foo
define non-prevailing __profd_foo
This can happen with interconnected weak symbols not-in COMDAT groups as well.
Assuming a set of interconnected symbols are defined all or none, in several lazy objects.
Arguably making them resolve to the same lazy object is preferable than making them come from different lazy objects.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95985
Files:
lld/ELF/InputFiles.cpp
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,15 @@
fatal(toString(this) + ": unexpected binding: " + Twine((int)binding));
}
+
+ for (size_t i : unds) {
+ const Elf_Sym &eSym = eSyms[i];
+ uint8_t binding = eSym.getBinding();
+ 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.321250.patch
Type: text/x-patch
Size: 1224 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210203/93bca126/attachment.bin>
More information about the llvm-commits
mailing list