diff --git a/lld/ELF/Adlt.cpp b/lld/ELF/Adlt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b3d8f4f56e797c0de62b39ddb1d5cb9591330218 --- /dev/null +++ b/lld/ELF/Adlt.cpp @@ -0,0 +1,65 @@ +//===- Adlt.cpp -------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// OHOS_LOCAL begin +#include "Adlt.h" +#include "llvm/Support/Casting.h" + +#include "InputFiles.h" + +using namespace llvm; + +using namespace lld; +using namespace lld::elf; +using namespace llvm::object; + +template +SharedFileExtended *AdltCtx::getSoExt(InputFile *file) { + assert(file); + return cast>(file); +} + +template +SharedFileExtended *AdltCtx::getSoExt(size_t orderId) { + assert(orderId < sharedFilesExtended.size()); + return cast>(sharedFilesExtended[orderId]); +} + +template +void AdltCtx::buildSymbolsHist(std::vector &files) { + for (auto *file : files) + if (auto *soExt = getSoExt(file)) + soExt->buildSymbolsHist(); + assert(!symNamesHist.empty()); +} + +void AdltCtx::scanDuplicatedSymbols() { + assert(!symNamesHist.empty()); + for (auto entry : symNamesHist) + if (entry.second > 1) + duplicatedSymNames.insert(CachedHashStringRef(entry.first)); + symNamesHist.clear(); +} + +// TODO: inherit from SharedFile +template SharedFileExtended *AdltCtx::getSoExt(InputFile *); +template SharedFileExtended *AdltCtx::getSoExt(InputFile *); +template SharedFileExtended *AdltCtx::getSoExt(InputFile *); +template SharedFileExtended *AdltCtx::getSoExt(InputFile *); + +template SharedFileExtended *AdltCtx::getSoExt(size_t); +template SharedFileExtended *AdltCtx::getSoExt(size_t); +template SharedFileExtended *AdltCtx::getSoExt(size_t); +template SharedFileExtended *AdltCtx::getSoExt(size_t); + +template void AdltCtx::buildSymbolsHist(std::vector &); +template void AdltCtx::buildSymbolsHist(std::vector &); +template void AdltCtx::buildSymbolsHist(std::vector &); +template void AdltCtx::buildSymbolsHist(std::vector &); + +// OHOS_LOCAL end diff --git a/lld/ELF/Adlt.h b/lld/ELF/Adlt.h new file mode 100644 index 0000000000000000000000000000000000000000..b6751cf54607edaea0a222f7e3386cff7cfc8487 --- /dev/null +++ b/lld/ELF/Adlt.h @@ -0,0 +1,62 @@ +//===- Adlt.h -------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// OHOS_LOCAL begin +#ifndef LLD_ELF_ADLT_H +#define LLD_ELF_ADLT_H + +#include "llvm/ADT/CachedHashString.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Support/Endian.h" +#include + +namespace lld { +namespace elf { + +class ELFFileBase; +class InputFile; +class Symbol; +struct PhdrEntry; + +template class SharedFileExtended; +struct PhdrEntry; + +class AdltCtx { +public: + llvm::SmallVector sharedFilesExtended; + + void scanDuplicatedSymbols(); + + template void buildSymbolsHist(std::vector &files); + + template SharedFileExtended *getSoExt(InputFile *file); + template SharedFileExtended *getSoExt(size_t orderId); + + llvm::SetVector commonProgramHeaders; + + bool withCfi = false; + + // From input .rela.dyn, .rela.plt: + // Keep input library indexes that are needed for got/plt symbol + llvm::DenseMap> + gotPltInfo; // sym, soFile->orderIdx array; + + llvm::DenseMap + symNamesHist; // hash, count usages + llvm::DenseSet duplicatedSymNames; +}; + +// The only instance of Ctx struct. +extern std::unique_ptr adltCtx; + +} // namespace elf +} // namespace lld + +#endif // LLD_ELF_ADLT_H +// OHOS_LOCAL end diff --git a/lld/ELF/CMakeLists.txt b/lld/ELF/CMakeLists.txt index b37035d3e7429af6784134bafd32ad83b7530ff5..de8b3bf51d5870e7507e7f5836b38bdabf86f57a 100644 --- a/lld/ELF/CMakeLists.txt +++ b/lld/ELF/CMakeLists.txt @@ -45,6 +45,7 @@ add_lld_library(lldELF Target.cpp Thunks.cpp Writer.cpp + Adlt.cpp LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 0d220c6afdf32fec06fe397395b55ac379f288b0..2eaee71cca74f71662b3a58e2f75b1efb3157919 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -34,8 +34,6 @@ class BinaryFile; class BitcodeFile; class ELFFileBase; class SharedFile; -template class SharedFileExtended; -struct PhdrEntry; // OHOS_LOCAL class InputSectionBase; class Symbol; @@ -388,9 +386,8 @@ struct DuplicateSymbol { struct Ctx { SmallVector> memoryBuffers; - SmallVector objectFiles; + SmallVector objectFiles; SmallVector sharedFiles; - SmallVector sharedFilesExtended; SmallVector binaryFiles; SmallVector bitcodeFiles; SmallVector lazyBitcodeFiles; @@ -409,23 +406,6 @@ struct Ctx { llvm::DenseMap> backwardReferences; - - // OHOS_LOCAL begin - struct AdltCtx { - template SharedFileExtended *getSoExt(InputFile *file) { - return cast>(file); - } - - llvm::SetVector commonProgramHeaders; - bool withCfi = false; - // From input .rela.dyn, .rela.plt: - // Keep input library indexes that are needed for got/plt symbol - llvm::DenseMap> - gotPltInfo; // sym, soFile->orderIdx array; - // Store duplicate symbols (only defined). - llvm::DenseSet duplicatedSymNames; - } adlt; - // OHOS_LOCAL end }; // The only instance of Ctx struct. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index a4ee33280065e9912b777d51a5368dc4f84d90e7..88ef20d590141ee1c13be40cf14865f1a826fdbb 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -24,6 +24,7 @@ #include "Driver.h" #include "Config.h" +#include "Adlt.h" #include "ICF.h" #include "InputFiles.h" #include "InputSection.h" @@ -76,6 +77,7 @@ using namespace lld::elf; std::unique_ptr elf::config; std::unique_ptr elf::ctx; +std::unique_ptr elf::adltCtx; // OHOS_LOCAL std::unique_ptr elf::driver; static void setConfigs(opt::InputArgList &args); @@ -849,7 +851,7 @@ static std::pair getPackDynRelocs(opt::InputArgList &args) { static void readCallGraph(MemoryBufferRef mb) { // Build a map from symbol name to section DenseMap map; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) for (Symbol *sym : file->getSymbols()) map[sym->getName()] = sym; @@ -1828,7 +1830,7 @@ static void excludeLibs(opt::InputArgList &args) { sym->versionId = VER_NDX_LOCAL; }; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) visit(file); @@ -2025,7 +2027,7 @@ static void writeDependencyFile() { // symbols of type CommonSymbol. static void replaceCommonSymbols() { llvm::TimeTraceScope timeScope("Replace common symbols"); - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) { if (!file->hasCommonSyms) continue; @@ -2102,7 +2104,7 @@ static void findKeepUniqueSections(opt::InputArgList &args) { // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (InputFile *f : files) { auto *obj = cast>(f); ArrayRef syms = obj->getSymbols(); @@ -2357,7 +2359,7 @@ static void redirectSymbols(ArrayRef wrapped) { return; // Update pointers in input files. - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; parallelForEach(files, [&](ELFFileBase *file) { for (Symbol *&sym : file->getMutableGlobalSymbols()) if (Symbol *s = map.lookup(sym)) @@ -2393,7 +2395,7 @@ static uint32_t getAndFeatures() { return 0; uint32_t ret = -1; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *f : files) { uint32_t features = f->andFeatures; @@ -2477,46 +2479,25 @@ static void postParseObjectFile(ELFFileBase *file) { } } -static void postParseSharedFileForAdlt(ELFFileBase *file) { +static void postParseSharedFile(ELFFileBase *file) { switch (config->ekind) { case ELF32LEKind: - cast>(file)->postParseForAdlt(); + adltCtx->getSoExt(file)->postParse(); break; case ELF32BEKind: - cast>(file)->postParseForAdlt(); + adltCtx->getSoExt(file)->postParse(); break; case ELF64LEKind: - cast>(file)->postParseForAdlt(); + adltCtx->getSoExt(file)->postParse(); break; case ELF64BEKind: - cast>(file)->postParseForAdlt(); + adltCtx->getSoExt(file)->postParse(); break; default: llvm_unreachable(""); } } -static bool isSectionValidForAdlt(int fileIdx, InputSectionBase *s) { - if (!s || s == &InputSection::discarded) - return false; - uint32_t type = s->type; - StringRef name = s->name; - - bool isBaseType = type == SHT_NOBITS || type == SHT_NOTE || - type == SHT_INIT_ARRAY || type == SHT_FINI_ARRAY; - // TODO: fix .debug_info relocation - bool isNeededProgBits = - type == SHT_PROGBITS && - !(name.startswith(".got.plt") || name.startswith(".plt") || name.startswith(".got") || - name.startswith(".eh_frame_hdr"));// || name.startswith(".debug_")); - bool ret = isBaseType || isNeededProgBits; - - bool isDebug = false; - if (ret && isDebug) - lld::outs() << "[isSectionValidForAdlt]: " << name << "\n"; - return ret; -} - // Do actual linking. Note that when this function is called, // all linker scripts have already been parsed. void LinkerDriver::link(opt::InputArgList &args) { @@ -2563,6 +2544,9 @@ void LinkerDriver::link(opt::InputArgList &args) { for (auto *arg : args.filtered(OPT_trace_symbol)) symtab->insert(arg->getValue())->traced = true; + if (config->adlt) // Init ADLT context + elf::adltCtx = std::make_unique(); + // Handle -u/--undefined before input files. If both a.a and b.so define foo, // -u foo a.a b.so will extract a.a. for (StringRef name : config->undefined) @@ -2570,13 +2554,8 @@ void LinkerDriver::link(opt::InputArgList &args) { // Fill duplicatedSymNames for defined syms. This will help to find duplicates. if (config->adlt) { - ESymsCntMap eSymsHist; - for (auto *file : files) - buildSymsHist(file, eSymsHist); - for (auto eSym : eSymsHist) - if (eSym.second > 1) - ctx->adlt.duplicatedSymNames.insert(eSym.first); - eSymsHist.clear(); + invokeELFT(adltCtx->buildSymbolsHist, files); + adltCtx->scanDuplicatedSymbols(); } // Add all files to the symbol table. This will add almost all @@ -2597,7 +2576,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // producing a shared library. // We also need one if any shared libraries are used and for pie executables // (probably because the dynamic linker needs it). - config->hasDynSymTab = (config->adlt ? !ctx->sharedFilesExtended.empty() + config->hasDynSymTab = (config->adlt ? !adltCtx->sharedFilesExtended.empty() : !ctx->sharedFiles.empty()) || config->isPic || config->exportDynamic; @@ -2655,7 +2634,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // No more lazy bitcode can be extracted at this point. Do post parse work // like checking duplicate symbols. if (config->adlt) - parallelForEach(ctx->sharedFilesExtended, postParseSharedFileForAdlt); + parallelForEach(adltCtx->sharedFilesExtended, postParseSharedFile); parallelForEach(ctx->objectFiles, initializeLocalSymbols); parallelForEach(ctx->objectFiles, postParseObjectFile); @@ -2724,7 +2703,6 @@ void LinkerDriver::link(opt::InputArgList &args) { // With this the symbol table should be complete. After this, no new names // except a few linker-synthesized ones will be added to the symbol table. const size_t numObjsBeforeLTO = ctx->objectFiles.size(); - const size_t numSoBeforeLTO = ctx->sharedFilesExtended.size(); invokeELFT(compileBitcodeFiles, skipLinkedOutput); // Symbol resolution finished. Report backward reference problems, @@ -2741,11 +2719,6 @@ void LinkerDriver::link(opt::InputArgList &args) { // compileBitcodeFiles may have produced lto.tmp object files. After this, no // more file will be added. - if (config->adlt) { - auto newSharedFiles = - makeArrayRef(ctx->sharedFilesExtended).slice(numSoBeforeLTO); - parallelForEach(newSharedFiles, postParseSharedFileForAdlt); - } auto newObjectFiles = makeArrayRef(ctx->objectFiles).slice(numObjsBeforeLTO); parallelForEach(newObjectFiles, initializeLocalSymbols); parallelForEach(newObjectFiles, postParseObjectFile); @@ -2770,12 +2743,11 @@ void LinkerDriver::link(opt::InputArgList &args) { // Beyond this point, no new files are added. // Aggregate all input sections into one place. if (config->adlt) - for (auto it : llvm::enumerate(ctx->sharedFilesExtended)) - for (InputSectionBase *s : it.value()->getSections()) - if (isSectionValidForAdlt(it.index(), s)) + for (auto *file : adltCtx->sharedFilesExtended) + for (InputSectionBase *s : file->getSections()) + if (file->isValidSection(s)) inputSections.push_back(s); - for (InputFile *f : ctx->objectFiles) for (InputSectionBase *s : f->getSections()) if (s && s != &InputSection::discarded) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 0b6ac03faff1887c20e05a72826db4cc320a1910..df9355f3b62573f97a0a18ad1e2e828a2e9df4ee 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -8,6 +8,7 @@ #include "InputFiles.h" #include "Config.h" +#include "Adlt.h" #include "DWARF.h" #include "Driver.h" #include "InputSection.h" @@ -158,18 +159,6 @@ static bool isCompatible(InputFile *file) { return false; } -template -static void doBuildSymsHist(InputFile *file, ESymsCntMap &eSymsHist) { - if (!isCompatible(file)) - return; - if (auto *f = dyn_cast>(file)) - f->buildSymsHist(eSymsHist); -} - -void elf::buildSymsHist(InputFile *file, ESymsCntMap &eSymsHist) { - invokeELFT(doBuildSymsHist, file, eSymsHist); -} - template static void doParseFile(InputFile *file) { if (!isCompatible(file)) return; @@ -198,9 +187,9 @@ template static void doParseFile(InputFile *file) { // .so file if (config->adlt) if (auto *f = dyn_cast>(file)) { - f->orderIdx = ctx->sharedFilesExtended.size(); - ctx->sharedFilesExtended.push_back(cast(file)); - f->parseForAdlt(); + f->orderIdx = adltCtx->sharedFilesExtended.size(); + adltCtx->sharedFilesExtended.push_back(f); + f->parse(); return; } @@ -346,6 +335,11 @@ static const Elf_Shdr *findSection(ArrayRef sections, uint32_t type) { return nullptr; } +// OHOS_LOCAL begin +void ELFFileBase::buildSymbolsHist() {} +bool ELFFileBase::isValidSection(InputSectionBase *s) const { return true; } +// OHOS_LOCAL end + template void ELFFileBase::init() { using Elf_Shdr = typename ELFT::Shdr; using Elf_Sym = typename ELFT::Sym; @@ -580,10 +574,12 @@ void ObjFile::initializeSections(bool ignoreComdats, } auto secName = check(obj.getSectionName(sec, shstrtab)); if (config->adlt && sec.sh_type == SHT_NULL) { + // TODO: add unique for output only auto name = getUniqueName(secName); this->sections[i] = createInputSection(i, sec, name); this->sections[i]->address = sec.sh_addr; this->sections[i]->size = sec.sh_size; + sectionsMap[sec.sh_addr] = i; } switch (sec.sh_type) { @@ -607,6 +603,7 @@ void ObjFile::initializeSections(bool ignoreComdats, .second; if (keepGroup) { if (config->relocatable) { + // TODO: add unique for output only auto name = config->adlt ? getUniqueName(secName) : secName; this->sections[i] = createInputSection(i, sec, name); if (config->adlt) { @@ -640,6 +637,7 @@ void ObjFile::initializeSections(bool ignoreComdats, ctx->hasSympart.store(true, std::memory_order_relaxed); LLVM_FALLTHROUGH; default: + // TODO: add unique for output only auto name = config->adlt ? getUniqueName(secName) : secName; this->sections[i] = createInputSection(i, sec, name); if (config->adlt) { @@ -1047,18 +1045,6 @@ InputSectionBase *ObjFile::createInputSection(uint32_t idx, return make(*this, sec, name); } - -template -void ObjFile::buildSymsHist(ESymsCntMap &eSymsHist) { - ArrayRef eSyms = this->getELFSyms(); - for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { - if (!eSyms[i].isDefined()) - continue; - StringRef name = CHECK(eSyms[i].getName(stringTable), this); - eSymsHist[CachedHashStringRef(name)]++; - } -} - // Initialize this->Symbols. this->Symbols is a parallel array as // its corresponding ELF symbol table. template @@ -1073,8 +1059,13 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { if (!symbols[i]) { StringRef name = CHECK(eSyms[i].getName(stringTable), this); if (config->adlt && eSyms[i].isDefined() && - ctx->adlt.duplicatedSymNames.count(CachedHashStringRef(name)) != 0) { - ctx->adlt.withCfi = ctx->adlt.withCfi || name == "__cfi_check"; + adltCtx->duplicatedSymNames.count(CachedHashStringRef(name)) != 0) { + if (name == "__cfi_check" && !adltCtx->withCfi) { + adltCtx->withCfi = true; + if (config->adltTrace) + lld::outs() << "[ADLT] Cfi mode is ON\n"; + } + // TODO: add unique for output only name = this->getUniqueName(name); } symbols[i] = symtab.insert(name); @@ -1246,14 +1237,6 @@ 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}); } } @@ -1622,311 +1605,137 @@ template void SharedFile::parse() { } template -void SharedFileExtended::resolveDuplicatesForAdlt() { - auto pred = [&](DuplicateSymbol dup) { - auto sym = dup.sym; - if (!sym->isDefined()) - return true; +SharedFileExtended::SharedFileExtended(MemoryBufferRef mb, + StringRef soName) + : ObjFile(InputFile::SharedKind, mb, soName), soName(soName) {} - auto d = cast(sym); - return !d->section && !d->getOutputSection(); - }; - static std::mutex mu; - { - std::lock_guard lock(mu); - llvm::erase_if(ctx->duplicates, pred); +template void SharedFileExtended::buildSymbolsHist() { + ArrayRef eSyms = this->template getELFSyms(); + for (size_t i = this->firstGlobal, end = eSyms.size(); i != end; ++i) { + if (!eSyms[i].isDefined()) + continue; + StringRef name = CHECK(eSyms[i].getName(this->stringTable), this); + adltCtx->symNamesHist[CachedHashStringRef(name)]++; } +} - if (ctx->duplicates.empty()) - return; +template +bool SharedFileExtended::isValidSection(InputSectionBase *s) const { + if (!s || s == &InputSection::discarded) + return false; + uint32_t type = s->type; + StringRef name = s->name; - { - std::lock_guard lock(mu); - for (DuplicateSymbol &dup : ctx->duplicates) - warn("duplicate: " + dup.file->getName() + ": " + dup.section->name + - ": " + dup.sym->getName()); - ctx->duplicates.clear(); - } + bool isBaseType = type == SHT_NOBITS || type == SHT_NOTE || + type == SHT_INIT_ARRAY || type == SHT_FINI_ARRAY; + // TODO: fix .debug-* sections relocation + // TODO: rename sections at outputStage. + bool isNeededProgBits = + type == SHT_PROGBITS && + !(name.startswith(".got") || name.startswith(".plt") || + name.startswith(".eh_frame_hdr") || name.startswith(".debug_")); + bool ret = isBaseType || isNeededProgBits; + return ret; } template -SharedFileExtended::SharedFileExtended(MemoryBufferRef mb, - StringRef soName) - : ObjFile(mb, soName), soName(soName), - simpleSoName(path::stem(soName)) { - const_cast(this->fileKind) = InputFile::SharedKind; +bool SharedFileExtended::isDynamicSection(InputSectionBase *s) const { + // TODO: rename sections at outputStage. + return s->type == llvm::ELF::SHT_NULL || s->name.startswith(".got.plt"); } -template void SharedFileExtended::parseForAdlt() { - this->parse(); +template void SharedFileExtended::parse(bool ignoreComdats) { + ObjFile::parse(ignoreComdats); parseDynamics(); parseElfSymTab(); - - bool isDebug = false; // debug hint - if (!isDebug) - return; - - const ELFFile obj = this->getObj(); - ArrayRef objSections = this->template getELFShdrs(); - - lld::outs() << "Parse symbols from .symtab:\n"; - auto p = obj.getSection(symTabSecIdx); - if (p.takeError()) { - fatal("getSection failed: " + llvm::toString(p.takeError())); - } - const Elf_Shdr *elfSymTab = *p; - StringRef strTable = *obj.getStringTableForSymtab(*elfSymTab); - - auto eSyms = *obj.symbols(elfSymTab); - this->symbols.resize(this->symbols.size() + eSyms.size()); - for (const Elf_Sym &sym : eSyms) { - if (!sym.isDefined()) - continue; - - auto rawSec = obj.getSection(sym.st_shndx); - if (rawSec.takeError()) - continue; - if (isDebug) - traceElfSymbol(sym, strTable); - } - if (isDebug) - lld::outs() << '\n'; - - lld::outs() << "Parse offsets of some sections:\n"; - for (const Elf_Shdr &sec : objSections) { - auto name = check(obj.getSectionName(sec)); - if (name == ".init_array" || name == ".fini_array" || name == ".data" || - name == ".data.rel.ro" || name == ".bss.rel.ro" || name == ".bss") - traceElfSection(sec); - } - lld::outs() << '\n'; } -template void SharedFileExtended::postParseForAdlt() { - this->initializeLocalSymbols(); - this->postParse(); - resolveDuplicatesForAdlt(); +template void SharedFileExtended::postParse() { + ObjFile::initializeLocalSymbols(); + ObjFile::postParse(); } template -StringRef SharedFileExtended::addAdltPostfix(StringRef input) const { +StringRef SharedFileExtended::getUniqueName(StringRef input) const { if (input.empty()) return input; auto suffix = Twine("__") + Twine::utohexstr(this->orderIdx); return saver().save(input + suffix); } template -bool SharedFileExtended::addAdltPostfix(Symbol *s) { - StringRef newName = addAdltPostfix(s->getName()); - if (s->getName() == newName) - return false; - s->setName(newName); - return true; -} - -template -StringRef SharedFileExtended::getUniqueName(StringRef origName) const { - return addAdltPostfix(origName); -} - -// TODO: optimize 2 lookups -template -bool SharedFileExtended::saveSymbol(const Defined& d) const { - auto found = elf::symtab->find(d.getName()); - if (found) - return false; - in.symTab->addSymbol(elf::symtab->addSymbol(d)); - return true; +Defined &SharedFileExtended::getDefinedLocalSym(uint64_t offset) { + auto getSym = [&](unsigned offs) { + return localSymbols[this->definedSymbolsMap[offs]]; + }; + auto *s = getSym(offset); + if (!s || s == localSymbols[0]) { + auto sec = findSection(offset); + s = getSym(sec->address); + } + assert(s && s->isDefined()); + return cast(*s); } template -Defined *SharedFileExtended::findSectionSymbol(uint64_t offset) const { - bool isDebug = false; - /*if (offset == 0x7738) // debug hint - isDebug = true;*/ - llvm::SmallVector candidates; - for (auto *sym : this->allSymbols) { - if (!sym || !sym->isSection()) - continue; - assert(sym->isDefined()); - Defined *d = cast(sym); - uint64_t low = d->section->address; - uint64_t high = low + d->section->size; - - if (isDebug) - lld::outs() << "offset: 0x" + utohexstr(offset) + - " sect name: " + d->section->name + "low 0x" + - utohexstr(low) + " high: 0x" + utohexstr(high) + "\n"; - bool isGood = (offset >= low) && (offset < high); - if (!isGood) - continue; - candidates.push_back(d); - } - if (candidates.empty()) // no suitable items found - return nullptr; - - llvm::sort(candidates, [offset](Defined *d1, Defined *d2) { - auto a1 = d1->section->address; - auto a2 = d2->section->address; - return (offset - a1 < offset - a2); - }); - - auto d = *candidates.begin(); - if (isDebug) - traceSymbol(*d, "found section sym: "); - return d; +InputSectionBase &SharedFileExtended::getSection(uint64_t offset) { + auto *sec = this->sections[this->sectionsMap[offset]]; + if (offset && sec->type == SHT_NULL) + sec = findSection(offset); + return *sec; } template -InputSectionBase * -SharedFileExtended::findInputSection(StringRef name) const { - for (InputSectionBase *sec : this->sections) - if (sec && sec->name == name) - return sec; - return nullptr; +InputSectionBase &SharedFileExtended::getSectionByOrder(size_t idx) { + auto *sec = this->sections[idx]; + if (!sec) + sec = &InputSection::discarded; + return *sec; } template -InputSectionBase * -SharedFileExtended::findInputSection(uint64_t offset) const { +InputSectionBase *SharedFileExtended::findSection(uint64_t offset) { llvm::SmallVector candidates; for (InputSectionBase *sec : this->sections) { if (!sec) continue; - if (sec->address == offset) - return sec; - uint64_t low = sec->address; - uint64_t high = low + sec->size; - bool isGood = (offset >= low) && (offset < high); - if (!isGood) - continue; - candidates.push_back(sec); + auto low = sec->address; + auto high = low + sec->size; + if (offset >= low && offset < high) + candidates.push_back(sec); } if (candidates.empty()) // no suitable items found return nullptr; - - auto lessAddr = [&](auto *s1, auto *s2) { return s1->address < s2->address; }; - auto i = candidates.begin(); - auto e = candidates.end(); - auto ret = std::min_element(i, e, lessAddr); - return *ret; -} - -template -bool SharedFileExtended::isDynamicSection(InputSectionBase &sec) const { - return sec.type == llvm::ELF::SHT_NULL || sec.name.startswith(".got.plt"); -} - -template -Defined *SharedFileExtended::findDefinedSymbol( - uint64_t offset, 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; - - Defined *d = cast(sym); - if (d->file != this) - return false; - - bool goodVal = d->section->address + d->value == offset; - return goodVal && extraCond(d); - }; - - auto i = this->allSymbols.begin(); - auto e = this->allSymbols.end(); - auto ret = std::find_if(i, e, predRange); - if (ret != e) { // item was found - Defined *d = cast(*ret); - if (isDebug) - traceSymbol(*d, d->isSection() ? "found section sym: " - : "found defined sym: "); - return d; - } - - auto *sectionSym = findSectionSymbol(offset); - if (isDebug && sectionSym) - traceSymbol(*sectionSym, "found section sym: "); - return sectionSym; -} - -template -StringRef -SharedFileExtended::getShStrTab(ArrayRef elfSections) { - return CHECK(this->getObj().getSectionStringTable(elfSections), this); -} - -template -void SharedFileExtended::traceElfSymbol(const Elf_Sym &sym, - StringRef strTable) const { - const ELFFile obj = this->getObj(); - auto rawSec = obj.getSection(sym.st_shndx); - auto parsedSec = - !rawSec.takeError() ? *obj.getSection(sym.st_shndx) : nullptr; - lld::outs() << "File: " << soName << " symName: " << *sym.getName(strTable) - << " val: 0x" << utohexstr(sym.st_value) << " sec of sym: " - << (parsedSec ? *obj.getSectionName(*parsedSec) : "unknown!") - << " sym type: 0x" << utohexstr(sym.getType()) - << " sym binding: 0x" << utohexstr(sym.getBinding()) << '\n'; -} - -template -void SharedFileExtended::traceElfSection(const Elf_Shdr &sec) const { - const ELFFile obj = this->getObj(); - - auto secName = *obj.getSectionName(sec); - lld::outs() << "File: " << soName << " sec: " << secName << " sec addr: 0x" - << utohexstr(sec.sh_addr) << " sec offs: 0x" - << utohexstr(sec.sh_offset) << " sec ent size: 0x" - << utohexstr(sec.sh_entsize) << '\n'; + llvm::sort(candidates, + [](auto *a, auto *b) { return a->address < b->address; }); + return *candidates.begin(); } template -void SharedFileExtended::traceSymbol(const Symbol &sym, - StringRef title) const { - lld::outs() << "File: " << soName << ": " + title - << " symName: " << sym.getName() << " exportDynamic: 0x" - << utohexstr(sym.exportDynamic); - if (!sym.isDefined()) { - lld::outs() << '\n'; - return; - } - auto &d = cast(sym); - lld::outs() << " val: 0x" << utohexstr(d.value) - << " sec of sym: " << (d.section ? d.section->name : "unknown!") - << " sym type: 0x" << utohexstr(d.type) << " sym binding: 0x" - << utohexstr(d.binding) << '\n'; +Symbol &SharedFileExtended::getDynamicSymbol(size_t symbolIndex) const { + return *this->symbols[symbolIndex]; } - template -void SharedFileExtended::traceSection(const SectionBase &sec, - StringRef title) const { - lld::outs() << "File: " << soName << ": " + title << " sec: " << sec.name - << " sec addr: 0x" << utohexstr(sec.address) << " sec offs: 0x" - << utohexstr(sec.getOffset(0)) << " sec ent size: 0x" - << utohexstr(sec.entsize) << '\n'; +Symbol &SharedFileExtended::getLocalSymbol(size_t symbolIndex) const{ + assert(symbolIndex && (symbolIndex < localSymbols.size())); + return *localSymbols[symbolIndex]; } template -Symbol &SharedFileExtended::getDynamicSymbol(uint32_t symbolIndex) const { - return *this->symbols[symbolIndex]; -} +Symbol &SharedFileExtended::getSymbol(size_t symbolIndex, + bool fromDynamic) { + if (!symbolIndex) + return *localSymbols[0]; + /* TODO + if (symbolIndex > static_cast(symTabFirstGlobal)) + return getDynamicSymbol(symbolIndex - (symTabFirstGlobal + 1)); + return fromDynamic ? getDynamicSymbol(symbolIndex) + : getLocalSymbol(symbolIndex); */ -template -Symbol &SharedFileExtended::getSymbolADLT(uint32_t symbolIndex, - bool fromDynamic) const { Symbol &sym = fromDynamic ? getDynamicSymbol(symbolIndex) - : getSymbolFromElfSymTab(symbolIndex); - + : getLocalSymbol(symbolIndex); StringRef name = sym.getName(); if (name.empty()) return sym; - - /*if (name.contains("__emutls_v.TLS_data1")) // debug hint - lld::outs() << "debug getSymbolADLT(): " << name << "\n";*/ - // check SymbolTable auto res = elf::symtab->find(name); if (res && (res->exportDynamic || res->versionId)) @@ -1943,6 +1752,12 @@ Symbol &SharedFileExtended::getSymbolADLT(uint32_t symbolIndex, return sym; } +template +ArrayRef SharedFileExtended::getLocalSymbols() { + assert(!localSymbols.empty()); + return llvm::makeArrayRef(localSymbols).slice(0, symTabFirstGlobal); +} + template void SharedFileExtended::parseDynamics() { const ELFFile obj = this->getObj(); ArrayRef sections = this->template getELFShdrs(); @@ -2040,8 +1855,8 @@ template void SharedFileExtended::parseDynamics() { StringRef name = CHECK(sym.getName(this->stringTable), this); // Add postfix for defined duplicates. if (config->adlt && sym.isDefined() && - ctx->adlt.duplicatedSymNames.count(CachedHashStringRef(name)) != 0) - name = this->getUniqueName(name); + adltCtx->duplicatedSymNames.count(CachedHashStringRef(name)) != 0) + name = getUniqueName(name); // TODO: add unique for output only if (sym.getBinding() == STB_LOCAL) { warn("found local symbol '" + name + @@ -2119,16 +1934,16 @@ template void SharedFileExtended::parseElfSymTab() { ArrayRef eSections = this->template getELFShdrs(); // Find a symbol table. - const Elf_Shdr *eSymtabSec = findSection(eSections, SHT_SYMTAB); + const Elf_Shdr *eSymtabSec = ::findSection(eSections, SHT_SYMTAB); if (!eSymtabSec) return; - eFirstGlobal = eSymtabSec->sh_info; + symTabFirstGlobal = eSymtabSec->sh_info; ArrayRef eSyms = CHECK(obj.symbols(eSymtabSec), this); auto numESyms = uint32_t(eSyms.size()); auto eStringTable = CHECK(obj.getStringTableForSymtab(*eSymtabSec, eSections), this); - this->allSymbols.resize(numESyms); + this->localSymbols.resize(numESyms); for (size_t i = 0; i < numESyms; i++) { const Elf_Sym &eSym = eSyms[i]; @@ -2157,13 +1972,14 @@ template void SharedFileExtended::parseElfSymTab() { }); bool isInDynSym = dynSym != this->symbols.end(); if (!isInDynSym) - name = addAdltPostfix(name); + name = getUniqueName(name); // TODO: add unique for output only /*if (name == "TLS_data1") // debug hint lld::outs() << name << '\n'; */ - this->allSymbols[i] = + this->localSymbols[i] = make(this, name, bind, other, type, val, eSym.st_size, sec); + this->definedSymbolsMap[eSym.st_value] = i; } else { - this->allSymbols[i] = make(this, name, bind, other, type, + this->localSymbols[i] = make(this, name, bind, other, type, /*discardedSecIdx=*/i); } } diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index b8d47779488d74177d74d89e94925c5d05d3b7d1..41f1561bb54510d5989180469742abf8b4e1178c 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -47,8 +47,6 @@ extern std::unique_ptr tar; llvm::Optional readFile(StringRef path); // Add symbols in File to the symbol table. -typedef llvm::DenseMap ESymsCntMap; -void buildSymsHist(InputFile *file, ESymsCntMap &eSymsHist); void parseFile(InputFile *file); // The root class of input files. @@ -96,14 +94,6 @@ public: fileKind == BitcodeKind); return symbols; } - - // ADLT beg - ArrayRef getAllSymbols() const { return allSymbols; } - - SmallVector allSymbols; - // ADLT end - - // Get filename to use for linker script processing. StringRef getNameForScript() const; @@ -211,6 +201,11 @@ public: return getELFSyms().slice(firstGlobal); } + // OHOS_LOCAL begin + virtual void buildSymbolsHist(); + virtual bool isValidSection(InputSectionBase *s) const; + // OHOS_LOCAL end + protected: // Initializes this class's member variables. template void init(); @@ -241,15 +236,19 @@ public: ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) { this->archiveName = archiveName; } + ObjFile(Kind k, MemoryBufferRef m, StringRef archiveName) // OHOS_LOCAL + : ELFFileBase(k, m) { + this->archiveName = archiveName; + } virtual ~ObjFile() {} - void parse(bool ignoreComdats = false); + virtual void parse(bool ignoreComdats = false); void parseLazy(); StringRef getShtGroupSignature(ArrayRef sections, const Elf_Shdr &sec); - virtual Symbol &getSymbol(uint32_t symbolIndex) const { + Symbol &getSymbol(uint32_t symbolIndex) const { if (symbolIndex >= this->symbols.size()) fatal(toString(this) + ": invalid symbol index"); return *this->symbols[symbolIndex]; @@ -294,13 +293,19 @@ public: // Get cached DWARF information. DWARFCache *getDwarf(); - void buildSymsHist(ESymsCntMap &eSymsHist); void initializeLocalSymbols(); - void postParse(); + virtual void postParse(); -protected: + // OHOS_LOCAL begin + // TODO: move to SharedFileExtended virtual StringRef getUniqueName(StringRef origName) const; +protected: + // TODO: move to SharedFileExtended + llvm::DenseMap sectionsMap; // offset, orderIdx + llvm::DenseMap definedSymbolsMap; // abs offset, orderIdx + // OHOS_LOCAL end + private: void initializeSections(bool ignoreComdats, const llvm::object::ELFFile &obj); @@ -400,60 +405,38 @@ public: static bool classof(const InputFile *f) { return f->kind() == InputFile::SharedKind; } + void buildSymbolsHist() override; + bool isValidSection(InputSectionBase *s) const override; + bool isDynamicSection(InputSectionBase *s) const; - void parseForAdlt(); - void postParseForAdlt(); - - StringRef addAdltPostfix(StringRef input) const; - bool addAdltPostfix(Symbol *s); + void parse(bool ignoreComdats = false) override; + void postParse() override; - bool saveSymbol(const Defined& d) const; + Defined &getDefinedLocalSym(uint64_t offset); - Defined *findSectionSymbol(uint64_t offset) const; - Defined *findDefinedSymbol( - uint64_t offset, - llvm::function_ref extraCond = [](Defined *) { - return true; - }) const; + InputSectionBase &getSection(uint64_t offset); + InputSectionBase &getSectionByOrder(size_t idx); + InputSectionBase *findSection(uint64_t offset); - InputSectionBase *findInputSection(StringRef name) const; - InputSectionBase *findInputSection(uint64_t offset) const; - bool isDynamicSection(InputSectionBase &sec) const; - - template - Symbol &getRelocTargetSymADLT(const RelT &rel, InputSectionBase &sec) const { + template Symbol &getRelocTargetSym(const RelT &rel) { uint32_t symIndex = rel.getSymbol(config->isMips64EL); - return getSymbolADLT(symIndex, isDynamicSection(sec)); - } - - ArrayRef getLocalSymbols() override { - if (this->allSymbols.empty()) - return {}; - return llvm::makeArrayRef(this->allSymbols).slice(1, eFirstGlobal - 1); + return getSymbol(symIndex, false); } - Symbol &getDynamicSymbol(uint32_t symbolIndex) const; - Symbol &getSymbolADLT(uint32_t symbolIndex, bool fromDynamic) const; + Symbol &getDynamicSymbol(size_t symbolIndex) const; + Symbol &getLocalSymbol(size_t symbolIndex) const; + Symbol &getSymbol(size_t symbolIndex, bool fromDynamic); - Symbol &getSymbolFromElfSymTab(uint32_t symbolIndex) const { - if (symbolIndex >= this->allSymbols.size()) - fatal(toString(this) + ": invalid symbol index"); - return *this->allSymbols[symbolIndex]; - } + ArrayRef getLocalSymbols() override; - void traceElfSymbol(const Elf_Sym &sym, StringRef strTable) const; - void traceElfSection(const Elf_Shdr &sec) const; - - void traceSymbol(const Symbol &sym, StringRef title = "") const; - void traceSection(const SectionBase &sec, StringRef title = "") const; public: // the input order of the file as it presented in ADLT image - size_t orderIdx; + size_t orderIdx = 0; int dynSymSecIdx = 0; int symTabSecIdx = 0; int symTabShndxSecIdx = 0; - int eFirstGlobal = 0; + int symTabFirstGlobal = 0; int gotPltSecIdx = 0; // .symtab's start of local symbols owned by library @@ -465,8 +448,10 @@ public: llvm::SetVector programHeaders; // From input .rela.dyn, .rela.plt: - llvm::SetVector dynRelIndexes; - llvm::SetVector pltRelIndexes; + llvm::SetVector + relaDynIndexes; // If not .relr.dyn exists, contains only Got/Abs/Tls + // relocs. Otherwise contains relative relocs also. + llvm::SetVector relaPltIndexes; // .got.plt relocs // SharedFile compability layer: // This is actually a vector of Elf_Verdef pointers. @@ -485,17 +470,15 @@ public: // parsed. Only filled for `--no-allow-shlib-undefined`. SmallVector requiredSymbols; -protected: - virtual StringRef getUniqueName(StringRef origName) const override; + // TODO: add unique for output only + StringRef getUniqueName(StringRef origName) const override; private: + SmallVector localSymbols; + void parseDynamics(); // SharedFile compability void parseElfSymTab(); // ObjectFile compability - void resolveDuplicatesForAdlt(); - - StringRef getShStrTab(ArrayRef elfSections); - std::vector parseVerneed(const llvm::object::ELFFile &obj, const typename ELFT::Shdr *sec); }; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 0eb2968413bddb05fb4888a7c749490fe14e98ac..bf2b1d7c5521e15e2d38220c737d7f16e4a28bfc 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -347,10 +347,9 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { for (const RelTy &rel : rels) { RelType type = rel.getType(config->isMips64EL); - const ObjFile *file = - config->adlt ? getSharedFile() : getFile(); + const ObjFile *file = getFile(); Symbol &sym = config->adlt - ? getSharedFile()->getRelocTargetSymADLT(rel, *sec) + ? getSoExt()->getRelocTargetSym(rel) : file->getRelocTargetSym(rel); auto *p = reinterpret_cast(buf); @@ -847,8 +846,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef rels) { if (!RelTy::IsRela) addend += target.getImplicitAddend(bufLoc, type); - Symbol &sym = config->adlt ? getSharedFile()->getSymbolFromElfSymTab( - rel.getSymbol(config->isMips64EL)) + Symbol &sym = config->adlt ? getSoExt()->getRelocTargetSym(rel) : getFile()->getRelocTargetSym(rel); if (config->adlt) { // TODO improve switch (type) { @@ -963,9 +961,8 @@ static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) { template void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) { - if (flags & SHF_EXECINSTR && - (config->adlt ? LLVM_UNLIKELY(getSharedFile()->splitStack) - : LLVM_UNLIKELY(getFile()->splitStack))) + if (!config->adlt && flags & SHF_EXECINSTR && + LLVM_UNLIKELY(getFile()->splitStack)) adjustSplitStackFunctionPrologues(buf, bufEnd); if (flags & SHF_ALLOC) { diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index b9f4541e77a9a43fd3b67b711ff0af755ea1882d..1bcf8b4eca2053d6f808ee15c7eb08ec53a7f4e3 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -17,6 +17,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Object/ELF.h" +#include "Adlt.h" namespace lld { namespace elf { @@ -138,8 +139,8 @@ public: } template - SharedFileExtended *getSharedFile() const { - return cast_or_null>(file); + SharedFileExtended *getSoExt() const { + return adltCtx->getSoExt(file); } // Used by --optimize-bb-jumps and RISC-V linker relaxation temporarily to diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 51353287c90e540f36549841479d11cc440673a0..5c1d109ef73b2dcaa2ace9eb95d184eedd143b03 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -55,7 +55,7 @@ static void writeHeader(raw_ostream &os, uint64_t vma, uint64_t lma, // Returns a list of all symbols that we want to print out. static std::vector getSymbols() { std::vector v; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) for (Symbol *b : file->getSymbols()) if (auto *dr = dyn_cast(b)) @@ -225,7 +225,7 @@ static void writeMapFile(raw_fd_ostream &os) { static void writeCref(raw_fd_ostream &os) { // Collect symbols and files. MapVector> map; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) { for (Symbol *sym : file->getSymbols()) { if (isa(sym)) diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 61be1e13287f75665e3d681fa601a22e04a428bb..f4fa5b90e2650800f51d0dda53bb5192c66b92ce 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -345,13 +345,14 @@ template void MarkLive::mark() { // to from __start_/__stop_ symbols because there will only be one set of // symbols for the whole program. template void MarkLive::moveToMain() { - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; - for (ELFFileBase *file : files) - for (Symbol *s : file->getSymbols()) - if (auto *d = dyn_cast(s)) - if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section && - d->section->isLive()) - markSymbol(s); + auto files = ctx->objectFiles; + if (!config->adlt) + for (ELFFileBase *file : files) + for (Symbol *s : file->getSymbols()) + if (auto *d = dyn_cast(s)) + if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section && + d->section->isLive()) + markSymbol(s); for (InputSectionBase *sec : inputSections) { if (!sec->isLive() || !isValidCIdentifier(sec->name)) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 7984401410256df7c663c07ff5d144a63cc9947e..c67ec01bf27ae03c119a1821670d080f85b13121 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -42,6 +42,7 @@ #include "Relocations.h" #include "Config.h" +#include "Adlt.h" #include "InputFiles.h" #include "LinkerScript.h" #include "OutputSections.h" @@ -433,6 +434,47 @@ private: size_t i = 0; }; + +// OHOS_LOCAL begin +template class AdltRelocationScanner { +public: + AdltRelocationScanner(InputSectionBase &isec) + : file(adltCtx->getSoExt(isec.file)), + fromDynamic(file->isDynamicSection(&isec)), sec(isec) {} + + SharedFileExtended *getSoExt() { return file; } + + Symbol &getSymbol(unsigned idx) { return file->getSymbol(idx, fromDynamic); } + + void process(Relocation *r); + void trackGotPlt(Symbol *sym); + void trackRelatives(); + void trackDynamics(); + + bool toProcessAux = false; + +private: + SharedFileExtended *file = nullptr; + bool fromDynamic = false; + InputSectionBase &sec; +}; + +template +void AdltRelocationScanner::trackGotPlt(Symbol *sym) { + adltCtx->gotPltInfo[sym].push_back(file->orderIdx); +} + +template void AdltRelocationScanner::trackRelatives() { + auto count = mainPart->relaDyn->relocs.size(); + file->relaDynIndexes.insert(count - 1); +} + +template void AdltRelocationScanner::trackDynamics() { + auto count = mainPart->relaDyn->relocs.size(); + file->relaDynIndexes.insert(count - 1); +} +// OHOS_LOCAL end + // This class encapsulates states needed to scan relocations for one // InputSectionBase. class RelocationScanner { @@ -458,16 +500,10 @@ private: int64_t computeAddend(const RelTy &rel, RelExpr expr, bool isLocal) const; bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym, uint64_t relOff) const; + void processAux(Relocation &r); // OHOS_LOCAL void processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym, int64_t addend) const; template void scanOne(RelTy *&i); - - // ADLT - template - void processForADLT(const RelTy &rel, Relocation *r, bool fromDynamic); - - template - void tracePushRelocADLT(InputSectionBase &isec, Relocation &r) const; }; } // namespace @@ -1036,6 +1072,11 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type, // sections. Given that it is ro, we will need an extra PT_LOAD. This // complicates things for the dynamic linker and means we would have to reserve // space for the extra PT_LOAD even if we end up not using it. + +void RelocationScanner::processAux(Relocation &r) { // OHOS_LOCAL + processAux(r.expr, r.type, r.offset, *r.sym, r.addend); +} + void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym, int64_t addend) const { // If the relocation is known to be a link-time constant, we know no dynamic @@ -1304,41 +1345,9 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, return 0; } +// OHOS_LOCAL begin template -static void trackDynRelocAdlt(SharedFileExtended *soFile) { - soFile->dynRelIndexes.insert(mainPart->relaDyn->relocs.size() - 1); -} - -template -static void trackGotPltAdlt(Symbol *sym, SharedFileExtended *soFile) { - ctx->adlt.gotPltInfo[sym].push_back(soFile->orderIdx); -} - -// ADLT BEGIN -template -void RelocationScanner::tracePushRelocADLT(InputSectionBase &isec, - Relocation &r) const { - auto file = sec.getSharedFile(); - auto fullOffset = isec.address + r.offset; - lld::outs() << "[ADLT] Before push: [0x" + utohexstr(fullOffset) + - "] type: " + toString(r.type) + - " expr: " + std::to_string(r.expr) + " offset: 0x" + - utohexstr(r.offset) + " addend: 0x" + utohexstr(r.addend) + - ".\n"; - lld::outs() << "section where: "; - file->traceSection(isec); - - lld::outs() << "r->sym: "; - file->traceSymbol(*r.sym); - lld::outs() << "\n"; -} - -template -void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, - bool fromDynamic) { - auto file = sec.getSharedFile(); - bool isDebug = false; - +void AdltRelocationScanner::process(Relocation *r) { /*if (r->offset == 0x21F) // debug hint isDebug = true; /*if (r->type == R_AARCH64_ABS64 && @@ -1346,40 +1355,37 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, isDebug = true;*/ // parse offset (where) - InputSectionBase *secWhere = file->findInputSection(r->offset); - assert(secWhere && "not found!"); + InputSectionBase &secWhere = + (sec.type != SHT_NULL) ? sec : file->getSection(r->offset); // process offset - r->offset -= fromDynamic ? secWhere->address : sec.address; + r->offset -= secWhere.address; assert(r->type); - if (isDebug) - tracePushRelocADLT(*secWhere, *r); - // resolve relocs switch (r->type) { // dyn relocs case R_AARCH64_RELATIVE: { - Defined *d = file->findDefinedSymbol(r->addend); + Defined *d = &file->getDefinedLocalSym(r->addend); assert(d && "R_AARCH64_RELATIVE: r->sym not found by addend!"); r->sym = d; r->addend -= d->section->address + d->value; - addRelativeReloc(*secWhere, r->offset, *r->sym, r->addend, r->expr, - r->type); - trackDynRelocAdlt(file); + addRelativeReloc(secWhere, r->offset, *r->sym, r->addend, r->expr, + r->type); + trackRelatives(); return; } case R_AARCH64_GLOB_DAT: assert(r->sym->exportDynamic); if (!r->sym->needsGot) r->sym->needsGot = 1; - trackGotPltAdlt(r->sym, file); + trackGotPlt(r->sym); 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); + trackGotPlt(r->sym); return; // abs relocs case R_AARCH64_ABS32: @@ -1388,10 +1394,10 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, case R_AARCH64_ABS64: if (fromDynamic) { assert(r->sym->exportDynamic); - sec.getPartition().relaDyn->addSymbolReloc(target.symbolicRel, *secWhere, + sec.getPartition().relaDyn->addSymbolReloc(r->type, secWhere, r->offset, *r->sym, r->addend, r->type); - trackDynRelocAdlt(file); + trackDynamics(); return; } sec.relocations.push_back(*r); @@ -1403,7 +1409,7 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, case R_AARCH64_LDST128_ABS_LO12_NC: case R_AARCH64_PREL32: case R_AARCH64_PREL64: - processAux(r->expr, r->type, r->offset, *r->sym, r->addend); + toProcessAux = true; return; // plt relocs case R_AARCH64_CALL26: @@ -1421,24 +1427,21 @@ void RelocationScanner::processForADLT(const RelTy &rel, Relocation *r, return; case R_AARCH64_ADR_GOT_PAGE: if (r->sym->isDefined() && !r->sym->needsGot) { - if (isDebug) - lld::outs() << "[ADLT] R_AARCH64_ADR_GOT_PAGE: sym not in GOT! "; - r->expr = R_PC; // prev: R_AARCH64_GOT_PAGE_PC || R_AARCH64_GOT_PAGE || - // R_GOT || R_GOT_PC - // TODO: replace reloc R_AARCH64_ADR_GOT_PAGE + // prev: R_AARCH64_GOT_PAGE_PC || R_AARCH64_GOT_PAGE || R_GOT || R_GOT_PC + r->expr = R_PC; sec.relocations.push_back(*r); return; } LLVM_FALLTHROUGH; case R_AARCH64_LD64_GOT_LO12_NC: case R_AARCH64_LD64_GOTPAGE_LO15: - processAux(r->expr, r->type, r->offset, *r->sym, r->addend); + toProcessAux = true; return; // tls relocs case R_AARCH64_TLSDESC: if (fromDynamic && !r->sym->needsTlsDesc) r->sym->needsTlsDesc = 1; - trackDynRelocAdlt(file); + trackGotPlt(r->sym); return; case R_AARCH64_TLSDESC_CALL: case R_AARCH64_TLS_TPREL64: @@ -1461,14 +1464,13 @@ 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); - bool fromDynamic = false; + std::unique_ptr> adltScanner = nullptr; if (config->adlt) - fromDynamic = sec.getSharedFile()->isDynamicSection(sec); - Symbol &sym = - config->adlt - ? sec.getSharedFile()->getSymbolADLT(symIndex, fromDynamic) - : sec.getFile()->getSymbol(symIndex); + adltScanner = std::make_unique>(sec); + uint32_t symIndex = rel.getSymbol(config->isMips64EL); + Symbol &sym = config->adlt + ? adltScanner->getSymbol(symIndex) + : sec.getFile()->getSymbol(symIndex); RelType type; // Deal with MIPS oddity. @@ -1502,7 +1504,9 @@ template void RelocationScanner::scanOne(RelTy *&i) { if (config->adlt) { Relocation r = {expr, type, offset, addend, &sym}; - processForADLT(rel, &r, fromDynamic); + adltScanner->process(&r); + if (adltScanner->toProcessAux) + processAux(r); return; } @@ -1716,11 +1720,6 @@ 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'; - } const RelsOrRelas rels = s.template relsOrRelas(); if (rels.areRelocsRel()) scanner.template scan(rels.rels); @@ -1807,15 +1806,25 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) { return true; } -template static void addGotPltIndexAdlt(Symbol *s, bool isPlt) { - auto &vec = ctx->adlt.gotPltInfo[s]; - for (auto &it : vec) { - auto *soFile = cast>(ctx->sharedFilesExtended[it]); +// OHOS_LOCAL begin +namespace lld { +namespace elf { +namespace adlt { +template static void addGotPltIndex(Symbol *s, bool isPlt) { + auto &vec = adltCtx->gotPltInfo[s]; + for (auto &orderId : vec) { + auto *soFile = adltCtx->getSoExt(orderId); auto &entries = isPlt ? in.relaPlt->relocs : mainPart->relaDyn->relocs; - auto &output = isPlt ? soFile->pltRelIndexes : soFile->dynRelIndexes; - output.insert(entries.size() - 1); + auto &output = isPlt ? soFile->relaPltIndexes : soFile->relaDynIndexes; + auto index = entries.size() - 1; + output.insert(index); } } +} // namespace adlt +} // namespace elf +} // namespace lld + +// OHOS_LOCAL end void elf::postScanRelocations() { auto fn = [](Symbol &sym) { @@ -1829,12 +1838,12 @@ void elf::postScanRelocations() { if (sym.needsGot) { addGotEntry(sym); if (config->adlt) - invokeELFT(addGotPltIndexAdlt, &sym, false); + invokeELFT(adlt::addGotPltIndex, &sym, false); } if (sym.needsPlt) { addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym); if (config->adlt) - invokeELFT(addGotPltIndexAdlt, &sym, true); + invokeELFT(adlt::addGotPltIndex, &sym, true); } if (sym.needsCopy) { if (sym.isObject()) { @@ -1869,7 +1878,8 @@ void elf::postScanRelocations() { mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible( target->tlsDescRel, *in.got, in.got->getTlsDescOffset(sym), sym, target->tlsDescRel); - invokeELFT(addGotPltIndexAdlt, &sym, false); + if (config->adlt) + invokeELFT(adlt::addGotPltIndex, &sym, false); } if (sym.needsTlsGd) { in.got->addDynTlsEntry(sym); @@ -1923,7 +1933,7 @@ void elf::postScanRelocations() { // Local symbols may need the aforementioned non-preemptible ifunc and GOT // handling. They don't need regular PLT. - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = config->adlt ? adltCtx->sharedFilesExtended : ctx->objectFiles; for (ELFFileBase *file : files) for (Symbol *sym : file->getLocalSymbols()) fn(*sym); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 61d52dc894b5ce2f046fd3a6d075277386f7b8bc..491a61dd15da04be1d3469dd45c4c24416b19e33 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -15,6 +15,7 @@ #include "SyntheticSections.h" #include "Config.h" +#include "Adlt.h" #include "DWARF.h" #include "EhFrame.h" #include "InputFiles.h" @@ -1398,11 +1399,11 @@ DynamicSection::computeContents() { part.dynStrTab->addString(config->rpath)); if (config->adlt) { - for (InputFile *file : ctx->sharedFilesExtended) { - auto *f = cast>(file); - for (size_t i = 0; i < f->dtNeeded.size(); i++) { + for (InputFile *file : adltCtx->sharedFilesExtended) { + auto *soExt = adltCtx->getSoExt(file); + for (size_t i = 0; i < soExt->dtNeeded.size(); i++) { auto tag = DT_NEEDED; - auto val = part.dynStrTab->addString(f->dtNeeded[i]); + auto val = part.dynStrTab->addString(soExt->dtNeeded[i]); if (llvm::find(entries, std::pair{tag, val}) == entries.end()) addInt(tag, val); @@ -1531,7 +1532,8 @@ DynamicSection::computeContents() { } if (config->emachine == EM_AARCH64) { - if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) + if (!config->adlt && + config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) addInt(DT_AARCH64_BTI_PLT, 0); if (config->zPacPlt) addInt(DT_AARCH64_PAC_PLT, 0); @@ -1549,40 +1551,17 @@ DynamicSection::computeContents() { addInSec(DT_HASH, *part.hashTab); if (isMain) { - if (config->adlt) { - auto findSection = [](StringRef name, unsigned partition = 1) { - for (SectionCommand *cmd : script->sectionCommands) - if (auto *osd = dyn_cast(cmd)) - if (osd->osec.name == name && osd->osec.partition == partition) - return &osd->osec; - return (OutputSection *)nullptr; - }; - for (InputFile *file : ctx->sharedFilesExtended) { - auto *f = cast>(file); - auto initArray = findSection(f->addAdltPostfix(".init_array")); - auto finiArray = findSection(f->addAdltPostfix(".fini_array")); - if (initArray) { - addInt(DT_INIT_ARRAY, initArray->addr); - addInt(DT_INIT_ARRAYSZ, initArray->size); - } - if (finiArray) { - addInt(DT_FINI_ARRAY, finiArray->addr); - addInt(DT_FINI_ARRAYSZ, finiArray->size); - } - } - } else { - if (Out::preinitArray) { - addInt(DT_PREINIT_ARRAY, Out::preinitArray->addr); - addInt(DT_PREINIT_ARRAYSZ, Out::preinitArray->size); - } - if (Out::initArray) { - addInt(DT_INIT_ARRAY, Out::initArray->addr); - addInt(DT_INIT_ARRAYSZ, Out::initArray->size); - } - if (Out::finiArray) { - addInt(DT_FINI_ARRAY, Out::finiArray->addr); - addInt(DT_FINI_ARRAYSZ, Out::finiArray->size); - } + if (Out::preinitArray) { + addInt(DT_PREINIT_ARRAY, Out::preinitArray->addr); + addInt(DT_PREINIT_ARRAYSZ, Out::preinitArray->size); + } + if (Out::initArray) { + addInt(DT_INIT_ARRAY, Out::initArray->addr); + addInt(DT_INIT_ARRAYSZ, Out::initArray->size); + } + if (Out::finiArray) { + addInt(DT_FINI_ARRAY, Out::finiArray->addr); + addInt(DT_FINI_ARRAYSZ, Out::finiArray->size); } if (Symbol *b = symtab->find(config->init)) @@ -2276,7 +2255,7 @@ void SymbolTableBaseSection::sortSymTabSymbolsInAdlt(size_t numLocals) { return {-1, file}; }; - for (InputFile* file : ctx->sharedFilesExtended) { + for (InputFile* file : adltCtx->sharedFilesExtended) { auto* soext = cast>(file); soext->sharedLocalSymbolIndex = llvm::None; soext->sharedGlobalSymbolIndex = llvm::None; @@ -2293,7 +2272,7 @@ void SymbolTableBaseSection::sortSymTabSymbolsInAdlt(size_t numLocals) { [makeKey](const SymbolTableEntry& lhs, const SymbolTableEntry& rhs) { return makeKey(lhs) <= makeKey(rhs); }); - + // extract file boundaries for local symbols for (auto iter = symbols.begin(); iter != localEnd; ++iter) if (auto* soext = dyn_cast_or_null>(iter->sym->file)) @@ -3495,7 +3474,7 @@ template void elf::splitSections() { llvm::TimeTraceScope timeScope("Split sections"); // splitIntoPieces needs to be called on each MergeInputSection // before calling finalizeContents(). - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; parallelForEach(files, [](ELFFileBase *file) { for (InputSectionBase *sec : file->getSections()) { if (!sec) @@ -4104,8 +4083,8 @@ AdltSection::AdltSection(StringTableSection& strTabSec) template void AdltSection::finalizeContents() { soInputs.clear(); - soInputs.reserve(ctx->sharedFilesExtended.size()); - for (InputFile* file : ctx->sharedFilesExtended) { + soInputs.reserve(adltCtx->sharedFilesExtended.size()); + for (InputFile* file : adltCtx->sharedFilesExtended) { auto* soext = cast>(file); soInputs.push_back(makeSoData(soext)); } @@ -4199,7 +4178,7 @@ typename AdltSection::CommonData AdltSection::makeCommonData() { return CommonData { UINT32_MAX, // .symtabSecIndex, filled in writeTo - ctx->adlt.commonProgramHeaders.size(), // .programHeadersAllocated + adltCtx->commonProgramHeaders.size(), // .programHeadersAllocated {}, // .phIndexes filled in writeTo }; } @@ -4219,11 +4198,11 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { }); } - data.initArrayName = soext->addAdltPostfix(".init_array"); - data.finiArrayName = soext->addAdltPostfix(".fini_array"); + data.initArrayName = soext->getUniqueName(".init_array"); + data.finiArrayName = soext->getUniqueName(".fini_array"); - data.relaDynIndx = soext->dynRelIndexes.getArrayRef(); - data.relaPltIndx = soext->pltRelIndexes.getArrayRef(); + data.relaDynIndx = soext->relaDynIndexes.getArrayRef(); + data.relaPltIndx = soext->relaPltIndexes.getArrayRef(); data.programHeadersAllocated = soext->programHeaders.size(); data.programHeaders = soext->programHeaders.getArrayRef(); @@ -4348,7 +4327,7 @@ void AdltSection::extractProgramHeaderIndexes() { phdrsIndexes[it.value()] = static_cast(it.index()); }; - for (const PhdrEntry* phentry : ctx->adlt.commonProgramHeaders) { + for (const PhdrEntry* phentry : adltCtx->commonProgramHeaders) { auto it = phdrsIndexes.find(phentry); if (it != phdrsIndexes.end()) { common.phIndexes.push_back(it->second); @@ -4382,7 +4361,7 @@ void AdltSection::finalizeOnWrite() { template void AdltSection::finalizeOnWrite(size_t idx, SoData& soData) { - auto* soext = cast>(ctx->sharedFilesExtended[idx]); + auto* soext = cast>(adltCtx->sharedFilesExtended[idx]); // require SymbolTableBaseSection::sortSymTabSymbolsInAdlt for .symtab called soData.sharedLocalIndex = soext->sharedLocalSymbolIndex; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 6743de95cd2f016b000c1eb1930453888dafe0f7..93fd33ccb2b9f1cf12d28e30dfa3d9165d0e3286 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -11,6 +11,7 @@ #include "ARMErrataFix.h" #include "CallGraphSort.h" #include "Config.h" +#include "Adlt.h" #include "InputFiles.h" #include "LinkerScript.h" #include "MapFile.h" @@ -314,6 +315,7 @@ template void elf::createSyntheticSections() { } if (config->adlt) { + assert(adltCtx && "ADLT: ctx not initialized!"); in.adltStrTab = std::make_unique(".adlt.strtab", false); in.adltData = std::make_unique>(*in.adltStrTab); add(*in.adltStrTab); @@ -526,7 +528,7 @@ template void elf::createSyntheticSections() { in.iplt = std::make_unique(); add(*in.iplt); - if (config->andFeatures) + if (!config->adlt && config->andFeatures) add(*make()); // .note.GNU-stack is always added when we are creating a re-linkable @@ -570,8 +572,10 @@ InputSection *AdltWriter::getInputSection(OutputSection *sec) { } template void AdltWriter::checkPhdrs() { - for (auto *file : ctx->sharedFilesExtended) - if (auto *soFile = ctx->adlt.getSoExt(file)) + assert(!adltCtx->commonProgramHeaders.empty() && + "Common headers can't be empty!"); + for (auto *file : adltCtx->sharedFilesExtended) + if (auto *soFile = adltCtx->getSoExt(file)) assert(!soFile->programHeaders.empty() && "ADLT: PHdr indexes can't be empty!"); } @@ -580,11 +584,11 @@ template void AdltWriter::checkRelocs() { assert(!mainPart->relaDyn->relocs.empty() && "ADLT: relaDyn can't be empty!"); assert(!in.relaPlt->relocs.empty() && "ADLT: relaPlt can't be empty!"); - for (auto *file : ctx->sharedFilesExtended) - if (auto *soFile = ctx->adlt.getSoExt(file)) { - assert(!soFile->dynRelIndexes.empty() && + for (auto *file : adltCtx->sharedFilesExtended) + if (auto *soFile = adltCtx->getSoExt(file)) { + assert(!soFile->relaDynIndexes.empty() && "ADLT: relaDyn indexes can't be empty!"); - assert(!soFile->pltRelIndexes.empty() && + assert(!soFile->relaPltIndexes.empty() && "ADLT: relaPlt indexes can't be empty!"); } } @@ -592,17 +596,17 @@ template void AdltWriter::checkRelocs() { template void AdltWriter::trackPhdr(OutputSection *sec, PhdrEntry *phdr) { auto *isec = getInputSection(sec); - if (isec && isec->file) - if (auto *soFile = ctx->adlt.getSoExt(isec->file)) { - soFile->programHeaders.insert(phdr); - return; - } - ctx->adlt.commonProgramHeaders.insert(phdr); + if (isec && isec->file) { + isec->getSoExt()->programHeaders.insert(phdr); + return; + } + adltCtx->commonProgramHeaders.insert(phdr); } template void AdltWriter::traceRelocs() { lld::outs() << "[ADLT]\n"; - lld::outs() << "Dyn relocs (" << mainPart->relaDyn->relocs.size() << ")\n"; + auto dynRelsSize = mainPart->relaDyn->relocs.size(); + lld::outs() << "Dyn relocs (" << dynRelsSize << ")\n"; lld::outs() << "Plt relocs (" << in.relaPlt->relocs.size() << ")\n"; auto printIndexes = [&](auto &vec) { @@ -612,25 +616,33 @@ template void AdltWriter::traceRelocs() { lld::outs() << "\n"; }; - auto printRelocTable = [&](auto *relSec, auto &outIndexes) { + auto printSym = [&](Symbol *sym) { + if (sym->getName().empty() && sym->isSection()) { + Defined *d = cast(sym); + return d->section->name; + } + return sym->getName(); + }; + + auto printRelaTable = [&](auto *relSec, auto &outIndexes) { for (auto &it : outIndexes) // print relocs if (DynamicReloc *rel = &relSec->relocs[it]) lld::outs() << it << ":\t" << rel->inputSec->name << " + 0x" << utohexstr(rel->offsetInSec) << "\t" - << toString(rel->type) << "\t" << rel->sym->getName() + << toString(rel->type) << "\t" << printSym(rel->sym) << " + 0x" << utohexstr(rel->addend) << '\n'; }; - for (auto *file : ctx->sharedFilesExtended) - if (auto *soFile = ctx->adlt.getSoExt(file)) { + for (auto *file : adltCtx->sharedFilesExtended) + if (auto *soFile = adltCtx->getSoExt(file)) { lld::outs() << soFile->soName << ":\n"; - lld::outs() << "Dyn relocs (" << soFile->dynRelIndexes.size() << ")"; - printIndexes(soFile->dynRelIndexes); - printRelocTable(mainPart->relaDyn.get(), soFile->dynRelIndexes); + lld::outs() << ".rela.dyn relocs (" << soFile->relaDynIndexes.size() << ")"; + printIndexes(soFile->relaDynIndexes); + printRelaTable(mainPart->relaDyn.get(), soFile->relaDynIndexes); - lld::outs() << "Plt relocs (" << soFile->pltRelIndexes.size() << ")"; - printIndexes(soFile->pltRelIndexes); - printRelocTable(in.relaPlt.get(), soFile->pltRelIndexes); + lld::outs() << ".rela.plt relocs (" << soFile->relaPltIndexes.size() << ")"; + printIndexes(soFile->relaPltIndexes); + printRelaTable(in.relaPlt.get(), soFile->relaPltIndexes); } } @@ -659,13 +671,13 @@ template void AdltWriter::tracePhdrs() { << "\t" << p->firstSec->name << '\n'; }; - auto &common = ctx->adlt.commonProgramHeaders; + auto &common = adltCtx->commonProgramHeaders; lld::outs() << "Common Program Headers (" << common.size() << ")"; printIndexes(common); printPhTable(common); - for (auto *file : ctx->sharedFilesExtended) - if (auto *soFile = ctx->adlt.getSoExt(file)) { + for (auto *file : adltCtx->sharedFilesExtended) + if (auto *soFile = adltCtx->getSoExt(file)) { auto &headers = soFile->programHeaders; lld::outs() << soFile->soName << "\n"; lld::outs() << "Program headers (" << headers.size() << ")"; @@ -790,7 +802,7 @@ template static void markUsedLocalSymbols() { // See MarkLive::resolveReloc(). if (config->gcSections) return; - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) { ObjFile *f = cast>(file); for (InputSectionBase *s : f->getSections()) { @@ -862,7 +874,7 @@ template void Writer::copyLocalSymbols() { llvm::TimeTraceScope timeScope("Add local symbols"); if (config->copyRelocs && config->discard != DiscardPolicy::None) markUsedLocalSymbols(); - auto files = /*config->adlt ? ctx->sharedFilesExtended :*/ ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) { for (Symbol *b : file->getLocalSymbols()) { assert(b->isLocal() && "should have been caught in initializeSymbols()"); @@ -1189,7 +1201,7 @@ void PhdrEntry::add(OutputSection *sec) { // OHOS_LOCAL begin if (config->adlt) { - if (ctx->adlt.withCfi && p_type == PT_LOAD) { + if (adltCtx->withCfi && p_type == PT_LOAD) { // check cfi.h: LIBRARY_ALIGNMENT and _BITS constexpr uint32_t kCFILibraryAlignment = 1UL << 18; firstSec->alignment = kCFILibraryAlignment; @@ -1489,7 +1501,7 @@ static DenseMap buildSectionOrder() { for (Symbol *sym : symtab->symbols()) addSym(*sym); - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (ELFFileBase *file : files) for (Symbol *sym : file->getLocalSymbols()) addSym(*sym); @@ -1906,7 +1918,7 @@ template void Writer::finalizeAddressDependentContent() { // block sections, input sections can shrink when the jump instructions at // the end of the section are relaxed. static void fixSymbolsAfterShrinking() { - auto files = config->adlt ? ctx->sharedFilesExtended : ctx->objectFiles; + auto files = ctx->objectFiles; for (InputFile *File : files) { parallelForEach(File->getSymbols(), [&](Symbol *Sym) { auto *def = dyn_cast(Sym); @@ -2127,7 +2139,7 @@ template void Writer::finalizeSections() { // copy relocations, etc. Note that relocations for non-alloc sections are // directly processed by InputSection::relocateNonAlloc. if (config->adlt) - for (auto &it : llvm::enumerate(ctx->sharedFilesExtended)) { + for (auto &it : llvm::enumerate(adltCtx->sharedFilesExtended)) { auto *soFile = cast>(it.value()); auto sections = soFile->getSections(); // scan .rela.dyn (base: SHT_NULL) @@ -2207,9 +2219,10 @@ template void Writer::finalizeSections() { if (sym->includeInDynsym()) { partitions[sym->partition - 1].dynSymTab->addSymbol(sym); - if (auto *file = dyn_cast_or_null(sym->file)) - if (file->isNeeded && !sym->isUndefined()) - addVerneed(sym); + if (!config->adlt) // ADLT support ver syms + if (auto *file = dyn_cast_or_null(sym->file)) + if (file->isNeeded && !sym->isUndefined()) + addVerneed(sym); } } @@ -2520,7 +2533,7 @@ SmallVector Writer::createPhdrs(Partition &part) { auto file = adltWriter.getInputSection(sec)->file; if (!file) return llvm::None; - return cast>(file)->orderIdx; + return adltCtx->getSoExt(file)->orderIdx; }; // OHOS_LOCAL end