https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/106681
>From 88cbdf9765e42dee7d2b050dcf8a20a08b4b148f Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH 1/8] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For mov name@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test $name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 ++++-- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def | 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +++++------ .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++++++++++++++++++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 48f17718365e24..1371cee410dc82 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in <internal> # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in <internal> +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in <internal> #--- a.s movl __stop_data@GOTPCREL(%rip), %eax # out of range movq __stop_data@GOTPCREL(%rip), %rax # out of range + movq __stop_data@GOTPCREL(%rip), %r16 # out of range movq __stop_data@GOTPCREL(%rip), %rax # in range .section data,"aw",@progbits @@ -23,5 +27,5 @@ #--- lds SECTIONS { .text 0x200000 : { *(.text) } - .got 0x80200010 : { *(.got) } + .got 0x80200016 : { *(.got) } } diff --git a/lld/test/ELF/x86-64-gotpc-relax.s b/lld/test/ELF/x86-64-gotpc-relax.s index 5945bfc04a0225..1fb3a3c76852ab 100644 --- a/lld/test/ELF/x86-64-gotpc-relax.s +++ b/lld/test/ELF/x86-64-gotpc-relax.s @@ -1,5 +1,5 @@ # REQUIRES: x86 -## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization. +## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX GOT optimization. # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld %t.o -o %t1 --no-apply-dynamic-relocs diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def index 18fdcf9472dc48..161b1969abfeb4 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def @@ -43,3 +43,4 @@ ELF_RELOC(R_X86_64_TLSDESC, 36) ELF_RELOC(R_X86_64_IRELATIVE, 37) ELF_RELOC(R_X86_64_GOTPCRELX, 41) ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42) +ELF_RELOC(R_X86_64_REX2_GOTPCRELX, 43) diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp index 1a4f7e93eeb74a..92618bdabbe519 100644 --- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -145,8 +145,8 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() { static cl::opt<bool> X86RelaxRelocations( "x86-relax-relocations", - cl::desc( - "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"), + cl::desc("Emit GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX instead of " + "GOTPCREL on x86-64 ELF"), cl::init(true)); MCBINDOPT(X86RelaxRelocations); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 1d08853faf582e..d1fd274433804b 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -631,8 +631,10 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"reloc_riprel_4byte_movq_load_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"reloc_riprel_4byte_relax_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_signed_4byte", 0, 32, 0}, {"reloc_signed_4byte_relax", 0, 32, 0}, {"reloc_global_offset_table", 0, 32, 0}, @@ -678,7 +680,9 @@ static unsigned getFixupKindSize(unsigned Kind) { case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_riprel_4byte_movq_load: + case X86::reloc_riprel_4byte_movq_load_rex2: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: case X86::reloc_global_offset_table: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp index 0b2efdfc16cc5d..9fdc62b8c8516f 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -74,7 +74,9 @@ static X86_64RelType getType64(MCFixupKind Kind, case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_riprel_4byte_movq_load: + case X86::reloc_riprel_4byte_movq_load_rex2: return RT64_32; case X86::reloc_branch_4byte_pcrel: Modifier = MCSymbolRefExpr::VK_PLT; @@ -205,7 +207,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, case MCSymbolRefExpr::VK_GOTPCREL: checkIs32(Ctx, Loc, Type); // Older versions of ld.bfd/ld.gold/lld - // do not support GOTPCRELX/REX_GOTPCRELX, + // do not support GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX, // and we want to keep back-compatibility. if (!Ctx.getTargetOptions()->X86RelaxRelocations) return ELF::R_X86_64_GOTPCREL; @@ -217,6 +219,9 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, case X86::reloc_riprel_4byte_relax_rex: case X86::reloc_riprel_4byte_movq_load: return ELF::R_X86_64_REX_GOTPCRELX; + case X86::reloc_riprel_4byte_relax_rex2: + case X86::reloc_riprel_4byte_movq_load_rex2: + return ELF::R_X86_64_REX2_GOTPCRELX; } llvm_unreachable("unexpected relocation type!"); case MCSymbolRefExpr::VK_GOTPCREL_NORELAX: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h index 2d5217115d07cb..29bb7eebae3f22 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h @@ -16,10 +16,14 @@ namespace X86 { enum Fixups { reloc_riprel_4byte = FirstTargetFixupKind, // 32-bit rip-relative reloc_riprel_4byte_movq_load, // 32-bit rip-relative in movq + reloc_riprel_4byte_movq_load_rex2, // 32-bit rip-relative in movq + // with rex2 prefix reloc_riprel_4byte_relax, // 32-bit rip-relative in relaxable // instruction reloc_riprel_4byte_relax_rex, // 32-bit rip-relative in relaxable // instruction with rex prefix + reloc_riprel_4byte_relax_rex2, // 32-bit rip-relative in relaxable + // instruction with rex2 prefix reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4 // this will be sign extended at // runtime. diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 71d42863fd5857..206436191c2584 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -568,8 +568,10 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc, if (FixupKind == FK_PCRel_4 || FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) || + FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load_rex2) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) || + FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex2) || FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) { ImmOffset -= 4; // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_: @@ -637,12 +639,11 @@ void X86MCCodeEmitter::emitMemModRMByte( default: return X86::reloc_riprel_4byte; case X86::MOV64rm: - // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a + // movq loads is a subset of reloc_riprel_4byte_relax_rex/rex2. It is a // special case because COFF and Mach-O don't support ELF's more - // flexible R_X86_64_REX_GOTPCRELX relaxation. - // TODO: Support new relocation for REX2. - assert(Kind == REX || Kind == REX2); - return X86::reloc_riprel_4byte_movq_load; + // flexible R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX relaxation. + return Kind == REX2 ? X86::reloc_riprel_4byte_movq_load_rex2 + : X86::reloc_riprel_4byte_movq_load; case X86::ADC32rm: case X86::ADD32rm: case X86::AND32rm: @@ -665,11 +666,9 @@ void X86MCCodeEmitter::emitMemModRMByte( case X86::SBB64rm: case X86::SUB64rm: case X86::XOR64rm: - // We haven't support relocation for REX2 prefix, so temporarily use REX - // relocation. - // TODO: Support new relocation for REX2. - return (Kind == REX || Kind == REX2) ? X86::reloc_riprel_4byte_relax_rex - : X86::reloc_riprel_4byte_relax; + return Kind == REX2 ? X86::reloc_riprel_4byte_relax_rex2 + : Kind == REX ? X86::reloc_riprel_4byte_relax_rex + : X86::reloc_riprel_4byte_relax; } }(); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp index ec95b1ffec387d..41ce5c9fcb82ad 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -66,8 +66,10 @@ class X86MachObjectWriter : public MCMachObjectTargetWriter { static bool isFixupKindRIPRel(unsigned Kind) { return Kind == X86::reloc_riprel_4byte || Kind == X86::reloc_riprel_4byte_movq_load || + Kind == X86::reloc_riprel_4byte_movq_load_rex2 || Kind == X86::reloc_riprel_4byte_relax || - Kind == X86::reloc_riprel_4byte_relax_rex; + Kind == X86::reloc_riprel_4byte_relax_rex || + Kind == X86::reloc_riprel_4byte_relax_rex2; } static unsigned getFixupKindLog2Size(unsigned Kind) { @@ -83,7 +85,9 @@ static unsigned getFixupKindLog2Size(unsigned Kind) { case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_riprel_4byte_movq_load: + case X86::reloc_riprel_4byte_movq_load_rex2: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: case X86::reloc_branch_4byte_pcrel: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp index 10fc176b59d8ab..7740500fb41830 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp @@ -66,8 +66,10 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx, case FK_PCRel_4: case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_movq_load: + case X86::reloc_riprel_4byte_movq_load_rex2: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_branch_4byte_pcrel: return COFF::IMAGE_REL_AMD64_REL32; case FK_Data_4: diff --git a/llvm/test/MC/ELF/relocation-alias.s b/llvm/test/MC/ELF/relocation-alias.s index 51fb0c37052fe7..66bf2ceea508ba 100644 --- a/llvm/test/MC/ELF/relocation-alias.s +++ b/llvm/test/MC/ELF/relocation-alias.s @@ -16,7 +16,10 @@ movabsq $memcpy+2, %rax # CHECK: movq (%rip), %rax # CHECK-NEXT: R_X86_64_REX_GOTPCRELX abs-0x4 +# CHECK: movq (%rip), %r16 +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX abs-0x4 movq abs@GOTPCREL(%rip), %rax +movq abs@GOTPCREL(%rip), %r16 abs = 42 # CHECK: movabsq $0, %rbx diff --git a/llvm/test/MC/X86/gotpcrelx.s b/llvm/test/MC/X86/gotpcrelx.s index e63e3e9a946fd1..5a8ba454bc904c 100644 --- a/llvm/test/MC/X86/gotpcrelx.s +++ b/llvm/test/MC/X86/gotpcrelx.s @@ -37,6 +37,16 @@ # CHECK-NEXT: R_X86_64_REX_GOTPCRELX sbb # CHECK-NEXT: R_X86_64_REX_GOTPCRELX sub # CHECK-NEXT: R_X86_64_REX_GOTPCRELX xor +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX mov +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX test +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX adc +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX add +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX and +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX cmp +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX or +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX sbb +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX sub +# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX xor # CHECK-NEXT: } # NORELAX-NEXT: R_X86_64_GOTPCREL mov @@ -71,6 +81,16 @@ # NORELAX-NEXT: R_X86_64_GOTPCREL sbb # NORELAX-NEXT: R_X86_64_GOTPCREL sub # NORELAX-NEXT: R_X86_64_GOTPCREL xor +# NORELAX-NEXT: R_X86_64_GOTPCREL mov +# NORELAX-NEXT: R_X86_64_GOTPCREL test +# NORELAX-NEXT: R_X86_64_GOTPCREL adc +# NORELAX-NEXT: R_X86_64_GOTPCREL add +# NORELAX-NEXT: R_X86_64_GOTPCREL and +# NORELAX-NEXT: R_X86_64_GOTPCREL cmp +# NORELAX-NEXT: R_X86_64_GOTPCREL or +# NORELAX-NEXT: R_X86_64_GOTPCREL sbb +# NORELAX-NEXT: R_X86_64_GOTPCREL sub +# NORELAX-NEXT: R_X86_64_GOTPCREL xor # NORELAX-NEXT: } movl mov@GOTPCREL(%rip), %eax @@ -108,10 +128,22 @@ sbb sbb@GOTPCREL(%rip), %rax sub sub@GOTPCREL(%rip), %rax xor xor@GOTPCREL(%rip), %rax +movq mov@GOTPCREL(%rip), %r16 +test %r16, test@GOTPCREL(%rip) +adc adc@GOTPCREL(%rip), %r16 +add add@GOTPCREL(%rip), %r16 +and and@GOTPCREL(%rip), %r16 +cmp cmp@GOTPCREL(%rip), %r16 +or or@GOTPCREL(%rip), %r16 +sbb sbb@GOTPCREL(%rip), %r16 +sub sub@GOTPCREL(%rip), %r16 +xor xor@GOTPCREL(%rip), %r16 + # COMMON-NEXT: Section ({{.*}}) .rela.norelax { # COMMON-NEXT: R_X86_64_GOTPCREL mov 0x0 # COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD # COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFC +# COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD # COMMON-NEXT: } # COMMON-NEXT: ] @@ -123,3 +155,5 @@ movl mov@GOTPCREL+4(%rip), %eax movq mov@GOTPCREL+1(%rip), %rax ## We could emit R_X86_64_GOTPCRELX, but it is probably unnecessary. movl mov@GOTPCREL+0(%rip), %eax +## Don't emit R_X86_64_GOTPCRELX. +movq mov@GOTPCREL+1(%rip), %r16 >From 732918170c2396a44bd0b333ebae568791dc30d7 Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Fri, 30 Aug 2024 16:20:27 +0800 Subject: [PATCH 2/8] add more test --- llvm/test/MC/X86/reloc-directive-elf-64.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/test/MC/X86/reloc-directive-elf-64.s b/llvm/test/MC/X86/reloc-directive-elf-64.s index 8f5d8c895e7d76..323603efc70618 100644 --- a/llvm/test/MC/X86/reloc-directive-elf-64.s +++ b/llvm/test/MC/X86/reloc-directive-elf-64.s @@ -9,6 +9,7 @@ # PRINT-NEXT: .reloc 0, R_X86_64_64, .data+2 # PRINT-NEXT: .reloc 0, R_X86_64_GOTPCRELX, foo+3 # PRINT-NEXT: .reloc 0, R_X86_64_REX_GOTPCRELX, 5 +# PRINT-NEXT: .reloc 0, R_X86_64_REX2_GOTPCRELX, 7 # PRINT: .reloc 0, BFD_RELOC_NONE, 9 # PRINT-NEXT: .reloc 0, BFD_RELOC_8, 9 # PRINT-NEXT: .reloc 0, BFD_RELOC_16, 9 @@ -21,6 +22,7 @@ # CHECK-NEXT: 0x0 R_X86_64_64 .data 0x2 # CHECK-NEXT: 0x0 R_X86_64_GOTPCRELX foo 0x3 # CHECK-NEXT: 0x0 R_X86_64_REX_GOTPCRELX - 0x5 +# CHECK-NEXT: 0x0 R_X86_64_REX2_GOTPCRELX - 0x7 # CHECK-NEXT: 0x0 R_X86_64_NONE - 0x9 # CHECK-NEXT: 0x0 R_X86_64_8 - 0x9 # CHECK-NEXT: 0x0 R_X86_64_16 - 0x9 @@ -37,6 +39,7 @@ .reloc 0, R_X86_64_64, .data+2 .reloc 0, R_X86_64_GOTPCRELX, foo+3 .reloc 0, R_X86_64_REX_GOTPCRELX, 5 + .reloc 0, R_X86_64_REX2_GOTPCRELX, 7 .reloc 0, BFD_RELOC_NONE, 9 .reloc 0, BFD_RELOC_8, 9 >From 44b828a13031a48810372c43d26b8c4084677aa8 Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Fri, 30 Aug 2024 16:30:18 +0800 Subject: [PATCH 3/8] clang-format --- llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp index 9fdc62b8c8516f..90222278d1ad6f 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -221,7 +221,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, return ELF::R_X86_64_REX_GOTPCRELX; case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_riprel_4byte_movq_load_rex2: - return ELF::R_X86_64_REX2_GOTPCRELX; + return ELF::R_X86_64_REX2_GOTPCRELX; } llvm_unreachable("unexpected relocation type!"); case MCSymbolRefExpr::VK_GOTPCREL_NORELAX: >From 6e981a096bb9f0edacfe5d655b8b295f945c23d1 Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Fri, 30 Aug 2024 17:06:47 +0800 Subject: [PATCH 4/8] add more test --- lld/test/ELF/x86-64-gotpc-relax-nopic.s | 109 +++++++++++++++--------- lld/test/ELF/x86-64-gotpc-relax.s | 13 +++ 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s b/lld/test/ELF/x86-64-gotpc-relax-nopic.s index 7481904d16f1b4..e3cd93d1d57962 100644 --- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s +++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s @@ -10,30 +10,39 @@ # SYMRELOC: Symbols [ # SYMRELOC: Symbol { # SYMRELOC: Name: bar -# SYMRELOC-NEXT: Value: 0x203248 +# SYMRELOC-NEXT: Value: 0x203290 ## 2105751 = 0x202197 (bar) # DISASM: Disassembly of section .text: # DISASM-EMPTY: # DISASM-NEXT: <_start>: -# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202240 -# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202240 -# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202240 -# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202240 -# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202240 -# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202240 -# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202240 -# DISASM-NEXT: xorl $0x203248, %r8d -# DISASM-NEXT: testl $0x203248, %r15d -# DISASM-NEXT: 201200: adcq $0x203248, %rax -# DISASM-NEXT: addq $0x203248, %rbx -# DISASM-NEXT: andq $0x203248, %rcx -# DISASM-NEXT: cmpq $0x203248, %rdx -# DISASM-NEXT: orq $0x203248, %rdi -# DISASM-NEXT: sbbq $0x203248, %rsi -# DISASM-NEXT: subq $0x203248, %rbp -# DISASM-NEXT: xorq $0x203248, %r8 -# DISASM-NEXT: testq $0x203248, %r15 +# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202288 +# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202288 +# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202288 +# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202288 +# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202288 +# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202288 +# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202288 +# DISASM-NEXT: xorl $0x203290, %r8d +# DISASM-NEXT: testl $0x203290, %r15d +# DISASM-NEXT: 201200: adcq $0x203290, %rax +# DISASM-NEXT: addq $0x203290, %rbx +# DISASM-NEXT: andq $0x203290, %rcx +# DISASM-NEXT: cmpq $0x203290, %rdx +# DISASM-NEXT: orq $0x203290, %rdi +# DISASM-NEXT: sbbq $0x203290, %rsi +# DISASM-NEXT: subq $0x203290, %rbp +# DISASM-NEXT: xorq $0x203290, %r8 +# DISASM-NEXT: testq $0x203290, %r15 +# DISASM-NEXT: 20123f: adcq $0x203290, %r16 +# DISASM-NEXT: addq $0x203290, %r17 +# DISASM-NEXT: andq $0x203290, %r18 +# DISASM-NEXT: cmpq $0x203290, %r19 +# DISASM-NEXT: orq $0x203290, %r20 +# DISASM-NEXT: sbbq $0x203290, %r21 +# DISASM-NEXT: subq $0x203290, %r22 +# DISASM-NEXT: xorq $0x203290, %r23 +# DISASM-NEXT: testq $0x203290, %r24 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2 # RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s @@ -46,8 +55,8 @@ # SEC-PIC-NEXT: SHF_ALLOC # SEC-PIC-NEXT: SHF_WRITE # SEC-PIC-NEXT: ] -# SEC-PIC-NEXT: Address: 0x2380 -# SEC-PIC-NEXT: Offset: 0x380 +# SEC-PIC-NEXT: Address: 0x23C8 +# SEC-PIC-NEXT: Offset: 0x3C8 # SEC-PIC-NEXT: Size: 8 # SEC-PIC-NEXT: Link: # SEC-PIC-NEXT: Info: @@ -57,7 +66,7 @@ # SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1 # SEC-PIC: Relocations [ # SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn { -# SEC-PIC-NEXT: 0x2380 R_X86_64_RELATIVE - 0x3388 +# SEC-PIC-NEXT: 0x23C8 R_X86_64_RELATIVE - 0x33D0 # SEC-PIC-NEXT: } # SEC-PIC-NEXT: ] @@ -65,24 +74,33 @@ # DISASM-PIC: Disassembly of section .text: # DISASM-PIC-EMPTY: # DISASM-PIC-NEXT: <_start>: -# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x2380 -# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x2380 -# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x2380 -# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x2380 -# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x2380 -# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x2380 -# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x2380 -# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x2380 -# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x2380 -# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x2380 -# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x2380 -# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x2380 -# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x2380 -# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x2380 -# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x2380 -# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x2380 -# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x2380 -# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x2380 +# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x23c8 +# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x23c8 +# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x23c8 +# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x23c8 +# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x23c8 +# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x23c8 +# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x23c8 +# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x23c8 +# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x23c8 +# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x23c8 +# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x23c8 +# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x23c8 +# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x23c8 +# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x23c8 +# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x23c8 +# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x23c8 +# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x23c8 +# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x23c8 +# DISASM-PIC-NEXT: 12df: adcq {{.*}}(%rip), %r16 # 0x23c8 +# DISASM-PIC-NEXT: addq {{.*}}(%rip), %r17 # 0x23c8 +# DISASM-PIC-NEXT: andq {{.*}}(%rip), %r18 # 0x23c8 +# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %r19 # 0x23c8 +# DISASM-PIC-NEXT: orq {{.*}}(%rip), %r20 # 0x23c8 +# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %r21 # 0x23c8 +# DISASM-PIC-NEXT: subq {{.*}}(%rip), %r22 # 0x23c8 +# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r23 # 0x23c8 +# DISASM-PIC-NEXT: testq %r24, {{.*}}(%rip) # 0x23c8 .data .type bar, @object @@ -115,3 +133,14 @@ _start: subq bar@GOTPCREL(%rip), %rbp xorq bar@GOTPCREL(%rip), %r8 testq %r15, bar@GOTPCREL(%rip) + +## R_X86_64_REX2_GOTPCRELX + adcq bar@GOTPCREL(%rip), %r16 + addq bar@GOTPCREL(%rip), %r17 + andq bar@GOTPCREL(%rip), %r18 + cmpq bar@GOTPCREL(%rip), %r19 + orq bar@GOTPCREL(%rip), %r20 + sbbq bar@GOTPCREL(%rip), %r21 + subq bar@GOTPCREL(%rip), %r22 + xorq bar@GOTPCREL(%rip), %r23 + testq %r24, bar@GOTPCREL(%rip) diff --git a/lld/test/ELF/x86-64-gotpc-relax.s b/lld/test/ELF/x86-64-gotpc-relax.s index 1fb3a3c76852ab..ee15738268d5a8 100644 --- a/lld/test/ELF/x86-64-gotpc-relax.s +++ b/lld/test/ELF/x86-64-gotpc-relax.s @@ -120,3 +120,16 @@ _start: jmp *hid@GOTPCREL(%rip) jmp *ifunc@GOTPCREL(%rip) jmp *ifunc@GOTPCREL(%rip) + + movq foo@GOTPCREL(%rip), %r16 + movq foo@GOTPCREL(%rip), %r16 + movq hid@GOTPCREL(%rip), %r16 + movq hid@GOTPCREL(%rip), %r16 + movq ifunc@GOTPCREL(%rip), %r16 + movq ifunc@GOTPCREL(%rip), %r16 + movq foo@GOTPCREL(%rip), %r16 + movq foo@GOTPCREL(%rip), %r16 + movq hid@GOTPCREL(%rip), %r16 + movq hid@GOTPCREL(%rip), %r16 + movq ifunc@GOTPCREL(%rip), %r16 + movq ifunc@GOTPCREL(%rip), %r16 >From 338a5650bec6d6f15cdbc9bf38a50f48400568b5 Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Fri, 30 Aug 2024 17:56:53 +0800 Subject: [PATCH 5/8] disable clang-format --- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index d1fd274433804b..2f6b55b0d6023e 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -629,6 +629,7 @@ std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const { const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { + // clang-format off {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_movq_load_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, @@ -640,6 +641,7 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"reloc_global_offset_table", 0, 32, 0}, {"reloc_global_offset_table8", 0, 64, 0}, {"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + // clang-format on }; // Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They >From 4bf2ab00947052a4e24ad4826dcdf9c576a45fce Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Sun, 1 Sep 2024 13:55:38 +0800 Subject: [PATCH 6/8] Make test x86-64-gotpc-relax.s pass --- lld/ELF/Arch/X86_64.cpp | 13 ++++++----- lld/test/ELF/x86-64-gotpc-relax.s | 39 ++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 1371cee410dc82..a02ba2f34ccf8f 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -862,12 +862,13 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, const uint8_t *loc) const { - // Only R_X86_64_[REX_]GOTPCRELX can be relaxed. GNU as may emit GOTPCRELX - // with addend != -4. Such an instruction does not load the full GOT entry, so - // we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax - // (addend=0) loads the high 32 bits of the GOT entry. + // Only R_X86_64_[REX_]|[REX2_]GOTPCRELX can be relaxed. GNU as may emit + // GOTPCRELX with addend != -4. Such an instruction does not load the full GOT + // entry, so we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), + // %rax (addend=0) loads the high 32 bits of the GOT entry. if (!ctx.arg.relax || addend != -4 || - (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)) + (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX && + type != R_X86_64_REX2_GOTPCRELX)) return R_GOT_PC; const uint8_t op = loc[-2]; const uint8_t modRm = loc[-1]; @@ -883,7 +884,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, if (op == 0xff && (modRm == 0x15 || modRm == 0x25)) return R_RELAX_GOT_PC; - // We don't support test/binop instructions without a REX prefix. + // We don't support test/binop instructions without a REX/REX2 prefix. if (type == R_X86_64_GOTPCRELX) return R_GOT_PC; diff --git a/lld/test/ELF/x86-64-gotpc-relax.s b/lld/test/ELF/x86-64-gotpc-relax.s index ee15738268d5a8..b1ff995b3fc211 100644 --- a/lld/test/ELF/x86-64-gotpc-relax.s +++ b/lld/test/ELF/x86-64-gotpc-relax.s @@ -15,16 +15,16 @@ ## In our implementation, .got is retained even if all GOT-generating relocations are optimized. # CHECK: Name Type Address Off Size ES Flg Lk Inf Al -# CHECK: .iplt PROGBITS 0000000000201280 000280 000010 00 AX 0 0 16 -# CHECK-NEXT: .got PROGBITS 0000000000202290 000290 000000 00 WA 0 0 8 +# CHECK: .iplt PROGBITS 00000000002012e0 0002e0 000010 00 AX 0 0 16 +# CHECK-NEXT: .got PROGBITS 00000000002022f0 0002f0 000000 00 WA 0 0 8 ## There is one R_X86_64_IRELATIVE relocations. # RELOC-LABEL: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entry: # CHECK: Offset Info Type Symbol's Value Symbol's Name + Addend -# CHECK: 0000000000203290 0000000000000025 R_X86_64_IRELATIVE 2011e2 +# CHECK: 00000000002032f0 0000000000000025 R_X86_64_IRELATIVE 2011e2 # CHECK-LABEL: Hex dump of section '.got.plt': -# NOAPPLY-NEXT: 0x00203290 00000000 00000000 -# APPLY-NEXT: 0x00203290 e2112000 00000000 +# NOAPPLY-NEXT: 0x002032f0 00000000 00000000 +# APPLY-NEXT: 0x002032f0 e2112000 00000000 # 0x201173 + 7 - 10 = 0x201170 # 0x20117a + 7 - 17 = 0x201170 @@ -43,20 +43,20 @@ # DISASM-NEXT: leaq -17(%rip), %rax # DISASM-NEXT: leaq -23(%rip), %rax # DISASM-NEXT: leaq -30(%rip), %rax -# DISASM-NEXT: movq 8330(%rip), %rax -# DISASM-NEXT: movq 8323(%rip), %rax +# DISASM-NEXT: movq 8426(%rip), %rax +# DISASM-NEXT: movq 8419(%rip), %rax # DISASM-NEXT: leaq -52(%rip), %rax # DISASM-NEXT: leaq -59(%rip), %rax # DISASM-NEXT: leaq -65(%rip), %rax # DISASM-NEXT: leaq -72(%rip), %rax -# DISASM-NEXT: movq 8288(%rip), %rax -# DISASM-NEXT: movq 8281(%rip), %rax +# DISASM-NEXT: movq 8384(%rip), %rax +# DISASM-NEXT: movq 8377(%rip), %rax # DISASM-NEXT: callq 0x2011e0 <foo> # DISASM-NEXT: callq 0x2011e0 <foo> # DISASM-NEXT: callq 0x2011e1 <hid> # DISASM-NEXT: callq 0x2011e1 <hid> -# DISASM-NEXT: callq *8251(%rip) -# DISASM-NEXT: callq *8245(%rip) +# DISASM-NEXT: callq *8347(%rip) +# DISASM-NEXT: callq *8341(%rip) # DISASM-NEXT: jmp 0x2011e0 <foo> # DISASM-NEXT: nop # DISASM-NEXT: jmp 0x2011e0 <foo> @@ -65,13 +65,26 @@ # DISASM-NEXT: nop # DISASM-NEXT: jmp 0x2011e1 <hid> # DISASM-NEXT: nop -# DISASM-NEXT: jmpq *8215(%rip) -# DISASM-NEXT: jmpq *8209(%rip) +# DISASM-NEXT: jmpq *8311(%rip) +# DISASM-NEXT: jmpq *8305(%rip) +# DISASM-NEXT: leaq -167(%rip), %r16 +# DISASM-NEXT: leaq -175(%rip), %r16 +# DISASM-NEXT: leaq -182(%rip), %r16 +# DISASM-NEXT: leaq -190(%rip), %r16 +# DISASM-NEXT: movq 8265(%rip), %r16 +# DISASM-NEXT: movq 8257(%rip), %r16 +# DISASM-NEXT: leaq -215(%rip), %r16 +# DISASM-NEXT: leaq -223(%rip), %r16 +# DISASM-NEXT: leaq -230(%rip), %r16 +# DISASM-NEXT: leaq -238(%rip), %r16 +# DISASM-NEXT: movq 8217(%rip), %r16 +# DISASM-NEXT: movq 8209(%rip), %r16 # NORELAX-LABEL: <_start>: # NORELAX-COUNT-12: movq # NORELAX-COUNT-6: callq * # NORELAX-COUNT-6: jmpq * +# NORELAX-COUNT-12: movq .text .globl foo >From 62a5da253afbe09a55066d279ed6ff9629e04a03 Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Sun, 1 Sep 2024 18:02:01 +0800 Subject: [PATCH 7/8] Make test x86-64-gotpc-relax-nopic.s pass --- lld/ELF/Arch/X86_64.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index a02ba2f34ccf8f..56e3b882b8b3c7 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -901,6 +901,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, uint8_t modRm) { const uint8_t rex = loc[-3]; + const bool isRex2 = loc[-4] == 0xd5; // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg". if (op == 0x85) { // See "TEST-Logical Compare" (4-428 Vol. 2B), @@ -925,7 +926,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // See "TEST-Logical Compare" (4-428 Vol. 2B). loc[-2] = 0xf7; - // Move R bit to the B bit in REX byte. + // Move R bit to the B bit in REX/REX2 byte. // REX byte is encoded as 0100WRXB, where // 0100 is 4bit fixed pattern. // REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the @@ -936,7 +937,18 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // REX.B This 1-bit value is an extension to the MODRM.rm field or the // SIB.base field. // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A). - loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; + // + // REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where + // 0xd5 is 1byte fixed pattern. + // REX2's [W,R,X,B] have the same meanings as REX's. + // REX2.M encodes the map id. + // R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B + // register identifiers, each of which can now address all 32 GPRs. + // TODO: Add the section number here after APX SPEC is merged into SDM. + if (isRex2) + loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2; + else + loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; write32le(loc, val); return; } @@ -957,7 +969,10 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for // descriptions about each operation. loc[-2] = 0x81; - loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; + if (isRex2) + loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2; + else + loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; write32le(loc, val); } >From 42e150fde2638501d8a615f358f50fbcfddb1a5a Mon Sep 17 00:00:00 2001 From: Shengchen Kan <shengchen....@intel.com> Date: Tue, 24 Sep 2024 16:06:21 +0800 Subject: [PATCH 8/8] Revert lld change --- lld/ELF/Arch/X86_64.cpp | 37 ++------ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 +-- lld/test/ELF/x86-64-gotpc-relax-nopic.s | 109 +++++++++-------------- lld/test/ELF/x86-64-gotpc-relax.s | 54 +++-------- 4 files changed, 66 insertions(+), 144 deletions(-) diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 56e3b882b8b3c7..48f17718365e24 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,7 +388,6 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: - case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -726,7 +725,6 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: - case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -810,7 +808,6 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: - case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { @@ -862,13 +859,12 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, const uint8_t *loc) const { - // Only R_X86_64_[REX_]|[REX2_]GOTPCRELX can be relaxed. GNU as may emit - // GOTPCRELX with addend != -4. Such an instruction does not load the full GOT - // entry, so we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), - // %rax (addend=0) loads the high 32 bits of the GOT entry. + // Only R_X86_64_[REX_]GOTPCRELX can be relaxed. GNU as may emit GOTPCRELX + // with addend != -4. Such an instruction does not load the full GOT entry, so + // we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax + // (addend=0) loads the high 32 bits of the GOT entry. if (!ctx.arg.relax || addend != -4 || - (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX && - type != R_X86_64_REX2_GOTPCRELX)) + (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)) return R_GOT_PC; const uint8_t op = loc[-2]; const uint8_t modRm = loc[-1]; @@ -884,7 +880,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, if (op == 0xff && (modRm == 0x15 || modRm == 0x25)) return R_RELAX_GOT_PC; - // We don't support test/binop instructions without a REX/REX2 prefix. + // We don't support test/binop instructions without a REX prefix. if (type == R_X86_64_GOTPCRELX) return R_GOT_PC; @@ -901,7 +897,6 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, uint8_t modRm) { const uint8_t rex = loc[-3]; - const bool isRex2 = loc[-4] == 0xd5; // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg". if (op == 0x85) { // See "TEST-Logical Compare" (4-428 Vol. 2B), @@ -926,7 +921,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // See "TEST-Logical Compare" (4-428 Vol. 2B). loc[-2] = 0xf7; - // Move R bit to the B bit in REX/REX2 byte. + // Move R bit to the B bit in REX byte. // REX byte is encoded as 0100WRXB, where // 0100 is 4bit fixed pattern. // REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the @@ -937,18 +932,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // REX.B This 1-bit value is an extension to the MODRM.rm field or the // SIB.base field. // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A). - // - // REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where - // 0xd5 is 1byte fixed pattern. - // REX2's [W,R,X,B] have the same meanings as REX's. - // REX2.M encodes the map id. - // R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B - // register identifiers, each of which can now address all 32 GPRs. - // TODO: Add the section number here after APX SPEC is merged into SDM. - if (isRex2) - loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2; - else - loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; + loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; write32le(loc, val); return; } @@ -969,10 +953,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for // descriptions about each operation. loc[-2] = 0x81; - if (isRex2) - loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2; - else - loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; + loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2; write32le(loc, val); } diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 4280c8fd1dc97e..618dca47755f41 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,19 +7,15 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in <internal> # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' -# CHECK-NEXT: >>> defined in <internal> -# CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in <internal> #--- a.s movl __stop_data@GOTPCREL(%rip), %eax # out of range movq __stop_data@GOTPCREL(%rip), %rax # out of range - movq __stop_data@GOTPCREL(%rip), %r16 # out of range movq __stop_data@GOTPCREL(%rip), %rax # in range .section data,"aw",@progbits @@ -27,5 +23,5 @@ #--- lds SECTIONS { .text 0x200000 : { *(.text) } - .got 0x80200016 : { *(.got) } + .got 0x80200010 : { *(.got) } } diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s b/lld/test/ELF/x86-64-gotpc-relax-nopic.s index e3cd93d1d57962..7481904d16f1b4 100644 --- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s +++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s @@ -10,39 +10,30 @@ # SYMRELOC: Symbols [ # SYMRELOC: Symbol { # SYMRELOC: Name: bar -# SYMRELOC-NEXT: Value: 0x203290 +# SYMRELOC-NEXT: Value: 0x203248 ## 2105751 = 0x202197 (bar) # DISASM: Disassembly of section .text: # DISASM-EMPTY: # DISASM-NEXT: <_start>: -# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202288 -# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202288 -# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202288 -# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202288 -# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202288 -# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202288 -# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202288 -# DISASM-NEXT: xorl $0x203290, %r8d -# DISASM-NEXT: testl $0x203290, %r15d -# DISASM-NEXT: 201200: adcq $0x203290, %rax -# DISASM-NEXT: addq $0x203290, %rbx -# DISASM-NEXT: andq $0x203290, %rcx -# DISASM-NEXT: cmpq $0x203290, %rdx -# DISASM-NEXT: orq $0x203290, %rdi -# DISASM-NEXT: sbbq $0x203290, %rsi -# DISASM-NEXT: subq $0x203290, %rbp -# DISASM-NEXT: xorq $0x203290, %r8 -# DISASM-NEXT: testq $0x203290, %r15 -# DISASM-NEXT: 20123f: adcq $0x203290, %r16 -# DISASM-NEXT: addq $0x203290, %r17 -# DISASM-NEXT: andq $0x203290, %r18 -# DISASM-NEXT: cmpq $0x203290, %r19 -# DISASM-NEXT: orq $0x203290, %r20 -# DISASM-NEXT: sbbq $0x203290, %r21 -# DISASM-NEXT: subq $0x203290, %r22 -# DISASM-NEXT: xorq $0x203290, %r23 -# DISASM-NEXT: testq $0x203290, %r24 +# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202240 +# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202240 +# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202240 +# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202240 +# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202240 +# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202240 +# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202240 +# DISASM-NEXT: xorl $0x203248, %r8d +# DISASM-NEXT: testl $0x203248, %r15d +# DISASM-NEXT: 201200: adcq $0x203248, %rax +# DISASM-NEXT: addq $0x203248, %rbx +# DISASM-NEXT: andq $0x203248, %rcx +# DISASM-NEXT: cmpq $0x203248, %rdx +# DISASM-NEXT: orq $0x203248, %rdi +# DISASM-NEXT: sbbq $0x203248, %rsi +# DISASM-NEXT: subq $0x203248, %rbp +# DISASM-NEXT: xorq $0x203248, %r8 +# DISASM-NEXT: testq $0x203248, %r15 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2 # RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s @@ -55,8 +46,8 @@ # SEC-PIC-NEXT: SHF_ALLOC # SEC-PIC-NEXT: SHF_WRITE # SEC-PIC-NEXT: ] -# SEC-PIC-NEXT: Address: 0x23C8 -# SEC-PIC-NEXT: Offset: 0x3C8 +# SEC-PIC-NEXT: Address: 0x2380 +# SEC-PIC-NEXT: Offset: 0x380 # SEC-PIC-NEXT: Size: 8 # SEC-PIC-NEXT: Link: # SEC-PIC-NEXT: Info: @@ -66,7 +57,7 @@ # SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1 # SEC-PIC: Relocations [ # SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn { -# SEC-PIC-NEXT: 0x23C8 R_X86_64_RELATIVE - 0x33D0 +# SEC-PIC-NEXT: 0x2380 R_X86_64_RELATIVE - 0x3388 # SEC-PIC-NEXT: } # SEC-PIC-NEXT: ] @@ -74,33 +65,24 @@ # DISASM-PIC: Disassembly of section .text: # DISASM-PIC-EMPTY: # DISASM-PIC-NEXT: <_start>: -# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x23c8 -# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x23c8 -# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x23c8 -# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x23c8 -# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x23c8 -# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x23c8 -# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x23c8 -# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x23c8 -# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x23c8 -# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x23c8 -# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x23c8 -# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x23c8 -# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x23c8 -# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x23c8 -# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x23c8 -# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x23c8 -# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x23c8 -# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x23c8 -# DISASM-PIC-NEXT: 12df: adcq {{.*}}(%rip), %r16 # 0x23c8 -# DISASM-PIC-NEXT: addq {{.*}}(%rip), %r17 # 0x23c8 -# DISASM-PIC-NEXT: andq {{.*}}(%rip), %r18 # 0x23c8 -# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %r19 # 0x23c8 -# DISASM-PIC-NEXT: orq {{.*}}(%rip), %r20 # 0x23c8 -# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %r21 # 0x23c8 -# DISASM-PIC-NEXT: subq {{.*}}(%rip), %r22 # 0x23c8 -# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r23 # 0x23c8 -# DISASM-PIC-NEXT: testq %r24, {{.*}}(%rip) # 0x23c8 +# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x2380 +# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x2380 +# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x2380 +# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x2380 +# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x2380 +# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x2380 +# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x2380 +# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x2380 +# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x2380 +# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x2380 +# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x2380 +# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x2380 +# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x2380 +# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x2380 +# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x2380 +# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x2380 +# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x2380 +# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x2380 .data .type bar, @object @@ -133,14 +115,3 @@ _start: subq bar@GOTPCREL(%rip), %rbp xorq bar@GOTPCREL(%rip), %r8 testq %r15, bar@GOTPCREL(%rip) - -## R_X86_64_REX2_GOTPCRELX - adcq bar@GOTPCREL(%rip), %r16 - addq bar@GOTPCREL(%rip), %r17 - andq bar@GOTPCREL(%rip), %r18 - cmpq bar@GOTPCREL(%rip), %r19 - orq bar@GOTPCREL(%rip), %r20 - sbbq bar@GOTPCREL(%rip), %r21 - subq bar@GOTPCREL(%rip), %r22 - xorq bar@GOTPCREL(%rip), %r23 - testq %r24, bar@GOTPCREL(%rip) diff --git a/lld/test/ELF/x86-64-gotpc-relax.s b/lld/test/ELF/x86-64-gotpc-relax.s index b1ff995b3fc211..5945bfc04a0225 100644 --- a/lld/test/ELF/x86-64-gotpc-relax.s +++ b/lld/test/ELF/x86-64-gotpc-relax.s @@ -1,5 +1,5 @@ # REQUIRES: x86 -## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX GOT optimization. +## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization. # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld %t.o -o %t1 --no-apply-dynamic-relocs @@ -15,16 +15,16 @@ ## In our implementation, .got is retained even if all GOT-generating relocations are optimized. # CHECK: Name Type Address Off Size ES Flg Lk Inf Al -# CHECK: .iplt PROGBITS 00000000002012e0 0002e0 000010 00 AX 0 0 16 -# CHECK-NEXT: .got PROGBITS 00000000002022f0 0002f0 000000 00 WA 0 0 8 +# CHECK: .iplt PROGBITS 0000000000201280 000280 000010 00 AX 0 0 16 +# CHECK-NEXT: .got PROGBITS 0000000000202290 000290 000000 00 WA 0 0 8 ## There is one R_X86_64_IRELATIVE relocations. # RELOC-LABEL: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entry: # CHECK: Offset Info Type Symbol's Value Symbol's Name + Addend -# CHECK: 00000000002032f0 0000000000000025 R_X86_64_IRELATIVE 2011e2 +# CHECK: 0000000000203290 0000000000000025 R_X86_64_IRELATIVE 2011e2 # CHECK-LABEL: Hex dump of section '.got.plt': -# NOAPPLY-NEXT: 0x002032f0 00000000 00000000 -# APPLY-NEXT: 0x002032f0 e2112000 00000000 +# NOAPPLY-NEXT: 0x00203290 00000000 00000000 +# APPLY-NEXT: 0x00203290 e2112000 00000000 # 0x201173 + 7 - 10 = 0x201170 # 0x20117a + 7 - 17 = 0x201170 @@ -43,20 +43,20 @@ # DISASM-NEXT: leaq -17(%rip), %rax # DISASM-NEXT: leaq -23(%rip), %rax # DISASM-NEXT: leaq -30(%rip), %rax -# DISASM-NEXT: movq 8426(%rip), %rax -# DISASM-NEXT: movq 8419(%rip), %rax +# DISASM-NEXT: movq 8330(%rip), %rax +# DISASM-NEXT: movq 8323(%rip), %rax # DISASM-NEXT: leaq -52(%rip), %rax # DISASM-NEXT: leaq -59(%rip), %rax # DISASM-NEXT: leaq -65(%rip), %rax # DISASM-NEXT: leaq -72(%rip), %rax -# DISASM-NEXT: movq 8384(%rip), %rax -# DISASM-NEXT: movq 8377(%rip), %rax +# DISASM-NEXT: movq 8288(%rip), %rax +# DISASM-NEXT: movq 8281(%rip), %rax # DISASM-NEXT: callq 0x2011e0 <foo> # DISASM-NEXT: callq 0x2011e0 <foo> # DISASM-NEXT: callq 0x2011e1 <hid> # DISASM-NEXT: callq 0x2011e1 <hid> -# DISASM-NEXT: callq *8347(%rip) -# DISASM-NEXT: callq *8341(%rip) +# DISASM-NEXT: callq *8251(%rip) +# DISASM-NEXT: callq *8245(%rip) # DISASM-NEXT: jmp 0x2011e0 <foo> # DISASM-NEXT: nop # DISASM-NEXT: jmp 0x2011e0 <foo> @@ -65,26 +65,13 @@ # DISASM-NEXT: nop # DISASM-NEXT: jmp 0x2011e1 <hid> # DISASM-NEXT: nop -# DISASM-NEXT: jmpq *8311(%rip) -# DISASM-NEXT: jmpq *8305(%rip) -# DISASM-NEXT: leaq -167(%rip), %r16 -# DISASM-NEXT: leaq -175(%rip), %r16 -# DISASM-NEXT: leaq -182(%rip), %r16 -# DISASM-NEXT: leaq -190(%rip), %r16 -# DISASM-NEXT: movq 8265(%rip), %r16 -# DISASM-NEXT: movq 8257(%rip), %r16 -# DISASM-NEXT: leaq -215(%rip), %r16 -# DISASM-NEXT: leaq -223(%rip), %r16 -# DISASM-NEXT: leaq -230(%rip), %r16 -# DISASM-NEXT: leaq -238(%rip), %r16 -# DISASM-NEXT: movq 8217(%rip), %r16 -# DISASM-NEXT: movq 8209(%rip), %r16 +# DISASM-NEXT: jmpq *8215(%rip) +# DISASM-NEXT: jmpq *8209(%rip) # NORELAX-LABEL: <_start>: # NORELAX-COUNT-12: movq # NORELAX-COUNT-6: callq * # NORELAX-COUNT-6: jmpq * -# NORELAX-COUNT-12: movq .text .globl foo @@ -133,16 +120,3 @@ _start: jmp *hid@GOTPCREL(%rip) jmp *ifunc@GOTPCREL(%rip) jmp *ifunc@GOTPCREL(%rip) - - movq foo@GOTPCREL(%rip), %r16 - movq foo@GOTPCREL(%rip), %r16 - movq hid@GOTPCREL(%rip), %r16 - movq hid@GOTPCREL(%rip), %r16 - movq ifunc@GOTPCREL(%rip), %r16 - movq ifunc@GOTPCREL(%rip), %r16 - movq foo@GOTPCREL(%rip), %r16 - movq foo@GOTPCREL(%rip), %r16 - movq hid@GOTPCREL(%rip), %r16 - movq hid@GOTPCREL(%rip), %r16 - movq ifunc@GOTPCREL(%rip), %r16 - movq ifunc@GOTPCREL(%rip), %r16 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits