Skip to content

Commit

Permalink
[ELF] Pass Ctx & to Arch-specific code
Browse files Browse the repository at this point in the history
  • Loading branch information
MaskRay committed Oct 13, 2024
1 parent e5f7e73 commit 0dbc85a
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 35 deletions.
28 changes: 14 additions & 14 deletions lld/ELF/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ void ARM::addPltHeaderSymbols(InputSection &isec) const {

// Long form PLT entries that do not have any restrictions on the displacement
// of the .plt from the .got.plt.
static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
static void writePltLong(Ctx &ctx, uint8_t *buf, uint64_t gotPltEntryAddr,
uint64_t pltEntryAddr) {
write32(ctx, buf + 0, 0xe59fc004); // ldr ip, L2
write32(ctx, buf + 4, 0xe08cc00f); // L1: add ip, ip, pc
Expand Down Expand Up @@ -339,7 +339,7 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym,
};
if (!llvm::isUInt<27>(offset)) {
// We cannot encode the Offset, use the long form.
writePltLong(buf, sym.getGotPltVA(ctx), pltEntryAddr);
writePltLong(ctx, buf, sym.getGotPltVA(ctx), pltEntryAddr);
return;
}
write32(ctx, buf + 0, pltData[0] | ((offset >> 20) & 0xff));
Expand Down Expand Up @@ -562,8 +562,8 @@ void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
(read32(ctx, loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
}

static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
int group) {
static void encodeLdrGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
uint64_t val, int group) {
// R_ARM_LDR_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
// function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
// bottom bit to recover S + A - P.
Expand All @@ -580,8 +580,8 @@ static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
write32(ctx, loc, (read32(ctx, loc) & 0xff7ff000) | opcode | imm);
}

static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
int group) {
static void encodeLdrsGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
uint64_t val, int group) {
// R_ARM_LDRS_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
// function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
// bottom bit to recover S + A - P.
Expand Down Expand Up @@ -804,22 +804,22 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
encodeAluGroup(loc, rel, val, 2, true);
break;
case R_ARM_LDR_PC_G0:
encodeLdrGroup(loc, rel, val, 0);
encodeLdrGroup(ctx, loc, rel, val, 0);
break;
case R_ARM_LDR_PC_G1:
encodeLdrGroup(loc, rel, val, 1);
encodeLdrGroup(ctx, loc, rel, val, 1);
break;
case R_ARM_LDR_PC_G2:
encodeLdrGroup(loc, rel, val, 2);
encodeLdrGroup(ctx, loc, rel, val, 2);
break;
case R_ARM_LDRS_PC_G0:
encodeLdrsGroup(loc, rel, val, 0);
encodeLdrsGroup(ctx, loc, rel, val, 0);
break;
case R_ARM_LDRS_PC_G1:
encodeLdrsGroup(loc, rel, val, 1);
encodeLdrsGroup(ctx, loc, rel, val, 1);
break;
case R_ARM_LDRS_PC_G2:
encodeLdrsGroup(loc, rel, val, 2);
encodeLdrsGroup(ctx, loc, rel, val, 2);
break;
case R_ARM_THM_ALU_PREL_11_0: {
// ADR encoding T2 (sub), T3 (add) i:imm3:imm8
Expand Down Expand Up @@ -1096,11 +1096,11 @@ static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
CodeState curState = static_cast<CodeState>(width);
if (curState == CodeState::Arm)
for (uint64_t i = start; i < end; i += width)
write32le(buf + i, read32(ctx, buf + i));
write32le(buf + i, read32be(buf + i));

if (curState == CodeState::Thumb)
for (uint64_t i = start; i < end; i += width)
write16le(buf + i, read16(ctx, buf + i));
write16le(buf + i, read16be(buf + i));
}

// Arm BE8 big endian format requires instructions to be little endian, with
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
}
}

static bool relax(InputSection &sec) {
static bool relax(Ctx &ctx, InputSection &sec) {
const uint64_t secAddr = sec.getVA();
const MutableArrayRef<Relocation> relocs = sec.relocs();
auto &aux = *sec.relaxAux;
Expand Down Expand Up @@ -833,7 +833,7 @@ bool LoongArch::relaxOnce(int pass) const {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage))
changed |= relax(*sec);
changed |= relax(ctx, *sec);
}
return changed;
}
Expand Down
13 changes: 7 additions & 6 deletions lld/ELF/Arch/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ static void writeShuffle(Ctx &ctx, uint8_t *loc, uint64_t v, uint8_t bitsSize,
}

template <endianness E>
static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
uint8_t shift) {
static void writeMicroRelocation16(Ctx &ctx, uint8_t *loc, uint64_t v,
uint8_t bitsSize, uint8_t shift) {
uint16_t instr = read16(ctx, loc);
uint16_t mask = 0xffff >> (16 - bitsSize);
uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
Expand Down Expand Up @@ -519,7 +519,8 @@ static bool isMicroBranchReloc(RelType type) {
}

template <class ELFT>
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
static uint64_t fixupCrossModeJump(Ctx &ctx, uint8_t *loc, RelType type,
uint64_t val) {
// Here we need to detect jump/branch from regular MIPS code
// to a microMIPS target and vice versa. In that cases jump
// instructions need to be replaced by their "cross-mode"
Expand Down Expand Up @@ -577,7 +578,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
std::tie(type, val) = calculateMipsRelChain(ctx, loc, type, val);

// Detect cross-mode jump/branch and fix instruction.
val = fixupCrossModeJump<ELFT>(loc, type, val);
val = fixupCrossModeJump<ELFT>(ctx, loc, type, val);

// Thread pointer and DRP offsets from the start of TLS data area.
// https://www.linux-mips.org/wiki/NPTL
Expand Down Expand Up @@ -727,11 +728,11 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
break;
case R_MICROMIPS_PC7_S1:
checkInt(loc, val, 8, rel);
writeMicroRelocation16<e>(loc, val, 7, 1);
writeMicroRelocation16<e>(ctx, loc, val, 7, 1);
break;
case R_MICROMIPS_PC10_S1:
checkInt(loc, val, 11, rel);
writeMicroRelocation16<e>(loc, val, 10, 1);
writeMicroRelocation16<e>(ctx, loc, val, 10, 1);
break;
case R_MICROMIPS_PC16_S1:
checkInt(loc, val, 17, rel);
Expand Down
3 changes: 2 additions & 1 deletion lld/ELF/Arch/PPC64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,8 @@ void PPC64::writePlt(uint8_t *buf, const Symbol &sym,

void PPC64::writeIplt(uint8_t *buf, const Symbol &sym,
uint64_t /*pltEntryAddr*/) const {
writePPC64LoadAndBranch(buf, sym.getGotPltVA(ctx) - getPPC64TocBase(ctx));
writePPC64LoadAndBranch(ctx, buf,
sym.getGotPltVA(ctx) - getPPC64TocBase(ctx));
}

static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {
Expand Down
5 changes: 3 additions & 2 deletions lld/ELF/OutputSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ template <class ELFT> void OutputSection::maybeCompress(Ctx &ctx) {
flags |= SHF_COMPRESSED;
}

static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
static void writeInt(Ctx &ctx, uint8_t *buf, uint64_t data, uint64_t size) {
if (size == 1)
*buf = data;
else if (size == 2)
Expand Down Expand Up @@ -563,7 +563,8 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
if (auto *data = dyn_cast<ByteCommand>(cmd)) {
if (!std::exchange(written, true))
fn(0, numSections);
writeInt(buf + data->offset, data->expression().getValue(), data->size);
writeInt(ctx, buf + data->offset, data->expression().getValue(),
data->size);
}
if (written || !numSections)
return;
Expand Down
11 changes: 6 additions & 5 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ void EhFrameSection::iterateFDEWithLSDA(
}
}

static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
static void writeCieFde(Ctx &ctx, uint8_t *buf, ArrayRef<uint8_t> d) {
memcpy(buf, d.data(), d.size());
// Fix the size field. -4 since size does not include the size field itself.
write32(ctx, buf, d.size() - 4);
Expand Down Expand Up @@ -632,11 +632,11 @@ void EhFrameSection::writeTo(uint8_t *buf) {
// Write CIE and FDE records.
for (CieRecord *rec : cieRecords) {
size_t cieOffset = rec->cie->outputOff;
writeCieFde(buf + cieOffset, rec->cie->data());
writeCieFde(ctx, buf + cieOffset, rec->cie->data());

for (EhSectionPiece *fde : rec->fdes) {
size_t off = fde->outputOff;
writeCieFde(buf + off, fde->data());
writeCieFde(ctx, buf + off, fde->data());

// FDE's second word should have the offset to an associated CIE.
// Write it.
Expand Down Expand Up @@ -4077,7 +4077,8 @@ static bool isExtabRef(uint32_t unwind) {
// unwinding instructions in Cur are identical to Prev. Linker generated
// EXIDX_CANTUNWIND entries are represented by nullptr as they do not have an
// InputSection.
static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
static bool isDuplicateArmExidxSec(Ctx &ctx, InputSection *prev,
InputSection *cur) {
// Get the last table Entry from the previous .ARM.exidx section. If Prev is
// nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
uint32_t prevUnwind = 1;
Expand Down Expand Up @@ -4166,7 +4167,7 @@ void ARMExidxSyntheticSection::finalizeContents() {
for (size_t i = 1; i < executableSections.size(); ++i) {
InputSection *ex1 = findExidxSection(executableSections[prev]);
InputSection *ex2 = findExidxSection(executableSections[i]);
if (!isDuplicateArmExidxSec(ex1, ex2)) {
if (!isDuplicateArmExidxSec(ctx, ex1, ex2)) {
selectedSections.push_back(executableSections[i]);
prev = i;
}
Expand Down
8 changes: 4 additions & 4 deletions lld/ELF/Thunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ void PPC32LongThunk::writeTo(uint8_t *buf) {
write32(ctx, buf + 4, 0x4e800420); // bctr
}

void elf::writePPC64LoadAndBranch(uint8_t *buf, int64_t offset) {
void elf::writePPC64LoadAndBranch(Ctx &ctx, uint8_t *buf, int64_t offset) {
uint16_t offHa = (offset + 0x8000) >> 16;
uint16_t offLo = offset & 0xffff;

Expand All @@ -1246,7 +1246,7 @@ void PPC64PltCallStub::writeTo(uint8_t *buf) {
int64_t offset = destination.getGotPltVA(ctx) - getPPC64TocBase(ctx);
// Save the TOC pointer to the save-slot reserved in the call frame.
write32(ctx, buf + 0, 0xf8410018); // std r2,24(r1)
writePPC64LoadAndBranch(buf + 4, offset);
writePPC64LoadAndBranch(ctx, buf + 4, offset);
}

void PPC64PltCallStub::addSymbols(ThunkSection &isec) {
Expand Down Expand Up @@ -1289,7 +1289,7 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
const int64_t offsetFromTOC =
ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
getPPC64TocBase(ctx);
writePPC64LoadAndBranch(buf + 4, offsetFromTOC);
writePPC64LoadAndBranch(ctx, buf + 4, offsetFromTOC);
}
}

Expand Down Expand Up @@ -1352,7 +1352,7 @@ void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
int64_t offset =
ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
getPPC64TocBase(ctx);
writePPC64LoadAndBranch(buf, offset);
writePPC64LoadAndBranch(ctx, buf, offset);
}

void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) {
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Thunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Thunk *addLandingPadThunk(Ctx &, Symbol &s, int64_t a);

void writePPC32PltCallStub(Ctx &, uint8_t *buf, uint64_t gotPltVA,
const InputFile *file, int64_t addend);
void writePPC64LoadAndBranch(uint8_t *buf, int64_t offset);
void writePPC64LoadAndBranch(Ctx &, uint8_t *buf, int64_t offset);

} // namespace lld::elf

Expand Down

0 comments on commit 0dbc85a

Please sign in to comment.