mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 13:26:45 +00:00
[ELF] Migrate away from global ctx
This commit is contained in:
parent
2de1e06736
commit
d69cc05bcf
@ -1107,7 +1107,7 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
|
||||
|
||||
template <class ELFT>
|
||||
static void
|
||||
addTaggedSymbolReferences(InputSectionBase &sec,
|
||||
addTaggedSymbolReferences(Ctx &ctx, InputSectionBase &sec,
|
||||
DenseMap<Symbol *, unsigned> &referenceCount) {
|
||||
assert(sec.type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC);
|
||||
|
||||
@ -1163,7 +1163,7 @@ void elf::createTaggedSymbols(Ctx &ctx) {
|
||||
if (!section || section->type != SHT_AARCH64_MEMTAG_GLOBALS_STATIC ||
|
||||
section == &InputSection::discarded)
|
||||
continue;
|
||||
invokeELFT(addTaggedSymbolReferences, *section,
|
||||
invokeELFT(addTaggedSymbolReferences, ctx, *section,
|
||||
taggedSymbolReferenceCount);
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ static bool isDuplex(uint32_t insn) {
|
||||
return (instParsePacketEnd & insn) == 0;
|
||||
}
|
||||
|
||||
static uint32_t findMaskR6(uint32_t insn) {
|
||||
static uint32_t findMaskR6(Ctx &ctx, uint32_t insn) {
|
||||
if (isDuplex(insn))
|
||||
return 0x03f00000;
|
||||
|
||||
@ -198,8 +198,8 @@ static uint32_t findMaskR6(uint32_t insn) {
|
||||
if ((0xff000000 & insn) == i.cmpMask)
|
||||
return i.relocMask;
|
||||
|
||||
ErrAlways(ctx) << "unrecognized instruction for 6_X relocation: 0x"
|
||||
<< utohexstr(insn);
|
||||
Err(ctx) << "unrecognized instruction for 6_X relocation: 0x"
|
||||
<< utohexstr(insn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ static uint32_t findMaskR11(uint32_t insn) {
|
||||
return 0x06003fe0;
|
||||
}
|
||||
|
||||
static uint32_t findMaskR16(uint32_t insn) {
|
||||
static uint32_t findMaskR16(Ctx &ctx, uint32_t insn) {
|
||||
if (isDuplex(insn))
|
||||
return 0x03f00000;
|
||||
|
||||
@ -246,8 +246,7 @@ static uint32_t findMaskR16(uint32_t insn) {
|
||||
if ((0xff000000 & insn) == i.cmpMask)
|
||||
return i.relocMask;
|
||||
|
||||
ErrAlways(ctx) << "unrecognized instruction for 16_X type: 0x"
|
||||
<< utohexstr(insn);
|
||||
Err(ctx) << "unrecognized instruction for 16_X type: 0x" << utohexstr(insn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -260,7 +259,7 @@ void Hexagon::relocate(uint8_t *loc, const Relocation &rel,
|
||||
break;
|
||||
case R_HEX_6_PCREL_X:
|
||||
case R_HEX_6_X:
|
||||
or32le(loc, applyMask(findMaskR6(read32le(loc)), val));
|
||||
or32le(loc, applyMask(findMaskR6(ctx, read32le(loc)), val));
|
||||
break;
|
||||
case R_HEX_8_X:
|
||||
or32le(loc, applyMask(findMaskR8(read32le(loc)), val));
|
||||
@ -289,10 +288,10 @@ void Hexagon::relocate(uint8_t *loc, const Relocation &rel,
|
||||
case R_HEX_GOT_16_X:
|
||||
case R_HEX_GOTREL_16_X:
|
||||
case R_HEX_TPREL_16_X:
|
||||
or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0x3f));
|
||||
or32le(loc, applyMask(findMaskR16(ctx, read32le(loc)), val & 0x3f));
|
||||
break;
|
||||
case R_HEX_TPREL_16:
|
||||
or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0xffff));
|
||||
or32le(loc, applyMask(findMaskR16(ctx, read32le(loc)), val & 0xffff));
|
||||
break;
|
||||
case R_HEX_32:
|
||||
case R_HEX_32_PCREL:
|
||||
|
@ -219,7 +219,7 @@ uint64_t elf::getPPC64TocBase(Ctx &ctx) {
|
||||
return tocVA + ppc64TocOffset;
|
||||
}
|
||||
|
||||
unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
|
||||
unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(Ctx &ctx, uint8_t stOther) {
|
||||
// The offset is encoded into the 3 most significant bits of the st_other
|
||||
// field, with some special values described in section 3.4.1 of the ABI:
|
||||
// 0 --> Zero offset between the GEP and LEP, and the function does NOT use
|
||||
@ -1455,9 +1455,9 @@ bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
|
||||
// If the offset exceeds the range of the branch type then it will need
|
||||
// a range-extending thunk.
|
||||
// See the comment in getRelocTargetVA() about R_PPC64_CALL.
|
||||
return !inBranchRange(type, branchAddr,
|
||||
s.getVA(ctx, a) +
|
||||
getPPC64GlobalEntryToLocalEntryOffset(s.stOther));
|
||||
return !inBranchRange(
|
||||
type, branchAddr,
|
||||
s.getVA(ctx, a) + getPPC64GlobalEntryToLocalEntryOffset(ctx, s.stOther));
|
||||
}
|
||||
|
||||
uint32_t PPC64::getThunkSectionSpacing() const {
|
||||
@ -1678,7 +1678,7 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
|
||||
uint8_t stOther) const {
|
||||
// If the caller has a global entry point adjust the buffer past it. The start
|
||||
// of the split-stack prologue will be at the local entry point.
|
||||
loc += getPPC64GlobalEntryToLocalEntryOffset(stOther);
|
||||
loc += getPPC64GlobalEntryToLocalEntryOffset(ctx, stOther);
|
||||
|
||||
// At the very least we expect to see a load of some split-stack data from the
|
||||
// tcb, and 2 instructions that calculate the ending stack address this
|
||||
|
@ -1059,7 +1059,7 @@ public:
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts,
|
||||
static void mergeArch(Ctx &ctx, RISCVISAUtils::OrderedExtensionMap &mergedExts,
|
||||
unsigned &mergedXlen, const InputSectionBase *sec,
|
||||
StringRef s) {
|
||||
auto maybeInfo = RISCVISAInfo::parseNormalizedArchString(s);
|
||||
@ -1086,7 +1086,7 @@ static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts,
|
||||
}
|
||||
}
|
||||
|
||||
static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it,
|
||||
static void mergeAtomic(Ctx &ctx, DenseMap<unsigned, unsigned>::iterator it,
|
||||
const InputSectionBase *oldSection,
|
||||
const InputSectionBase *newSection,
|
||||
RISCVAttrs::RISCVAtomicAbiTag oldTag,
|
||||
@ -1104,8 +1104,8 @@ static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it,
|
||||
<< ": atomic_abi=" << Twine(static_cast<unsigned>(newTag));
|
||||
};
|
||||
|
||||
auto reportUnknownAbiError = [](const InputSectionBase *section,
|
||||
RISCVAtomicAbiTag tag) {
|
||||
auto reportUnknownAbiError = [&](const InputSectionBase *section,
|
||||
RISCVAtomicAbiTag tag) {
|
||||
switch (tag) {
|
||||
case RISCVAtomicAbiTag::UNKNOWN:
|
||||
case RISCVAtomicAbiTag::A6C:
|
||||
@ -1214,7 +1214,7 @@ mergeAttributesSection(Ctx &ctx,
|
||||
case RISCVAttrs::ARCH:
|
||||
if (auto s = parser.getAttributeString(tag.attr)) {
|
||||
hasArch = true;
|
||||
mergeArch(exts, xlen, sec, *s);
|
||||
mergeArch(ctx, exts, xlen, sec, *s);
|
||||
}
|
||||
continue;
|
||||
|
||||
@ -1230,7 +1230,7 @@ mergeAttributesSection(Ctx &ctx,
|
||||
if (r.second)
|
||||
firstAtomicAbi = sec;
|
||||
else
|
||||
mergeAtomic(r.first, firstAtomicAbi, sec,
|
||||
mergeAtomic(ctx, r.first, firstAtomicAbi, sec,
|
||||
static_cast<RISCVAtomicAbiTag>(r.first->getSecond()),
|
||||
static_cast<RISCVAtomicAbiTag>(*i));
|
||||
}
|
||||
|
@ -197,7 +197,8 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
|
||||
} // namespace lld
|
||||
|
||||
// Parses a linker -m option.
|
||||
static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
|
||||
static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(Ctx &ctx,
|
||||
StringRef emul) {
|
||||
uint8_t osabi = 0;
|
||||
StringRef s = emul;
|
||||
if (s.ends_with("_fbsd")) {
|
||||
@ -578,7 +579,7 @@ static GnuStackKind getZGnuStack(opt::InputArgList &args) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t getZStartStopVisibility(opt::InputArgList &args) {
|
||||
static uint8_t getZStartStopVisibility(Ctx &ctx, opt::InputArgList &args) {
|
||||
uint8_t ret = STV_PROTECTED;
|
||||
for (auto *arg : args.filtered(OPT_z)) {
|
||||
std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
|
||||
@ -1556,7 +1557,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
|
||||
ctx.arg.zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
|
||||
ctx.arg.zStartStopGC =
|
||||
getZFlag(args, "start-stop-gc", "nostart-stop-gc", true);
|
||||
ctx.arg.zStartStopVisibility = getZStartStopVisibility(args);
|
||||
ctx.arg.zStartStopVisibility = getZStartStopVisibility(ctx, args);
|
||||
ctx.arg.zText = getZFlag(args, "text", "notext", true);
|
||||
ctx.arg.zWxneeded = hasZOption(args, "wxneeded");
|
||||
setUnresolvedSymbolPolicy(ctx, args);
|
||||
@ -1759,7 +1760,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
|
||||
if (auto *arg = args.getLastArg(OPT_m)) {
|
||||
StringRef s = arg->getValue();
|
||||
std::tie(ctx.arg.ekind, ctx.arg.emachine, ctx.arg.osabi) =
|
||||
parseEmulation(s);
|
||||
parseEmulation(ctx, s);
|
||||
ctx.arg.mipsN32Abi =
|
||||
(s.starts_with("elf32btsmipn32") || s.starts_with("elf32ltsmipn32"));
|
||||
ctx.arg.emulation = s;
|
||||
@ -2756,17 +2757,19 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
|
||||
ctx.symtab->wrap(w.sym, w.real, w.wrap);
|
||||
}
|
||||
|
||||
static void reportMissingFeature(StringRef config, const Twine &report) {
|
||||
static void reportMissingFeature(Ctx &ctx, StringRef config,
|
||||
const Twine &report) {
|
||||
if (config == "error")
|
||||
ErrAlways(ctx) << report;
|
||||
else if (config == "warning")
|
||||
Warn(ctx) << report;
|
||||
}
|
||||
|
||||
static void checkAndReportMissingFeature(StringRef config, uint32_t features,
|
||||
uint32_t mask, const Twine &report) {
|
||||
static void checkAndReportMissingFeature(Ctx &ctx, StringRef config,
|
||||
uint32_t features, uint32_t mask,
|
||||
const Twine &report) {
|
||||
if (!(features & mask))
|
||||
reportMissingFeature(config, report);
|
||||
reportMissingFeature(ctx, config, report);
|
||||
}
|
||||
|
||||
// To enable CET (x86's hardware-assisted control flow enforcement), each
|
||||
@ -2805,22 +2808,22 @@ static void readSecurityNotes(Ctx &ctx) {
|
||||
uint32_t features = f->andFeatures;
|
||||
|
||||
checkAndReportMissingFeature(
|
||||
ctx.arg.zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI,
|
||||
ctx, ctx.arg.zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI,
|
||||
toString(f) + ": -z bti-report: file does not have "
|
||||
"GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
|
||||
|
||||
checkAndReportMissingFeature(
|
||||
ctx.arg.zGcsReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_GCS,
|
||||
ctx, ctx.arg.zGcsReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_GCS,
|
||||
toString(f) + ": -z gcs-report: file does not have "
|
||||
"GNU_PROPERTY_AARCH64_FEATURE_1_GCS property");
|
||||
|
||||
checkAndReportMissingFeature(
|
||||
ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT,
|
||||
ctx, ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT,
|
||||
toString(f) + ": -z cet-report: file does not have "
|
||||
"GNU_PROPERTY_X86_FEATURE_1_IBT property");
|
||||
|
||||
checkAndReportMissingFeature(
|
||||
ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK,
|
||||
ctx, ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK,
|
||||
toString(f) + ": -z cet-report: file does not have "
|
||||
"GNU_PROPERTY_X86_FEATURE_1_SHSTK property");
|
||||
|
||||
@ -2852,7 +2855,7 @@ static void readSecurityNotes(Ctx &ctx) {
|
||||
continue;
|
||||
|
||||
if (f->aarch64PauthAbiCoreInfo.empty()) {
|
||||
reportMissingFeature(ctx.arg.zPauthReport,
|
||||
reportMissingFeature(ctx, ctx.arg.zPauthReport,
|
||||
toString(f) +
|
||||
": -z pauth-report: file does not have AArch64 "
|
||||
"PAuth core info while '" +
|
||||
|
@ -113,7 +113,7 @@ size_t InputSectionBase::getSize() const {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static void decompressAux(const InputSectionBase &sec, uint8_t *out,
|
||||
static void decompressAux(Ctx &ctx, const InputSectionBase &sec, uint8_t *out,
|
||||
size_t size) {
|
||||
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(sec.content_);
|
||||
auto compressed = ArrayRef<uint8_t>(sec.content_, sec.compressedSize)
|
||||
@ -134,7 +134,7 @@ void InputSectionBase::decompress() const {
|
||||
uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
|
||||
}
|
||||
|
||||
invokeELFT(decompressAux, *this, uncompressedBuf, size);
|
||||
invokeELFT(decompressAux, ctx, *this, uncompressedBuf, size);
|
||||
content_ = uncompressedBuf;
|
||||
compressed = false;
|
||||
}
|
||||
@ -914,7 +914,8 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
|
||||
// the callee. For local calls the caller and callee share the same
|
||||
// TOC base and so the TOC pointer initialization code should be skipped by
|
||||
// branching to the local entry point.
|
||||
return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(r.sym->stOther);
|
||||
return symVA - p +
|
||||
getPPC64GlobalEntryToLocalEntryOffset(ctx, r.sym->stOther);
|
||||
}
|
||||
case R_PPC64_TOCBASE:
|
||||
return getPPC64TocBase(ctx) + a;
|
||||
|
@ -2856,13 +2856,12 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni,
|
||||
}
|
||||
|
||||
void DebugNamesBaseSection::parseDebugNames(
|
||||
InputChunk &inputChunk, OutputChunk &chunk,
|
||||
Ctx &ctx, InputChunk &inputChunk, OutputChunk &chunk,
|
||||
DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor,
|
||||
function_ref<SmallVector<uint32_t, 0>(
|
||||
uint32_t numCus, const DWARFDebugNames::Header &,
|
||||
const DWARFDebugNames::DWARFDebugNamesOffsets &)>
|
||||
readOffsets) {
|
||||
Ctx &ctx = elf::ctx;
|
||||
const LLDDWARFSection &namesSec = inputChunk.section;
|
||||
DenseMap<uint32_t, IndexEntry *> offsetMap;
|
||||
// Number of CUs seen in previous NameIndex sections within current chunk.
|
||||
@ -3216,7 +3215,7 @@ DebugNamesSection<ELFT>::DebugNamesSection(Ctx &ctx)
|
||||
Err(ctx) << dobj.getNamesSection().sec << Twine(": ") << std::move(e);
|
||||
}
|
||||
parseDebugNames(
|
||||
inputChunk, chunk, namesExtractor, strExtractor,
|
||||
ctx, inputChunk, chunk, namesExtractor, strExtractor,
|
||||
[&chunk, namesData = dobj.getNamesSection().Data.data()](
|
||||
uint32_t numCus, const DWARFDebugNames::Header &hdr,
|
||||
const DWARFDebugNames::DWARFDebugNamesOffsets &locs) {
|
||||
@ -3376,7 +3375,7 @@ readCuList(DWARFContext &dwarf) {
|
||||
}
|
||||
|
||||
static SmallVector<GdbIndexSection::AddressEntry, 0>
|
||||
readAddressAreas(DWARFContext &dwarf, InputSection *sec) {
|
||||
readAddressAreas(Ctx &ctx, DWARFContext &dwarf, InputSection *sec) {
|
||||
SmallVector<GdbIndexSection::AddressEntry, 0> ret;
|
||||
|
||||
uint32_t cuIdx = 0;
|
||||
@ -3564,7 +3563,7 @@ std::unique_ptr<GdbIndexSection> GdbIndexSection::create(Ctx &ctx) {
|
||||
// this only picks the last one. Other address ranges are lost.
|
||||
chunks[i].sec = dobj.getInfoSection();
|
||||
chunks[i].compilationUnits = readCuList(dwarf);
|
||||
chunks[i].addressAreas = readAddressAreas(dwarf, chunks[i].sec);
|
||||
chunks[i].addressAreas = readAddressAreas(ctx, dwarf, chunks[i].sec);
|
||||
nameAttrs[i] =
|
||||
readPubNamesAndTypes<ELFT>(ctx, dobj, chunks[i].compilationUnits);
|
||||
});
|
||||
@ -4366,7 +4365,7 @@ void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
|
||||
// must be a local-call.
|
||||
write64(ctx, buf,
|
||||
sym->getVA(ctx, addend) +
|
||||
getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
|
||||
getPPC64GlobalEntryToLocalEntryOffset(ctx, sym->stOther));
|
||||
buf += 8;
|
||||
}
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ public:
|
||||
protected:
|
||||
void init(llvm::function_ref<void(InputFile *, InputChunk &, OutputChunk &)>);
|
||||
static void
|
||||
parseDebugNames(InputChunk &inputChunk, OutputChunk &chunk,
|
||||
parseDebugNames(Ctx &, InputChunk &inputChunk, OutputChunk &chunk,
|
||||
llvm::DWARFDataExtractor &namesExtractor,
|
||||
llvm::DataExtractor &strExtractor,
|
||||
llvm::function_ref<SmallVector<uint32_t, 0>(
|
||||
|
@ -229,7 +229,7 @@ unsigned getPPCDSFormOp(unsigned secondaryOp);
|
||||
// offset between GEP and LEP is encoded in a function's st_other flags.
|
||||
// This function will return the offset (in bytes) from the global entry-point
|
||||
// to the local entry-point.
|
||||
unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther);
|
||||
unsigned getPPC64GlobalEntryToLocalEntryOffset(Ctx &, uint8_t stOther);
|
||||
|
||||
// Write a prefixed instruction, which is a 4-byte prefix followed by a 4-byte
|
||||
// instruction (regardless of endianness). Therefore, the prefix is always in
|
||||
|
@ -519,7 +519,7 @@ public:
|
||||
ctx.mainPart->relaDyn->addRelativeReloc(
|
||||
ctx.target->relativeRel, *ctx.in.ppc64LongBranchTarget,
|
||||
*index * UINT64_C(8), dest,
|
||||
addend + getPPC64GlobalEntryToLocalEntryOffset(dest.stOther),
|
||||
addend + getPPC64GlobalEntryToLocalEntryOffset(ctx, dest.stOther),
|
||||
ctx.target->symbolicRel, R_ABS);
|
||||
}
|
||||
}
|
||||
|
@ -2625,7 +2625,8 @@ struct SectionOffset {
|
||||
|
||||
// Check whether sections overlap for a specific address range (file offsets,
|
||||
// load and virtual addresses).
|
||||
static void checkOverlap(StringRef name, std::vector<SectionOffset> §ions,
|
||||
static void checkOverlap(Ctx &ctx, StringRef name,
|
||||
std::vector<SectionOffset> §ions,
|
||||
bool isVirtualAddr) {
|
||||
llvm::sort(sections, [=](const SectionOffset &a, const SectionOffset &b) {
|
||||
return a.offset < b.offset;
|
||||
@ -2676,7 +2677,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
|
||||
if (sec->size > 0 && sec->type != SHT_NOBITS &&
|
||||
(!ctx.arg.oFormatBinary || (sec->flags & SHF_ALLOC)))
|
||||
fileOffs.push_back({sec, sec->offset});
|
||||
checkOverlap("file", fileOffs, false);
|
||||
checkOverlap(ctx, "file", fileOffs, false);
|
||||
|
||||
// When linking with -r there is no need to check for overlapping virtual/load
|
||||
// addresses since those addresses will only be assigned when the final
|
||||
@ -2693,7 +2694,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
|
||||
for (OutputSection *sec : ctx.outputSections)
|
||||
if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
|
||||
vmas.push_back({sec, sec->addr});
|
||||
checkOverlap("virtual address", vmas, true);
|
||||
checkOverlap(ctx, "virtual address", vmas, true);
|
||||
|
||||
// Finally, check that the load addresses don't overlap. This will usually be
|
||||
// the same as the virtual addresses but can be different when using a linker
|
||||
@ -2702,7 +2703,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
|
||||
for (OutputSection *sec : ctx.outputSections)
|
||||
if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
|
||||
lmas.push_back({sec, sec->getLMA()});
|
||||
checkOverlap("load address", lmas, false);
|
||||
checkOverlap(ctx, "load address", lmas, false);
|
||||
}
|
||||
|
||||
// The entry point address is chosen in the following ways.
|
||||
|
Loading…
x
Reference in New Issue
Block a user