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:
@@ -48,6 +48,10 @@ public:
|
||||
bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
|
||||
void relocate(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const override;
|
||||
|
||||
private:
|
||||
void encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
|
||||
int group, bool check) const;
|
||||
};
|
||||
enum class CodeState { Data = 0, Thumb = 2, Arm = 4 };
|
||||
} // namespace
|
||||
@@ -534,8 +538,8 @@ static std::pair<uint32_t, uint32_t> getRemAndLZForGroup(unsigned group,
|
||||
return {rem, lz};
|
||||
}
|
||||
|
||||
static void encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
|
||||
int group, bool check) {
|
||||
void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
|
||||
int group, bool check) const {
|
||||
// ADD/SUB (immediate) add = bit23, sub = bit22
|
||||
// immediate field carries is a 12-bit modified immediate, made up of a 4-bit
|
||||
// even rotate right and an 8-bit immediate.
|
||||
|
||||
@@ -159,7 +159,7 @@ static bool isJirl(uint32_t insn) {
|
||||
return (insn & 0xfc000000) == JIRL;
|
||||
}
|
||||
|
||||
static void handleUleb128(uint8_t *loc, uint64_t val) {
|
||||
static void handleUleb128(Ctx &ctx, uint8_t *loc, uint64_t val) {
|
||||
const uint32_t maxcount = 1 + 64 / 7;
|
||||
uint32_t count;
|
||||
const char *error = nullptr;
|
||||
@@ -700,7 +700,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
|
||||
write64le(loc, read64le(loc) + val);
|
||||
return;
|
||||
case R_LARCH_ADD_ULEB128:
|
||||
handleUleb128(loc, val);
|
||||
handleUleb128(ctx, loc, val);
|
||||
return;
|
||||
case R_LARCH_SUB6:
|
||||
*loc = (*loc & 0xc0) | ((*loc - val) & 0x3f);
|
||||
@@ -718,7 +718,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
|
||||
write64le(loc, read64le(loc) - val);
|
||||
return;
|
||||
case R_LARCH_SUB_ULEB128:
|
||||
handleUleb128(loc, -val);
|
||||
handleUleb128(ctx, loc, -val);
|
||||
return;
|
||||
|
||||
case R_LARCH_MARK_LA:
|
||||
|
||||
@@ -39,6 +39,12 @@ public:
|
||||
|
||||
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
|
||||
void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
|
||||
|
||||
private:
|
||||
void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -344,7 +350,8 @@ void X86::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
|
||||
}
|
||||
}
|
||||
|
||||
static void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
if (rel.type == R_386_TLS_GD) {
|
||||
// Convert (loc[-2] == 0x04)
|
||||
// leal x@tlsgd(, %ebx, 1), %eax
|
||||
@@ -379,7 +386,8 @@ static void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
static void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
if (rel.type == R_386_TLS_GD) {
|
||||
// Convert (loc[-2] == 0x04)
|
||||
// leal x@tlsgd(, %ebx, 1), %eax
|
||||
@@ -413,7 +421,8 @@ static void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
|
||||
// In some conditions, relocations can be optimized to avoid using GOT.
|
||||
// This function does that for Initial Exec to Local Exec case.
|
||||
static void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
// Ulrich's document section 6.2 says that @gotntpoff can
|
||||
// be used with MOVL or ADDL instructions.
|
||||
// @indntpoff is similar to @gotntpoff, but for use in
|
||||
@@ -450,7 +459,8 @@ static void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
write32le(loc, val);
|
||||
}
|
||||
|
||||
static void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
if (rel.type == R_386_TLS_LDO_32) {
|
||||
write32le(loc, val);
|
||||
return;
|
||||
|
||||
@@ -50,6 +50,12 @@ public:
|
||||
bool deleteFallThruJmpInsn(InputSection &is, InputFile *file,
|
||||
InputSection *nextIS) const override;
|
||||
bool relaxOnce(int pass) const override;
|
||||
|
||||
private:
|
||||
void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -460,7 +466,8 @@ RelType X86_64::getDynRel(RelType type) const {
|
||||
return R_X86_64_NONE;
|
||||
}
|
||||
|
||||
static void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86_64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
if (rel.type == R_X86_64_TLSGD) {
|
||||
// Convert
|
||||
// .byte 0x66
|
||||
@@ -500,7 +507,8 @@ static void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
static void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
if (rel.type == R_X86_64_TLSGD) {
|
||||
// Convert
|
||||
// .byte 0x66
|
||||
@@ -541,7 +549,8 @@ static void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
|
||||
// In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
|
||||
// R_X86_64_TPOFF32 so that it does not use GOT.
|
||||
static void relaxTlsIeToLe(uint8_t *loc, const Relocation &, uint64_t val) {
|
||||
void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
uint8_t *inst = loc - 3;
|
||||
uint8_t reg = loc[-1] >> 3;
|
||||
uint8_t *regSlot = loc - 1;
|
||||
@@ -582,7 +591,8 @@ static void relaxTlsIeToLe(uint8_t *loc, const Relocation &, uint64_t val) {
|
||||
write32le(loc, val + 4);
|
||||
}
|
||||
|
||||
static void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
|
||||
void X86_64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
const uint8_t inst[] = {
|
||||
0x66, 0x66, // .word 0x6666
|
||||
0x66, // .byte 0x66
|
||||
|
||||
@@ -479,7 +479,7 @@ static void sortSections(MutableArrayRef<InputSectionBase *> vec,
|
||||
// --sort-section is handled as an inner SORT command.
|
||||
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
|
||||
// 4. If no SORT command is given, sort according to --sort-section.
|
||||
static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
|
||||
static void sortInputSections(Ctx &ctx, MutableArrayRef<InputSectionBase *> vec,
|
||||
SortSectionPolicy outer,
|
||||
SortSectionPolicy inner) {
|
||||
if (outer == SortSectionPolicy::None)
|
||||
@@ -517,6 +517,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
|
||||
for (size_t i = begin; i != end; ++i)
|
||||
ret[i] = sections[indexes[i]];
|
||||
sortInputSections(
|
||||
ctx,
|
||||
MutableArrayRef<InputSectionBase *>(ret).slice(begin, end - begin),
|
||||
ctx.arg.sortSection, SortSectionPolicy::None);
|
||||
};
|
||||
@@ -584,6 +585,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
|
||||
// ret[sizeBeforeCurrPat,ret.size()) are already in the input order, so we
|
||||
// just sort by sortOuter and sortInner.
|
||||
sortInputSections(
|
||||
ctx,
|
||||
MutableArrayRef<InputSectionBase *>(ret).slice(sizeBeforeCurrPat),
|
||||
pat.sortOuter, pat.sortInner);
|
||||
sizeAfterPrevSort = ret.size();
|
||||
@@ -865,7 +867,8 @@ static OutputDesc *createSection(InputSectionBase *isec, StringRef outsecName) {
|
||||
return osd;
|
||||
}
|
||||
|
||||
static OutputDesc *addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
|
||||
static OutputDesc *addInputSec(Ctx &ctx,
|
||||
StringMap<TinyPtrVector<OutputSection *>> &map,
|
||||
InputSectionBase *isec, StringRef outsecName) {
|
||||
// Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
|
||||
// option is given. A section with SHT_GROUP defines a "section group", and
|
||||
@@ -983,7 +986,7 @@ void LinkerScript::addOrphanSections() {
|
||||
} else if (OutputSection *sec = findByName(sectionCommands, name)) {
|
||||
sec->recordSection(s);
|
||||
} else {
|
||||
if (OutputDesc *osd = addInputSec(map, s, name))
|
||||
if (OutputDesc *osd = addInputSec(ctx, map, s, name))
|
||||
v.push_back(osd);
|
||||
assert(isa<MergeInputSection>(s) ||
|
||||
s->getOutputSection()->sectionIndex == UINT32_MAX);
|
||||
@@ -1114,7 +1117,7 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
|
||||
return {nullptr, nullptr};
|
||||
}
|
||||
|
||||
static OutputSection *findFirstSection(PhdrEntry *load) {
|
||||
static OutputSection *findFirstSection(Ctx &ctx, PhdrEntry *load) {
|
||||
for (OutputSection *sec : ctx.outputSections)
|
||||
if (sec->ptLoad == load)
|
||||
return sec;
|
||||
@@ -1187,7 +1190,7 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
|
||||
|
||||
// Propagate state->lmaOffset to the first "non-header" section.
|
||||
if (PhdrEntry *l = sec->ptLoad)
|
||||
if (sec == findFirstSection(l))
|
||||
if (sec == findFirstSection(ctx, l))
|
||||
l->lmaOffset = state->lmaOffset;
|
||||
|
||||
// We can call this method multiple times during the creation of
|
||||
@@ -1462,7 +1465,7 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
|
||||
|
||||
ctx.out.elfHeader->ptLoad = nullptr;
|
||||
ctx.out.programHeaders->ptLoad = nullptr;
|
||||
firstPTLoad->firstSec = findFirstSection(firstPTLoad);
|
||||
firstPTLoad->firstSec = findFirstSection(ctx, firstPTLoad);
|
||||
|
||||
llvm::erase_if(phdrs,
|
||||
[](const PhdrEntry *e) { return e->p_type == PT_PHDR; });
|
||||
|
||||
Reference in New Issue
Block a user