diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index ef9e1cfc030d121a58dee162a52527e8aa3841aa..65c51fd7d59bd21445065b33413516b9ddd372a1 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1693,6 +1693,17 @@ Defined* SharedFileExtended::findSectionSymbol(uint64_t offset) { return nullptr; } +template +Defined* SharedFileExtended::findDefinedSymbol(uint64_t offset) { + Defined *foundSymbol = findSymbolByValue(offset); + if (foundSymbol) + return foundSymbol; + Defined *d = findSectionSymbol(offset); + if (d) + return d; + return static_cast(nullptr); +} + template StringRef SharedFileExtended::getShStrTab(ArrayRef elfSections) { return CHECK(this->getObj().getSectionStringTable(elfSections), this); @@ -1724,8 +1735,8 @@ void SharedFileExtended::traceElfSection(const Elf_Shdr &sec) const { } template -void SharedFileExtended::traceSymbol(const Symbol& sym) const { - lld::outs() << "File: " << soName << " symName: " << sym.getName(); +void SharedFileExtended::traceSymbol(const Symbol& sym, StringRef title) const { + lld::outs() << "File: " << soName << ": " + title << " symName: " << sym.getName(); if (!sym.isDefined()) { lld::outs() << '\n'; return; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 6712c4841d65729129ab86a7c49cdd26ff487bfd..58be116cf5d6d4dc9a4f560687780f7162d1e57b 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -403,6 +403,7 @@ public: bool addAdltPrefix(Symbol *s); Defined* findSectionSymbol(uint64_t offset); + Defined* findDefinedSymbol(uint64_t offset); ArrayRef getLocalSymbols() override { if (this->allSymbols.empty()) @@ -422,7 +423,7 @@ public: void traceElfSymbol(const Elf_Sym &sym, StringRef strTable) const; void traceElfSection(const Elf_Shdr &sec) const; - void traceSymbol(const Symbol& sym) const; + void traceSymbol(const Symbol& sym, StringRef title = "") const; void traceSection(const SectionBase& sec) const; int dynSymSecIdx = 0; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index a0ef192d6711f7d876ec524ec1bbe13191a42470..0b6bc74bbec340876161c9887a5adb6f6ab9a213 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1325,7 +1325,7 @@ template void RelocationScanner::scanOne(RelTy *&i) { auto file = sec.getSharedFile(); bool isDebug = false; - auto saveSymIfNeeded = [](const Defined& d) { + auto saveSymIfNeeded = [&](const Defined& d) { auto found = elf::symtab->find(d.getName()); if (!found) in.symTab->addSymbol(elf::symtab->addSymbol(d)); @@ -1341,31 +1341,24 @@ template void RelocationScanner::scanOne(RelTy *&i) { << " addend: 0x" + Twine::utohexstr(addend) + "\n" ; // parse offset (where) - Defined *foundSymbol = file->findSymbolByValue(offset); - if (!foundSymbol) { + Defined *foundSymbol = file->findDefinedSymbol(offset); + if (!foundSymbol) fatal(title + "sym not found! offset: 0x" + Twine::utohexstr(offset) + "\n"); - return; - } - if (!foundSymbol->exportDynamic) + if (!foundSymbol->exportDynamic && !foundSymbol->isSection()) file->addAdltPrefix(cast(foundSymbol)); Defined &symWhere = *foundSymbol; saveSymIfNeeded(symWhere); + offset = symWhere.isSection() ? (offset - symWhere.section->address) : 0; // parse addent (replacement) - foundSymbol = file->findSymbolByValue(addend); - if (!foundSymbol) { - Defined *d = file->findSectionSymbol(addend); - if (!d) - fatal(title + "sym not found! addend: 0x" + Twine::utohexstr(addend) + "\n"); - foundSymbol = d; - } + foundSymbol = file->findDefinedSymbol(addend); + if (!foundSymbol) + fatal(title + "sym not found! addend: 0x" + Twine::utohexstr(addend) + "\n"); Defined &inputSym = *foundSymbol; addend = inputSym.isSection() ? (addend - inputSym.section->address) : 0; - if (isDebug) { - lld::outs() << "handle relative reloc: inputSym: "; - file->traceSymbol(inputSym); - } + if (isDebug) + file->traceSymbol(inputSym, "handle relative reloc: inputSym: "); if (!foundSymbol->exportDynamic) file->addAdltPrefix(&inputSym); saveSymIfNeeded(inputSym); @@ -1453,6 +1446,8 @@ template void RelocationScanner::scanOne(RelTy *&i) { sec.relocations.push_back({expr, type, offset, addend, s}); }; + bool isSymDefined = s && s->isDefined(); + switch (type) { // abs relocs case R_AARCH64_ABS32: @@ -1470,7 +1465,7 @@ template void RelocationScanner::scanOne(RelTy *&i) { // plt relocs case R_AARCH64_CALL26: case R_AARCH64_JUMP26: { - if (s && s->isDefined()) + if (isSymDefined) expr = R_PC; // prev: R_PLT_PC pushReloc(); return;