diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 65c51fd7d59bd21445065b33413516b9ddd372a1..e08eab19071596a7ce6b0e94a255f8ebe4a70c2f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1209,6 +1209,14 @@ template void ObjFile::postParse() { if (sym.binding == STB_WEAK || binding == STB_WEAK) continue; std::lock_guard lock(mu); + if (config->adlt) { + auto *f = cast>(this); + bool isDebug = false; + if (isDebug) { + lld::outs() << "Put to duplicates for: " << archiveName << "\n"; + f->traceSymbol(sym); + } + } ctx->duplicates.push_back({&sym, this, sec, eSym.st_value}); } } @@ -1674,7 +1682,8 @@ bool SharedFileExtended::addAdltPrefix(Symbol *s) { } template -Defined* SharedFileExtended::findSectionSymbol(uint64_t offset) { +Defined *SharedFileExtended::findSectionSymbol(uint64_t offset) const { + bool isDebug = false; auto predRange = [=](Symbol *sym) { if (!sym || sym->isUndefined() || !sym->isSection()) return false; @@ -1687,21 +1696,43 @@ Defined* SharedFileExtended::findSectionSymbol(uint64_t offset) { auto i = this->allSymbols.begin(); auto e = this->allSymbols.end(); auto ret = std::find_if(i, e, predRange); - if (ret != e) // item was found - return cast(*ret); + if (ret == e) // item was not found + return nullptr; - return nullptr; + auto d = cast(*ret); + if (isDebug) + traceSymbol(*d, "found section sym: "); + + return d; } 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); +Defined *SharedFileExtended::findDefinedSymbol( + uint64_t offset, llvm::function_ref extraCond) const { + bool isDebug = false; + SmallVector matches; + for (Symbol *sym : this->allSymbols) { + if (!sym || sym->isUndefined()) + continue; + + Defined *d = cast(sym); + if (d->file != this) + continue; + + bool goodVal = d->section->address + d->value == offset; + bool goodType = d->type == STT_FUNC || d->type == STT_OBJECT; + if (!(goodVal && goodType && extraCond(d))) + continue; + + if (isDebug) + traceSymbol(*sym, "found sym: "); + matches.push_back(d); + } + + if (!matches.empty()) + return matches[0]; // TODO: resolve multiple variants + + return findSectionSymbol(offset); } template @@ -1744,8 +1775,8 @@ void SharedFileExtended::traceSymbol(const Symbol& sym, StringRef title) c auto &d = cast(sym); lld::outs() << " val: 0x" << Twine::utohexstr(d.value) << " sec of sym: " << (d.section ? d.section->name : "unknown!") - << " sym type: 0x" << Twine::utohexstr(sym.type) - << " sym binding: 0x" << Twine::utohexstr(sym.binding) + << " sym type: 0x" << Twine::utohexstr(d.type) + << " sym binding: 0x" << Twine::utohexstr(d.binding) << '\n'; } @@ -1764,51 +1795,6 @@ Symbol& SharedFileExtended::getSymbol(uint32_t symbolIndex) const { return *this->symbols[symbolIndex]; } -template -Defined *SharedFileExtended::findSymbolByValue(uint32_t value) const { - bool isDebug = false; - auto predValues = [=](Symbol *sym) { - if (!sym || sym->isUndefined()) - return false; - const Defined *d = cast(sym); - bool goodVal = d->section->address + d->value == value; - bool goodFile = d->file == this; - bool isGood = goodVal && goodFile; - if (isDebug && isGood) - lld::outs() << "good\n"; - return isGood; - }; - - // filter by value for .dynsym, else for .symtab - SmallVector matches; - auto i = this->symbols.begin(); - auto e = this->symbols.end(); - std::copy_if(i, e, std::back_inserter(matches), predValues); - - if (matches.empty()) { - auto i = this->allSymbols.begin(); - auto e = this->allSymbols.end(); - std::copy_if(i, e, std::back_inserter(matches), predValues); - } - - if (matches.empty()) { - // warn("Symbol not found! Value: 0x" + Twine::utohexstr(value)); - return nullptr; - } - - // filter by type else return first item - i = matches.begin(); - e = matches.end(); - auto predTypes = [=](Symbol *sym) { - return sym->type == STT_FUNC || sym->type == STT_OBJECT; - }; - auto ret = std::find_if(i, e, predTypes); - if (ret != e) // item was found - return cast(*ret); - - // todo fix it - return cast(*i); -} template void SharedFileExtended::parseDynamics() { const ELFFile obj = this->getObj(); @@ -2327,4 +2313,4 @@ template void SharedFile::parse(); template class elf::SharedFileExtended; template class elf::SharedFileExtended; template class elf::SharedFileExtended; -template class elf::SharedFileExtended; \ No newline at end of file +template class elf::SharedFileExtended; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 58be116cf5d6d4dc9a4f560687780f7162d1e57b..5207ef34344cb8357e1866acfd5611c5b15abc85 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -402,8 +402,10 @@ public: StringRef addAdltPrefix(StringRef input); bool addAdltPrefix(Symbol *s); - Defined* findSectionSymbol(uint64_t offset); - Defined* findDefinedSymbol(uint64_t offset); + Defined *findSectionSymbol(uint64_t offset) const; + Defined *findDefinedSymbol( + uint64_t offset, llvm::function_ref extraCond = + [](Defined *) { return true; }) const; ArrayRef getLocalSymbols() override { if (this->allSymbols.empty()) @@ -412,7 +414,6 @@ public: } Symbol &getSymbol(uint32_t symbolIndex) const override; - Defined *findSymbolByValue(uint32_t value) const; Symbol &getSymbolFromElfSymTab(uint32_t symbolIndex) const { if (symbolIndex >= this->allSymbols.size()) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 0b6bc74bbec340876161c9887a5adb6f6ab9a213..278c4927bccffcbb7c3ace44aadf065ecaebe0ac 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1338,34 +1338,34 @@ template void RelocationScanner::scanOne(RelTy *&i) { StringRef title = "handle relative reloc: "; if (isDebug) lld::outs() << title << "offset: 0x" + Twine::utohexstr(offset) - << " addend: 0x" + Twine::utohexstr(addend) + "\n" ; + << " addend: 0x" + Twine::utohexstr(addend) + "\n"; // parse offset (where) - Defined *foundSymbol = file->findDefinedSymbol(offset); - if (!foundSymbol) - fatal(title + "sym not found! offset: 0x" + Twine::utohexstr(offset) + "\n"); - if (!foundSymbol->exportDynamic && !foundSymbol->isSection()) - file->addAdltPrefix(cast(foundSymbol)); - Defined &symWhere = *foundSymbol; - saveSymIfNeeded(symWhere); - offset = symWhere.isSection() ? (offset - symWhere.section->address) : 0; + const Defined *symWhere = file->findDefinedSymbol(offset); + if (!symWhere) + fatal(title + "symWhere not found! offset: 0x" + + Twine::utohexstr(offset) + "\n"); + auto iSec = cast(symWhere->section); + offset = + symWhere->isSection() ? (offset - symWhere->section->address) : 0; + saveSymIfNeeded(*symWhere); // parse addent (replacement) - 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; + Defined *inputSym = file->findDefinedSymbol( + addend, [](Defined *d) { return !d->isPreemptible; }); + + if (!inputSym) + fatal(title + "inputSym not found! addend: 0x" + + Twine::utohexstr(addend) + "\n"); + addend = + inputSym->isSection() ? (addend - inputSym->section->address) : 0; if (isDebug) - file->traceSymbol(inputSym, "handle relative reloc: inputSym: "); - if (!foundSymbol->exportDynamic) - file->addAdltPrefix(&inputSym); - saveSymIfNeeded(inputSym); - - // parse section from offset of relative reloc - addRelativeReloc(cast(*symWhere.section), - symWhere.value, inputSym, addend, expr, type); + file->traceSymbol(*inputSym, "handle relative reloc: inputSym: "); + saveSymIfNeeded(*inputSym); + + // finally + addRelativeReloc(*iSec, symWhere->value, *inputSym, addend, expr, type); }; switch (type) { case R_AARCH64_RELATIVE: @@ -1455,6 +1455,7 @@ template void RelocationScanner::scanOne(RelTy *&i) { case R_AARCH64_ADD_ABS_LO12_NC: case R_AARCH64_ADR_PREL_PG_HI21: case R_AARCH64_LDST8_ABS_LO12_NC: + case R_AARCH64_LDST16_ABS_LO12_NC: case R_AARCH64_LDST32_ABS_LO12_NC: case R_AARCH64_LDST64_ABS_LO12_NC: case R_AARCH64_LDST128_ABS_LO12_NC: @@ -1473,6 +1474,15 @@ template void RelocationScanner::scanOne(RelTy *&i) { // got relocs case R_AARCH64_ADR_GOT_PAGE: + if (isSymDefined && !s->needsGot) { + if (isDebug) { + lld::outs() << "[ADLT] R_AARCH64_ADR_GOT_PAGE: sym not in GOT! "; + file->traceSymbol(*s); + } + expr = R_PC; // prev: R_AARCH64_GOT_PAGE_PC || R_AARCH64_GOT_PAGE || + // R_GOT || R_GOT_PC + } + LLVM_FALLTHROUGH; case R_AARCH64_LD64_GOT_LO12_NC: pushReloc(); return;