makeArrayRef(reinterpret_cast<uint8_t *>(buf.data() + first),
4 * (buf.size() - first)),
".text");
- inputSections.push_back(sec);
+ ctx.inputSections.push_back(sec);
for (Defined *sym : defined) {
sym->section = sec;
sym->value -= 4 * first;
class ELFFileBase;
class SharedFile;
class InputSectionBase;
+class EhInputSection;
class Symbol;
class BitcodeCompiler;
SmallVector<BinaryFile *, 0> binaryFiles;
SmallVector<BitcodeFile *, 0> bitcodeFiles;
SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;
+ SmallVector<InputSectionBase *, 0> inputSections;
+ SmallVector<EhInputSection *, 0> ehInputSections;
// Duplicate symbol candidates.
SmallVector<DuplicateSymbol, 0> duplicates;
// Symbols in a non-prevailing COMDAT group which should be changed to an
binaryFiles.clear();
bitcodeFiles.clear();
lazyBitcodeFiles.clear();
+ inputSections.clear();
+ ehInputSections.clear();
duplicates.clear();
nonPrevailingSyms.clear();
whyExtractRecords.clear();
elf::ctx.reset();
symtab = SymbolTable();
- inputSections.clear();
- ehInputSections.clear();
outputSections.clear();
symAux.clear();
auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
bss->file = s->file;
- inputSections.push_back(bss);
+ ctx.inputSections.push_back(bss);
Defined(s->file, StringRef(), s->binding, s->stOther, s->type,
/*value=*/0, s->size, bss)
.overwrite(*s);
if (!s || s == &InputSection::discarded)
continue;
if (LLVM_UNLIKELY(isa<EhInputSection>(s)))
- ehInputSections.push_back(cast<EhInputSection>(s));
+ ctx.ehInputSections.push_back(cast<EhInputSection>(s));
else
- inputSections.push_back(s);
+ ctx.inputSections.push_back(s);
}
}
for (BinaryFile *f : ctx.binaryFiles)
for (InputSectionBase *s : f->getSections())
- inputSections.push_back(cast<InputSection>(s));
+ ctx.inputSections.push_back(cast<InputSection>(s));
}
{
llvm::TimeTraceScope timeScope("Strip sections");
if (ctx.hasSympart.load(std::memory_order_relaxed)) {
- llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ llvm::erase_if(ctx.inputSections, [](InputSectionBase *s) {
if (s->type != SHT_LLVM_SYMPART)
return false;
invokeELFT(readSymbolPartitionSection, s);
// We do not want to emit debug sections if --strip-all
// or --strip-debug are given.
if (config->strip != StripPolicy::None) {
- llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ llvm::erase_if(ctx.inputSections, [](InputSectionBase *s) {
if (isDebugSection(*s))
return true;
if (auto *isec = dyn_cast<InputSection>(s))
// This adds a .comment section containing a version string.
if (!config->relocatable)
- inputSections.push_back(createCommentSection());
+ ctx.inputSections.push_back(createCommentSection());
// Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection.
invokeELFT(splitSections);
[&](InputSection &s) { s.eqClass[0] = s.eqClass[1] = ++uniqueId; });
// Collect sections to merge.
- for (InputSectionBase *sec : inputSections) {
+ for (InputSectionBase *sec : ctx.inputSections) {
auto *s = dyn_cast<InputSection>(sec);
if (s && s->eqClass[0] == 0) {
if (isEligible(s))
using namespace lld;
using namespace lld::elf;
-SmallVector<InputSectionBase *, 0> elf::inputSections;
-SmallVector<EhInputSection *, 0> elf::ehInputSections;
DenseSet<std::pair<const Symbol *, uint64_t>> elf::ppc64noTocRelax;
// Returns a string to construct an error message.
sec.name.startswith(".debug");
}
-// The list of all input sections.
-extern SmallVector<InputSectionBase *, 0> inputSections;
-extern SmallVector<EhInputSection *, 0> ehInputSections;
-
// The set of TOC entries (.toc + addend) for which we should not apply
// toc-indirect to toc-relative relaxation. const Symbol * refers to the
// STT_SECTION symbol associated to the .toc input section.
for (SectionCommand *cmd : outCmd.commands) {
if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
- isd->sectionBases = computeInputSections(isd, inputSections);
+ isd->sectionBases = computeInputSections(isd, ctx.inputSections);
for (InputSectionBase *s : isd->sectionBases)
s->parent = &outCmd;
ret.insert(ret.end(), isd->sectionBases.begin(), isd->sectionBases.end());
// to create target sections first. We do not want priority handling
// for synthetic sections because them are special.
size_t n = 0;
- for (InputSectionBase *isec : inputSections) {
+ for (InputSectionBase *isec : ctx.inputSections) {
// Process InputSection and MergeInputSection.
if (LLVM_LIKELY(isa<InputSection>(isec)))
- inputSections[n++] = isec;
+ ctx.inputSections[n++] = isec;
// In -r links, SHF_LINK_ORDER sections are added while adding their parent
// sections because we need to know the parent's output section before we
add(depSec);
}
// Keep just InputSection.
- inputSections.resize(n);
+ ctx.inputSections.resize(n);
// If no SECTIONS command was given, we should insert sections commands
// before others, so that we can handle scripts which refers them,
// that point to .eh_frames. Otherwise, the garbage collector would drop
// all of them. We also want to preserve personality routines and LSDA
// referenced by .eh_frame sections, so we scan them for that here.
- for (EhInputSection *eh : ehInputSections) {
+ for (EhInputSection *eh : ctx.ehInputSections) {
const RelsOrRelas<ELFT> rels = eh->template relsOrRelas<ELFT>();
if (rels.areRelocsRel())
scanEhFrameSection(*eh, rels.rels);
else if (rels.relas.size())
scanEhFrameSection(*eh, rels.relas);
}
- for (InputSectionBase *sec : inputSections) {
+ for (InputSectionBase *sec : ctx.inputSections) {
if (sec->flags & SHF_GNU_RETAIN) {
enqueue(sec, 0);
continue;
d->section->isLive())
markSymbol(s);
- for (InputSectionBase *sec : inputSections) {
+ for (InputSectionBase *sec : ctx.inputSections) {
if (!sec->isLive() || !isValidCIdentifier(sec->name))
continue;
if (symtab.find(("__start_" + sec->name).str()) ||
return;
}
- for (InputSectionBase *sec : inputSections)
+ for (InputSectionBase *sec : ctx.inputSections)
sec->markDead();
// Follow the graph to mark all live sections.
// Report garbage-collected sections.
if (config->printGcSections)
- for (InputSectionBase *sec : inputSections)
+ for (InputSectionBase *sec : ctx.inputSections)
if (!sec->isLive())
message("removing unused section " + toString(sec));
}
Elf_Mips_ABIFlags flags = {};
bool create = false;
- for (InputSectionBase *sec : inputSections) {
+ for (InputSectionBase *sec : ctx.inputSections) {
if (sec->type != SHT_MIPS_ABIFLAGS)
continue;
sec->markDead();
return nullptr;
SmallVector<InputSectionBase *, 0> sections;
- for (InputSectionBase *sec : inputSections)
+ for (InputSectionBase *sec : ctx.inputSections)
if (sec->type == SHT_MIPS_OPTIONS)
sections.push_back(sec);
return nullptr;
SmallVector<InputSectionBase *, 0> sections;
- for (InputSectionBase *sec : inputSections)
+ for (InputSectionBase *sec : ctx.inputSections)
if (sec->type == SHT_MIPS_REGINFO)
sections.push_back(sec);
// note that isec->data() may uncompress the full content, which should be
// parallelized.
SetVector<InputFile *> files;
- for (InputSectionBase *s : inputSections) {
+ for (InputSectionBase *s : ctx.inputSections) {
InputSection *isec = dyn_cast<InputSection>(s);
if (!isec)
continue;
files.insert(isec->file);
}
// Drop .rel[a].debug_gnu_pub{names,types} for --emit-relocs.
- llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ llvm::erase_if(ctx.inputSections, [](InputSectionBase *s) {
if (auto *isec = dyn_cast<InputSection>(s))
if (InputSectionBase *rel = isec->getRelocatedSection())
return !rel->isLive();
void elf::combineEhSections() {
llvm::TimeTraceScope timeScope("Combine EH sections");
- for (EhInputSection *sec : ehInputSections) {
+ for (EhInputSection *sec : ctx.ehInputSections) {
EhFrameSection &eh = *sec->getPartition().ehFrame;
sec->parent = &eh;
eh.alignment = std::max(eh.alignment, sec->alignment);
if (!mainPart->armExidx)
return;
- llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ llvm::erase_if(ctx.inputSections, [](InputSectionBase *s) {
// Ignore dead sections and the partition end marker (.part.end),
// whose partition number is out of bounds.
if (!s->isLive() || s->partition == 255)
ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
assert(loc != nullptr);
- for (InputSectionBase *d : inputSections) {
+ for (InputSectionBase *d : ctx.inputSections) {
auto *isec = dyn_cast<InputSection>(d);
if (!isec || !isec->getParent() || (isec->type & SHT_NOBITS))
continue;
void elf::copySectionsIntoPartitions() {
SmallVector<InputSectionBase *, 0> newSections;
- const size_t ehSize = ehInputSections.size();
+ const size_t ehSize = ctx.ehInputSections.size();
for (unsigned part = 2; part != partitions.size() + 1; ++part) {
- for (InputSectionBase *s : inputSections) {
+ for (InputSectionBase *s : ctx.inputSections) {
if (!(s->flags & SHF_ALLOC) || !s->isLive() || s->type != SHT_NOTE)
continue;
auto *copy = make<InputSection>(cast<InputSection>(*s));
newSections.push_back(copy);
}
for (size_t i = 0; i != ehSize; ++i) {
- assert(ehInputSections[i]->isLive());
- auto *copy = make<EhInputSection>(*ehInputSections[i]);
+ assert(ctx.ehInputSections[i]->isLive());
+ auto *copy = make<EhInputSection>(*ctx.ehInputSections[i]);
copy->partition = part;
- ehInputSections.push_back(copy);
+ ctx.ehInputSections.push_back(copy);
}
}
- inputSections.insert(inputSections.end(), newSections.begin(),
- newSections.end());
+ ctx.inputSections.insert(ctx.inputSections.end(), newSections.begin(),
+ newSections.end());
}
static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
for (size_t i = 1; i <= partitions.size(); ++i) {
InputSection *sec = createInterpSection();
sec->partition = i;
- inputSections.push_back(sec);
+ ctx.inputSections.push_back(sec);
}
}
- auto add = [](SyntheticSection &sec) { inputSections.push_back(&sec); };
+ auto add = [](SyntheticSection &sec) { ctx.inputSections.push_back(&sec); };
in.shStrTab = std::make_unique<StringTableSection>(".shstrtab", false);
for (Partition &part : partitions) {
auto add = [&](SyntheticSection &sec) {
sec.partition = part.getNumber();
- inputSections.push_back(&sec);
+ ctx.inputSections.push_back(&sec);
};
if (!part.name.empty()) {
if (config->shuffleSections.empty())
return;
- SmallVector<InputSectionBase *, 0> matched, sections = inputSections;
+ SmallVector<InputSectionBase *, 0> matched, sections = ctx.inputSections;
matched.reserve(sections.size());
for (const auto &patAndSeed : config->shuffleSections) {
matched.clear();
// All input synthetic sections that can be empty are placed after
// all regular ones. Reverse iterate to find the first synthetic section
// after a non-synthetic one which will be our starting point.
- auto start = std::find_if(inputSections.rbegin(), inputSections.rend(),
- [](InputSectionBase *s) {
- return !isa<SyntheticSection>(s);
- })
- .base();
+ auto start =
+ std::find_if(
+ ctx.inputSections.rbegin(), ctx.inputSections.rend(),
+ [](InputSectionBase *s) { return !isa<SyntheticSection>(s); })
+ .base();
- // Remove unused synthetic sections from inputSections;
+ // Remove unused synthetic sections from ctx.inputSections;
DenseSet<InputSectionBase *> unused;
auto end =
- std::remove_if(start, inputSections.end(), [&](InputSectionBase *s) {
+ std::remove_if(start, ctx.inputSections.end(), [&](InputSectionBase *s) {
auto *sec = cast<SyntheticSection>(s);
if (sec->getParent() && sec->isNeeded())
return false;
unused.insert(sec);
return true;
});
- inputSections.erase(end, inputSections.end());
+ ctx.inputSections.erase(end, ctx.inputSections.end());
// Remove unused synthetic sections from the corresponding input section
// description and orphanSections.