From 90d195d026f5c90e26f09614e23d4112b3dfaaa1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Dec 2019 15:09:43 -0800 Subject: [PATCH] [ELF] Delete relOff from TargetInfo::writePLT This change only affects EM_386. relOff can be computed from `index` easily, so it is unnecessarily passed as a parameter. Both in.plt and in.iplt entries are written by writePLT. For in.iplt, the instruction `push reloc_offset` will change because `index` is now different. Fortunately, this does not matter because `push; jmp` is only used by PLT. IPLT does not need the code sequence. Reviewed By: grimar, ruiu Differential Revision: https://reviews.llvm.org/D71518 --- lld/ELF/Arch/AArch64.cpp | 10 ++++------ lld/ELF/Arch/ARM.cpp | 10 ++++------ lld/ELF/Arch/Hexagon.cpp | 5 ++--- lld/ELF/Arch/Mips.cpp | 5 ++--- lld/ELF/Arch/PPC.cpp | 2 +- lld/ELF/Arch/PPC64.cpp | 5 ++--- lld/ELF/Arch/RISCV.cpp | 5 ++--- lld/ELF/Arch/SPARCV9.cpp | 5 ++--- lld/ELF/Arch/X86.cpp | 18 +++++++++--------- lld/ELF/Arch/X86_64.cpp | 15 ++++++--------- lld/ELF/SyntheticSections.cpp | 8 +------- lld/ELF/Target.h | 3 +-- lld/test/ELF/gnu-ifunc-i386.s | 4 ++-- lld/test/ELF/gnu-ifunc-plt-i386.s | 4 ++-- 14 files changed, 40 insertions(+), 59 deletions(-) diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 4e80e3d..6697ee3 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -38,7 +38,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; bool needsThunk(RelExpr expr, RelType type, const InputFile *file, uint64_t branchAddr, const Symbol &s, int64_t a) const override; @@ -214,8 +214,7 @@ void AArch64::writePltHeader(uint8_t *buf) const { } void AArch64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t inst[] = { 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n])) 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))] @@ -570,7 +569,7 @@ public: AArch64BtiPac(); void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; private: bool btiHeader; // bti instruction needed in PLT Header @@ -630,8 +629,7 @@ void AArch64BtiPac::writePltHeader(uint8_t *buf) const { } void AArch64BtiPac::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { // The PLT entry is of the form: // [btiData] addrInst (pacBr | stdBr) [nopData] const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 0f522d3..d4df027 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -35,7 +35,7 @@ public: void writeIgotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; void addPltSymbols(InputSection &isec, uint64_t off) const override; void addPltHeaderSymbols(InputSection &isd) const override; bool needsThunk(RelExpr expr, RelType type, const InputFile *file, @@ -216,8 +216,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 .plt.got. static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) { + uint64_t pltEntryAddr) { const uint8_t pltData[] = { 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc @@ -232,8 +231,7 @@ static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr, // The default PLT entries require the .plt.got to be within 128 Mb of the // .plt in the positive direction. void ARM::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t /*index*/) const { // The PLT entry is similar to the example given in Appendix A of ELF for // the Arm Architecture. Instead of using the Group Relocations to find the // optimal rotation for the 8-bit immediate used in the add instructions we @@ -248,7 +246,7 @@ void ARM::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t offset = gotPltEntryAddr - pltEntryAddr - 8; if (!llvm::isUInt<27>(offset)) { // We cannot encode the Offset, use the long form. - writePltLong(buf, gotPltEntryAddr, pltEntryAddr, index, relOff); + writePltLong(buf, gotPltEntryAddr, pltEntryAddr); return; } write32le(buf + 0, pltData[0] | ((offset >> 20) & 0xff)); diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp index 67264a2..7759f31 100644 --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -34,7 +34,7 @@ public: void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; }; } // namespace @@ -303,8 +303,7 @@ void Hexagon::writePltHeader(uint8_t *buf) const { } void Hexagon::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t inst[] = { 0x00, 0x40, 0x00, 0x00, // { immext (#0) 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) } diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp index 317b22e..048a749 100644 --- a/lld/ELF/Arch/Mips.cpp +++ b/lld/ELF/Arch/Mips.cpp @@ -33,7 +33,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; bool needsThunk(RelExpr expr, RelType type, const InputFile *file, uint64_t branchAddr, const Symbol &s, int64_t a) const override; @@ -319,8 +319,7 @@ template void MIPS::writePltHeader(uint8_t *buf) const { template void MIPS::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t /*index*/) const { if (isMicroMips()) { // Overwrite trap instructions written by Writer::writeTrapInstr. memset(buf, 0, pltEntrySize); diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp index b0d93c6..be8ca30a 100644 --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -32,7 +32,7 @@ public: llvm_unreachable("should call writePPC32GlinkSection() instead"); } void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override { + int32_t index) const override { llvm_unreachable("should call writePPC32GlinkSection() instead"); } void writeGotPlt(uint8_t *buf, const Symbol &s) const override; diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 41639fb..e9a1c53 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -201,7 +201,7 @@ public: RelType getDynRel(RelType type) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; void writeGotHeader(uint8_t *buf) const override; bool needsThunk(RelExpr expr, RelType type, const InputFile *file, @@ -669,8 +669,7 @@ void PPC64::writePltHeader(uint8_t *buf) const { } void PPC64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { int32_t offset = pltHeaderSize + index * pltEntrySize; // bl __glink_PLTresolve write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc)); diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index e7c0e36..4b5006e 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -28,7 +28,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; RelType getDynRel(RelType type) const override; RelExpr getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const override; @@ -163,8 +163,7 @@ void RISCV::writePltHeader(uint8_t *buf) const { } void RISCV::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t /*index*/) const { // 1: auipc t3, %pcrel_hi(f@.got.plt) // l[wd] t3, %pcrel_lo(1b)(t3) // jalr t1, t3 diff --git a/lld/ELF/Arch/SPARCV9.cpp b/lld/ELF/Arch/SPARCV9.cpp index a0afdff..e870c25 100644 --- a/lld/ELF/Arch/SPARCV9.cpp +++ b/lld/ELF/Arch/SPARCV9.cpp @@ -27,7 +27,7 @@ public: RelExpr getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const override; void writePlt(uint8_t *buf, uint64_t gotEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; }; } // namespace @@ -125,8 +125,7 @@ void SPARCV9::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { } void SPARCV9::writePlt(uint8_t *buf, uint64_t gotEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t pltData[] = { 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1 diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp index b27a6e3..31b3b0a 100644 --- a/lld/ELF/Arch/X86.cpp +++ b/lld/ELF/Arch/X86.cpp @@ -34,7 +34,7 @@ public: void writeIgotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, @@ -214,8 +214,8 @@ void X86::writePltHeader(uint8_t *buf) const { } void X86::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { + unsigned relOff = in.relaPlt->entsize * index; if (config->isPic) { const uint8_t inst[] = { 0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx) @@ -416,7 +416,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; }; class RetpolineNoPic : public X86 { @@ -425,7 +425,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; }; } // namespace @@ -460,8 +460,8 @@ void RetpolinePic::writePltHeader(uint8_t *buf) const { } void RetpolinePic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { + unsigned relOff = in.relaPlt->entsize * index; const uint8_t insn[] = { 0x50, // pushl %eax 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax @@ -518,8 +518,8 @@ void RetpolineNoPic::writePltHeader(uint8_t *buf) const { } void RetpolineNoPic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { + unsigned relOff = in.relaPlt->entsize * index; const uint8_t insn[] = { 0x50, // 0: pushl %eax 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index bb8d92f..459fd110 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -34,7 +34,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, @@ -156,8 +156,7 @@ void X86_64::writePltHeader(uint8_t *buf) const { } void X86_64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t inst[] = { 0xff, 0x25, 0, 0, 0, 0, // jmpq *got(%rip) 0x68, 0, 0, 0, 0, // pushq @@ -584,7 +583,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; }; class RetpolineZNow : public X86_64 { @@ -593,7 +592,7 @@ public: void writeGotPlt(uint8_t *buf, const Symbol &s) const override {} void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override; + int32_t index) const override; }; } // namespace @@ -629,8 +628,7 @@ void Retpoline::writePltHeader(uint8_t *buf) const { } void Retpoline::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t insn[] = { 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20 @@ -672,8 +670,7 @@ void RetpolineZNow::writePltHeader(uint8_t *buf) const { } void RetpolineZNow::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const { + uint64_t pltEntryAddr, int32_t index) const { const uint8_t insn[] = { 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11 0xe9, 0, 0, 0, 0, // jmp plt+0 diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index d5b45c8..46529eb 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2471,17 +2471,11 @@ void PltSection::writeTo(uint8_t *buf) { target->writePltHeader(buf); size_t off = headerSize; - RelocationBaseSection *relSec = isIplt ? in.relaIplt : in.relaPlt; - - // The IPlt is immediately after the Plt, account for this in relOff - size_t pltOff = isIplt ? in.plt->getSize() : 0; - for (size_t i = 0, e = entries.size(); i != e; ++i) { const Symbol *b = entries[i]; - unsigned relOff = relSec->entsize * i + pltOff; uint64_t got = b->getGotPltVA(); uint64_t plt = this->getVA() + off; - target->writePlt(buf + off, got, plt, b->pltIndex, relOff); + target->writePlt(buf + off, got, plt, b->pltIndex); off += target->pltEntrySize; } } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 9d147ed..8abf580 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -42,8 +42,7 @@ public: virtual void writePltHeader(uint8_t *buf) const {} virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr, - uint64_t pltEntryAddr, int32_t index, - unsigned relOff) const {} + uint64_t pltEntryAddr, int32_t index) const {} virtual void addPltHeaderSymbols(InputSection &isec) const {} virtual void addPltSymbols(InputSection &isec, uint64_t off) const {} diff --git a/lld/test/ELF/gnu-ifunc-i386.s b/lld/test/ELF/gnu-ifunc-i386.s index 2e1a506..6d35059 100644 --- a/lld/test/ELF/gnu-ifunc-i386.s +++ b/lld/test/ELF/gnu-ifunc-i386.s @@ -122,11 +122,11 @@ // DISASM-EMPTY: // DISASM-NEXT: foo: // DISASM-NEXT: 401100: jmpl *4202784 -// DISASM-NEXT: pushl $16 +// DISASM-NEXT: pushl $0 // DISASM-NEXT: jmp -32 <_start+0xa> // DISASM: bar: // DISASM-NEXT: 401110: jmpl *4202788 -// DISASM-NEXT: pushl $24 +// DISASM-NEXT: pushl $8 // DISASM-NEXT: jmp -48 <_start+0xa> .text diff --git a/lld/test/ELF/gnu-ifunc-plt-i386.s b/lld/test/ELF/gnu-ifunc-plt-i386.s index 9fd933d..180ecc3 100644 --- a/lld/test/ELF/gnu-ifunc-plt-i386.s +++ b/lld/test/ELF/gnu-ifunc-plt-i386.s @@ -62,10 +62,10 @@ // DISASM-NEXT: pushl $8 // DISASM-NEXT: jmp -48 <.plt> // DISASM-NEXT: jmpl *4207276 -// DISASM-NEXT: pushl $48 +// DISASM-NEXT: pushl $0 // DISASM-NEXT: jmp -32 // DISASM-NEXT: jmpl *4207280 -// DISASM-NEXT: pushl $56 +// DISASM-NEXT: pushl $8 // DISASM-NEXT: jmp -48 .text -- 2.7.4