diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 0c9a7e00682255692e123e1f2f48c6455e4f0362..28ba4baeb66a2129d30f0264a835aeec52bf4148 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1953,6 +1953,16 @@ template void SharedFileExtended::parseDynamics() { case SHT_GNU_verneed: verneedSec = &sec; break; + case SHT_RELR: + config->relrPackDynRelocs = true; + relrDynIdx = secIdx; + break; + case SHT_ANDROID_RELA: + config->androidPackDynRelocs = true; + andrPackDynIdx = secIdx; + break; + default: + break; } auto secName = check(this->getObj().getSectionName(sec)); if (secName == ".got.plt") diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 1db53c987f94ae0b383afa3affbd3fc491bd68ba..8b325af6fa965e1a04aae15d11d3e9616698e8c0 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -453,6 +453,10 @@ public: int eFirstGlobal = 0; int gotPltSecIdx = 0; + // related to config->relrPackDynRelocs and config->androidPackDynRelocs + int relrDynIdx = 0; + int andrPackDynIdx = 0; + // .symtab's start of local symbols owned by library llvm::Optional sharedLocalSymbolIndex; // .symtab's start of global symbols owned by library diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 936a4a2a4bb5bf0dfdce35482e9d1a04fc5f1959..27e350f10a9c530d7eb626a7e2f07ed38b523d61 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -442,6 +442,9 @@ public: } template void scan(ArrayRef rels); + // ADLT + uint32_t relSecType; + private: InputSectionBase &sec; OffsetGetter getter; @@ -468,6 +471,16 @@ private: template void tracePushRelocADLT(InputSectionBase &isec, Relocation &r) const; + + template + void trackGotPltADLT(Symbol *sym, SharedFileExtended *soFile); + template + void trackDynRelocADLT(SharedFileExtended *soFile); + + unsigned getDynamicRelocsCount(); + + bool isRELR() { return relSecType == SHT_RELR; } + bool isAndroidPack() { return relSecType == SHT_ANDROID_RELA; } }; } // namespace @@ -878,7 +891,7 @@ RelType RelocationScanner::getMipsN32RelType(RelTy *&rel) const { static void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym, int64_t addend, RelExpr expr, - RelType type) { + RelType type, bool fromRELR=false) { Partition &part = isec.getPartition(); // Add a relative relocation. If relrDyn section is enabled, and the @@ -888,7 +901,8 @@ static void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec, // don't store the addend values, so we must write it to the relocated // address. if (part.relrDyn && isec.alignment >= 2 && offsetInSec % 2 == 0) { - isec.relocations.push_back({expr, type, offsetInSec, addend, &sym}); + if (!fromRELR) + isec.relocations.push_back({expr, type, offsetInSec, addend, &sym}); part.relrDyn->relocs.push_back({&isec, offsetInSec}); return; } @@ -1304,22 +1318,23 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, return 0; } +// ADLT BEGIN template -static void trackDynRelocAdlt(SharedFileExtended *soFile) { - soFile->dynRelIndexes.insert(mainPart->relaDyn->relocs.size() - 1); +void RelocationScanner::trackGotPltADLT(Symbol *sym, + SharedFileExtended *soFile) { + ctx->gotPltInfoAdlt[sym].push_back(soFile->orderIdx); } template -static void trackGotPltAdlt(Symbol *sym, SharedFileExtended *soFile) { - ctx->gotPltInfoAdlt[sym].push_back(soFile->orderIdx); +void RelocationScanner::trackDynRelocADLT(SharedFileExtended *soFile) { + soFile->dynRelIndexes.insert(getDynamicRelocsCount() - 1); } -// ADLT BEGIN template void RelocationScanner::tracePushRelocADLT(InputSectionBase &isec, Relocation &r) const { - auto file = sec.getSharedFile(); auto fullOffset = isec.address + r.offset; + auto file = sec.getSharedFile(); lld::outs() << "[ADLT] Before push: [0x" + utohexstr(fullOffset) + "] type: " + toString(r.type) + " expr: " + std::to_string(r.expr) + " offset: 0x" + @@ -1333,6 +1348,12 @@ void RelocationScanner::tracePushRelocADLT(InputSectionBase &isec, lld::outs() << "\n"; } +unsigned RelocationScanner::getDynamicRelocsCount() { + auto currentSize = isRELR() ? mainPart->relrDyn->relocs.size() + : mainPart->relaDyn->relocs.size(); + return currentSize; +} + template void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, bool fromDynamic) { @@ -1365,21 +1386,22 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, r->sym = d; r->addend -= d->section->address + d->value; addRelativeReloc(*secWhere, r->offset, *r->sym, r->addend, r->expr, - r->type); - trackDynRelocAdlt(file); + r->type, isRELR()); + assert(getDynamicRelocsCount()); + trackDynRelocADLT(file); return; } case R_AARCH64_GLOB_DAT: assert(r->sym->exportDynamic); if (!r->sym->needsGot) r->sym->needsGot = 1; - trackGotPltAdlt(r->sym, file); + trackGotPltADLT(r->sym, file); return; case R_AARCH64_JUMP_SLOT: assert(r->sym->exportDynamic); if (r->sym->isUndefined() && !r->sym->needsPlt) r->sym->needsPlt = 1; - trackGotPltAdlt(r->sym, file); + trackGotPltADLT(r->sym, file); return; // abs relocs case R_AARCH64_ABS32: @@ -1391,7 +1413,7 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, sec.getPartition().relaDyn->addSymbolReloc(target.symbolicRel, *secWhere, r->offset, *r->sym, r->addend, r->type); - trackDynRelocAdlt(file); + trackDynRelocADLT(file); return; } sec.relocations.push_back(*r); @@ -1438,7 +1460,6 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, case R_AARCH64_TLSDESC: if (fromDynamic && !r->sym->needsTlsDesc) r->sym->needsTlsDesc = 1; - trackDynRelocAdlt(file); return; case R_AARCH64_TLSDESC_CALL: case R_AARCH64_TLS_TPREL64: @@ -1461,7 +1482,8 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, template void RelocationScanner::scanOne(RelTy *&i) { const RelTy &rel = *i; - uint32_t symIndex = rel.getSymbol(config->isMips64EL); + uint32_t symIndex = + (config->adlt && isRELR()) ? 0 : rel.getSymbol(config->isMips64EL); bool fromDynamic = false; if (config->adlt) fromDynamic = sec.getSharedFile()->isDynamicSection(sec); @@ -1498,7 +1520,9 @@ template void RelocationScanner::scanOne(RelTy *&i) { return; // Read an addend. - int64_t addend = computeAddend(rel, expr, sym.isLocal()); + int64_t addend = (config->adlt && isRELR()) + ? 0 + : computeAddend(rel, expr, sym.isLocal()); if (config->adlt) { Relocation r = {expr, type, offset, addend, &sym}; @@ -1716,10 +1740,27 @@ void RelocationScanner::scan(ArrayRef rels) { template void elf::scanRelocations(InputSectionBase &s) { RelocationScanner scanner(s); - if (config->adlt) { - bool isDebug = false; - if (isDebug) - lld::outs() << s.file->getName().str() + ": " + s.name.str() + '\n'; + if (config->adlt && s.type == SHT_NULL && + (config->relrPackDynRelocs || config->androidPackDynRelocs)) { + auto *soFile = cast>(s.file); + auto obj = soFile->getObj(); + auto shdrs = soFile->template getELFShdrs(); + if (soFile->relrDynIdx) { + auto shdr = shdrs[soFile->relrDynIdx]; + auto raw = cantFail(obj.relrs(shdr)); + auto decoded = obj.decode_relrs(raw); + auto ref = makeArrayRef(decoded); + scanner.relSecType = shdr.sh_type; + scanner.template scan(ref); + } + if (soFile->andrPackDynIdx) { + auto shdr = shdrs[soFile->andrPackDynIdx]; + auto decoded = cantFail(obj.android_relas(shdr)); + auto ref = makeArrayRef(decoded); + scanner.relSecType = shdr.sh_type; + scanner.template scan(ref); + } + return; } const RelsOrRelas rels = s.template relsOrRelas(); if (rels.areRelocsRel()) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7439ed63c6448f56c82972145328d064124cce6b..0130b2501d083f491aacb34702ed1f80c71ea64c 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1902,6 +1902,9 @@ static void removeUnusedSyntheticSections() { template static void adltTraceRelocationIndexes() { auto &relaDyn = mainPart->relaDyn; + auto &relrDyn = mainPart->relrDyn; + if (config->relrPackDynRelocs) + assert(!relrDyn->relocs.empty() && "ADLT: relrDyn can't be empty!"); assert(!relaDyn->relocs.empty() && "ADLT: relaDyn can't be empty!"); assert(!in.relaPlt->relocs.empty() && "ADLT: relaPlt can't be empty!"); @@ -2033,7 +2036,7 @@ template void Writer::finalizeSections() { for (auto &it : llvm::enumerate(ctx->sharedFilesExtended)) { auto *soFile = cast>(it.value()); auto sections = soFile->getSections(); - // scan .rela.dyn (base: SHT_NULL) + // scan .rela.dyn or/and .relr.dyn (base: SHT_NULL) scanRelocations(*sections[0]); // scan .rela.plt (base: .got.plt) scanRelocations(*sections[soFile->gotPltSecIdx]); @@ -2512,7 +2515,7 @@ SmallVector Writer::createPhdrs(Partition &part) { if (config->adlt) tlsHdr = addHdr(PT_TLS, PF_R); tlsHdr->add(sec); - } + } if (!config->adlt && tlsHdr->firstSec) ret.push_back(tlsHdr);