Author: Fangrui Song Date: 2020-11-25T08:43:26-08:00 New Revision: 572d18397cf0d8808ec85f9bd51471cd80266c27
URL: https://github.com/llvm/llvm-project/commit/572d18397cf0d8808ec85f9bd51471cd80266c27 DIFF: https://github.com/llvm/llvm-project/commit/572d18397cf0d8808ec85f9bd51471cd80266c27.diff LOG: [ELF] Add TargetInfo::adjustGotPcExpr for `R_GOT_PC` relaxations. NFC With this change, `TargetInfo::adjustRelaxExpr` is only related to TLS relaxations and a subsequent clean-up can delete the `data` parameter. Differential Revision: https://reviews.llvm.org/D92079 Added: Modified: lld/ELF/Arch/PPC64.cpp lld/ELF/Arch/X86_64.cpp lld/ELF/Relocations.cpp lld/ELF/Target.cpp lld/ELF/Target.h Removed: ################################################################################ diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 8a3de2b3cbb2..a18cf9591125 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -384,6 +384,8 @@ class PPC64 final : public TargetInfo { bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override; RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, RelExpr expr) const override; + RelExpr adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *loc) const override; void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const override; void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, @@ -1392,20 +1394,23 @@ bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const { RelExpr PPC64::adjustRelaxExpr(RelType type, const uint8_t *data, RelExpr expr) const { + if (type != R_PPC64_GOT_TLSGD_PCREL34 && expr == R_RELAX_TLS_GD_TO_IE) + return R_RELAX_TLS_GD_TO_IE_GOT_OFF; + if (expr == R_RELAX_TLS_LD_TO_LE) + return R_RELAX_TLS_LD_TO_LE_ABS; + return expr; +} + +RelExpr PPC64::adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *loc) const { if ((type == R_PPC64_GOT_PCREL34 || type == R_PPC64_PCREL_OPT) && config->pcRelOptimize) { // It only makes sense to optimize pld since paddi means that the address // of the object in the GOT is required rather than the object itself. - assert(data && "Expecting an instruction encoding here"); - if ((readPrefixedInstruction(data) & 0xfc000000) == 0xe4000000) + if ((readPrefixedInstruction(loc) & 0xfc000000) == 0xe4000000) return R_PPC64_RELAX_GOT_PC; } - - if (type != R_PPC64_GOT_TLSGD_PCREL34 && expr == R_RELAX_TLS_GD_TO_IE) - return R_RELAX_TLS_GD_TO_IE_GOT_OFF; - if (expr == R_RELAX_TLS_LD_TO_LE) - return R_RELAX_TLS_LD_TO_LE_ABS; - return expr; + return R_GOT_PC; } // Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement. diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 93fd8ecb7c8e..618922844238 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -40,8 +40,8 @@ class X86_64 : public TargetInfo { void applyJumpInstrMod(uint8_t *loc, JumpModType type, unsigned size) const override; - RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, - RelExpr expr) const override; + RelExpr adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *loc) const override; void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const override; void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, @@ -728,12 +728,12 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { } } -RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data, - RelExpr relExpr) const { +RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *loc) const { if (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX) - return relExpr; - const uint8_t op = data[-2]; - const uint8_t modRm = data[-1]; + return R_GOT_PC; + const uint8_t op = loc[-2]; + const uint8_t modRm = loc[-1]; // FIXME: When PIC is disabled and foo is defined locally in the // lower 32 bit address space, memory operand in mov can be converted into @@ -748,11 +748,11 @@ RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data, // We don't support test/binop instructions without a REX prefix. if (type == R_X86_64_GOTPCRELX) - return relExpr; + return R_GOT_PC; // Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor. // If PIC then no relaxation is available. - return config->isPic ? relExpr : R_RELAX_GOT_PC_NOPIC; + return config->isPic ? R_GOT_PC : R_RELAX_GOT_PC_NOPIC; } // A subset of relaxations can only be applied for no-PIC. This method diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index abb21f1d7274..115957ffefe1 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1361,9 +1361,7 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i, // runtime, because the main executable is always at the beginning of a search // list. We can leverage that fact. if (!sym.isPreemptible && (!sym.isGnuIFunc() || config->zIfuncNoplt)) { - if (expr == R_GOT_PC && !isAbsoluteValue(sym)) { - expr = target->adjustRelaxExpr(type, relocatedAddr, expr); - } else { + if (expr != R_GOT_PC) { // The 0x8000 bit of r_addend of R_PPC_PLTREL24 is used to choose call // stub type. It should be ignored if optimized to R_PC. if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL) @@ -1375,6 +1373,8 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i, type == R_HEX_GD_PLT_B22_PCREL_X || type == R_HEX_GD_PLT_B32_PCREL_X))) expr = fromPlt(expr); + } else if (!isAbsoluteValue(sym)) { + expr = target->adjustGotPcExpr(type, addend, relocatedAddr); } } diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 6abd8b452e23..324c07dc7fda 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -155,6 +155,11 @@ RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data, return expr; } +RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *data) const { + return R_GOT_PC; +} + void TargetInfo::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const { llvm_unreachable("Should not have claimed to be relaxable"); diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 9399ecf526f4..d59d7422e42d 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -150,6 +150,8 @@ class TargetInfo { virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, RelExpr expr) const; + virtual RelExpr adjustGotPcExpr(RelType type, int64_t addend, + const uint8_t *loc) const; virtual void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const; virtual void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits