diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 5a0c9963d5a654c9cc43f9a22db2c4c636dc1c80..810ff3f5d9d9854c2e505c2aee7217c46119f5ee 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -87,6 +87,10 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, case R_AARCH64_JUMP_SLOT: case R_AARCH64_RELATIVE: return R_ABS; + case R_AARCH64_TLSDESC: + return R_TLSDESC; + case R_AARCH64_TLS_TPREL64: + return R_TPREL; default: break; } @@ -382,15 +386,7 @@ void AArch64::deRelocate(uint8_t *loc, const Relocation &rel, switch (rel.type) { case R_AARCH64_JUMP26: - case R_AARCH64_CALL26: { - /*if (*val & (1UL << 32)) { - if (isDebug) - debugMessage("found 32 bit turned on! Disabling"); - *val = *val & ~(1UL << 32); - }*/ - orClear32le(); - break; - } + case R_AARCH64_CALL26: case R_AARCH64_CONDBR19: case R_AARCH64_LD_PREL_LO19: case R_AARCH64_MOVW_UABS_G0_NC: @@ -407,10 +403,7 @@ void AArch64::deRelocate(uint8_t *loc, const Relocation &rel, case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: case R_AARCH64_LDST32_ABS_LO12_NC: case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: - case R_AARCH64_LDST64_ABS_LO12_NC: { - orClearAArch64Imm(); - break; - } + case R_AARCH64_LDST64_ABS_LO12_NC: case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index a30bf61d36c635f6fe8decab14743674dc771988..25d5fe886bd5406bc1276c2fed3a6b53cde5ca0e 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1076,7 +1076,8 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { fatal("getSection failed: " + llvm::toString(p.takeError())); } const Elf_Shdr *eSec = *p; - value -= eSec->sh_addr; + if (type != STT_TLS) + value -= eSec->sh_addr; } uint64_t size = eSym.st_size; @@ -1715,6 +1716,8 @@ bool SharedFileExtended::saveSymbol(const Defined& d) const { template Defined *SharedFileExtended::findSectionSymbol(uint64_t offset) const { bool isDebug = false; + /*if (offset == 0x7738) // debug hint + isDebug = true;*/ auto predRange = [=](Symbol *sym) { if (!sym || sym->isUndefined() || !sym->isSection()) return false; @@ -1724,16 +1727,14 @@ Defined *SharedFileExtended::findSectionSymbol(uint64_t offset) const { if (isDebug) lld::outs() << "offset: 0x" + utohexstr(offset) + - "sect name: " + d->section->name + "low 0x" + + " sect name: " + d->section->name + "low 0x" + utohexstr(low) + " high: 0x" + - utohexstr(offset) + "\n"; + utohexstr(high) + "\n"; return (offset >= low) && (offset < high); }; auto i = this->allSymbols.begin(); auto e = this->allSymbols.end(); - /*if (offset == 0x4a18) // debug hint - isDebug = true; */ auto ret = std::find_if(i, e, predRange); if (ret == e) // item was not found return nullptr; @@ -1768,6 +1769,8 @@ Defined *SharedFileExtended::findDefinedSymbol( uint64_t offset, StringRef fatalTitle, llvm::function_ref extraCond) const { bool isDebug = false; + /*if (offset == 0x7738) // debug hint + isDebug = true;*/ auto predRange = [=](Symbol *sym) { if (!sym || sym->isUndefined()) return false; @@ -1782,8 +1785,6 @@ Defined *SharedFileExtended::findDefinedSymbol( auto i = this->allSymbols.begin(); auto e = this->allSymbols.end(); - /*if (offset == 0x4a18) // debug hint - isDebug = true; */ auto ret = std::find_if(i, e, predRange); if (ret != e) { // item was found Defined *d = cast(*ret); @@ -2090,13 +2091,17 @@ template void SharedFileExtended::parseElfSymTab() { } const Elf_Shdr *eSec = *p; InputSectionBase *sec = this->sections[secIdx]; - auto val = eSym.st_value - eSec->sh_addr; + auto val = eSym.st_value; + if (type != STT_TLS) + val -= eSec->sh_addr; auto dynSym = llvm::find_if(this->symbols, [=](const Symbol *s) { return s && s->getName() == name; }); bool isInDynSym = dynSym != this->symbols.end(); if (!isInDynSym) name = addAdltPostfix(name); + /*if (name == "TLS_data1") // debug hint + lld::outs() << name << '\n'; */ this->allSymbols[i] = make(this, name, bind, other, type, val, eSym.st_size, sec); } else { diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index a025cb2bc0fcb7716a608737bf170d8023b560ee..7357297af5b09cec846de7cd0d86b9067980e31a 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -1000,6 +1000,8 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) { if (auto *sec = dyn_cast(this)) secAddr += sec->outSecOff; const uint64_t addrLoc = secAddr + offset; + /*if (config->adlt && addrLoc == 68600) // debug hint + lld::outs() << "addrLoc 0x" << utohexstr(addrLoc) << "\n";*/ const uint64_t targetVA = SignExtend64(getRelocTargetVA(file, rel.type, rel.addend, addrLoc, *rel.sym, rel.expr), diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 3218b5a1272ed8ac24fc11a84773837029ee98ec..ead89a3f74bcfee9d194fcbfe7eaa64c013159ab 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -111,6 +111,11 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v, hint += "; consider recompiling with -fdebug-types-section to reduce size " "of debug sections"; + if (config->adlt) { + auto offset = errPlace.isec->address + rel.offset; // debug hint: put bkpt here + hint += " [ADLT] Offset: 0x" + utohexstr(offset) + "\n"; + } + errorOrWarn(errPlace.loc + "relocation " + lld::toString(rel.type) + " out of range: " + v.str() + " is not in [" + Twine(min).str() + ", " + Twine(max).str() + "]" + hint); @@ -461,13 +466,8 @@ private: template void processForADLT(const RelTy &rel, Relocation *r, bool fromDynamic); - template - void addRelativeRelocForAdlt(const RelTy &rel, Defined &symWhere, - uint64_t offset, Defined &inputSym) const; - void pushRelocAdlt(Relocation *r) const; - template - void tracePushRelocADLT(Defined &symWhere, Relocation &r) const; + void tracePushRelocADLT(InputSectionBase &isec, Relocation &r) const; }; } // namespace @@ -1305,41 +1305,18 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, } // ADLT BEGIN -template -void RelocationScanner::addRelativeRelocForAdlt(const RelTy &rel, - Defined &symWhere, - uint64_t offset, - Defined &inputSym) const { - // auto file = sec.getSharedFile(); - std::string title = "addRelativeRelocForAdlt: "; - std::string failTitle = ""; - - RelType type = R_AARCH64_ABS64; - RelExpr expr = R_ABS; - int64_t addend = computeAddend(rel, expr, false); - addend -= inputSym.section->address + inputSym.value; - - // finally - addRelativeReloc(*cast(symWhere.section), offset, - inputSym, addend, expr, type); -} - -void RelocationScanner::pushRelocAdlt(Relocation *r) const { - sec.relocations.push_back(*r); -} - template -void RelocationScanner::tracePushRelocADLT(Defined &symWhere, +void RelocationScanner::tracePushRelocADLT(InputSectionBase &isec, Relocation &r) const { auto file = sec.getSharedFile(); - auto fullOffset = symWhere.section->address + r.offset; - lld::outs() << "[ADLT] Before push: [" + utohexstr(fullOffset) + + auto fullOffset = isec.address + r.offset; + lld::outs() << "[ADLT] Before push: [0x" + utohexstr(fullOffset) + "] type: " + toString(r.type) + - " expr: " + toString(r.expr) + " offset: 0x" + + " expr: " + std::to_string(r.expr) + " offset: 0x" + utohexstr(r.offset) + " addend: 0x" + utohexstr(r.addend) + ".\n"; - lld::outs() << "symWhere: "; - file->traceSymbol(symWhere); + lld::outs() << "section where: "; + file->traceSection(isec); lld::outs() << "r->sym: "; file->traceSymbol(*r.sym); @@ -1355,33 +1332,39 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, "processForADLT: symIndex: " + std::to_string(symIndex) + " "; bool isDebug = false; - /*if (r->offset == 0x296) // debug hint + /*if (r->offset == 0x21F) // debug hint isDebug = true; - if (r->sym->getName() == "__emutls_t.TLS_data1") + /*if (r->type == R_AARCH64_ABS64 && + r->sym->getName() == "__emutls_t.TLS_data1") isDebug = true;*/ - // parse offset (where) std::string failTitle = title + "symWhere not found! offset: "; - Defined *symWhere = file->findDefinedSymbol(r->offset, failTitle); - file->saveSymbol(*symWhere); + InputSectionBase *secWhere = cast( + fromDynamic + ? file->findDefinedSymbol(r->offset, failTitle)->section + : (r->sym->isDefined() ? cast(r->sym)->section : &sec)); // process offset - r->offset -= fromDynamic ? symWhere->section->address : sec.address; + r->offset -= fromDynamic ? secWhere->address : sec.address; + assert(r->type); if (isDebug) - tracePushRelocADLT(*symWhere, *r); + tracePushRelocADLT(*secWhere, *r); // resolve relocs switch (r->type) { // dyn relocs - case R_AARCH64_RELATIVE: + case R_AARCH64_RELATIVE: { failTitle = title + " " + toString(r->type) + ": r->sym not found! addend: "; - if (auto *d = file->findDefinedSymbol( - r->addend, failTitle, [](Defined *d) { return !d->isPreemptible; })) - addRelativeRelocForAdlt(rel, *symWhere, r->offset, *d); + Defined *d = file->findDefinedSymbol(r->addend, failTitle); + assert(d); + r->addend -= d->section->address + d->value; + addRelativeReloc(*secWhere, r->offset, *d, r->addend, r->expr, + r->type); return; + } case R_AARCH64_GLOB_DAT: assert(r->sym->exportDynamic); r->sym->needsGot = 1; @@ -1395,15 +1378,18 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, return; // abs relocs case R_AARCH64_ABS32: + sec.relocations.push_back(*r); + return; case R_AARCH64_ABS64: if (fromDynamic) { assert(r->sym->exportDynamic); - sec.getPartition().relaDyn->addSymbolReloc( - target.symbolicRel, cast(*symWhere->section), - r->offset, *r->sym, r->addend, r->type); + sec.getPartition().relaDyn->addSymbolReloc(target.symbolicRel, *secWhere, + r->offset, *r->sym, r->addend, + r->type); return; } - LLVM_FALLTHROUGH; + sec.relocations.push_back(*r); + return; case R_AARCH64_ADD_ABS_LO12_NC: case R_AARCH64_ADR_PREL_PG_HI21: case R_AARCH64_LDST8_ABS_LO12_NC: @@ -1413,14 +1399,14 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, case R_AARCH64_LDST128_ABS_LO12_NC: case R_AARCH64_PREL32: case R_AARCH64_PREL64: - pushRelocAdlt(r); + processAux(r->expr, r->type, r->offset, *r->sym, r->addend); return; // plt relocs case R_AARCH64_CALL26: case R_AARCH64_JUMP26: if (r->sym->isDefined()) r->expr = R_PC; // prev: R_PLT_PC - pushRelocAdlt(r); + sec.relocations.push_back(*r); return; // got relocs case R_AARCH64_ADR_GOT_PAGE: @@ -1432,10 +1418,23 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, } LLVM_FALLTHROUGH; case R_AARCH64_LD64_GOT_LO12_NC: - pushRelocAdlt(r); + processAux(r->expr, r->type, r->offset, *r->sym, r->addend); + return; + // tls relocs + case R_AARCH64_TLSDESC: + case R_AARCH64_TLSDESC_CALL: + case R_AARCH64_TLS_TPREL64: + case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: + case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: + case R_AARCH64_TLSDESC_ADR_PAGE21: + case R_AARCH64_TLSDESC_LD64_LO12: + case R_AARCH64_TLSDESC_ADD_LO12: + case R_AARCH64_TLSLE_ADD_TPREL_HI12: + case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + handleTlsRelocation(r->type, *r->sym, sec, r->offset, r->addend, r->expr); return; default: - fatal("Unhandled " + toString(fromDynamic ? "dynamic" : "") + + fatal("[ADLT] Unhandled " + toString(fromDynamic ? "dynamic " : "") + "reloc: " + toString(r->type)); break; }