mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 21:55:39 +08:00
[ELF] Pass Ctx &
This commit is contained in:
@@ -398,9 +398,9 @@ Patch843419Section::Patch843419Section(Ctx &ctx, InputSection *p, uint64_t off)
|
||||
patchee(p), patcheeOffset(off) {
|
||||
this->parent = p->getParent();
|
||||
patchSym = addSyntheticLocal(
|
||||
saver().save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC,
|
||||
0, getSize(), *this);
|
||||
addSyntheticLocal(saver().save("$x"), STT_NOTYPE, 0, 0, *this);
|
||||
ctx, saver().save("__CortexA53843419_" + utohexstr(getLDSTAddr())),
|
||||
STT_FUNC, 0, getSize(), *this);
|
||||
addSyntheticLocal(ctx, saver().save("$x"), STT_NOTYPE, 0, 0, *this);
|
||||
}
|
||||
|
||||
uint64_t Patch843419Section::getLDSTAddr() const {
|
||||
|
||||
@@ -141,9 +141,10 @@ Patch657417Section::Patch657417Section(Ctx &ctx, InputSection *p, uint64_t off,
|
||||
patchee(p), patcheeOffset(off), instr(instr), isARM(isARM) {
|
||||
parent = p->getParent();
|
||||
patchSym = addSyntheticLocal(
|
||||
saver().save("__CortexA8657417_" + utohexstr(getBranchAddr())), STT_FUNC,
|
||||
isARM ? 0 : 1, getSize(), *this);
|
||||
addSyntheticLocal(saver().save(isARM ? "$a" : "$t"), STT_NOTYPE, 0, 0, *this);
|
||||
ctx, saver().save("__CortexA8657417_" + utohexstr(getBranchAddr())),
|
||||
STT_FUNC, isARM ? 0 : 1, getSize(), *this);
|
||||
addSyntheticLocal(ctx, saver().save(isARM ? "$a" : "$t"), STT_NOTYPE, 0, 0,
|
||||
*this);
|
||||
}
|
||||
|
||||
uint64_t Patch657417Section::getBranchAddr() const {
|
||||
@@ -259,6 +260,7 @@ struct ScanResult {
|
||||
// branch so the minimum offset for a patch is 4.
|
||||
static ScanResult scanCortexA8Errata657417(InputSection *isec, uint64_t &off,
|
||||
uint64_t limit) {
|
||||
Ctx &ctx = isec->getCtx();
|
||||
uint64_t isecAddr = isec->getVA(0);
|
||||
// Advance Off so that (isecAddr + off) modulo 0x1000 is at least 0xffa. We
|
||||
// need to check for a 32-bit instruction immediately before a 32-bit branch
|
||||
|
||||
@@ -300,11 +300,11 @@ void ARM::writePltHeader(uint8_t *buf) const {
|
||||
|
||||
void ARM::addPltHeaderSymbols(InputSection &isec) const {
|
||||
if (useThumbPLTs(ctx)) {
|
||||
addSyntheticLocal("$t", STT_NOTYPE, 0, 0, isec);
|
||||
addSyntheticLocal("$d", STT_NOTYPE, 12, 0, isec);
|
||||
addSyntheticLocal(ctx, "$t", STT_NOTYPE, 0, 0, isec);
|
||||
addSyntheticLocal(ctx, "$d", STT_NOTYPE, 12, 0, isec);
|
||||
} else {
|
||||
addSyntheticLocal("$a", STT_NOTYPE, 0, 0, isec);
|
||||
addSyntheticLocal("$d", STT_NOTYPE, 16, 0, isec);
|
||||
addSyntheticLocal(ctx, "$a", STT_NOTYPE, 0, 0, isec);
|
||||
addSyntheticLocal(ctx, "$d", STT_NOTYPE, 16, 0, isec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,10 +377,10 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym,
|
||||
|
||||
void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {
|
||||
if (useThumbPLTs(ctx)) {
|
||||
addSyntheticLocal("$t", STT_NOTYPE, off, 0, isec);
|
||||
addSyntheticLocal(ctx, "$t", STT_NOTYPE, off, 0, isec);
|
||||
} else {
|
||||
addSyntheticLocal("$a", STT_NOTYPE, off, 0, isec);
|
||||
addSyntheticLocal("$d", STT_NOTYPE, off + 12, 0, isec);
|
||||
addSyntheticLocal(ctx, "$a", STT_NOTYPE, off, 0, isec);
|
||||
addSyntheticLocal(ctx, "$d", STT_NOTYPE, off + 12, 0, isec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ void ArmCmseSGSection::writeTo(uint8_t *buf) {
|
||||
}
|
||||
|
||||
void ArmCmseSGSection::addMappingSymbol() {
|
||||
addSyntheticLocal("$t", STT_NOTYPE, /*off=*/0, /*size=*/0, *this);
|
||||
addSyntheticLocal(ctx, "$t", STT_NOTYPE, /*off=*/0, /*size=*/0, *this);
|
||||
}
|
||||
|
||||
size_t ArmCmseSGSection::getSize() const {
|
||||
|
||||
@@ -186,7 +186,7 @@ static bool isFallThruRelocation(InputSection &is, InputFile *file,
|
||||
return false;
|
||||
|
||||
uint64_t addrLoc = is.getOutputSection()->addr + is.outSecOff + r.offset;
|
||||
uint64_t targetOffset = is.getRelocTargetVA(ctx, r, addrLoc);
|
||||
uint64_t targetOffset = is.getRelocTargetVA(is.getCtx(), r, addrLoc);
|
||||
|
||||
// If this jmp is a fall thru, the target offset is the beginning of the
|
||||
// next section.
|
||||
|
||||
@@ -1324,8 +1324,8 @@ static bool isBitcodeNonCommonDef(MemoryBufferRef mb, StringRef symName,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static bool isNonCommonDef(ELFKind ekind, MemoryBufferRef mb, StringRef symName,
|
||||
StringRef archiveName) {
|
||||
static bool isNonCommonDef(Ctx &ctx, ELFKind ekind, MemoryBufferRef mb,
|
||||
StringRef symName, StringRef archiveName) {
|
||||
ObjFile<ELFT> *obj = make<ObjFile<ELFT>>(ctx, ekind, mb, archiveName);
|
||||
obj->init();
|
||||
StringRef stringtable = obj->getStringTable();
|
||||
@@ -1343,13 +1343,13 @@ static bool isNonCommonDef(MemoryBufferRef mb, StringRef symName,
|
||||
StringRef archiveName) {
|
||||
switch (getELFKind(mb, archiveName)) {
|
||||
case ELF32LEKind:
|
||||
return isNonCommonDef<ELF32LE>(ELF32LEKind, mb, symName, archiveName);
|
||||
return isNonCommonDef<ELF32LE>(ctx, ELF32LEKind, mb, symName, archiveName);
|
||||
case ELF32BEKind:
|
||||
return isNonCommonDef<ELF32BE>(ELF32BEKind, mb, symName, archiveName);
|
||||
return isNonCommonDef<ELF32BE>(ctx, ELF32BEKind, mb, symName, archiveName);
|
||||
case ELF64LEKind:
|
||||
return isNonCommonDef<ELF64LE>(ELF64LEKind, mb, symName, archiveName);
|
||||
return isNonCommonDef<ELF64LE>(ctx, ELF64LEKind, mb, symName, archiveName);
|
||||
case ELF64BEKind:
|
||||
return isNonCommonDef<ELF64BE>(ELF64BEKind, mb, symName, archiveName);
|
||||
return isNonCommonDef<ELF64BE>(ctx, ELF64BEKind, mb, symName, archiveName);
|
||||
default:
|
||||
llvm_unreachable("getELFKind");
|
||||
}
|
||||
|
||||
@@ -437,7 +437,8 @@ void InputSection::copyRelocations(uint8_t *buf) {
|
||||
template <class ELFT, class RelTy, class RelIt>
|
||||
void InputSection::copyRelocations(uint8_t *buf,
|
||||
llvm::iterator_range<RelIt> rels) {
|
||||
const TargetInfo &target = *elf::ctx.target;
|
||||
Ctx &ctx = getCtx();
|
||||
const TargetInfo &target = *ctx.target;
|
||||
InputSectionBase *sec = getRelocatedSection();
|
||||
(void)sec->contentMaybeDecompress(); // uncompress if needed
|
||||
|
||||
|
||||
@@ -861,7 +861,8 @@ static OutputSection *findByName(ArrayRef<SectionCommand *> vec,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static OutputDesc *createSection(InputSectionBase *isec, StringRef outsecName) {
|
||||
static OutputDesc *createSection(Ctx &ctx, InputSectionBase *isec,
|
||||
StringRef outsecName) {
|
||||
OutputDesc *osd = ctx.script->createOutputSection(outsecName, "<internal>");
|
||||
osd->osec.recordSection(isec);
|
||||
return osd;
|
||||
@@ -878,7 +879,7 @@ static OutputDesc *addInputSec(Ctx &ctx,
|
||||
// as-is because adding/removing members or merging them with other groups
|
||||
// change their semantics.
|
||||
if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP))
|
||||
return createSection(isec, outsecName);
|
||||
return createSection(ctx, isec, outsecName);
|
||||
|
||||
// Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
|
||||
// relocation sections .rela.foo and .rela.bar for example. Most tools do
|
||||
@@ -895,7 +896,7 @@ static OutputDesc *addInputSec(Ctx &ctx,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OutputDesc *osd = createSection(isec, outsecName);
|
||||
OutputDesc *osd = createSection(ctx, isec, outsecName);
|
||||
out->relocationSection = &osd->osec;
|
||||
return osd;
|
||||
}
|
||||
@@ -966,7 +967,7 @@ static OutputDesc *addInputSec(Ctx &ctx,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OutputDesc *osd = createSection(isec, outsecName);
|
||||
OutputDesc *osd = createSection(ctx, isec, outsecName);
|
||||
v.push_back(&osd->osec);
|
||||
return osd;
|
||||
}
|
||||
@@ -982,7 +983,7 @@ void LinkerScript::addOrphanSections() {
|
||||
|
||||
StringRef name = getOutputSectionName(s);
|
||||
if (ctx.arg.unique) {
|
||||
v.push_back(createSection(s, name));
|
||||
v.push_back(createSection(ctx, s, name));
|
||||
} else if (OutputSection *sec = findByName(sectionCommands, name)) {
|
||||
sec->recordSection(s);
|
||||
} else {
|
||||
|
||||
@@ -63,7 +63,7 @@ static uint64_t readUint(Ctx &ctx, uint8_t *buf) {
|
||||
return ctx.arg.is64 ? read64(buf) : read32(buf);
|
||||
}
|
||||
|
||||
static void writeUint(uint8_t *buf, uint64_t val) {
|
||||
static void writeUint(Ctx &ctx, uint8_t *buf, uint64_t val) {
|
||||
if (ctx.arg.is64)
|
||||
write64(buf, val);
|
||||
else
|
||||
@@ -264,7 +264,7 @@ MipsReginfoSection<ELFT>::create(Ctx &ctx) {
|
||||
return std::make_unique<MipsReginfoSection<ELFT>>(ctx, reginfo);
|
||||
}
|
||||
|
||||
InputSection *elf::createInterpSection(Ctx &) {
|
||||
InputSection *elf::createInterpSection(Ctx &ctx) {
|
||||
// StringSaver guarantees that the returned string ends with '\0'.
|
||||
StringRef s = saver().save(ctx.arg.dynamicLinker);
|
||||
ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
|
||||
@@ -273,8 +273,9 @@ InputSection *elf::createInterpSection(Ctx &) {
|
||||
contents, ".interp");
|
||||
}
|
||||
|
||||
Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
|
||||
uint64_t size, InputSectionBase §ion) {
|
||||
Defined *elf::addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
|
||||
uint64_t value, uint64_t size,
|
||||
InputSectionBase §ion) {
|
||||
Defined *s = makeDefined(section.file, name, STB_LOCAL, STV_DEFAULT, type,
|
||||
value, size, §ion);
|
||||
if (ctx.in.symTab)
|
||||
@@ -1117,13 +1118,14 @@ 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 + ctx.arg.wordsize, (uint64_t)1 << (ctx.arg.wordsize * 8 - 1));
|
||||
writeUint(ctx, 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 * ctx.arg.wordsize, va);
|
||||
writeUint(ctx, 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 :
|
||||
@@ -1304,7 +1306,7 @@ DynamicSection<ELFT>::DynamicSection(Ctx &ctx)
|
||||
// .rela.dyn
|
||||
//
|
||||
// DT_RELASZ is the total size of the included sections.
|
||||
static uint64_t addRelaSz(const RelocationBaseSection &relaDyn) {
|
||||
static uint64_t addRelaSz(Ctx &ctx, const RelocationBaseSection &relaDyn) {
|
||||
size_t size = relaDyn.getSize();
|
||||
if (ctx.in.relaPlt->getParent() == relaDyn.getParent())
|
||||
size += ctx.in.relaPlt->getSize();
|
||||
@@ -1315,7 +1317,7 @@ static uint64_t addRelaSz(const RelocationBaseSection &relaDyn) {
|
||||
// output section. When this occurs we cannot just use the OutputSection
|
||||
// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
|
||||
// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
|
||||
static uint64_t addPltRelSz() { return ctx.in.relaPlt->getSize(); }
|
||||
static uint64_t addPltRelSz(Ctx &ctx) { return ctx.in.relaPlt->getSize(); }
|
||||
|
||||
// Add remaining entries to complete .dynamic contents.
|
||||
template <class ELFT>
|
||||
@@ -1405,7 +1407,7 @@ DynamicSection<ELFT>::computeContents() {
|
||||
if (part.relaDyn->isNeeded()) {
|
||||
addInSec(part.relaDyn->dynamicTag, *part.relaDyn);
|
||||
entries.emplace_back(part.relaDyn->sizeDynamicTag,
|
||||
addRelaSz(*part.relaDyn));
|
||||
addRelaSz(ctx, *part.relaDyn));
|
||||
|
||||
bool isRela = ctx.arg.isRela;
|
||||
addInt(isRela ? DT_RELAENT : DT_RELENT,
|
||||
@@ -1437,7 +1439,7 @@ DynamicSection<ELFT>::computeContents() {
|
||||
}
|
||||
if (isMain && ctx.in.relaPlt->isNeeded()) {
|
||||
addInSec(DT_JMPREL, *ctx.in.relaPlt);
|
||||
entries.emplace_back(DT_PLTRELSZ, addPltRelSz());
|
||||
entries.emplace_back(DT_PLTRELSZ, addPltRelSz(ctx));
|
||||
switch (ctx.arg.emachine) {
|
||||
case EM_MIPS:
|
||||
addInSec(DT_MIPS_PLTGOT, *ctx.in.gotPlt);
|
||||
@@ -2126,15 +2128,18 @@ SymbolTableBaseSection::SymbolTableBaseSection(Ctx &ctx,
|
||||
// See "Global Offset Table" in Chapter 5 in the following document
|
||||
// for detailed description:
|
||||
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
||||
static bool sortMipsSymbols(const SymbolTableEntry &l,
|
||||
const SymbolTableEntry &r) {
|
||||
// Sort entries related to non-local preemptible symbols by GOT indexes.
|
||||
// All other entries go to the beginning of a dynsym in arbitrary order.
|
||||
if (l.sym->isInGot(ctx) && r.sym->isInGot(ctx))
|
||||
return l.sym->getGotIdx(ctx) < r.sym->getGotIdx(ctx);
|
||||
if (!l.sym->isInGot(ctx) && !r.sym->isInGot(ctx))
|
||||
return false;
|
||||
return !l.sym->isInGot(ctx);
|
||||
static void sortMipsSymbols(Ctx &ctx, SmallVector<SymbolTableEntry, 0> &syms) {
|
||||
llvm::stable_sort(syms,
|
||||
[&](const SymbolTableEntry &l, const SymbolTableEntry &r) {
|
||||
// Sort entries related to non-local preemptible symbols
|
||||
// by GOT indexes. All other entries go to the beginning
|
||||
// of a dynsym in arbitrary order.
|
||||
if (l.sym->isInGot(ctx) && r.sym->isInGot(ctx))
|
||||
return l.sym->getGotIdx(ctx) < r.sym->getGotIdx(ctx);
|
||||
if (!l.sym->isInGot(ctx) && !r.sym->isInGot(ctx))
|
||||
return false;
|
||||
return !l.sym->isInGot(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
void SymbolTableBaseSection::finalizeContents() {
|
||||
@@ -2157,7 +2162,7 @@ void SymbolTableBaseSection::finalizeContents() {
|
||||
// NB: It also sorts Symbols to meet the GNU hash table requirements.
|
||||
getPartition().gnuHashTab->addSymbols(symbols);
|
||||
} else if (ctx.arg.emachine == EM_MIPS) {
|
||||
llvm::stable_sort(symbols, sortMipsSymbols);
|
||||
sortMipsSymbols(ctx, symbols);
|
||||
}
|
||||
|
||||
// Only the main partition's dynsym indexes are stored in the symbols
|
||||
@@ -2440,7 +2445,7 @@ void GnuHashTableSection::writeTo(uint8_t *buf) {
|
||||
uint64_t val = readUint(ctx, buf + i * ctx.arg.wordsize);
|
||||
val |= uint64_t(1) << (sym.hash % c);
|
||||
val |= uint64_t(1) << ((sym.hash >> Shift2) % c);
|
||||
writeUint(buf + i * ctx.arg.wordsize, val);
|
||||
writeUint(ctx, buf + i * ctx.arg.wordsize, val);
|
||||
}
|
||||
buf += ctx.arg.wordsize * maskWords;
|
||||
|
||||
|
||||
@@ -1439,8 +1439,9 @@ bool canHaveMemtagGlobals(Ctx &);
|
||||
template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part);
|
||||
template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);
|
||||
|
||||
Defined *addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
|
||||
uint64_t size, InputSectionBase §ion);
|
||||
Defined *addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
|
||||
uint64_t value, uint64_t size,
|
||||
InputSectionBase §ion);
|
||||
|
||||
void addVerneed(Symbol *ss);
|
||||
|
||||
|
||||
@@ -537,7 +537,7 @@ public:
|
||||
|
||||
Defined *Thunk::addSymbol(StringRef name, uint8_t type, uint64_t value,
|
||||
InputSectionBase §ion) {
|
||||
Defined *d = addSyntheticLocal(name, type, value, /*size=*/0, section);
|
||||
Defined *d = addSyntheticLocal(ctx, name, type, value, /*size=*/0, section);
|
||||
syms.push_back(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user