[lld] eba30b3 - [ELF] Replace config-> with ctx.arg. in [IS]*.cpp
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 21 12:47:52 PDT 2024
Author: Fangrui Song
Date: 2024-09-21T12:47:47-07:00
New Revision: eba30b3370e1269ec9772e75c3818080cb1f272a
URL: https://github.com/llvm/llvm-project/commit/eba30b3370e1269ec9772e75c3818080cb1f272a
DIFF: https://github.com/llvm/llvm-project/commit/eba30b3370e1269ec9772e75c3818080cb1f272a.diff
LOG: [ELF] Replace config-> with ctx.arg. in [IS]*.cpp
Added:
Modified:
lld/ELF/ICF.cpp
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/InputSection.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
Removed:
################################################################################
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 952e4dfe982c80..9caff0bbe2b630 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -242,7 +242,7 @@ bool ICF<ELFT>::constantEq(const InputSection *secA, Relocs<RelTy> ra,
auto rai = ra.begin(), rae = ra.end(), rbi = rb.begin();
for (; rai != rae; ++rai, ++rbi) {
if (rai->r_offset != rbi->r_offset ||
- rai->getType(config->isMips64EL) != rbi->getType(config->isMips64EL))
+ rai->getType(ctx.arg.isMips64EL) != rbi->getType(ctx.arg.isMips64EL))
return false;
uint64_t addA = getAddend<ELFT>(*rai);
@@ -458,7 +458,7 @@ static void combineRelocHashes(unsigned cnt, InputSection *isec,
}
static void print(const Twine &s) {
- if (config->printIcfSections)
+ if (ctx.arg.printIcfSections)
message(s);
}
@@ -467,7 +467,7 @@ template <class ELFT> void ICF<ELFT>::run() {
// Compute isPreemptible early. We may add more symbols later, so this loop
// cannot be merged with the later computeIsPreemptible() pass which is used
// by scanRelocations().
- if (config->hasDynSymTab)
+ if (ctx.arg.hasDynSymTab)
for (Symbol *sym : symtab.getSymbols())
sym->isPreemptible = computeIsPreemptible(*sym);
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3f5f29591d2374..07a32a5ccea436 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -135,10 +135,10 @@ static void updateARMVFPArgs(const ARMAttributeParser &attributes,
return;
}
// Follow ld.bfd and error if there is a mix of calling conventions.
- if (config->armVFPArgs != arg && config->armVFPArgs != ARMVFPArgKind::Default)
+ if (ctx.arg.armVFPArgs != arg && ctx.arg.armVFPArgs != ARMVFPArgKind::Default)
error(toString(f) + ": incompatible Tag_ABI_VFP_args");
else
- config->armVFPArgs = arg;
+ ctx.arg.armVFPArgs = arg;
}
// The ARM support in lld makes some use of instructions that are not available
@@ -168,19 +168,19 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {
case ARMBuildAttrs::v6:
case ARMBuildAttrs::v6KZ:
case ARMBuildAttrs::v6K:
- config->armHasBlx = true;
+ ctx.arg.armHasBlx = true;
// Architectures used in pre-Cortex processors do not support
// The J1 = 1 J2 = 1 Thumb branch range extension, with the exception
// of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do.
break;
default:
// All other Architectures have BLX and extended branch encoding
- config->armHasBlx = true;
- config->armJ1J2BranchEncoding = true;
+ ctx.arg.armHasBlx = true;
+ ctx.arg.armJ1J2BranchEncoding = true;
if (arch != ARMBuildAttrs::v6_M && arch != ARMBuildAttrs::v6S_M)
// All Architectures used in Cortex processors with the exception
// of v6-M and v6S-M have the MOVT and MOVW instructions.
- config->armHasMovtMovw = true;
+ ctx.arg.armHasMovtMovw = true;
break;
}
@@ -191,7 +191,7 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {
return;
if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base &&
profile == ARMBuildAttrs::MicroControllerProfile)
- config->armCMSESupport = true;
+ ctx.arg.armCMSESupport = true;
// The thumb PLT entries require Thumb2 which can be used on multiple archs.
// For now, let's limit it to ones where ARM isn't available and we know have
@@ -200,8 +200,8 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {
attributes.getAttributeValue(ARMBuildAttrs::ARM_ISA_use);
std::optional<unsigned> thumb =
attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
- config->armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed;
- config->armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
+ ctx.arg.armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed;
+ ctx.arg.armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
}
InputFile::InputFile(Kind k, MemoryBufferRef m)
@@ -217,16 +217,16 @@ std::optional<MemoryBufferRef> elf::readFile(StringRef path) {
// The --chroot option changes our virtual root directory.
// This is useful when you are dealing with files created by --reproduce.
- if (!config->chroot.empty() && path.starts_with("/"))
- path = saver().save(config->chroot + path);
+ if (!ctx.arg.chroot.empty() && path.starts_with("/"))
+ path = saver().save(ctx.arg.chroot + path);
bool remapped = false;
- auto it = config->remapInputs.find(path);
- if (it != config->remapInputs.end()) {
+ auto it = ctx.arg.remapInputs.find(path);
+ if (it != ctx.arg.remapInputs.end()) {
path = it->second;
remapped = true;
} else {
- for (const auto &[pat, toFile] : config->remapInputsWildcards) {
+ for (const auto &[pat, toFile] : ctx.arg.remapInputsWildcards) {
if (pat.match(path)) {
path = toFile;
remapped = true;
@@ -244,7 +244,7 @@ std::optional<MemoryBufferRef> elf::readFile(StringRef path) {
}
log(path);
- config->dependencyFiles.insert(llvm::CachedHashString(path));
+ ctx.arg.dependencyFiles.insert(llvm::CachedHashString(path));
auto mbOrErr = MemoryBuffer::getFile(path, /*IsText=*/false,
/*RequiresNullTerminator=*/false);
@@ -268,15 +268,15 @@ static bool isCompatible(InputFile *file) {
if (!file->isElf() && !isa<BitcodeFile>(file))
return true;
- if (file->ekind == config->ekind && file->emachine == config->emachine) {
- if (config->emachine != EM_MIPS)
+ if (file->ekind == ctx.arg.ekind && file->emachine == ctx.arg.emachine) {
+ if (ctx.arg.emachine != EM_MIPS)
return true;
- if (isMipsN32Abi(file) == config->mipsN32Abi)
+ if (isMipsN32Abi(file) == ctx.arg.mipsN32Abi)
return true;
}
StringRef target =
- !config->bfdname.empty() ? config->bfdname : config->emulation;
+ !ctx.arg.bfdname.empty() ? ctx.arg.bfdname : ctx.arg.emulation;
if (!target.empty()) {
error(toString(file) + " is incompatible with " + target);
return false;
@@ -311,7 +311,7 @@ template <class ELFT> static void doParseFile(InputFile *file) {
return;
}
- if (config->trace)
+ if (ctx.arg.trace)
message(toString(file));
if (file->kind() == InputFile::ObjKind) {
@@ -419,7 +419,7 @@ StringRef InputFile::getNameForScript() const {
// is a form of autolinking and is called `dependent libraries`. It is currently
// unique to LLVM and lld.
static void addDependentLibrary(StringRef specifier, const InputFile *f) {
- if (!config->dependentLibraries)
+ if (!ctx.arg.dependentLibraries)
return;
if (std::optional<std::string> s = searchLibraryBaseName(specifier))
ctx.driver.addFile(saver().save(*s), /*withLOption=*/true);
@@ -599,7 +599,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
sections.resize(size);
for (size_t i = 0; i != size; ++i) {
const Elf_Shdr &sec = objSections[i];
- if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !config->relocatable) {
+ if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !ctx.arg.relocatable) {
StringRef name = check(obj.getSectionName(sec, shstrtab));
ArrayRef<char> data = CHECK(
this->getObj().template getSectionContentsAsArray<char>(sec), this);
@@ -619,7 +619,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
continue;
}
- if (sec.sh_type == SHT_ARM_ATTRIBUTES && config->emachine == EM_ARM) {
+ if (sec.sh_type == SHT_ARM_ATTRIBUTES && ctx.arg.emachine == EM_ARM) {
ARMAttributeParser attributes;
ArrayRef<uint8_t> contents =
check(this->getObj().getSectionContents(sec));
@@ -672,7 +672,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
symtab.comdatGroups.try_emplace(CachedHashStringRef(signature), this)
.second;
if (keepGroup) {
- if (!config->resolveGroups)
+ if (!ctx.arg.resolveGroups)
this->sections[i] = createInputSection(
i, sec, check(obj.getSectionName(sec, shstrtab)));
continue;
@@ -718,7 +718,7 @@ bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) {
// SHF_MERGE sections based both on their name and sh_entsize, but that seems
// to be more trouble than it is worth. Instead, we just use the regular (-O1)
// logic for -r.
- if (config->optimize == 0 && !config->relocatable)
+ if (ctx.arg.optimize == 0 && !ctx.arg.relocatable)
return false;
// A mergeable section with size 0 is useless because they don't have
@@ -786,7 +786,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
// This is compatible with GNU.
- if ((sec.sh_flags & SHF_EXCLUDE) && !config->relocatable) {
+ if ((sec.sh_flags & SHF_EXCLUDE) && !ctx.arg.relocatable) {
if (type == SHT_LLVM_CALL_GRAPH_PROFILE)
cgProfileSectionIndex = i;
if (type == SHT_LLVM_ADDRSIG) {
@@ -796,7 +796,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// in the address-significance table, which refers to symbols by index.
if (sec.sh_link != 0)
this->addrsigSec = &sec;
- else if (config->icf == ICFLevel::Safe)
+ else if (ctx.arg.icf == ICFLevel::Safe)
warn(toString(this) +
": --icf=safe conservatively ignores "
"SHT_LLVM_ADDRSIG [index " +
@@ -810,7 +810,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
switch (type) {
case SHT_GROUP: {
- if (!config->relocatable)
+ if (!ctx.arg.relocatable)
sections[i] = &InputSection::discarded;
StringRef signature =
cantFail(this->getELFSyms<ELFT>()[sec.sh_info].getName(stringTable));
@@ -846,7 +846,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// The concatenated output does not properly reflect the linking
// semantics. In addition, since we do not use the bitcode wrapper format,
// the concatenated raw bitcode would be invalid.
- if (config->relocatable && !config->fatLTOObjects) {
+ if (ctx.arg.relocatable && !ctx.arg.fatLTOObjects) {
sections[i] = &InputSection::discarded;
break;
}
@@ -856,7 +856,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));
if (type == SHT_LLVM_SYMPART)
ctx.hasSympart.store(true, std::memory_order_relaxed);
- else if (config->rejectMismatch &&
+ else if (ctx.arg.rejectMismatch &&
!isKnownSpecificSectionType(type, sec.sh_flags))
errorOrWarn(toString(this->sections[i]) + ": unknown section type 0x" +
Twine::utohexstr(type));
@@ -909,7 +909,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// `nullptr` for the normal case. However, if -r or --emit-relocs is
// specified, we need to copy them to the output. (Some post link analysis
// tools specify --emit-relocs to obtain the information.)
- if (config->copyRelocs) {
+ if (ctx.arg.copyRelocs) {
auto *isec = makeThreadLocal<InputSection>(
*this, sec, check(obj.getSectionName(sec, shstrtab)));
// If the relocated section is discarded (due to /DISCARD/ or
@@ -973,7 +973,7 @@ void readGnuProperty(const InputSection &sec, ObjFile<ELFT> &f) {
continue;
}
- uint32_t featureAndType = config->emachine == EM_AARCH64
+ uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;
@@ -996,7 +996,7 @@ void readGnuProperty(const InputSection &sec, ObjFile<ELFT> &f) {
if (size < 4)
reportFatal(place, "FEATURE_1_AND entry is too short");
f.andFeatures |= read32<ELFT::Endianness>(desc.data());
- } else if (config->emachine == EM_AARCH64 &&
+ } else if (ctx.arg.emachine == EM_AARCH64 &&
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
if (!f.aarch64PauthAbiCoreInfo.empty()) {
reportFatal(data.data(),
@@ -1080,7 +1080,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled
// for split stack will include a .note.GNU-split-stack section.
if (name == ".note.GNU-split-stack") {
- if (config->relocatable) {
+ if (ctx.arg.relocatable) {
error(
"cannot mix split-stack and non-split-stack in a relocatable link");
return &InputSection::discarded;
@@ -1109,7 +1109,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// The linker merges EH (exception handling) frames and creates a
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
- if (name == ".eh_frame" && !config->relocatable)
+ if (name == ".eh_frame" && !ctx.arg.relocatable)
return makeThreadLocal<EhInputSection>(*this, sec, name);
if ((sec.sh_flags & SHF_MERGE) && shouldMerge(sec, name))
@@ -1358,7 +1358,7 @@ unsigned SharedFile::vernauxNum;
SharedFile::SharedFile(MemoryBufferRef m, StringRef defaultSoName)
: ELFFileBase(SharedKind, getELFKind(m, ""), m), soName(defaultSoName),
- isNeeded(!config->asNeeded) {}
+ isNeeded(!ctx.arg.asNeeded) {}
// Parse the version definitions in the object file if present, and return a
// vector whose nth element contains a pointer to the Elf_Verdef for version
@@ -1578,7 +1578,7 @@ template <class ELFT> void SharedFile::parse() {
Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});
s->exportDynamic = true;
if (sym.getBinding() != STB_WEAK &&
- config->unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)
+ ctx.arg.unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)
requiredSymbols.push_back(s);
continue;
}
@@ -1588,7 +1588,7 @@ template <class ELFT> void SharedFile::parse() {
// In GNU ld < 2.31 (before 3be08ea4728b56d35e136af4e6fd3086ade17764), the
// MIPS port puts _gp_disp symbol into DSO files and incorrectly assigns
// VER_NDX_LOCAL. Workaround this bug.
- if (config->emachine == EM_MIPS && name == "_gp_disp")
+ if (ctx.arg.emachine == EM_MIPS && name == "_gp_disp")
continue;
error("corrupt input file: version definition index " + Twine(idx) +
" for symbol " + name + " is out of bounds\n>>> defined in " +
@@ -1702,7 +1702,7 @@ BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
this->lazy = lazy;
std::string path = mb.getBufferIdentifier().str();
- if (config->thinLTOIndexOnly)
+ if (ctx.arg.thinLTOIndexOnly)
path = replaceThinLTOSuffix(mb.getBufferIdentifier());
// ThinLTO assumes that all MemoryBufferRefs given to it have a unique
@@ -1917,7 +1917,7 @@ bool InputFile::shouldExtractForCommon(StringRef name) const {
}
std::string elf::replaceThinLTOSuffix(StringRef path) {
- auto [suffix, repl] = config->thinLTOObjectSuffixReplace;
+ auto [suffix, repl] = ctx.arg.thinLTOObjectSuffixReplace;
if (path.consume_back(suffix))
return (path + repl).str();
return std::string(path);
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index b0a74877d0aaeb..4e777761e143b1 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -105,7 +105,7 @@ class InputFile {
}
template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
- uint32_t symIndex = rel.getSymbol(config->isMips64EL);
+ uint32_t symIndex = rel.getSymbol(ctx.arg.isMips64EL);
return getSymbol(symIndex);
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 363afe36c2449e..12c4a622ebba8e 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -79,7 +79,7 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
// --force-group-allocation, the SHF_GROUP flag and section groups are retained.
static uint64_t getFlags(uint64_t flags) {
flags &= ~(uint64_t)SHF_INFO_LINK;
- if (config->resolveGroups)
+ if (ctx.arg.resolveGroups)
flags &= ~(uint64_t)SHF_GROUP;
return flags;
}
@@ -298,7 +298,7 @@ std::string InputSectionBase::getLocation(uint64_t offset) const {
// We don't have file for synthetic sections.
if (file == nullptr)
- return (config->outputFile + ":(" + secAndOffset).str();
+ return (ctx.arg.outputFile + ":(" + secAndOffset).str();
std::string filename = toString(file);
if (Defined *d = getEnclosingFunction(offset))
@@ -398,8 +398,8 @@ InputSectionBase *InputSection::getRelocatedSection() const {
template <class ELFT, class RelTy>
void InputSection::copyRelocations(uint8_t *buf) {
- if (config->relax && !config->relocatable &&
- (config->emachine == EM_RISCV || config->emachine == EM_LOONGARCH)) {
+ if (ctx.arg.relax && !ctx.arg.relocatable &&
+ (ctx.arg.emachine == EM_RISCV || ctx.arg.emachine == EM_LOONGARCH)) {
// On LoongArch and RISC-V, relaxation might change relocations: copy
// from internal ones that are updated by relaxation.
InputSectionBase *sec = getRelocatedSection();
@@ -412,7 +412,7 @@ void InputSection::copyRelocations(uint8_t *buf) {
const ObjFile<ELFT> &file;
Relocation operator()(const RelTy &rel) const {
// RelExpr is not used so set to a dummy value.
- return Relocation{R_NONE, rel.getType(config->isMips64EL), rel.r_offset,
+ return Relocation{R_NONE, rel.getType(ctx.arg.isMips64EL), rel.r_offset,
getAddend<ELFT>(rel), &file.getRelocTargetSym(rel)};
}
};
@@ -453,7 +453,7 @@ void InputSection::copyRelocations(uint8_t *buf,
// section, but for --emit-relocs it is a virtual address.
p->r_offset = sec->getVA(rel.offset);
p->setSymbolAndType(ctx.in.symTab->getSymbolIndex(sym), type,
- config->isMips64EL);
+ ctx.arg.isMips64EL);
if (sym.type == STT_SECTION) {
// We combine multiple section symbols into only one per
@@ -490,7 +490,7 @@ void InputSection::copyRelocations(uint8_t *buf,
if (!RelTy::HasAddend)
addend = target.getImplicitAddend(bufLoc, type);
- if (config->emachine == EM_MIPS &&
+ if (ctx.arg.emachine == EM_MIPS &&
target.getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
// Some MIPS relocations depend on "gp" value. By default,
// this value has 0x7ff0 offset from a .got section. But
@@ -513,10 +513,10 @@ void InputSection::copyRelocations(uint8_t *buf,
// writeSections will update the implicit addend. Non-SHF_ALLOC sections
// utilize relocateNonAlloc to process raw relocations and do not need
// this sec->relocations change.
- else if (config->relocatable && (sec->flags & SHF_ALLOC) &&
+ else if (ctx.arg.relocatable && (sec->flags & SHF_ALLOC) &&
type != target.noneRel)
sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
- } else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 &&
+ } else if (ctx.arg.emachine == EM_PPC && type == R_PPC_PLTREL24 &&
p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
// Similar to R_MIPS_GPREL{16,32}. If the addend of R_PPC_PLTREL24
// indicates that r30 is relative to the input section .got2
@@ -682,12 +682,12 @@ static int64_t getTlsTpOffset(const Symbol &s) {
PhdrEntry *tls = ctx.tlsPhdr;
if (!tls) // Reported an error in getSymVA
return 0;
- switch (config->emachine) {
+ switch (ctx.arg.emachine) {
// Variant 1.
case EM_ARM:
case EM_AARCH64:
- return s.getVA(0) + config->wordsize * 2 +
- ((tls->p_vaddr - config->wordsize * 2) & (tls->p_align - 1));
+ return s.getVA(0) + ctx.arg.wordsize * 2 +
+ ((tls->p_vaddr - ctx.arg.wordsize * 2) & (tls->p_align - 1));
case EM_MIPS:
case EM_PPC:
case EM_PPC64:
@@ -845,13 +845,13 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
// aware of the issue) while ensuring no overflow.
// Note: if the symbol is hidden, its binding has been converted to local,
// so we just check isUndefined() here.
- if (config->emachine == EM_ARM)
+ if (ctx.arg.emachine == EM_ARM)
dest = getARMUndefinedRelativeWeakVA(type, a, p);
- else if (config->emachine == EM_AARCH64)
+ else if (ctx.arg.emachine == EM_AARCH64)
dest = getAArch64UndefinedRelativeWeakVA(type, p) + a;
- else if (config->emachine == EM_PPC)
+ else if (ctx.arg.emachine == EM_PPC)
dest = p;
- else if (config->emachine == EM_RISCV)
+ else if (ctx.arg.emachine == EM_RISCV)
dest = getRISCVUndefinedRelativeWeakVA(type, p) + a;
else
dest = sym.getVA(a);
@@ -958,7 +958,7 @@ template <class ELFT, class RelTy>
void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
const unsigned bits = sizeof(typename ELFT::uint) * 8;
const TargetInfo &target = *elf::ctx.target;
- const auto emachine = config->emachine;
+ const auto emachine = ctx.arg.emachine;
const bool isDebug = isDebugSection(*this);
const bool isDebugLine = isDebug && name == ".debug_line";
std::optional<uint64_t> tombstone;
@@ -970,7 +970,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
else
tombstone = 0;
}
- for (const auto &patAndValue : llvm::reverse(config->deadRelocInNonAlloc))
+ for (const auto &patAndValue : llvm::reverse(ctx.arg.deadRelocInNonAlloc))
if (patAndValue.first.match(this->name)) {
tombstone = patAndValue.second;
break;
@@ -979,7 +979,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
const InputFile *f = this->file;
for (auto it = rels.begin(), end = rels.end(); it != end; ++it) {
const RelTy &rel = *it;
- const RelType type = rel.getType(config->isMips64EL);
+ const RelType type = rel.getType(ctx.arg.isMips64EL);
const uint64_t offset = rel.r_offset;
uint8_t *bufLoc = buf + offset;
int64_t addend = getAddend<ELFT>(rel);
@@ -1060,7 +1060,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
// explicit addend, such as RELA, remain unchanged and we can stop here.
// While content relocated by relocation types with an implicit addend, such
// as REL, needs the implicit addend updated.
- if (config->relocatable && (RelTy::HasAddend || sym.type != STT_SECTION))
+ if (ctx.arg.relocatable && (RelTy::HasAddend || sym.type != STT_SECTION))
continue;
// R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
@@ -1371,7 +1371,7 @@ static size_t findNull(StringRef s, size_t entSize) {
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(StringRef s, size_t entSize) {
- const bool live = !(flags & SHF_ALLOC) || !config->gcSections;
+ const bool live = !(flags & SHF_ALLOC) || !ctx.arg.gcSections;
const char *p = s.data(), *end = s.data() + s.size();
if (!std::all_of(end - entSize, end, [](char c) { return c == 0; }))
fatal(toString(this) + ": string is not null terminated");
@@ -1397,7 +1397,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
size_t entSize) {
size_t size = data.size();
assert((size % entSize) == 0);
- const bool live = !(flags & SHF_ALLOC) || !config->gcSections;
+ const bool live = !(flags & SHF_ALLOC) || !ctx.arg.gcSections;
pieces.resize_for_overwrite(size / entSize);
for (size_t i = 0, j = 0; i != size; i += entSize, j++)
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 258a78ab40bb57..4a4b4d3deed409 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -198,7 +198,7 @@ SmallVector<Symbol *, 0> SymbolTable::findAllByVersion(SymbolVersion ver,
void SymbolTable::handleDynamicList() {
SmallVector<Symbol *, 0> syms;
- for (SymbolVersion &ver : config->dynamicList) {
+ for (SymbolVersion &ver : ctx.arg.dynamicList) {
if (ver.hasWildcard)
syms = findAllByVersion(ver, /*includeNonDefault=*/true);
else
@@ -222,7 +222,7 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
return "VER_NDX_LOCAL";
if (ver == VER_NDX_GLOBAL)
return "VER_NDX_GLOBAL";
- return ("version '" + config->versionDefinitions[ver].name + "'").str();
+ return ("version '" + ctx.arg.versionDefinitions[ver].name + "'").str();
};
// Assign the version.
@@ -269,7 +269,7 @@ void SymbolTable::scanVersionScript() {
SmallString<128> buf;
// First, we assign versions to exact matching symbols,
// i.e. version definitions not containing any glob meta-characters.
- for (VersionDefinition &v : config->versionDefinitions) {
+ for (VersionDefinition &v : ctx.arg.versionDefinitions) {
auto assignExact = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
bool found =
assignExactVersion(pat, id, ver, /*includeNonDefault=*/false);
@@ -277,7 +277,7 @@ void SymbolTable::scanVersionScript() {
found |= assignExactVersion({(pat.name + "@" + v.name).toStringRef(buf),
pat.isExternCpp, /*hasWildCard=*/false},
id, ver, /*includeNonDefault=*/true);
- if (!found && !config->undefinedVersion)
+ if (!found && !ctx.arg.undefinedVersion)
errorOrWarn("version script assignment of '" + ver + "' to symbol '" +
pat.name + "' failed: symbol not defined");
};
@@ -300,7 +300,7 @@ void SymbolTable::scanVersionScript() {
id,
/*includeNonDefault=*/true);
};
- for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) {
+ for (VersionDefinition &v : llvm::reverse(ctx.arg.versionDefinitions)) {
for (SymbolVersion &pat : v.nonLocalPatterns)
if (pat.hasWildcard && pat.name != "*")
assignWildcard(pat, v.id, v.name);
@@ -311,7 +311,7 @@ void SymbolTable::scanVersionScript() {
// Then, assign versions to "*". In GNU linkers they have lower priority than
// other wildcards.
- for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) {
+ for (VersionDefinition &v : llvm::reverse(ctx.arg.versionDefinitions)) {
for (SymbolVersion &pat : v.nonLocalPatterns)
if (pat.hasWildcard && pat.name == "*")
assignWildcard(pat, v.id, v.name);
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index cd3fdce06f7788..65283adf4e5052 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -45,7 +45,7 @@ LLVM_ATTRIBUTE_UNUSED static inline void assertSymbols() {
// Returns a symbol for an error message.
static std::string maybeDemangleSymbol(StringRef symName) {
- return elf::config->demangle ? demangle(symName.str()) : symName.str();
+ return elf::ctx.arg.demangle ? demangle(symName.str()) : symName.str();
}
std::string lld::toString(const elf::Symbol &sym) {
@@ -109,11 +109,11 @@ static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
// a symbol value as-is (.dynamic section, `Elf_Ehdr::e_entry`
// field etc) do the same trick as compiler uses to mark microMIPS
// for CPU - set the less-significant bit.
- if (config->emachine == EM_MIPS && isMicroMips() &&
+ if (ctx.arg.emachine == EM_MIPS && isMicroMips() &&
((sym.stOther & STO_MIPS_MICROMIPS) || sym.hasFlag(NEEDS_COPY)))
va |= 1;
- if (d.isTls() && !config->relocatable) {
+ if (d.isTls() && !ctx.arg.relocatable) {
// Use the address of the TLS segment's first section rather than the
// segment's address, because segment addresses aren't initialized until
// after sections are finalized. (e.g. Measuring the size of .rela.dyn
@@ -177,7 +177,7 @@ uint64_t Symbol::getPltVA() const {
// While linking microMIPS code PLT code are always microMIPS
// code. Set the less-significant bit to track that fact.
// See detailed comment in the `getSymVA` function.
- if (config->emachine == EM_MIPS && isMicroMips())
+ if (ctx.arg.emachine == EM_MIPS && isMicroMips())
outVA |= 1;
return outVA;
}
@@ -242,7 +242,7 @@ void Symbol::parseSymbolVersion() {
// so we do not report error in this case. We also do not error
// if the symbol has a local version as it won't be in the dynamic
// symbol table.
- if (config->shared && versionId != VER_NDX_LOCAL)
+ if (ctx.arg.shared && versionId != VER_NDX_LOCAL)
error(toString(file) + ": symbol " + s + " has undefined version " +
verstr);
}
@@ -258,7 +258,7 @@ uint8_t Symbol::computeBinding() const {
auto v = visibility();
if ((v != STV_DEFAULT && v != STV_PROTECTED) || versionId == VER_NDX_LOCAL)
return STB_LOCAL;
- if (binding == STB_GNU_UNIQUE && !config->gnuUnique)
+ if (binding == STB_GNU_UNIQUE && !ctx.arg.gnuUnique)
return STB_GLOBAL;
return binding;
}
@@ -271,7 +271,7 @@ bool Symbol::includeInDynsym() const {
// expects undefined weak symbols not to exist in .dynsym, e.g.
// __pthread_mutex_lock reference in _dl_add_to_namespace_list,
// __pthread_initialize_minimal reference in csu/libc-start.c.
- return !(isUndefWeak() && config->noDynamicLinker);
+ return !(isUndefWeak() && ctx.arg.noDynamicLinker);
return exportDynamic || inDynamicList;
}
@@ -299,7 +299,7 @@ static void recordWhyExtract(const InputFile *reference,
}
void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
- if (!config->warnSymbolOrdering)
+ if (!ctx.arg.warnSymbolOrdering)
return;
// If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning is
@@ -309,7 +309,7 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
// Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols,
// but we don't have to be compatible here.
if (sym->isUndefined() && !cast<Undefined>(sym)->discardedSecIdx &&
- config->unresolvedSymbols == UnresolvedPolicy::Ignore)
+ ctx.arg.unresolvedSymbols == UnresolvedPolicy::Ignore)
return;
const InputFile *file = sym->file;
@@ -347,18 +347,18 @@ bool elf::computeIsPreemptible(const Symbol &sym) {
if (!sym.isDefined())
return true;
- if (!config->shared)
+ if (!ctx.arg.shared)
return false;
// If -Bsymbolic or --dynamic-list is specified, or -Bsymbolic-functions is
// specified and the symbol is STT_FUNC, the symbol is preemptible iff it is
// in the dynamic list. -Bsymbolic-non-weak-functions is a non-weak subset of
// -Bsymbolic-functions.
- if (config->symbolic ||
- (config->bsymbolic == BsymbolicKind::NonWeak &&
+ if (ctx.arg.symbolic ||
+ (ctx.arg.bsymbolic == BsymbolicKind::NonWeak &&
sym.binding != STB_WEAK) ||
- (config->bsymbolic == BsymbolicKind::Functions && sym.isFunc()) ||
- (config->bsymbolic == BsymbolicKind::NonWeakFunctions && sym.isFunc() &&
+ (ctx.arg.bsymbolic == BsymbolicKind::Functions && sym.isFunc()) ||
+ (ctx.arg.bsymbolic == BsymbolicKind::NonWeakFunctions && sym.isFunc() &&
sym.binding != STB_WEAK))
return sym.inDynamicList;
return true;
@@ -458,11 +458,11 @@ void Symbol::resolve(const Undefined &other) {
// A forms group 0. B form group 1. C and D (including their member object
// files) form group 2. E forms group 3. I think that you can see how this
// group assignment rule simulates the traditional linker's semantics.
- bool backref = config->warnBackrefs && other.file &&
+ bool backref = ctx.arg.warnBackrefs && other.file &&
file->groupId < other.file->groupId;
extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
recordWhyExtract(other.file, *file, *this);
// We don't report backward references to weak symbols as they can be
@@ -495,7 +495,7 @@ void Symbol::resolve(const Undefined &other) {
// Compare two symbols. Return true if the new symbol should win.
bool Symbol::shouldReplace(const Defined &other) const {
if (LLVM_UNLIKELY(isCommon())) {
- if (config->warnCommon)
+ if (ctx.arg.warnCommon)
warn("common " + getName() + " is overridden");
return !other.isWeak();
}
@@ -513,7 +513,7 @@ bool Symbol::shouldReplace(const Defined &other) const {
void elf::reportDuplicate(const Symbol &sym, const InputFile *newFile,
InputSectionBase *errSec, uint64_t errOffset) {
- if (config->allowMultipleDefinition)
+ if (ctx.arg.allowMultipleDefinition)
return;
// In glibc<2.32, crti.o has .gnu.linkonce.t.__x86.get_pc_thunk.bx, which
// is sort of proto-comdat. There is actually no duplicate if we have
@@ -568,13 +568,13 @@ void Symbol::resolve(const CommonSymbol &other) {
setVisibility(v == STV_DEFAULT ? ov : std::min(v, ov));
}
if (isDefined() && !isWeak()) {
- if (config->warnCommon)
+ if (ctx.arg.warnCommon)
warn("common " + getName() + " is overridden");
return;
}
if (CommonSymbol *oldSym = dyn_cast<CommonSymbol>(this)) {
- if (config->warnCommon)
+ if (ctx.arg.warnCommon)
warn("multiple common of " + getName());
oldSym->alignment = std::max(oldSym->alignment, other.alignment);
if (oldSym->size < other.size) {
@@ -617,7 +617,7 @@ void Symbol::resolve(const LazySymbol &other) {
// For common objects, we want to look for global or weak definitions that
// should be extracted as the canonical definition instead.
- if (LLVM_UNLIKELY(isCommon()) && elf::config->fortranCommon &&
+ if (LLVM_UNLIKELY(isCommon()) && elf::ctx.arg.fortranCommon &&
other.file->shouldExtractForCommon(getName())) {
ctx.backwardReferences.erase(this);
other.overwrite(*this);
@@ -644,7 +644,7 @@ void Symbol::resolve(const LazySymbol &other) {
const InputFile *oldFile = file;
other.extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
recordWhyExtract(oldFile, *file, *this);
}
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 05aed16bfb0dc9..57aa423f28cae5 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -365,7 +365,7 @@ class Defined : public Symbol {
uint8_t type, uint64_t value, uint64_t size, SectionBase *section)
: Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
size(size), section(section) {
- exportDynamic = config->exportDynamic;
+ exportDynamic = ctx.arg.exportDynamic;
}
void overwrite(Symbol &sym) const;
@@ -403,7 +403,7 @@ class CommonSymbol : public Symbol {
uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
: Symbol(CommonKind, file, name, binding, stOther, type),
alignment(alignment), size(size) {
- exportDynamic = config->exportDynamic;
+ exportDynamic = ctx.arg.exportDynamic;
}
void overwrite(Symbol &sym) const {
Symbol::overwrite(sym, CommonKind);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2239c3645ae921..ecb4a02acc19fe 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -60,11 +60,11 @@ using llvm::support::endian::write64le;
constexpr size_t MergeNoTailSection::numShards;
static uint64_t readUint(uint8_t *buf) {
- return config->is64 ? read64(buf) : read32(buf);
+ return ctx.arg.is64 ? read64(buf) : read32(buf);
}
static void writeUint(uint8_t *buf, uint64_t val) {
- if (config->is64)
+ if (ctx.arg.is64)
write64(buf, val);
else
write32(buf, val);
@@ -167,7 +167,7 @@ template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) {
options->kind = ODK_REGINFO;
options->size = getSize();
- if (!config->relocatable)
+ if (!ctx.arg.relocatable)
reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
memcpy(buf + sizeof(Elf_Mips_Options), ®info, sizeof(reginfo));
}
@@ -224,7 +224,7 @@ MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo reginfo)
}
template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) {
- if (!config->relocatable)
+ if (!ctx.arg.relocatable)
reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
memcpy(buf, ®info, sizeof(reginfo));
}
@@ -262,7 +262,7 @@ std::unique_ptr<MipsReginfoSection<ELFT>> MipsReginfoSection<ELFT>::create() {
InputSection *elf::createInterpSection() {
// StringSaver guarantees that the returned string ends with '\0'.
- StringRef s = saver().save(config->dynamicLinker);
+ StringRef s = saver().save(ctx.arg.dynamicLinker);
ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
return make<InputSection>(ctx.internalFile, SHF_ALLOC, SHT_PROGBITS, 1,
@@ -276,7 +276,7 @@ Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
if (ctx.in.symTab)
ctx.in.symTab->addSymbol(s);
- if (config->emachine == EM_ARM && !config->isLE && config->armBe8 &&
+ if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8 &&
(section.flags & SHF_EXECINSTR))
// Adding Linker generated mapping symbols to the arm specific mapping
// symbols list.
@@ -286,7 +286,7 @@ Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
}
static size_t getHashSize() {
- switch (config->buildId) {
+ switch (ctx.arg.buildId) {
case BuildIdKind::Fast:
return 8;
case BuildIdKind::Md5:
@@ -295,7 +295,7 @@ static size_t getHashSize() {
case BuildIdKind::Sha1:
return 20;
case BuildIdKind::Hexstring:
- return config->buildIdVector.size();
+ return ctx.arg.buildIdVector.size();
default:
llvm_unreachable("unknown BuildIdKind");
}
@@ -315,7 +315,7 @@ static size_t getHashSize() {
// we don't create this section.
GnuPropertySection::GnuPropertySection()
: SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
- config->wordsize, ".note.gnu.property") {}
+ ctx.arg.wordsize, ".note.gnu.property") {}
void GnuPropertySection::writeTo(uint8_t *buf) {
write32(buf, 4); // Name size
@@ -323,16 +323,16 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
memcpy(buf + 12, "GNU", 4); // Name string
- uint32_t featureAndType = config->emachine == EM_AARCH64
+ uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;
unsigned offset = 16;
- if (config->andFeatures != 0) {
+ if (ctx.arg.andFeatures != 0) {
write32(buf + offset + 0, featureAndType); // Feature type
write32(buf + offset + 4, 4); // Feature size
- write32(buf + offset + 8, config->andFeatures); // Feature flags
- if (config->is64)
+ write32(buf + offset + 8, ctx.arg.andFeatures); // Feature flags
+ if (ctx.arg.is64)
write32(buf + offset + 12, 0); // Padding
offset += 16;
}
@@ -347,8 +347,8 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
size_t GnuPropertySection::getSize() const {
uint32_t contentSize = 0;
- if (config->andFeatures != 0)
- contentSize += config->is64 ? 16 : 12;
+ if (ctx.arg.andFeatures != 0)
+ contentSize += ctx.arg.is64 ? 16 : 12;
if (!ctx.aarch64PauthAbiCoreInfo.empty())
contentSize += 4 + 4 + ctx.aarch64PauthAbiCoreInfo.size();
assert(contentSize != 0);
@@ -508,7 +508,7 @@ static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
void EhFrameSection::finalizeContents() {
assert(!this->size); // Not finalized.
- switch (config->ekind) {
+ switch (ctx.arg.ekind) {
case ELFNoneKind:
llvm_unreachable("invalid ekind");
case ELF32LEKind:
@@ -615,7 +615,7 @@ uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
size_t off = fdeOff + 8;
uint64_t addr = readFdeAddr(buf + off, enc & 0xf);
if ((enc & 0x70) == DW_EH_PE_absptr)
- return config->is64 ? addr : uint32_t(addr);
+ return ctx.arg.is64 ? addr : uint32_t(addr);
if ((enc & 0x70) == DW_EH_PE_pcrel)
return addr + getParent()->addr + off + outSecOff;
fatal("unknown FDE size relative encoding");
@@ -679,13 +679,13 @@ bool GotSection::addDynTlsEntry(const Symbol &sym) {
bool GotSection::addTlsIndex() {
if (tlsIndexOff != uint32_t(-1))
return false;
- tlsIndexOff = numEntries * config->wordsize;
+ tlsIndexOff = numEntries * ctx.arg.wordsize;
numEntries += 2;
return true;
}
uint32_t GotSection::getTlsDescOffset(const Symbol &sym) const {
- return sym.getTlsDescIdx() * config->wordsize;
+ return sym.getTlsDescIdx() * ctx.arg.wordsize;
}
uint64_t GotSection::getTlsDescAddr(const Symbol &sym) const {
@@ -693,20 +693,20 @@ uint64_t GotSection::getTlsDescAddr(const Symbol &sym) const {
}
uint64_t GotSection::getGlobalDynAddr(const Symbol &b) const {
- return this->getVA() + b.getTlsGdIdx() * config->wordsize;
+ return this->getVA() + b.getTlsGdIdx() * ctx.arg.wordsize;
}
uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
- return b.getTlsGdIdx() * config->wordsize;
+ return b.getTlsGdIdx() * ctx.arg.wordsize;
}
void GotSection::finalizeContents() {
- if (config->emachine == EM_PPC64 &&
+ if (ctx.arg.emachine == EM_PPC64 &&
numEntries <= ctx.target->gotHeaderEntriesNum &&
!ctx.sym.globalOffsetTable)
size = 0;
else
- size = numEntries * config->wordsize;
+ size = numEntries * ctx.arg.wordsize;
}
bool GotSection::isNeeded() const {
@@ -806,7 +806,7 @@ uint64_t MipsGotSection::getPageEntryOffset(const InputFile *f,
} else {
index = g.local16.lookup({nullptr, getMipsPageAddr(sym.getVA(addend))});
}
- return index * config->wordsize;
+ return index * ctx.arg.wordsize;
}
uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
@@ -814,22 +814,22 @@ uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
const FileGot &g = gots[f->mipsGotIndex];
Symbol *sym = const_cast<Symbol *>(&s);
if (sym->isTls())
- return g.tls.lookup(sym) * config->wordsize;
+ return g.tls.lookup(sym) * ctx.arg.wordsize;
if (sym->isPreemptible)
- return g.global.lookup(sym) * config->wordsize;
- return g.local16.lookup({sym, addend}) * config->wordsize;
+ return g.global.lookup(sym) * ctx.arg.wordsize;
+ return g.local16.lookup({sym, addend}) * ctx.arg.wordsize;
}
uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *f) const {
const FileGot &g = gots[f->mipsGotIndex];
- return g.dynTlsSymbols.lookup(nullptr) * config->wordsize;
+ return g.dynTlsSymbols.lookup(nullptr) * ctx.arg.wordsize;
}
uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *f,
const Symbol &s) const {
const FileGot &g = gots[f->mipsGotIndex];
Symbol *sym = const_cast<Symbol *>(&s);
- return g.dynTlsSymbols.lookup(sym) * config->wordsize;
+ return g.dynTlsSymbols.lookup(sym) * ctx.arg.wordsize;
}
const Symbol *MipsGotSection::getFirstGlobalEntry() const {
@@ -862,7 +862,7 @@ bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) {
size_t count = isPrimary ? headerEntriesNum : 0;
count += tmp.getIndexedEntriesNum();
- if (count * config->wordsize > config->mipsGotSize)
+ if (count * ctx.arg.wordsize > ctx.arg.mipsGotSize)
return false;
std::swap(tmp, dst);
@@ -872,9 +872,9 @@ bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) {
void MipsGotSection::finalizeContents() { updateAllocSize(); }
bool MipsGotSection::updateAllocSize() {
- size = headerEntriesNum * config->wordsize;
+ size = headerEntriesNum * ctx.arg.wordsize;
for (const FileGot &g : gots)
- size += g.getEntriesNum() * config->wordsize;
+ size += g.getEntriesNum() * ctx.arg.wordsize;
return false;
}
@@ -1013,20 +1013,20 @@ void MipsGotSection::build() {
// Create dynamic relocations for TLS entries.
for (std::pair<Symbol *, size_t> &p : got.tls) {
Symbol *s = p.first;
- uint64_t offset = p.second * config->wordsize;
+ uint64_t offset = p.second * ctx.arg.wordsize;
// When building a shared library we still need a dynamic relocation
// for the TP-relative offset as we don't know how much other data will
// be allocated before us in the static TLS block.
- if (s->isPreemptible || config->shared)
+ if (s->isPreemptible || ctx.arg.shared)
ctx.mainPart->relaDyn->addReloc(
{ctx.target->tlsGotRel, this, offset,
DynamicReloc::AgainstSymbolWithTargetVA, *s, 0, R_ABS});
}
for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
Symbol *s = p.first;
- uint64_t offset = p.second * config->wordsize;
+ uint64_t offset = p.second * ctx.arg.wordsize;
if (s == nullptr) {
- if (!config->shared)
+ if (!ctx.arg.shared)
continue;
ctx.mainPart->relaDyn->addReloc(
{ctx.target->tlsModuleIndexRel, this, offset});
@@ -1035,7 +1035,7 @@ void MipsGotSection::build() {
// for the module index. Therefore only checking for
// S->isPreemptible is not sufficient (this happens e.g. for
// thread-locals that have been marked as local through a linker script)
- if (!s->isPreemptible && !config->shared)
+ if (!s->isPreemptible && !ctx.arg.shared)
continue;
ctx.mainPart->relaDyn->addSymbolReloc(ctx.target->tlsModuleIndexRel,
*this, offset, *s);
@@ -1043,7 +1043,7 @@ void MipsGotSection::build() {
// symbols since it is known even in shared libraries
if (!s->isPreemptible)
continue;
- offset += config->wordsize;
+ offset += ctx.arg.wordsize;
ctx.mainPart->relaDyn->addSymbolReloc(ctx.target->tlsOffsetRel, *this,
offset, *s);
}
@@ -1056,24 +1056,24 @@ void MipsGotSection::build() {
// Dynamic relocations for "global" entries.
for (const std::pair<Symbol *, size_t> &p : got.global) {
- uint64_t offset = p.second * config->wordsize;
+ uint64_t offset = p.second * ctx.arg.wordsize;
ctx.mainPart->relaDyn->addSymbolReloc(ctx.target->relativeRel, *this,
offset, *p.first);
}
- if (!config->isPic)
+ if (!ctx.arg.isPic)
continue;
// Dynamic relocations for "local" entries in case of PIC.
for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
got.pagesMap) {
size_t pageCount = l.second.count;
for (size_t pi = 0; pi < pageCount; ++pi) {
- uint64_t offset = (l.second.firstIndex + pi) * config->wordsize;
+ uint64_t offset = (l.second.firstIndex + pi) * ctx.arg.wordsize;
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
l.first, int64_t(pi * 0x10000)});
}
}
for (const std::pair<GotEntry, size_t> &p : got.local16) {
- uint64_t offset = p.second * config->wordsize;
+ uint64_t offset = p.second * ctx.arg.wordsize;
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
DynamicReloc::AddendOnlyWithTargetVA,
*p.first.first, p.first.second, R_ABS});
@@ -1084,7 +1084,7 @@ void MipsGotSection::build() {
bool MipsGotSection::isNeeded() const {
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
- return !config->relocatable;
+ return !ctx.arg.relocatable;
}
uint64_t MipsGotSection::getGp(const InputFile *f) const {
@@ -1093,7 +1093,7 @@ uint64_t MipsGotSection::getGp(const InputFile *f) const {
// individual _gp values.
if (!f || f->mipsGotIndex == uint32_t(-1) || f->mipsGotIndex == 0)
return ctx.sym.mipsGp->getVA(0);
- return getVA() + gots[f->mipsGotIndex].startIndex * config->wordsize + 0x7ff0;
+ return getVA() + gots[f->mipsGotIndex].startIndex * ctx.arg.wordsize + 0x7ff0;
}
void MipsGotSection::writeTo(uint8_t *buf) {
@@ -1111,13 +1111,13 @@ void MipsGotSection::writeTo(uint8_t *buf) {
// we've been doing this for years, it is probably a safe bet to
// keep doing this for now. We really need to revisit this to see
// if we had to do this.
- writeUint(buf + config->wordsize, (uint64_t)1 << (config->wordsize * 8 - 1));
+ writeUint(buf + ctx.arg.wordsize, (uint64_t)1 << (ctx.arg.wordsize * 8 - 1));
for (const FileGot &g : gots) {
auto write = [&](size_t i, const Symbol *s, int64_t a) {
uint64_t va = a;
if (s)
va = s->getVA(a);
- writeUint(buf + i * config->wordsize, va);
+ writeUint(buf + i * ctx.arg.wordsize, va);
};
// Write 'page address' entries to the local part of the GOT.
for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
@@ -1143,15 +1143,15 @@ void MipsGotSection::writeTo(uint8_t *buf) {
write(p.second, p.first, 0);
for (const std::pair<Symbol *, size_t> &p : g.tls)
write(p.second, p.first,
- p.first->isPreemptible || config->shared ? 0 : -0x7000);
+ p.first->isPreemptible || ctx.arg.shared ? 0 : -0x7000);
for (const std::pair<Symbol *, size_t> &p : g.dynTlsSymbols) {
- if (p.first == nullptr && !config->shared)
+ if (p.first == nullptr && !ctx.arg.shared)
write(p.second, nullptr, 1);
else if (p.first && !p.first->isPreemptible) {
// If we are emitting a shared library with relocations we mustn't write
// anything to the GOT here. When using Elf_Rel relocations the value
// one will be treated as an addend and will cause crashes at runtime
- if (!config->shared)
+ if (!ctx.arg.shared)
write(p.second, nullptr, 1);
write(p.second + 1, p.first, -0x8000);
}
@@ -1164,11 +1164,11 @@ void MipsGotSection::writeTo(uint8_t *buf) {
// section. I don't know why we have a BSS style type for the section but it is
// consistent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
GotPltSection::GotPltSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, ctx.arg.wordsize,
".got.plt") {
- if (config->emachine == EM_PPC) {
+ if (ctx.arg.emachine == EM_PPC) {
name = ".plt";
- } else if (config->emachine == EM_PPC64) {
+ } else if (ctx.arg.emachine == EM_PPC64) {
type = SHT_NOBITS;
name = ".plt";
}
@@ -1202,12 +1202,12 @@ bool GotPltSection::isNeeded() const {
static StringRef getIgotPltName() {
// On ARM the IgotPltSection is part of the GotSection.
- if (config->emachine == EM_ARM)
+ if (ctx.arg.emachine == EM_ARM)
return ".got";
// On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
// needs to be named the same.
- if (config->emachine == EM_PPC64)
+ if (ctx.arg.emachine == EM_PPC64)
return ".plt";
return ".got.plt";
@@ -1217,7 +1217,7 @@ static StringRef getIgotPltName() {
// with the IgotPltSection.
IgotPltSection::IgotPltSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- config->emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
+ ctx.arg.emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
ctx.target->gotEntrySize, getIgotPltName()) {}
void IgotPltSection::addEntry(Symbol &sym) {
@@ -1280,7 +1280,7 @@ static unsigned getVerDefNum() {
template <class ELFT>
DynamicSection<ELFT>::DynamicSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, config->wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, ctx.arg.wordsize,
".dynamic") {
this->entsize = ELFT::Is64Bits ? 16 : 8;
@@ -1288,7 +1288,7 @@ DynamicSection<ELFT>::DynamicSection()
// which passes -z rodynamic.
// See "Special Section" in Chapter 4 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (config->emachine == EM_MIPS || config->zRodynamic)
+ if (ctx.arg.emachine == EM_MIPS || ctx.arg.zRodynamic)
this->flags = SHF_ALLOC;
}
@@ -1327,58 +1327,58 @@ DynamicSection<ELFT>::computeContents() {
entries.emplace_back(tag, sec.getVA());
};
- for (StringRef s : config->filterList)
+ for (StringRef s : ctx.arg.filterList)
addInt(DT_FILTER, part.dynStrTab->addString(s));
- for (StringRef s : config->auxiliaryList)
+ for (StringRef s : ctx.arg.auxiliaryList)
addInt(DT_AUXILIARY, part.dynStrTab->addString(s));
- if (!config->rpath.empty())
- addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH,
- part.dynStrTab->addString(config->rpath));
+ if (!ctx.arg.rpath.empty())
+ addInt(ctx.arg.enableNewDtags ? DT_RUNPATH : DT_RPATH,
+ part.dynStrTab->addString(ctx.arg.rpath));
for (SharedFile *file : ctx.sharedFiles)
if (file->isNeeded)
addInt(DT_NEEDED, part.dynStrTab->addString(file->soName));
if (isMain) {
- if (!config->soName.empty())
- addInt(DT_SONAME, part.dynStrTab->addString(config->soName));
+ if (!ctx.arg.soName.empty())
+ addInt(DT_SONAME, part.dynStrTab->addString(ctx.arg.soName));
} else {
- if (!config->soName.empty())
- addInt(DT_NEEDED, part.dynStrTab->addString(config->soName));
+ if (!ctx.arg.soName.empty())
+ addInt(DT_NEEDED, part.dynStrTab->addString(ctx.arg.soName));
addInt(DT_SONAME, part.dynStrTab->addString(part.name));
}
// Set DT_FLAGS and DT_FLAGS_1.
uint32_t dtFlags = 0;
uint32_t dtFlags1 = 0;
- if (config->bsymbolic == BsymbolicKind::All)
+ if (ctx.arg.bsymbolic == BsymbolicKind::All)
dtFlags |= DF_SYMBOLIC;
- if (config->zGlobal)
+ if (ctx.arg.zGlobal)
dtFlags1 |= DF_1_GLOBAL;
- if (config->zInitfirst)
+ if (ctx.arg.zInitfirst)
dtFlags1 |= DF_1_INITFIRST;
- if (config->zInterpose)
+ if (ctx.arg.zInterpose)
dtFlags1 |= DF_1_INTERPOSE;
- if (config->zNodefaultlib)
+ if (ctx.arg.zNodefaultlib)
dtFlags1 |= DF_1_NODEFLIB;
- if (config->zNodelete)
+ if (ctx.arg.zNodelete)
dtFlags1 |= DF_1_NODELETE;
- if (config->zNodlopen)
+ if (ctx.arg.zNodlopen)
dtFlags1 |= DF_1_NOOPEN;
- if (config->pie)
+ if (ctx.arg.pie)
dtFlags1 |= DF_1_PIE;
- if (config->zNow) {
+ if (ctx.arg.zNow) {
dtFlags |= DF_BIND_NOW;
dtFlags1 |= DF_1_NOW;
}
- if (config->zOrigin) {
+ if (ctx.arg.zOrigin) {
dtFlags |= DF_ORIGIN;
dtFlags1 |= DF_1_ORIGIN;
}
- if (!config->zText)
+ if (!ctx.arg.zText)
dtFlags |= DF_TEXTREL;
- if (ctx.hasTlsIe && config->shared)
+ if (ctx.hasTlsIe && ctx.arg.shared)
dtFlags |= DF_STATIC_TLS;
if (dtFlags)
@@ -1394,7 +1394,7 @@ DynamicSection<ELFT>::computeContents() {
// systems (currently only Fuchsia OS) provide other means to give the
// debugger this information. Such systems may choose make .dynamic read-only.
// If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
- if (!config->shared && !config->relocatable && !config->zRodynamic)
+ if (!ctx.arg.shared && !ctx.arg.relocatable && !ctx.arg.zRodynamic)
addInt(DT_DEBUG, 0);
if (part.relaDyn->isNeeded()) {
@@ -1402,26 +1402,26 @@ DynamicSection<ELFT>::computeContents() {
entries.emplace_back(part.relaDyn->sizeDynamicTag,
addRelaSz(*part.relaDyn));
- bool isRela = config->isRela;
+ bool isRela = ctx.arg.isRela;
addInt(isRela ? DT_RELAENT : DT_RELENT,
isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
// MIPS dynamic loader does not support RELCOUNT tag.
// The problem is in the tight relation between dynamic
// relocations and GOT. So do not emit this tag on MIPS.
- if (config->emachine != EM_MIPS) {
+ if (ctx.arg.emachine != EM_MIPS) {
size_t numRelativeRels = part.relaDyn->getRelativeRelocCount();
- if (config->zCombreloc && numRelativeRels)
+ if (ctx.arg.zCombreloc && numRelativeRels)
addInt(isRela ? DT_RELACOUNT : DT_RELCOUNT, numRelativeRels);
}
}
if (part.relrDyn && part.relrDyn->getParent() &&
!part.relrDyn->relocs.empty()) {
- addInSec(config->useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
+ addInSec(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
*part.relrDyn);
- addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
+ addInt(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
part.relrDyn->getParent()->size);
- addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
+ addInt(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
sizeof(Elf_Relr));
}
if (part.relrAuthDyn && part.relrAuthDyn->getParent() &&
@@ -1433,7 +1433,7 @@ DynamicSection<ELFT>::computeContents() {
if (isMain && ctx.in.relaPlt->isNeeded()) {
addInSec(DT_JMPREL, *ctx.in.relaPlt);
entries.emplace_back(DT_PLTRELSZ, addPltRelSz());
- switch (config->emachine) {
+ switch (ctx.arg.emachine) {
case EM_MIPS:
addInSec(DT_MIPS_PLTGOT, *ctx.in.gotPlt);
break;
@@ -1462,19 +1462,19 @@ DynamicSection<ELFT>::computeContents() {
addInSec(DT_PLTGOT, *ctx.in.gotPlt);
break;
}
- addInt(DT_PLTREL, config->isRela ? DT_RELA : DT_REL);
+ addInt(DT_PLTREL, ctx.arg.isRela ? DT_RELA : DT_REL);
}
- if (config->emachine == EM_AARCH64) {
- if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+ if (ctx.arg.emachine == EM_AARCH64) {
+ if (ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
addInt(DT_AARCH64_BTI_PLT, 0);
- if (config->zPacPlt)
+ if (ctx.arg.zPacPlt)
addInt(DT_AARCH64_PAC_PLT, 0);
if (hasMemtag()) {
- addInt(DT_AARCH64_MEMTAG_MODE, config->androidMemtagMode == NT_MEMTAG_LEVEL_ASYNC);
- addInt(DT_AARCH64_MEMTAG_HEAP, config->androidMemtagHeap);
- addInt(DT_AARCH64_MEMTAG_STACK, config->androidMemtagStack);
+ addInt(DT_AARCH64_MEMTAG_MODE, ctx.arg.androidMemtagMode == NT_MEMTAG_LEVEL_ASYNC);
+ addInt(DT_AARCH64_MEMTAG_HEAP, ctx.arg.androidMemtagHeap);
+ addInt(DT_AARCH64_MEMTAG_STACK, ctx.arg.androidMemtagStack);
if (ctx.mainPart->memtagGlobalDescriptors->isNeeded()) {
addInSec(DT_AARCH64_MEMTAG_GLOBALS,
*ctx.mainPart->memtagGlobalDescriptors);
@@ -1488,7 +1488,7 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_SYMENT, sizeof(Elf_Sym));
addInSec(DT_STRTAB, *part.dynStrTab);
addInt(DT_STRSZ, part.dynStrTab->getSize());
- if (!config->zText)
+ if (!ctx.arg.zText)
addInt(DT_TEXTREL, 0);
if (part.gnuHashTab && part.gnuHashTab->getParent())
addInSec(DT_GNU_HASH, *part.gnuHashTab);
@@ -1509,10 +1509,10 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_FINI_ARRAYSZ, ctx.out.finiArray->size);
}
- if (Symbol *b = symtab.find(config->init))
+ if (Symbol *b = symtab.find(ctx.arg.init))
if (b->isDefined())
addInt(DT_INIT, b->getVA());
- if (Symbol *b = symtab.find(config->fini))
+ if (Symbol *b = symtab.find(ctx.arg.fini))
if (b->isDefined())
addInt(DT_FINI, b->getVA());
}
@@ -1532,7 +1532,7 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_VERNEEDNUM, needNum);
}
- if (config->emachine == EM_MIPS) {
+ if (ctx.arg.emachine == EM_MIPS) {
addInt(DT_MIPS_RLD_VERSION, 1);
addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
addInt(DT_MIPS_BASE_ADDRESS, ctx.target->getImageBase());
@@ -1545,7 +1545,7 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_MIPS_GOTSYM, part.dynSymTab->getNumSymbols());
addInSec(DT_PLTGOT, *ctx.in.mipsGot);
if (ctx.in.mipsRldMap) {
- if (!config->pie)
+ if (!ctx.arg.pie)
addInSec(DT_MIPS_RLD_MAP, *ctx.in.mipsRldMap);
// Store the offset to the .rld_map section
// relative to the address of the tag.
@@ -1556,18 +1556,18 @@ DynamicSection<ELFT>::computeContents() {
// DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent,
// glibc assumes the old-style BSS PLT layout which we don't support.
- if (config->emachine == EM_PPC)
+ if (ctx.arg.emachine == EM_PPC)
addInSec(DT_PPC_GOT, *ctx.in.got);
// Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
- if (config->emachine == EM_PPC64 && ctx.in.plt->isNeeded()) {
+ if (ctx.arg.emachine == EM_PPC64 && ctx.in.plt->isNeeded()) {
// The Glink tag points to 32 bytes before the first lazy symbol resolution
// stub, which starts directly after the header.
addInt(DT_PPC64_GLINK,
ctx.in.plt->getVA() + ctx.target->pltHeaderSize - 32);
}
- if (config->emachine == EM_PPC64)
+ if (ctx.arg.emachine == EM_PPC64)
addInt(DT_PPC64_OPT, getPPC64TargetInfo()->ppc64DynamicSectionOpt);
addInt(DT_NULL, 0);
@@ -1606,7 +1606,7 @@ int64_t DynamicReloc::computeAddend() const {
case AgainstSymbolWithTargetVA: {
uint64_t ca = InputSection::getRelocTargetVA(inputSec->file, type, addend,
getOffset(), *sym, expr);
- return config->is64 ? ca : SignExtend64<32>(ca);
+ return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
}
case MipsMultiGotPage:
assert(sym == nullptr);
@@ -1632,7 +1632,7 @@ RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
int32_t sizeDynamicTag,
bool combreloc,
unsigned concurrency)
- : SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
+ : SyntheticSection(SHF_ALLOC, type, ctx.arg.wordsize, name),
dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag),
relocsVec(concurrency), combreloc(combreloc) {}
@@ -1725,11 +1725,11 @@ void RelocationBaseSection::computeRels() {
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(StringRef name, bool combreloc,
unsigned concurrency)
- : RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
- config->isRela ? DT_RELA : DT_REL,
- config->isRela ? DT_RELASZ : DT_RELSZ, combreloc,
+ : RelocationBaseSection(name, ctx.arg.isRela ? SHT_RELA : SHT_REL,
+ ctx.arg.isRela ? DT_RELA : DT_REL,
+ ctx.arg.isRela ? DT_RELASZ : DT_RELSZ, combreloc,
concurrency) {
- this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ this->entsize = ctx.arg.isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
@@ -1737,10 +1737,10 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
for (const DynamicReloc &rel : relocs) {
auto *p = reinterpret_cast<Elf_Rela *>(buf);
p->r_offset = rel.r_offset;
- p->setSymbolAndType(rel.r_sym, rel.type, config->isMips64EL);
- if (config->isRela)
+ p->setSymbolAndType(rel.r_sym, rel.type, ctx.arg.isMips64EL);
+ if (ctx.arg.isRela)
p->r_addend = rel.addend;
- buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ buf += ctx.arg.isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
}
@@ -1749,8 +1749,8 @@ RelrBaseSection::RelrBaseSection(unsigned concurrency, bool isAArch64Auth)
SHF_ALLOC,
isAArch64Auth
? SHT_AARCH64_AUTH_RELR
- : (config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR),
- config->wordsize, isAArch64Auth ? ".relr.auth.dyn" : ".relr.dyn"),
+ : (ctx.arg.useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR),
+ ctx.arg.wordsize, isAArch64Auth ? ".relr.auth.dyn" : ".relr.dyn"),
relocsVec(concurrency) {}
void RelrBaseSection::mergeRels() {
@@ -1767,9 +1767,9 @@ template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
StringRef name, unsigned concurrency)
: RelocationBaseSection(
- name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
- config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
- config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
+ name, ctx.arg.isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
+ ctx.arg.isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
+ ctx.arg.isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
/*combreloc=*/false, concurrency) {
this->entsize = 1;
}
@@ -1840,9 +1840,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
r.r_offset = rel.getOffset();
r.setSymbolAndType(rel.getSymIndex(getPartition().dynSymTab.get()),
rel.type, false);
- r.r_addend = config->isRela ? rel.computeAddend() : 0;
+ r.r_addend = ctx.arg.isRela ? rel.computeAddend() : 0;
- if (r.getType(config->isMips64EL) == ctx.target->relativeRel)
+ if (r.getType(ctx.arg.isMips64EL) == ctx.target->relativeRel)
relatives.push_back(r);
else
nonRelatives.push_back(r);
@@ -1864,7 +1864,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
std::vector<Elf_Rela> group;
do {
group.push_back(*i++);
- } while (i != e && (i - 1)->r_offset + config->wordsize == i->r_offset);
+ } while (i != e && (i - 1)->r_offset + ctx.arg.wordsize == i->r_offset);
if (group.size() < 8)
ungroupedRelatives.insert(ungroupedRelatives.end(), group.begin(),
@@ -1909,9 +1909,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
for (auto i = nonRelatives.begin(), e = nonRelatives.end(); i != e;) {
auto j = i + 1;
while (j != e && i->r_info == j->r_info &&
- (!config->isRela || i->r_addend == j->r_addend))
+ (!ctx.arg.isRela || i->r_addend == j->r_addend))
++j;
- if (j - i < 3 || (config->isRela && i->r_addend != 0))
+ if (j - i < 3 || (ctx.arg.isRela && i->r_addend != 0))
ungroupedNonRelatives.insert(ungroupedNonRelatives.end(), i, j);
else
nonRelativeGroups.emplace_back(i, j);
@@ -1924,7 +1924,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
});
unsigned hasAddendIfRela =
- config->isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
+ ctx.arg.isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
uint64_t offset = 0;
uint64_t addend = 0;
@@ -1941,7 +1941,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
add(g[0].r_offset - offset);
add(ctx.target->relativeRel);
- if (config->isRela) {
+ if (ctx.arg.isRela) {
add(g[0].r_addend - addend);
addend = g[0].r_addend;
}
@@ -1950,9 +1950,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
add(g.size() - 1);
add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
- add(config->wordsize);
+ add(ctx.arg.wordsize);
add(ctx.target->relativeRel);
- if (config->isRela) {
+ if (ctx.arg.isRela) {
for (const auto &i : llvm::drop_begin(g)) {
add(i.r_addend - addend);
addend = i.r_addend;
@@ -1970,7 +1970,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
for (Elf_Rela &r : ungroupedRelatives) {
add(r.r_offset - offset);
offset = r.r_offset;
- if (config->isRela) {
+ if (ctx.arg.isRela) {
add(r.r_addend - addend);
addend = r.r_addend;
}
@@ -1997,7 +1997,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
add(r.r_offset - offset);
offset = r.r_offset;
add(r.r_info);
- if (config->isRela) {
+ if (ctx.arg.isRela) {
add(r.r_addend - addend);
addend = r.r_addend;
}
@@ -2020,7 +2020,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
template <class ELFT>
RelrSection<ELFT>::RelrSection(unsigned concurrency, bool isAArch64Auth)
: RelrBaseSection(concurrency, isAArch64Auth) {
- this->entsize = config->wordsize;
+ this->entsize = ctx.arg.wordsize;
}
template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
@@ -2109,7 +2109,7 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &strTabSec)
: SyntheticSection(strTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
strTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
- config->wordsize,
+ ctx.arg.wordsize,
strTabSec.isDynamic() ? ".dynsym" : ".symtab"),
strTabSec(strTabSec) {}
@@ -2148,7 +2148,7 @@ void SymbolTableBaseSection::finalizeContents() {
if (getPartition().gnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
getPartition().gnuHashTab->addSymbols(symbols);
- } else if (config->emachine == EM_MIPS) {
+ } else if (ctx.arg.emachine == EM_MIPS) {
llvm::stable_sort(symbols, sortMipsSymbols);
}
@@ -2228,7 +2228,7 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &strTabSec)
}
static BssSection *getCommonSec(Symbol *sym) {
- if (config->relocatable)
+ if (ctx.arg.relocatable)
if (auto *d = dyn_cast<Defined>(sym))
return dyn_cast_or_null<BssSection>(d->section);
return nullptr;
@@ -2291,7 +2291,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
// pointer equality by STO_MIPS_PLT flag. That is necessary to help
// dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
// https://sourceware.org/ml/binutils/2008-07/txt00000.txt
- if (config->emachine == EM_MIPS) {
+ if (ctx.arg.emachine == EM_MIPS) {
auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
for (SymbolTableEntry &ent : symbols) {
@@ -2313,7 +2313,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
eSym->st_other |= STO_MIPS_MICROMIPS;
}
}
- if (config->relocatable)
+ if (ctx.arg.relocatable)
if (auto *d = dyn_cast<Defined>(sym))
if (isMipsPIC<ELFT>(d))
eSym->st_other |= STO_MIPS_PIC;
@@ -2391,7 +2391,7 @@ size_t SymtabShndxSection::getSize() const {
// about .gnu.hash, you want to specify --hash-style=gnu. Otherwise, a
// safe bet is to specify --hash-style=both for backward compatibility.
GnuHashTableSection::GnuHashTableSection()
- : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, config->wordsize, ".gnu.hash") {
+ : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, ctx.arg.wordsize, ".gnu.hash") {
}
void GnuHashTableSection::finalizeContents() {
@@ -2404,11 +2404,11 @@ void GnuHashTableSection::finalizeContents() {
maskWords = 1;
} else {
uint64_t numBits = symbols.size() * 12;
- maskWords = NextPowerOf2(numBits / (config->wordsize * 8));
+ maskWords = NextPowerOf2(numBits / (ctx.arg.wordsize * 8));
}
size = 16; // Header
- size += config->wordsize * maskWords; // Bloom filter
+ size += ctx.arg.wordsize * maskWords; // Bloom filter
size += nBuckets * 4; // Hash buckets
size += symbols.size() * 4; // Hash values
}
@@ -2422,17 +2422,17 @@ void GnuHashTableSection::writeTo(uint8_t *buf) {
buf += 16;
// Write the 2-bit bloom filter.
- const unsigned c = config->is64 ? 64 : 32;
+ const unsigned c = ctx.arg.is64 ? 64 : 32;
for (const Entry &sym : symbols) {
// When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
// the word using bits [0:5] and [26:31].
size_t i = (sym.hash / c) & (maskWords - 1);
- uint64_t val = readUint(buf + i * config->wordsize);
+ uint64_t val = readUint(buf + i * ctx.arg.wordsize);
val |= uint64_t(1) << (sym.hash % c);
val |= uint64_t(1) << ((sym.hash >> Shift2) % c);
- writeUint(buf + i * config->wordsize, val);
+ writeUint(buf + i * ctx.arg.wordsize, val);
}
- buf += config->wordsize * maskWords;
+ buf += ctx.arg.wordsize * maskWords;
// Write the hash table.
uint32_t *buckets = reinterpret_cast<uint32_t *>(buf);
@@ -2543,20 +2543,20 @@ PltSection::PltSection()
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
headerSize(ctx.target->pltHeaderSize) {
// On PowerPC, this section contains lazy symbol resolvers.
- if (config->emachine == EM_PPC64) {
+ if (ctx.arg.emachine == EM_PPC64) {
name = ".glink";
addralign = 4;
}
// On x86 when IBT is enabled, this section contains the second PLT (lazy
// symbol resolvers).
- if ((config->emachine == EM_386 || config->emachine == EM_X86_64) &&
- (config->andFeatures & GNU_PROPERTY_X86_FEATURE_1_IBT))
+ if ((ctx.arg.emachine == EM_386 || ctx.arg.emachine == EM_X86_64) &&
+ (ctx.arg.andFeatures & GNU_PROPERTY_X86_FEATURE_1_IBT))
name = ".plt.sec";
// The PLT needs to be writable on SPARC as the dynamic linker will
// modify the instructions in the PLT entries.
- if (config->emachine == EM_SPARCV9)
+ if (ctx.arg.emachine == EM_SPARCV9)
this->flags |= SHF_WRITE;
}
@@ -2584,7 +2584,7 @@ size_t PltSection::getSize() const {
bool PltSection::isNeeded() const {
// For -z retpolineplt, .iplt needs the .plt header.
- return !entries.empty() || (config->zRetpolineplt && ctx.in.iplt->isNeeded());
+ return !entries.empty() || (ctx.arg.zRetpolineplt && ctx.in.iplt->isNeeded());
}
// Used by ARM to add mapping symbols in the PLT section, which aid
@@ -2601,7 +2601,7 @@ void PltSection::addSymbols() {
IpltSection::IpltSection()
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".iplt") {
- if (config->emachine == EM_PPC || config->emachine == EM_PPC64) {
+ if (ctx.arg.emachine == EM_PPC || ctx.arg.emachine == EM_PPC64) {
name = ".glink";
addralign = 4;
}
@@ -3027,7 +3027,7 @@ std::pair<uint32_t, uint32_t> DebugNamesBaseSection::computeEntryPool(
// Speed it up using multithreading, as the number of symbols can be in the
// order of millions.
const size_t concurrency =
- bit_floor(std::min<size_t>(config->threadCount, numShards));
+ bit_floor(std::min<size_t>(ctx.arg.threadCount, numShards));
const size_t shift = 32 - countr_zero(numShards);
const uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first;
DenseMap<CachedHashStringRef, size_t> maps[numShards];
@@ -3431,7 +3431,7 @@ createSymbols(
// Shard GdbSymbols by hash's high bits.
constexpr size_t numShards = 32;
const size_t concurrency =
- llvm::bit_floor(std::min<size_t>(config->threadCount, numShards));
+ llvm::bit_floor(std::min<size_t>(ctx.arg.threadCount, numShards));
const size_t shift = 32 - llvm::countr_zero(numShards);
auto map =
std::make_unique<DenseMap<CachedHashStringRef, size_t>[]>(numShards);
@@ -3672,9 +3672,9 @@ VersionDefinitionSection::VersionDefinitionSection()
StringRef VersionDefinitionSection::getFileDefName() {
if (!getPartition().name.empty())
return getPartition().name;
- if (!config->soName.empty())
- return config->soName;
- return config->outputFile;
+ if (!ctx.arg.soName.empty())
+ return ctx.arg.soName;
+ return ctx.arg.outputFile;
}
void VersionDefinitionSection::finalizeContents() {
@@ -3789,7 +3789,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
verneeds.emplace_back();
Verneed &vn = verneeds.back();
vn.nameStrTab = getPartition().dynStrTab->addString(f->soName);
- bool isLibc = config->relrGlibc && f->soName.starts_with("libc.so.");
+ bool isLibc = ctx.arg.relrGlibc && f->soName.starts_with("libc.so.");
bool isGlibc2 = false;
for (unsigned i = 0; i != f->vernauxs.size(); ++i) {
if (f->vernauxs[i] == 0)
@@ -3911,7 +3911,7 @@ void MergeNoTailSection::finalizeContents() {
// Concurrency level. Must be a power of 2 to avoid expensive modulo
// operations in the following tight loop.
const size_t concurrency =
- llvm::bit_floor(std::min<size_t>(config->threadCount, numShards));
+ llvm::bit_floor(std::min<size_t>(ctx.arg.threadCount, numShards));
// Add section pieces to the builders.
parallelFor(0, concurrency, [&](size_t threadId) {
@@ -3987,12 +3987,12 @@ void elf::combineEhSections() {
}
MipsRldMapSection::MipsRldMapSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, ctx.arg.wordsize,
".rld_map") {}
ARMExidxSyntheticSection::ARMExidxSyntheticSection()
: SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
- config->wordsize, ".ARM.exidx") {}
+ ctx.arg.wordsize, ".ARM.exidx") {}
static InputSection *findExidxSection(InputSection *isec) {
for (InputSection *d : isec->dependentSections)
@@ -4029,7 +4029,7 @@ bool ARMExidxSyntheticSection::addSection(InputSection *isec) {
// and we would have to erase at a late stage relocations from merged entries.
// Given that exception tables are already position independent and a binary
// analyzer could derive the relocations we choose to erase the relocations.
- if (config->emitRelocs && isec->type == SHT_REL)
+ if (ctx.arg.emitRelocs && isec->type == SHT_REL)
if (InputSectionBase *ex = isec->getRelocatedSection())
if (isa<InputSection>(ex) && ex->type == SHT_ARM_EXIDX)
return true;
@@ -4090,7 +4090,7 @@ void ARMExidxSyntheticSection::finalizeContents() {
// of sections.
if (!originalExecutableSections.empty())
executableSections = originalExecutableSections;
- else if (config->enableNonContiguousRegions)
+ else if (ctx.arg.enableNonContiguousRegions)
originalExecutableSections = executableSections;
// The executableSections and exidxSections that we use to derive the final
@@ -4128,7 +4128,7 @@ void ARMExidxSyntheticSection::finalizeContents() {
llvm::stable_sort(executableSections, compareByFilePosition);
sentinel = executableSections.back();
// std::optionally merge adjacent duplicate entries.
- if (config->mergeArmExidx) {
+ if (ctx.arg.mergeArmExidx) {
SmallVector<InputSection *, 0> selectedSections;
selectedSections.reserve(executableSections.size());
selectedSections.push_back(executableSections[0]);
@@ -4216,7 +4216,7 @@ bool ARMExidxSyntheticSection::isNeeded() const {
ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
- config->emachine == EM_PPC64 ? 16 : 4, ".text.thunk") {
+ ctx.arg.emachine == EM_PPC64 ? 16 : 4, ".text.thunk") {
this->parent = os;
this->outSecOff = off;
}
@@ -4293,7 +4293,7 @@ void PPC32Got2Section::finalizeContents() {
// allocated and filled in by the dynamic linker.
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- config->isPic ? SHT_NOBITS : SHT_PROGBITS, 8,
+ ctx.arg.isPic ? SHT_NOBITS : SHT_PROGBITS, 8,
".branch_lt") {}
uint64_t PPC64LongBranchTargetSection::getEntryVA(const Symbol *sym,
@@ -4319,7 +4319,7 @@ void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
// If linking non-pic we have the final addresses of the targets and they get
// written to the table directly. For pic the dynamic linker will allocate
// the section and fill it.
- if (config->isPic)
+ if (ctx.arg.isPic)
return;
for (auto entry : entries) {
@@ -4346,14 +4346,14 @@ bool PPC64LongBranchTargetSection::isNeeded() const {
static uint8_t getAbiVersion() {
// MIPS non-PIC executable gets ABI version 1.
- if (config->emachine == EM_MIPS) {
- if (!config->isPic && !config->relocatable &&
- (config->eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
+ if (ctx.arg.emachine == EM_MIPS) {
+ if (!ctx.arg.isPic && !ctx.arg.relocatable &&
+ (ctx.arg.eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
return 1;
return 0;
}
- if (config->emachine == EM_AMDGPU && !ctx.objectFiles.empty()) {
+ if (ctx.arg.emachine == EM_AMDGPU && !ctx.objectFiles.empty()) {
uint8_t ver = ctx.objectFiles[0]->abiVersion;
for (InputFile *file : ArrayRef(ctx.objectFiles).slice(1))
if (file->abiVersion != ver)
@@ -4372,16 +4372,16 @@ template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
eHdr->e_ident[EI_DATA] =
ELFT::Endianness == endianness::little ? ELFDATA2LSB : ELFDATA2MSB;
eHdr->e_ident[EI_VERSION] = EV_CURRENT;
- eHdr->e_ident[EI_OSABI] = config->osabi;
+ eHdr->e_ident[EI_OSABI] = ctx.arg.osabi;
eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
- eHdr->e_machine = config->emachine;
+ eHdr->e_machine = ctx.arg.emachine;
eHdr->e_version = EV_CURRENT;
- eHdr->e_flags = config->eflags;
+ eHdr->e_flags = ctx.arg.eflags;
eHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
eHdr->e_phnum = part.phdrs.size();
eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
- if (!config->relocatable) {
+ if (!ctx.arg.relocatable) {
eHdr->e_phoff = sizeof(typename ELFT::Ehdr);
eHdr->e_phentsize = sizeof(typename ELFT::Phdr);
}
@@ -4497,13 +4497,13 @@ void InStruct::reset() {
}
static bool needsInterpSection() {
- return !config->relocatable && !config->shared &&
- !config->dynamicLinker.empty() && ctx.script->needsInterpSection();
+ return !ctx.arg.relocatable && !ctx.arg.shared &&
+ !ctx.arg.dynamicLinker.empty() && ctx.script->needsInterpSection();
}
bool elf::hasMemtag() {
- return config->emachine == EM_AARCH64 &&
- config->androidMemtagMode != ELF::NT_MEMTAG_LEVEL_NONE;
+ return ctx.arg.emachine == EM_AARCH64 &&
+ ctx.arg.androidMemtagMode != ELF::NT_MEMTAG_LEVEL_NONE;
}
// Fully static executables don't support MTE globals at this point in time, as
@@ -4514,7 +4514,7 @@ bool elf::hasMemtag() {
// that ifuncs use in fully static executables.
bool elf::canHaveMemtagGlobals() {
return hasMemtag() &&
- (config->relocatable || config->shared || needsInterpSection());
+ (ctx.arg.relocatable || ctx.arg.shared || needsInterpSection());
}
constexpr char kMemtagAndroidNoteName[] = "Android";
@@ -4531,12 +4531,12 @@ void MemtagAndroidNote::writeTo(uint8_t *buf) {
buf += 12 + alignTo(sizeof(kMemtagAndroidNoteName), 4);
uint32_t value = 0;
- value |= config->androidMemtagMode;
- if (config->androidMemtagHeap)
+ value |= ctx.arg.androidMemtagMode;
+ if (ctx.arg.androidMemtagHeap)
value |= ELF::NT_MEMTAG_HEAP;
// Note, MTE stack is an ABI break. Attempting to run an MTE stack-enabled
// binary on Android 11 or 12 will result in a checkfail in the loader.
- if (config->androidMemtagStack)
+ if (ctx.arg.androidMemtagStack)
value |= ELF::NT_MEMTAG_STACK;
write32(buf, value); // note value
}
@@ -4549,16 +4549,16 @@ size_t MemtagAndroidNote::getSize() const {
void PackageMetadataNote::writeTo(uint8_t *buf) {
write32(buf, 4);
- write32(buf + 4, config->packageMetadata.size() + 1);
+ write32(buf + 4, ctx.arg.packageMetadata.size() + 1);
write32(buf + 8, FDO_PACKAGING_METADATA);
memcpy(buf + 12, "FDO", 4);
- memcpy(buf + 16, config->packageMetadata.data(),
- config->packageMetadata.size());
+ memcpy(buf + 16, ctx.arg.packageMetadata.data(),
+ ctx.arg.packageMetadata.size());
}
size_t PackageMetadataNote::getSize() const {
return sizeof(llvm::ELF::Elf64_Nhdr) + 4 +
- alignTo(config->packageMetadata.size() + 1, 4);
+ alignTo(ctx.arg.packageMetadata.size() + 1, 4);
}
// Helper function, return the size of the ULEB128 for 'v', optionally writing
@@ -4667,13 +4667,13 @@ template <class ELFT> void elf::createSyntheticSections() {
auto add = [](SyntheticSection &sec) { ctx.inputSections.push_back(&sec); };
- if (config->zSectionHeader)
+ if (ctx.arg.zSectionHeader)
ctx.in.shStrTab = std::make_unique<StringTableSection>(".shstrtab", false);
ctx.out.programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
- ctx.out.programHeaders->addralign = config->wordsize;
+ ctx.out.programHeaders->addralign = ctx.arg.wordsize;
- if (config->strip != StripPolicy::All) {
+ if (ctx.arg.strip != StripPolicy::All) {
ctx.in.strTab = std::make_unique<StringTableSection>(".strtab", false);
ctx.in.symTab = std::make_unique<SymbolTableSection<ELFT>>(*ctx.in.strTab);
ctx.in.symTabShndx = std::make_unique<SymtabShndxSection>();
@@ -4692,8 +4692,8 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*ctx.in.bssRelRo);
// Add MIPS-specific sections.
- if (config->emachine == EM_MIPS) {
- if (!config->shared && config->hasDynSymTab) {
+ if (ctx.arg.emachine == EM_MIPS) {
+ if (!ctx.arg.shared && ctx.arg.hasDynSymTab) {
ctx.in.mipsRldMap = std::make_unique<MipsRldMapSection>();
add(*ctx.in.mipsRldMap);
}
@@ -4705,9 +4705,9 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*ctx.in.mipsReginfo);
}
- StringRef relaDynName = config->isRela ? ".rela.dyn" : ".rel.dyn";
+ StringRef relaDynName = ctx.arg.isRela ? ".rela.dyn" : ".rel.dyn";
- const unsigned threadCount = config->threadCount;
+ const unsigned threadCount = ctx.arg.threadCount;
for (Partition &part : ctx.partitions) {
auto add = [&](SyntheticSection &sec) {
sec.partition = part.getNumber();
@@ -4724,7 +4724,7 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*part.programHeaders);
}
- if (config->buildId != BuildIdKind::None) {
+ if (ctx.arg.buildId != BuildIdKind::None) {
part.buildId = std::make_unique<BuildIdSection>();
add(*part.buildId);
}
@@ -4735,7 +4735,7 @@ template <class ELFT> void elf::createSyntheticSections() {
part.dynSymTab =
std::make_unique<SymbolTableSection<ELFT>>(*part.dynStrTab);
- if (config->relocatable)
+ if (ctx.arg.relocatable)
continue;
part.dynamic = std::make_unique<DynamicSection<ELFT>>();
@@ -4749,14 +4749,14 @@ template <class ELFT> void elf::createSyntheticSections() {
}
}
- if (config->androidPackDynRelocs)
+ if (ctx.arg.androidPackDynRelocs)
part.relaDyn = std::make_unique<AndroidPackedRelocationSection<ELFT>>(
relaDynName, threadCount);
else
part.relaDyn = std::make_unique<RelocationSection<ELFT>>(
- relaDynName, config->zCombreloc, threadCount);
+ relaDynName, ctx.arg.zCombreloc, threadCount);
- if (config->hasDynSymTab) {
+ if (ctx.arg.hasDynSymTab) {
add(*part.dynSymTab);
part.verSym = std::make_unique<VersionTableSection>();
@@ -4770,12 +4770,12 @@ template <class ELFT> void elf::createSyntheticSections() {
part.verNeed = std::make_unique<VersionNeedSection<ELFT>>();
add(*part.verNeed);
- if (config->gnuHash) {
+ if (ctx.arg.gnuHash) {
part.gnuHashTab = std::make_unique<GnuHashTableSection>();
add(*part.gnuHashTab);
}
- if (config->sysvHash) {
+ if (ctx.arg.sysvHash) {
part.hashTab = std::make_unique<HashTableSection>();
add(*part.hashTab);
}
@@ -4785,7 +4785,7 @@ template <class ELFT> void elf::createSyntheticSections() {
}
add(*part.relaDyn);
- if (config->relrPackDynRelocs) {
+ if (ctx.arg.relrPackDynRelocs) {
part.relrDyn = std::make_unique<RelrSection<ELFT>>(threadCount);
add(*part.relrDyn);
part.relrAuthDyn = std::make_unique<RelrSection<ELFT>>(
@@ -4793,20 +4793,20 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*part.relrAuthDyn);
}
- if (config->ehFrameHdr) {
+ if (ctx.arg.ehFrameHdr) {
part.ehFrameHdr = std::make_unique<EhFrameHeader>();
add(*part.ehFrameHdr);
}
part.ehFrame = std::make_unique<EhFrameSection>();
add(*part.ehFrame);
- if (config->emachine == EM_ARM) {
+ if (ctx.arg.emachine == EM_ARM) {
// This section replaces all the individual .ARM.exidx InputSections.
part.armExidx = std::make_unique<ARMExidxSyntheticSection>();
add(*part.armExidx);
}
- if (!config->packageMetadata.empty()) {
+ if (!ctx.arg.packageMetadata.empty()) {
part.packageMetadataNote = std::make_unique<PackageMetadataNote>();
add(*part.packageMetadataNote);
}
@@ -4817,7 +4817,7 @@ template <class ELFT> void elf::createSyntheticSections() {
// so that it is sorted after all other partitions. It also has other
// special handling (see createPhdrs() and combineEhSections()).
ctx.in.partEnd =
- std::make_unique<BssSection>(".part.end", config->maxPageSize, 1);
+ std::make_unique<BssSection>(".part.end", ctx.arg.maxPageSize, 1);
ctx.in.partEnd->partition = 255;
add(*ctx.in.partEnd);
@@ -4830,7 +4830,7 @@ template <class ELFT> void elf::createSyntheticSections() {
// Add .got. MIPS' .got is so
diff erent from the other archs,
// it has its own class.
- if (config->emachine == EM_MIPS) {
+ if (ctx.arg.emachine == EM_MIPS) {
ctx.in.mipsGot = std::make_unique<MipsGotSection>();
add(*ctx.in.mipsGot);
} else {
@@ -4838,12 +4838,12 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*ctx.in.got);
}
- if (config->emachine == EM_PPC) {
+ if (ctx.arg.emachine == EM_PPC) {
ctx.in.ppc32Got2 = std::make_unique<PPC32Got2Section>();
add(*ctx.in.ppc32Got2);
}
- if (config->emachine == EM_PPC64) {
+ if (ctx.arg.emachine == EM_PPC64) {
ctx.in.ppc64LongBranchTarget =
std::make_unique<PPC64LongBranchTargetSection>();
add(*ctx.in.ppc64LongBranchTarget);
@@ -4855,21 +4855,21 @@ template <class ELFT> void elf::createSyntheticSections() {
add(*ctx.in.igotPlt);
// Add .relro_padding if DATA_SEGMENT_RELRO_END is used; otherwise, add the
// section in the absence of PHDRS/SECTIONS commands.
- if (config->zRelro &&
+ if (ctx.arg.zRelro &&
((ctx.script->phdrsCommands.empty() && !ctx.script->hasSectionsCommand) ||
ctx.script->seenRelroEnd)) {
ctx.in.relroPadding = std::make_unique<RelroPaddingSection>();
add(*ctx.in.relroPadding);
}
- if (config->emachine == EM_ARM) {
+ if (ctx.arg.emachine == EM_ARM) {
ctx.in.armCmseSGSection = std::make_unique<ArmCmseSGSection>();
add(*ctx.in.armCmseSGSection);
}
// _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
// it as a relocation and ensure the referenced section is created.
- if (ctx.sym.globalOffsetTable && config->emachine != EM_MIPS) {
+ if (ctx.sym.globalOffsetTable && ctx.arg.emachine != EM_MIPS) {
if (ctx.target->gotBaseSymInGotPlt)
ctx.in.gotPlt->hasGotPltOffRel = true;
else
@@ -4879,17 +4879,17 @@ template <class ELFT> void elf::createSyntheticSections() {
// We always need to add rel[a].plt to output if it has entries.
// Even for static linking it can contain R_[*]_IRELATIVE relocations.
ctx.in.relaPlt = std::make_unique<RelocationSection<ELFT>>(
- config->isRela ? ".rela.plt" : ".rel.plt", /*sort=*/false,
+ ctx.arg.isRela ? ".rela.plt" : ".rel.plt", /*sort=*/false,
/*threadCount=*/1);
add(*ctx.in.relaPlt);
- if ((config->emachine == EM_386 || config->emachine == EM_X86_64) &&
- (config->andFeatures & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
+ if ((ctx.arg.emachine == EM_386 || ctx.arg.emachine == EM_X86_64) &&
+ (ctx.arg.andFeatures & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
ctx.in.ibtPlt = std::make_unique<IBTPltSection>();
add(*ctx.in.ibtPlt);
}
- if (config->emachine == EM_PPC)
+ if (ctx.arg.emachine == EM_PPC)
ctx.in.plt = std::make_unique<PPC32GlinkSection>();
else
ctx.in.plt = std::make_unique<PltSection>();
@@ -4897,15 +4897,15 @@ template <class ELFT> void elf::createSyntheticSections() {
ctx.in.iplt = std::make_unique<IpltSection>();
add(*ctx.in.iplt);
- if (config->andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty())
+ if (ctx.arg.andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty())
add(*make<GnuPropertySection>());
- if (config->debugNames) {
+ if (ctx.arg.debugNames) {
ctx.in.debugNames = std::make_unique<DebugNamesSection<ELFT>>();
add(*ctx.in.debugNames);
}
- if (config->gdbIndex) {
+ if (ctx.arg.gdbIndex) {
ctx.in.gdbIndex = GdbIndexSection::create<ELFT>();
add(*ctx.in.gdbIndex);
}
@@ -4915,7 +4915,7 @@ template <class ELFT> void elf::createSyntheticSections() {
// section to control the executable-ness of the stack area, but that
// is irrelevant these days. Stack area should always be non-executable
// by default. So we emit this section unconditionally.
- if (config->relocatable)
+ if (ctx.arg.relocatable)
add(*make<GnuStackSection>());
if (ctx.in.symTab)
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 8e2664d64118b7..6d0634e0a16e90 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -533,7 +533,7 @@ class RelocationBaseSection : public SyntheticSection {
RelType addendRelType) {
// Write the addends to the relocated address if required. We skip
// it if the written value would be zero.
- if (config->writeAddends && (expr != R_ADDEND || addend != 0))
+ if (ctx.arg.writeAddends && (expr != R_ADDEND || addend != 0))
sec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});
addReloc<shard>({dynType, &sec, offsetInSec, kind, sym, addend, expr});
}
@@ -551,7 +551,7 @@ class RelocationBaseSection : public SyntheticSection {
(d->type == llvm::ELF::SHT_RELA || d->type == llvm::ELF::SHT_REL ||
d->type == llvm::ELF::SHT_RELR ||
(d->type == llvm::ELF::SHT_AARCH64_AUTH_RELR &&
- config->emachine == llvm::ELF::EM_AARCH64));
+ ctx.arg.emachine == llvm::ELF::EM_AARCH64));
}
int32_t dynamicTag, sizeDynamicTag;
SmallVector<DynamicReloc, 0> relocs;
@@ -1190,7 +1190,7 @@ template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
class MipsRldMapSection final : public SyntheticSection {
public:
MipsRldMapSection();
- size_t getSize() const override { return config->wordsize; }
+ size_t getSize() const override { return ctx.arg.wordsize; }
void writeTo(uint8_t *buf) override {}
};
More information about the llvm-commits
mailing list