[lld] 09dd0fe - [ELF] Move Out into Ctx. NFC
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 11:00:15 PDT 2024
Author: Fangrui Song
Date: 2024-08-03T11:00:11-07:00
New Revision: 09dd0febbbd59a0c470b3909690cae6618a2416a
URL: https://github.com/llvm/llvm-project/commit/09dd0febbbd59a0c470b3909690cae6618a2416a
DIFF: https://github.com/llvm/llvm-project/commit/09dd0febbbd59a0c470b3909690cae6618a2416a.diff
LOG: [ELF] Move Out into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons. ctx's hidden visibility optimizes generated instructions.
bufferStart and tlsPhdr, which are not OutputSection, can now be moved
outside of `Out`.
Added:
Modified:
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/InputSection.cpp
lld/ELF/LinkerScript.cpp
lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/Symbols.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/Target.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 183dc88a93e2f..162631aaba42a 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -44,6 +44,8 @@ class InputSectionBase;
class EhInputSection;
class Symbol;
class BitcodeCompiler;
+class OutputSection;
+struct PhdrEntry;
enum ELFKind : uint8_t {
ELFNoneKind,
@@ -478,6 +480,20 @@ struct DuplicateSymbol {
struct Ctx {
LinkerDriver driver;
+
+ // These variables are initialized by Writer and should not be used before
+ // Writer is initialized.
+ uint8_t *bufferStart;
+ PhdrEntry *tlsPhdr;
+ struct OutSections {
+ OutputSection *elfHeader;
+ OutputSection *programHeaders;
+ OutputSection *preinitArray;
+ OutputSection *initArray;
+ OutputSection *finiArray;
+ };
+ OutSections out;
+
SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
SmallVector<ELFFileBase *, 0> objectFiles;
SmallVector<SharedFile *, 0> sharedFiles;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a8c52e8c2b8e1..7b5b86363ac9c 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -93,6 +93,11 @@ void elf::errorOrWarn(const Twine &msg) {
void Ctx::reset() {
driver = LinkerDriver();
+
+ bufferStart = nullptr;
+ tlsPhdr = nullptr;
+ out = OutSections{};
+
memoryBuffers.clear();
objectFiles.clear();
sharedFiles.clear();
@@ -2934,7 +2939,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Create elfHeader early. We need a dummy section in
// addReservedSymbols to mark the created symbols as not absolute.
- Out::elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
+ ctx.out.elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
// We need to create some reserved symbols such as _end. Create them.
if (!config->relocatable)
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 570e485455bad..7f8dded51fdab 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -679,7 +679,7 @@ static int64_t getTlsTpOffset(const Symbol &s) {
// Variant 2. Static TLS blocks, followed by alignment padding are placed
// before TP. The alignment padding is added so that (TP - padding -
// p_memsz) is congruent to p_vaddr modulo p_align.
- PhdrEntry *tls = Out::tlsPhdr;
+ PhdrEntry *tls = ctx.tlsPhdr;
switch (config->emachine) {
// Variant 1.
case EM_ARM:
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 055fa21d44ca6..bf7491f11eff5 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1359,8 +1359,8 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
if ((paged || hasExplicitHeaders) &&
headerSize <= min - computeBase(min, hasExplicitHeaders)) {
min = alignDown(min - headerSize, config->maxPageSize);
- Out::elfHeader->addr = min;
- Out::programHeaders->addr = min + Out::elfHeader->size;
+ ctx.out.elfHeader->addr = min;
+ ctx.out.programHeaders->addr = min + ctx.out.elfHeader->size;
return;
}
@@ -1368,8 +1368,8 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
if (hasExplicitHeaders)
error("could not allocate headers");
- Out::elfHeader->ptLoad = nullptr;
- Out::programHeaders->ptLoad = nullptr;
+ ctx.out.elfHeader->ptLoad = nullptr;
+ ctx.out.programHeaders->ptLoad = nullptr;
firstPTLoad->firstSec = findFirstSection(firstPTLoad);
llvm::erase_if(phdrs,
@@ -1397,8 +1397,8 @@ LinkerScript::assignAddresses() {
} else {
// Assign addresses to headers right now.
dot = target->getImageBase();
- Out::elfHeader->addr = dot;
- Out::programHeaders->addr = dot + Out::elfHeader->size;
+ ctx.out.elfHeader->addr = dot;
+ ctx.out.programHeaders->addr = dot + ctx.out.elfHeader->size;
dot += getHeaderSize();
}
@@ -1543,9 +1543,9 @@ SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
PhdrEntry *phdr = make<PhdrEntry>(cmd.type, cmd.flags.value_or(PF_R));
if (cmd.hasFilehdr)
- phdr->add(Out::elfHeader);
+ phdr->add(ctx.out.elfHeader);
if (cmd.hasPhdrs)
- phdr->add(Out::programHeaders);
+ phdr->add(ctx.out.programHeaders);
if (cmd.lmaExpr) {
phdr->p_paddr = cmd.lmaExpr().getValue();
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 29f18f89274f3..509098eed2b83 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -39,14 +39,6 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-uint8_t *Out::bufferStart;
-PhdrEntry *Out::tlsPhdr;
-OutputSection *Out::elfHeader;
-OutputSection *Out::programHeaders;
-OutputSection *Out::preinitArray;
-OutputSection *Out::initArray;
-OutputSection *Out::finiArray;
-
SmallVector<OutputSection *, 0> elf::outputSections;
uint32_t OutputSection::getPhdrFlags() const {
@@ -272,7 +264,7 @@ static void sortByOrder(MutableArrayRef<InputSection *> in,
uint64_t elf::getHeaderSize() {
if (config->oFormatBinary)
return 0;
- return Out::elfHeader->size + Out::programHeaders->size;
+ return ctx.out.elfHeader->size + ctx.out.programHeaders->size;
}
void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) {
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 8c0c52f34ac9f..6ced44be47e46 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -150,19 +150,6 @@ llvm::ArrayRef<InputSection *>
getInputSections(const OutputSection &os,
SmallVector<InputSection *, 0> &storage);
-// All output sections that are handled by the linker specially are
-// globally accessible. Writer initializes them, so don't use them
-// until Writer is initialized.
-struct Out {
- static uint8_t *bufferStart;
- static PhdrEntry *tlsPhdr;
- static OutputSection *elfHeader;
- static OutputSection *programHeaders;
- static OutputSection *preinitArray;
- static OutputSection *initArray;
- static OutputSection *finiArray;
-};
-
uint64_t getHeaderSize();
LLVM_LIBRARY_VISIBILITY extern llvm::SmallVector<OutputSection *, 0>
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 263d4f35c5b9a..9cab824c37c3c 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -135,10 +135,10 @@ static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
// after sections are finalized. (e.g. Measuring the size of .rela.dyn
// for Android relocation packing requires knowing TLS symbol addresses
// during section finalization.)
- if (!Out::tlsPhdr || !Out::tlsPhdr->firstSec)
+ if (!ctx.tlsPhdr || !ctx.tlsPhdr->firstSec)
fatal(toString(d.file) +
" has an STT_TLS symbol but doesn't have an SHF_TLS section");
- return va - Out::tlsPhdr->firstSec->addr;
+ return va - ctx.tlsPhdr->firstSec->addr;
}
return va;
}
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 8ffa917635120..81068e65bcfea 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -553,7 +553,7 @@ void EhFrameSection::finalizeContents() {
// to get an FDE from an address to which FDE is applied. This function
// returns a list of such pairs.
SmallVector<EhFrameSection::FdeData, 0> EhFrameSection::getFdeData() const {
- uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
+ uint8_t *buf = ctx.bufferStart + getParent()->offset + outSecOff;
SmallVector<FdeData, 0> ret;
uint64_t va = getPartition().ehFrameHdr->getVA();
@@ -1493,17 +1493,17 @@ DynamicSection<ELFT>::computeContents() {
addInSec(DT_HASH, *part.hashTab);
if (isMain) {
- if (Out::preinitArray) {
- addInt(DT_PREINIT_ARRAY, Out::preinitArray->addr);
- addInt(DT_PREINIT_ARRAYSZ, Out::preinitArray->size);
+ if (ctx.out.preinitArray) {
+ addInt(DT_PREINIT_ARRAY, ctx.out.preinitArray->addr);
+ addInt(DT_PREINIT_ARRAYSZ, ctx.out.preinitArray->size);
}
- if (Out::initArray) {
- addInt(DT_INIT_ARRAY, Out::initArray->addr);
- addInt(DT_INIT_ARRAYSZ, Out::initArray->size);
+ if (ctx.out.initArray) {
+ addInt(DT_INIT_ARRAY, ctx.out.initArray->addr);
+ addInt(DT_INIT_ARRAYSZ, ctx.out.initArray->size);
}
- if (Out::finiArray) {
- addInt(DT_FINI_ARRAY, Out::finiArray->addr);
- addInt(DT_FINI_ARRAYSZ, Out::finiArray->size);
+ if (ctx.out.finiArray) {
+ addInt(DT_FINI_ARRAY, ctx.out.finiArray->addr);
+ addInt(DT_FINI_ARRAYSZ, ctx.out.finiArray->size);
}
if (Symbol *b = symtab.find(config->init))
@@ -3631,7 +3631,7 @@ void EhFrameHeader::writeTo(uint8_t *buf) {
// the starting PC from where FDEs covers, and the FDE's address.
// It is sorted by PC.
void EhFrameHeader::write() {
- uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
+ uint8_t *buf = ctx.bufferStart + getParent()->offset + outSecOff;
using FdeData = EhFrameSection::FdeData;
SmallVector<FdeData, 0> fdes = getPartition().ehFrame->getFdeData();
@@ -4647,13 +4647,6 @@ static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
}
template <class ELFT> void elf::createSyntheticSections() {
- // Initialize all pointers with NULL. This is needed because
- // you can call lld::elf::main more than once as a library.
- Out::tlsPhdr = nullptr;
- Out::preinitArray = nullptr;
- Out::initArray = nullptr;
- Out::finiArray = nullptr;
-
// Add the .interp section first because it is not a SyntheticSection.
// The removeUnusedSyntheticSections() function relies on the
// SyntheticSections coming last.
@@ -4670,8 +4663,8 @@ template <class ELFT> void elf::createSyntheticSections() {
if (config->zSectionHeader)
in.shStrTab = std::make_unique<StringTableSection>(".shstrtab", false);
- Out::programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
- Out::programHeaders->addralign = config->wordsize;
+ ctx.out.programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
+ ctx.out.programHeaders->addralign = config->wordsize;
if (config->strip != StripPolicy::All) {
in.strTab = std::make_unique<StringTableSection>(".strtab", false);
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 3e221646ce247..584e9270469d0 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -104,8 +104,8 @@ ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
continue;
const uint8_t *isecLoc =
- Out::bufferStart
- ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
+ ctx.bufferStart
+ ? (ctx.bufferStart + isec->getParent()->offset + isec->outSecOff)
: isec->contentMaybeDecompress().data();
if (isecLoc == nullptr) {
assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 2ceae215ae278..bb4b958d87c42 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -211,7 +211,7 @@ void elf::addReservedSymbols() {
gotOff = 0x8000;
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
- STT_NOTYPE, gotOff, /*size=*/0, Out::elfHeader});
+ STT_NOTYPE, gotOff, /*size=*/0, ctx.out.elfHeader});
ElfSym::globalOffsetTable = cast<Defined>(s);
}
@@ -219,23 +219,23 @@ void elf::addReservedSymbols() {
// this symbol unconditionally even when using a linker script, which
//
diff ers from the behavior implemented by GNU linker which only define
// this symbol if ELF headers are in the memory mapped segment.
- addOptionalRegular("__ehdr_start", Out::elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__ehdr_start", ctx.out.elfHeader, 0, STV_HIDDEN);
// __executable_start is not documented, but the expectation of at
// least the Android libc is that it points to the ELF header.
- addOptionalRegular("__executable_start", Out::elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__executable_start", ctx.out.elfHeader, 0, STV_HIDDEN);
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
// each DSO. The address of the symbol doesn't matter as long as they are
//
diff erent in
diff erent DSOs, so we chose the start address of the DSO.
- addOptionalRegular("__dso_handle", Out::elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__dso_handle", ctx.out.elfHeader, 0, STV_HIDDEN);
// If linker script do layout we do not need to create any standard symbols.
if (script->hasSectionsCommand)
return;
auto add = [](StringRef s, int64_t pos) {
- return addOptionalRegular(s, Out::elfHeader, pos, STV_DEFAULT);
+ return addOptionalRegular(s, ctx.out.elfHeader, pos, STV_DEFAULT);
};
ElfSym::bss = add("__bss_start", 0);
@@ -796,13 +796,14 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
return;
// __rela_iplt_{start,end} are initially defined relative to dummy section 0.
- // We'll override Out::elfHeader with relaDyn later when we are sure that
+ // We'll override ctx.out.elfHeader with relaDyn later when we are sure that
// .rela.dyn will be present in the output.
std::string name = config->isRela ? "__rela_iplt_start" : "__rel_iplt_start";
ElfSym::relaIpltStart =
- addOptionalRegular(name, Out::elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
name.replace(name.size() - 5, 5, "end");
- ElfSym::relaIpltEnd = addOptionalRegular(name, Out::elfHeader, 0, STV_HIDDEN);
+ ElfSym::relaIpltEnd =
+ addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
}
// This function generates assignments for predefined symbols (e.g. _end or
@@ -1693,9 +1694,9 @@ static void removeUnusedSyntheticSections() {
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!config->relocatable) {
- Out::preinitArray = findSection(".preinit_array");
- Out::initArray = findSection(".init_array");
- Out::finiArray = findSection(".fini_array");
+ ctx.out.preinitArray = findSection(".preinit_array");
+ ctx.out.initArray = findSection(".init_array");
+ ctx.out.finiArray = findSection(".fini_array");
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
// symbols for sections, so that the runtime can get the start and end
@@ -1722,13 +1723,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800. This symbol
// should only be defined in an executable. If .sdata does not exist, its
// value/section does not matter but it has to be relative, so set its
- // st_shndx arbitrarily to 1 (Out::elfHeader).
+ // st_shndx arbitrarily to 1 (ctx.out.elfHeader).
if (config->emachine == EM_RISCV) {
ElfSym::riscvGlobalPointer = nullptr;
if (!config->shared) {
OutputSection *sec = findSection(".sdata");
- addOptionalRegular(
- "__global_pointer$", sec ? sec : Out::elfHeader, 0x800, STV_DEFAULT);
+ addOptionalRegular("__global_pointer$", sec ? sec : ctx.out.elfHeader,
+ 0x800, STV_DEFAULT);
// Set riscvGlobalPointer to be used by the optional global pointer
// relaxation.
if (config->relaxGP) {
@@ -1916,8 +1917,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// This is a bit of a hack. A value of 0 means undef, so we set it
// to 1 to make __ehdr_start defined. The section number is not
// particularly relevant.
- Out::elfHeader->sectionIndex = 1;
- Out::elfHeader->size = sizeof(typename ELFT::Ehdr);
+ ctx.out.elfHeader->sectionIndex = 1;
+ ctx.out.elfHeader->size = sizeof(typename ELFT::Ehdr);
// Binary and relocatable output does not have PHDRS.
// The headers have to be created before finalize as that can influence the
@@ -1940,7 +1941,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
addPhdrForSection(part, SHT_RISCV_ATTRIBUTES, PT_RISCV_ATTRIBUTES,
PF_R);
}
- Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
+ ctx.out.programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
// Find the TLS segment. This happens before the section layout loop so that
// Android relocation packing can look up TLS symbol addresses. We only need
@@ -1948,7 +1949,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// to the main partition (see MarkLive.cpp).
for (PhdrEntry *p : mainPart->phdrs)
if (p->p_type == PT_TLS)
- Out::tlsPhdr = p;
+ ctx.tlsPhdr = p;
}
// Some symbols are defined in term of program headers. Now that we
@@ -2100,14 +2101,14 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
if (startSym || stopSym)
os->usedInExpression = true;
} else {
- addOptionalRegular(start, Out::elfHeader, 0);
- addOptionalRegular(end, Out::elfHeader, 0);
+ addOptionalRegular(start, ctx.out.elfHeader, 0);
+ addOptionalRegular(end, ctx.out.elfHeader, 0);
}
};
- define("__preinit_array_start", "__preinit_array_end", Out::preinitArray);
- define("__init_array_start", "__init_array_end", Out::initArray);
- define("__fini_array_start", "__fini_array_end", Out::finiArray);
+ define("__preinit_array_start", "__preinit_array_end", ctx.out.preinitArray);
+ define("__init_array_start", "__init_array_end", ctx.out.initArray);
+ define("__fini_array_start", "__fini_array_end", ctx.out.finiArray);
// As a special case, don't unnecessarily retain .ARM.exidx, which would
// create an empty PT_ARM_EXIDX.
@@ -2177,7 +2178,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
// The first phdr entry is PT_PHDR which describes the program header
// itself.
if (isMain)
- addHdr(PT_PHDR, PF_R)->add(Out::programHeaders);
+ addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders);
else
addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
@@ -2190,8 +2191,8 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
// need to be added here.
if (isMain) {
load = addHdr(PT_LOAD, flags);
- load->add(Out::elfHeader);
- load->add(Out::programHeaders);
+ load->add(ctx.out.elfHeader);
+ load->add(ctx.out.programHeaders);
}
}
@@ -2263,7 +2264,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
load && !sec->lmaExpr && sec->lmaRegion == load->firstSec->lmaRegion;
if (load && sec != relroEnd &&
sec->memRegion == load->firstSec->memRegion &&
- (sameLMARegion || load->lastSec == Out::programHeaders) &&
+ (sameLMARegion || load->lastSec == ctx.out.programHeaders) &&
(script->hasSectionsCommand || sec->type == SHT_NOBITS ||
load->lastSec->type != SHT_NOBITS)) {
load->p_flags |= newFlags;
@@ -2410,11 +2411,11 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
// p_align for dynamic TLS blocks (PR/24606), FreeBSD rtld has the same
// bug, musl (TLS Variant 1 architectures) before 1.1.23 handled TLS
// blocks correctly. We need to keep the workaround for a while.
- else if (Out::tlsPhdr && Out::tlsPhdr->firstSec == p->firstSec)
+ else if (ctx.tlsPhdr && ctx.tlsPhdr->firstSec == p->firstSec)
cmd->addrExpr = [] {
return alignToPowerOf2(script->getDot(), config->maxPageSize) +
alignToPowerOf2(script->getDot() % config->maxPageSize,
- Out::tlsPhdr->p_align);
+ ctx.tlsPhdr->p_align);
};
else
cmd->addrExpr = [] {
@@ -2446,9 +2447,8 @@ static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
// File offsets are not significant for .bss sections other than the first one
// in a PT_LOAD/PT_TLS. By convention, we keep section offsets monotonically
// increasing rather than setting to zero.
- if (os->type == SHT_NOBITS &&
- (!Out::tlsPhdr || Out::tlsPhdr->firstSec != os))
- return off;
+ if (os->type == SHT_NOBITS && (!ctx.tlsPhdr || ctx.tlsPhdr->firstSec != os))
+ return off;
// If the section is not in a PT_LOAD, we just have to align it.
if (!os->ptLoad)
@@ -2487,8 +2487,8 @@ static std::string rangeToString(uint64_t addr, uint64_t len) {
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
- Out::programHeaders->offset = Out::elfHeader->size;
- uint64_t off = Out::elfHeader->size + Out::programHeaders->size;
+ ctx.out.programHeaders->offset = ctx.out.elfHeader->size;
+ uint64_t off = ctx.out.elfHeader->size + ctx.out.programHeaders->size;
PhdrEntry *lastRX = nullptr;
for (Partition &part : partitions)
@@ -2709,10 +2709,10 @@ static uint16_t getELFType() {
}
template <class ELFT> void Writer<ELFT>::writeHeader() {
- writeEhdr<ELFT>(Out::bufferStart, *mainPart);
- writePhdrs<ELFT>(Out::bufferStart + sizeof(Elf_Ehdr), *mainPart);
+ writeEhdr<ELFT>(ctx.bufferStart, *mainPart);
+ writePhdrs<ELFT>(ctx.bufferStart + sizeof(Elf_Ehdr), *mainPart);
- auto *eHdr = reinterpret_cast<Elf_Ehdr *>(Out::bufferStart);
+ auto *eHdr = reinterpret_cast<Elf_Ehdr *>(ctx.bufferStart);
eHdr->e_type = getELFType();
eHdr->e_entry = getEntryAddr();
@@ -2730,7 +2730,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// the value. The sentinel values and fields are:
// e_shnum = 0, SHdrs[0].sh_size = number of sections.
// e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index.
- auto *sHdrs = reinterpret_cast<Elf_Shdr *>(Out::bufferStart + eHdr->e_shoff);
+ auto *sHdrs = reinterpret_cast<Elf_Shdr *>(ctx.bufferStart + eHdr->e_shoff);
size_t num = outputSections.size() + 1;
if (num >= SHN_LORESERVE)
sHdrs->sh_size = num;
@@ -2778,14 +2778,14 @@ template <class ELFT> void Writer<ELFT>::openFile() {
return;
}
buffer = std::move(*bufferOrErr);
- Out::bufferStart = buffer->getBufferStart();
+ ctx.bufferStart = buffer->getBufferStart();
}
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
parallel::TaskGroup tg;
for (OutputSection *sec : outputSections)
if (sec->flags & SHF_ALLOC)
- sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg);
+ sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
}
static void fillTrap(uint8_t *i, uint8_t *end) {
@@ -2804,11 +2804,10 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
// Fill the last page.
for (PhdrEntry *p : part.phdrs)
if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
- fillTrap(Out::bufferStart +
- alignDown(p->firstSec->offset + p->p_filesz, 4),
- Out::bufferStart +
- alignToPowerOf2(p->firstSec->offset + p->p_filesz,
- config->maxPageSize));
+ fillTrap(
+ ctx.bufferStart + alignDown(p->firstSec->offset + p->p_filesz, 4),
+ ctx.bufferStart + alignToPowerOf2(p->firstSec->offset + p->p_filesz,
+ config->maxPageSize));
// Round up the file size of the last segment to the page boundary iff it is
// an executable segment to ensure that other tools don't accidentally
@@ -2835,20 +2834,20 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
parallel::TaskGroup tg;
for (OutputSection *sec : outputSections)
if (isStaticRelSecType(sec->type))
- sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg);
+ sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
}
{
parallel::TaskGroup tg;
for (OutputSection *sec : outputSections)
if (!isStaticRelSecType(sec->type))
- sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg);
+ sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
}
// Finally, check that all dynamic relocation addends were written correctly.
if (config->checkDynamicRelocs && config->writeAddends) {
for (OutputSection *sec : outputSections)
if (isStaticRelSecType(sec->type))
- sec->checkDynRelAddends(Out::bufferStart);
+ sec->checkDynRelAddends(ctx.bufferStart);
}
}
@@ -2887,7 +2886,7 @@ template <class ELFT> void Writer<ELFT>::writeBuildId() {
size_t hashSize = mainPart->buildId->hashSize;
std::unique_ptr<uint8_t[]> buildId(new uint8_t[hashSize]);
MutableArrayRef<uint8_t> output(buildId.get(), hashSize);
- llvm::ArrayRef<uint8_t> input{Out::bufferStart, size_t(fileSize)};
+ llvm::ArrayRef<uint8_t> input{ctx.bufferStart, size_t(fileSize)};
// Fedora introduced build ID as "approximation of true uniqueness across all
// binaries that might be used by overlapping sets of people". It does not
More information about the llvm-commits
mailing list