Skip to content

Commit ab4e066

Browse files
authored
[X86][MC] Add R_X86_64_CODE_6_GOTTPOFF (#117277)
For add %reg1, name@GOTTPOFF(%rip), %reg2 add name@GOTTPOFF(%rip), %reg1, %reg2 {nf} add %reg1, name@GOTTPOFF(%rip), %reg2 {nf} add name@GOTTPOFF(%rip), %reg1, %reg2 {nf} add name@GOTTPOFF(%rip), %reg add `R_X86_64_CODE_6_GOTTPOFF` = 50 if the instruction starts at 6 bytes before the relocation offset. It's similar to R_X86_64_GOTTPOFF. Linker can treat `R_X86_64_CODE_6_GOTTPOFF` as `R_X86_64_GOTTPOFF` or convert the instructions above to add $name@tpoff, %reg1, %reg2 add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg if the first byte of the instruction at the relocation `offset - 6` is `0xd5` (namely, encoded w/REX2 prefix) when possible. Binutils patch: bminor/binutils-gdb@5bc71c2 Binutils mailthread: https://sourceware.org/pipermail/binutils/2024-February/132351.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/FhEZjCtDLFw/m/VHDjN4orAgAJ Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
1 parent 76f0ff8 commit ab4e066

File tree

8 files changed

+68
-33
lines changed

8 files changed

+68
-33
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
4646
ELF_RELOC(R_X86_64_CODE_4_GOTPCRELX, 43)
4747
ELF_RELOC(R_X86_64_CODE_4_GOTTPOFF, 44)
4848
ELF_RELOC(R_X86_64_CODE_4_GOTPC32_TLSDESC, 45)
49+
ELF_RELOC(R_X86_64_CODE_6_GOTTPOFF, 50)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
634634
{"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
635635
{"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
636636
{"reloc_riprel_4byte_relax_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
637+
{"reloc_riprel_6byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
637638
{"reloc_signed_4byte", 0, 32, 0},
638639
{"reloc_signed_4byte_relax", 0, 32, 0},
639640
{"reloc_global_offset_table", 0, 32, 0},
@@ -683,6 +684,7 @@ static unsigned getFixupKindSize(unsigned Kind) {
683684
case X86::reloc_riprel_4byte_relax_rex2:
684685
case X86::reloc_riprel_4byte_movq_load:
685686
case X86::reloc_riprel_4byte_movq_load_rex2:
687+
case X86::reloc_riprel_6byte_relax:
686688
case X86::reloc_signed_4byte:
687689
case X86::reloc_signed_4byte_relax:
688690
case X86::reloc_global_offset_table:

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static X86_64RelType getType64(MCFixupKind Kind,
7777
case X86::reloc_riprel_4byte_relax_rex2:
7878
case X86::reloc_riprel_4byte_movq_load:
7979
case X86::reloc_riprel_4byte_movq_load_rex2:
80+
case X86::reloc_riprel_6byte_relax:
8081
return RT64_32;
8182
case X86::reloc_branch_4byte_pcrel:
8283
Modifier = MCSymbolRefExpr::VK_PLT;
@@ -202,6 +203,8 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
202203
if ((unsigned)Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
203204
(unsigned)Kind == X86::reloc_riprel_4byte_relax_rex2)
204205
return ELF::R_X86_64_CODE_4_GOTTPOFF;
206+
else if ((unsigned)Kind == X86::reloc_riprel_6byte_relax)
207+
return ELF::R_X86_64_CODE_6_GOTTPOFF;
205208
return ELF::R_X86_64_GOTTPOFF;
206209
case MCSymbolRefExpr::VK_TLSLD:
207210
checkIs32(Ctx, Loc, Type);
@@ -227,6 +230,8 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
227230
case X86::reloc_riprel_4byte_relax_rex2:
228231
case X86::reloc_riprel_4byte_movq_load_rex2:
229232
return ELF::R_X86_64_CODE_4_GOTPCRELX;
233+
case X86::reloc_riprel_6byte_relax:
234+
return ELF::R_X86_64_CODE_6_GOTTPOFF;
230235
}
231236
llvm_unreachable("unexpected relocation type!");
232237
case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:

llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ enum Fixups {
2424
// instruction with rex prefix
2525
reloc_riprel_4byte_relax_rex2, // 32-bit rip-relative in relaxable
2626
// instruction with rex2 prefix
27+
reloc_riprel_6byte_relax, // 32-bit rip-relative in relaxable
28+
// instruction with APX NDD
2729
reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4
2830
// this will be sign extended at
2931
// runtime.

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,9 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
579579
// this needs to be a GOTPC32 relocation.
580580
if (startsWithGlobalOffsetTable(Expr) != GOT_None)
581581
FixupKind = MCFixupKind(X86::reloc_global_offset_table);
582-
}
582+
} else if (FixupKind == MCFixupKind(X86::reloc_riprel_6byte_relax))
583+
ImmOffset -= 6;
584+
583585
if (FixupKind == FK_PCRel_2)
584586
ImmOffset -= 2;
585587
if (FixupKind == FK_PCRel_1)
@@ -670,6 +672,12 @@ void X86MCCodeEmitter::emitMemModRMByte(
670672
return Kind == REX2 ? X86::reloc_riprel_4byte_relax_rex2
671673
: Kind == REX ? X86::reloc_riprel_4byte_relax_rex
672674
: X86::reloc_riprel_4byte_relax;
675+
case X86::ADD64rm_NF:
676+
case X86::ADD64rm_ND:
677+
case X86::ADD64mr_ND:
678+
case X86::ADD64mr_NF_ND:
679+
case X86::ADD64rm_NF_ND:
680+
return X86::reloc_riprel_6byte_relax;
673681
}
674682
}();
675683

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ static bool isFixupKindRIPRel(unsigned Kind) {
6969
Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
7070
Kind == X86::reloc_riprel_4byte_relax ||
7171
Kind == X86::reloc_riprel_4byte_relax_rex ||
72-
Kind == X86::reloc_riprel_4byte_relax_rex2;
72+
Kind == X86::reloc_riprel_4byte_relax_rex2 ||
73+
Kind == X86::reloc_riprel_6byte_relax;
7374
}
7475

7576
static unsigned getFixupKindLog2Size(unsigned Kind) {
@@ -91,6 +92,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
9192
case X86::reloc_signed_4byte:
9293
case X86::reloc_signed_4byte_relax:
9394
case X86::reloc_branch_4byte_pcrel:
95+
case X86::reloc_riprel_6byte_relax:
9496
case FK_Data_4: return 2;
9597
case FK_Data_8: return 3;
9698
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
7070
case X86::reloc_riprel_4byte_relax:
7171
case X86::reloc_riprel_4byte_relax_rex:
7272
case X86::reloc_riprel_4byte_relax_rex2:
73+
case X86::reloc_riprel_6byte_relax:
7374
case X86::reloc_branch_4byte_pcrel:
7475
return COFF::IMAGE_REL_AMD64_REL32;
7576
case FK_Data_4:

llvm/test/MC/ELF/relocation.s

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ bar:
2121
leaq foo@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
2222
movq foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
2323
addq foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
24+
# NDD
25+
addq %r8, foo@GOTTPOFF(%rip), %r16 # R_X86_64_CODE_6_GOTTPOFF
26+
addq foo@GOTTPOFF(%rip), %rax, %r12 # R_X86_64_CODE_6_GOTTPOFF
27+
# NDD + NF
28+
{nf} addq %r8, foo@GOTTPOFF(%rip), %r16 # R_X86_64_CODE_6_GOTTPOFF
29+
{nf} addq foo@GOTTPOFF(%rip), %rax, %r12 # R_X86_64_CODE_6_GOTTPOFF
30+
# NF
31+
{nf} addq foo@GOTTPOFF(%rip), %r12 # R_X86_64_CODE_6_GOTTPOFF
32+
2433
leaq foo@TLSGD(%rip), %rax # R_X86_64_TLSGD
2534
leaq foo@TPOFF(%rax), %rax # R_X86_64_TPOFF32
2635
leaq foo@TLSLD(%rip), %rdi # R_X86_64_TLSLD
@@ -81,37 +90,42 @@ weak_sym:
8190
// CHECK-NEXT: 0x2D R_X86_64_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
8291
// CHECK-NEXT: 0x35 R_X86_64_CODE_4_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
8392
// 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
93+
// CHECK-NEXT: 0x47 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
94+
// CHECK-NEXT: 0x51 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
95+
// CHECK-NEXT: 0x5B R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
96+
// CHECK-NEXT: 0x65 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
97+
// CHECK-NEXT: 0x6F R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
98+
// CHECK-NEXT: 0x76 R_X86_64_TLSGD foo 0xFFFFFFFFFFFFFFFC
99+
// CHECK-NEXT: 0x7D R_X86_64_TPOFF32 foo 0x0
100+
// CHECK-NEXT: 0x84 R_X86_64_TLSLD foo 0xFFFFFFFFFFFFFFFC
101+
// CHECK-NEXT: 0x8B R_X86_64_DTPOFF32 foo 0x0
102+
// CHECK-NEXT: 0x91 R_X86_64_GOT64 foo 0x0
103+
// CHECK-NEXT: 0x9B R_X86_64_GOTOFF64 foo 0x0
104+
// CHECK-NEXT: 0xA4 R_X86_64_32S .text 0x0
105+
// CHECK-NEXT: 0xAB R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
106+
// CHECK-NEXT: 0xB2 R_X86_64_PC32 foo 0xB2
107+
// CHECK-NEXT: 0xB9 R_X86_64_32S .text 0x0
108+
// CHECK-NEXT: 0xBD R_X86_64_DTPOFF64 foo 0x0
109+
// CHECK-NEXT: 0xC7 R_X86_64_TPOFF64 baz 0x0
110+
// CHECK-NEXT: 0xCF R_X86_64_PC16 foo 0xCF
111+
// CHECK-NEXT: 0xD1 R_X86_64_PC8 foo 0xD1
112+
// CHECK-NEXT: 0xD3 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
113+
// CHECK-NEXT: 0xDA R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
114+
// CHECK-NEXT: 0xE1 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x3
115+
// CHECK-NEXT: 0xE8 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0xFFFFFFFFFFFFFFFC
116+
// CHECK-NEXT: 0xED R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
117+
// CHECK-NEXT: 0xF3 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
118+
// CHECK-NEXT: 0xFB R_X86_64_SIZE64 blah 0x0
119+
// CHECK-NEXT: 0x103 R_X86_64_SIZE64 blah 0x20
120+
// CHECK-NEXT: 0x10B R_X86_64_SIZE64 blah 0xFFFFFFFFFFFFFFE0
121+
// CHECK-NEXT: 0x116 R_X86_64_SIZE32 blah 0x0
122+
// CHECK-NEXT: 0x11D R_X86_64_SIZE32 blah 0x20
123+
// CHECK-NEXT: 0x124 R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
124+
// CHECK-NEXT: 0x128 R_X86_64_GOTPCREL foo 0x0
125+
// CHECK-NEXT: 0x12C R_X86_64_PLT32 foo 0x0
126+
// CHECK-NEXT: 0x140 R_X86_64_32 .text 0x140
127+
// CHECK-NEXT: 0x145 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
128+
// CHECK-NEXT: 0x147 R_X86_64_PC32 pr23272 0x0
115129
// CHECK-NEXT: ]
116130
// CHECK-NEXT: }
117131

0 commit comments

Comments
 (0)