Skip to content

Commit 6f76b2a

Browse files
authored
[X86][MC] Add R_X86_64_CODE_4_GOTTPOFF (#116633)
For mov name@GOTTPOFF(%rip), %reg add name@GOTTPOFF(%rip), %reg add `R_X86_64_CODE_4_GOTTPOFF` = 44 if the instruction starts at 4 bytes before the relocation offset. It's similar to R_X86_64_GOTTPOFF. Linker can treat `R_X86_64_CODE_4_GOTTPOFF` as `R_X86_64_GOTTPOFF` or convert the instructions above to mov $name@tpoff, %reg add $name@tpoff, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/REX2 prefix) when possible. Binutils patch: bminor/binutils-gdb@a533c8d Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
1 parent 46f43b6 commit 6f76b2a

File tree

3 files changed

+39
-32
lines changed

3 files changed

+39
-32
lines changed

llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ ELF_RELOC(R_X86_64_IRELATIVE, 37)
4444
ELF_RELOC(R_X86_64_GOTPCRELX, 41)
4545
ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
4646
ELF_RELOC(R_X86_64_CODE_4_GOTPCRELX, 43)
47+
ELF_RELOC(R_X86_64_CODE_4_GOTTPOFF, 44)

llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
197197
return ELF::R_X86_64_TLSGD;
198198
case MCSymbolRefExpr::VK_GOTTPOFF:
199199
checkIs32(Ctx, Loc, Type);
200+
if ((unsigned)Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
201+
(unsigned)Kind == X86::reloc_riprel_4byte_relax_rex2)
202+
return ELF::R_X86_64_CODE_4_GOTTPOFF;
200203
return ELF::R_X86_64_GOTTPOFF;
201204
case MCSymbolRefExpr::VK_TLSLD:
202205
checkIs32(Ctx, Loc, Type);

llvm/test/MC/ELF/relocation.s

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ bar:
1919
movq bar, %rdx # R_X86_64_32S
2020
.long bar # R_X86_64_32
2121
leaq foo@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
22+
movq foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
23+
addq foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
2224
leaq foo@TLSGD(%rip), %rax # R_X86_64_TLSGD
2325
leaq foo@TPOFF(%rax), %rax # R_X86_64_TPOFF32
2426
leaq foo@TLSLD(%rip), %rdi # R_X86_64_TLSLD
@@ -67,7 +69,6 @@ pr24486:
6769
weak_sym:
6870
.long pr23272-weak_sym
6971

70-
7172
// CHECK: Section {
7273
// CHECK: Name: .rela.text
7374
// CHECK: Relocations [
@@ -78,37 +79,39 @@ weak_sym:
7879
// CHECK-NEXT: 0x22 R_X86_64_32S .text
7980
// CHECK-NEXT: 0x26 R_X86_64_32 .text
8081
// CHECK-NEXT: 0x2D R_X86_64_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
81-
// CHECK-NEXT: 0x34 R_X86_64_TLSGD foo 0xFFFFFFFFFFFFFFFC
82-
// CHECK-NEXT: 0x3B R_X86_64_TPOFF32 foo 0x0
83-
// CHECK-NEXT: 0x42 R_X86_64_TLSLD foo 0xFFFFFFFFFFFFFFFC
84-
// CHECK-NEXT: 0x49 R_X86_64_DTPOFF32 foo 0x0
85-
// CHECK-NEXT: 0x4F R_X86_64_GOT64 foo 0x0
86-
// CHECK-NEXT: 0x59 R_X86_64_GOTOFF64 foo 0x0
87-
// CHECK-NEXT: 0x62 R_X86_64_32S .text 0x0
88-
// CHECK-NEXT: 0x69 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
89-
// CHECK-NEXT: 0x70 R_X86_64_PC32 foo 0x70
90-
// CHECK-NEXT: 0x77 R_X86_64_32S .text 0x0
91-
// CHECK-NEXT: 0x7B R_X86_64_DTPOFF64 foo 0x0
92-
// CHECK-NEXT: 0x85 R_X86_64_TPOFF64 baz 0x0
93-
// CHECK-NEXT: 0x8D R_X86_64_PC16 foo 0x8D
94-
// CHECK-NEXT: 0x8F R_X86_64_PC8 foo 0x8F
95-
// CHECK-NEXT: 0x91 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
96-
// CHECK-NEXT: 0x98 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
97-
// CHECK-NEXT: 0x9F R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x3
98-
// CHECK-NEXT: 0xA6 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0xFFFFFFFFFFFFFFFC
99-
// CHECK-NEXT: 0xAB R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
100-
// CHECK-NEXT: 0xB1 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
101-
// CHECK-NEXT: 0xB9 R_X86_64_SIZE64 blah 0x0
102-
// CHECK-NEXT: 0xC1 R_X86_64_SIZE64 blah 0x20
103-
// CHECK-NEXT: 0xC9 R_X86_64_SIZE64 blah 0xFFFFFFFFFFFFFFE0
104-
// CHECK-NEXT: 0xD4 R_X86_64_SIZE32 blah 0x0
105-
// CHECK-NEXT: 0xDB R_X86_64_SIZE32 blah 0x20
106-
// CHECK-NEXT: 0xE2 R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
107-
// CHECK-NEXT: 0xE6 R_X86_64_GOTPCREL foo 0x0
108-
// CHECK-NEXT: 0xEA R_X86_64_PLT32 foo 0x0
109-
// CHECK-NEXT: 0xFE R_X86_64_32 .text 0xFE
110-
// CHECK-NEXT: 0x103 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
111-
// CHECK-NEXT: 0x105 R_X86_64_PC32 pr23272 0x0
82+
// CHECK-NEXT: 0x35 R_X86_64_CODE_4_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
83+
// CHECK-NEXT: 0x3D R_X86_64_CODE_4_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
84+
// CHECK-NEXT: 0x44 R_X86_64_TLSGD foo 0xFFFFFFFFFFFFFFFC
85+
// CHECK-NEXT: 0x4B R_X86_64_TPOFF32 foo 0x0
86+
// CHECK-NEXT: 0x52 R_X86_64_TLSLD foo 0xFFFFFFFFFFFFFFFC
87+
// CHECK-NEXT: 0x59 R_X86_64_DTPOFF32 foo 0x0
88+
// CHECK-NEXT: 0x5F R_X86_64_GOT64 foo 0x0
89+
// CHECK-NEXT: 0x69 R_X86_64_GOTOFF64 foo 0x0
90+
// CHECK-NEXT: 0x72 R_X86_64_32S .text 0x0
91+
// CHECK-NEXT: 0x79 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
92+
// CHECK-NEXT: 0x80 R_X86_64_PC32 foo 0x80
93+
// CHECK-NEXT: 0x87 R_X86_64_32S .text 0x0
94+
// CHECK-NEXT: 0x8B R_X86_64_DTPOFF64 foo 0x0
95+
// CHECK-NEXT: 0x95 R_X86_64_TPOFF64 baz 0x0
96+
// CHECK-NEXT: 0x9D R_X86_64_PC16 foo 0x9D
97+
// CHECK-NEXT: 0x9F R_X86_64_PC8 foo 0x9F
98+
// CHECK-NEXT: 0xA1 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
99+
// CHECK-NEXT: 0xA8 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
100+
// CHECK-NEXT: 0xAF R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x3
101+
// CHECK-NEXT: 0xB6 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0xFFFFFFFFFFFFFFFC
102+
// CHECK-NEXT: 0xBB R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
103+
// CHECK-NEXT: 0xC1 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
104+
// CHECK-NEXT: 0xC9 R_X86_64_SIZE64 blah 0x0
105+
// CHECK-NEXT: 0xD1 R_X86_64_SIZE64 blah 0x20
106+
// CHECK-NEXT: 0xD9 R_X86_64_SIZE64 blah 0xFFFFFFFFFFFFFFE0
107+
// CHECK-NEXT: 0xE4 R_X86_64_SIZE32 blah 0x0
108+
// CHECK-NEXT: 0xEB R_X86_64_SIZE32 blah 0x20
109+
// CHECK-NEXT: 0xF2 R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
110+
// CHECK-NEXT: 0xF6 R_X86_64_GOTPCREL foo 0x0
111+
// CHECK-NEXT: 0xFA R_X86_64_PLT32 foo 0x0
112+
// CHECK-NEXT: 0x10E R_X86_64_32 .text 0x10E
113+
// CHECK-NEXT: 0x113 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
114+
// CHECK-NEXT: 0x115 R_X86_64_PC32 pr23272 0x0
112115
// CHECK-NEXT: ]
113116
// CHECK-NEXT: }
114117

0 commit comments

Comments
 (0)