[llvm] [X86][MC] Add R_X86_64_CODE_6_GOTTPOFF (PR #117277)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 21 18:37:18 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Feng Zou (fzou1)
<details>
<summary>Changes</summary>
For
add %reg1, name@<!-- -->GOTTPOFF(%rip), %reg2
add name@<!-- -->GOTTPOFF(%rip), %reg1, %reg2
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
if the first byte of the instruction at the relocation `offset - 6` is `0xd5` (namely, encoded w/REX2 prefix) when possible.
Binutils patch: https://github.com/bminor/binutils-gdb/commit/5bc71c2a6b8efb27089baa1fecded82be4f550a7
Binutils mailthread: https://sourceware.org/pipermail/binutils/2024-February/132351.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/jOtHcziQOBE
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
---
Full diff: https://github.com/llvm/llvm-project/pull/117277.diff
8 Files Affected:
- (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (+1)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (+2)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (+5)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h (+2)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+8-1)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp (+3-1)
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp (+1)
- (modified) llvm/test/MC/ELF/relocation.s (+41-31)
``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
index 0c026cf443361a..a93d92870cf32d 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
@@ -46,3 +46,4 @@ ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
ELF_RELOC(R_X86_64_CODE_4_GOTPCRELX, 43)
ELF_RELOC(R_X86_64_CODE_4_GOTTPOFF, 44)
ELF_RELOC(R_X86_64_CODE_4_GOTPC32_TLSDESC, 45)
+ELF_RELOC(R_X86_64_CODE_6_GOTTPOFF, 50)
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 8be8f0b6d735c4..01b6c84419fc88 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -634,6 +634,7 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"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_riprel_6byte_relax", 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},
@@ -683,6 +684,7 @@ static unsigned getFixupKindSize(unsigned Kind) {
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_riprel_6byte_relax:
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 349cd011eff303..29a1af97d24fa9 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -77,6 +77,7 @@ static X86_64RelType getType64(MCFixupKind Kind,
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_riprel_6byte_relax:
return RT64_32;
case X86::reloc_branch_4byte_pcrel:
Modifier = MCSymbolRefExpr::VK_PLT;
@@ -202,6 +203,8 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
if ((unsigned)Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
(unsigned)Kind == X86::reloc_riprel_4byte_relax_rex2)
return ELF::R_X86_64_CODE_4_GOTTPOFF;
+ else if ((unsigned)Kind == X86::reloc_riprel_6byte_relax)
+ return ELF::R_X86_64_CODE_6_GOTTPOFF;
return ELF::R_X86_64_GOTTPOFF;
case MCSymbolRefExpr::VK_TLSLD:
checkIs32(Ctx, Loc, Type);
@@ -227,6 +230,8 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_riprel_4byte_movq_load_rex2:
return ELF::R_X86_64_CODE_4_GOTPCRELX;
+ case X86::reloc_riprel_6byte_relax:
+ return ELF::R_X86_64_CODE_6_GOTTPOFF;
}
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 29bb7eebae3f22..52592a5a13b978 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
@@ -24,6 +24,8 @@ enum Fixups {
// instruction with rex prefix
reloc_riprel_4byte_relax_rex2, // 32-bit rip-relative in relaxable
// instruction with rex2 prefix
+ reloc_riprel_6byte_relax, // 32-bit rip-relative in relaxable
+ // instruction with APX NDD
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 f12275ffaba8bb..02a306b350d717 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -579,7 +579,9 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
// this needs to be a GOTPC32 relocation.
if (startsWithGlobalOffsetTable(Expr) != GOT_None)
FixupKind = MCFixupKind(X86::reloc_global_offset_table);
- }
+ } else if (FixupKind == MCFixupKind(X86::reloc_riprel_6byte_relax))
+ ImmOffset -= 6;
+
if (FixupKind == FK_PCRel_2)
ImmOffset -= 2;
if (FixupKind == FK_PCRel_1)
@@ -670,6 +672,11 @@ void X86MCCodeEmitter::emitMemModRMByte(
return Kind == REX2 ? X86::reloc_riprel_4byte_relax_rex2
: Kind == REX ? X86::reloc_riprel_4byte_relax_rex
: X86::reloc_riprel_4byte_relax;
+ case X86::ADD64rm_ND:
+ case X86::ADD64mr_ND:
+ case X86::ADD64mr_NF_ND:
+ case X86::ADD64rm_NF_ND:
+ return X86::reloc_riprel_6byte_relax;
}
}();
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index 41ce5c9fcb82ad..413650e90de657 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -69,7 +69,8 @@ static bool isFixupKindRIPRel(unsigned Kind) {
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_rex2;
+ Kind == X86::reloc_riprel_4byte_relax_rex2 ||
+ Kind == X86::reloc_riprel_6byte_relax;
}
static unsigned getFixupKindLog2Size(unsigned Kind) {
@@ -91,6 +92,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
case X86::reloc_signed_4byte:
case X86::reloc_signed_4byte_relax:
case X86::reloc_branch_4byte_pcrel:
+ case X86::reloc_riprel_6byte_relax:
case FK_Data_4: return 2;
case FK_Data_8: return 3;
}
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
index 7740500fb41830..48d4707bbe1ebd 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
@@ -70,6 +70,7 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
case X86::reloc_riprel_4byte_relax:
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_relax_rex2:
+ case X86::reloc_riprel_6byte_relax:
case X86::reloc_branch_4byte_pcrel:
return COFF::IMAGE_REL_AMD64_REL32;
case FK_Data_4:
diff --git a/llvm/test/MC/ELF/relocation.s b/llvm/test/MC/ELF/relocation.s
index 88301f8447bc2a..8e1297be1f1ce5 100644
--- a/llvm/test/MC/ELF/relocation.s
+++ b/llvm/test/MC/ELF/relocation.s
@@ -21,6 +21,12 @@ bar:
leaq foo at GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
movq foo at GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
addq foo at GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
+ # NDD
+ addq %r8, foo at GOTTPOFF(%rip), %r16
+ addq foo at GOTTPOFF(%rip), %rax, %r12
+ {nf} addq %r8, foo at GOTTPOFF(%rip), %r16
+ {nf} addq foo at GOTTPOFF(%rip), %rax, %r12
+
leaq foo at TLSGD(%rip), %rax # R_X86_64_TLSGD
leaq foo at TPOFF(%rax), %rax # R_X86_64_TPOFF32
leaq foo at TLSLD(%rip), %rdi # R_X86_64_TLSLD
@@ -81,37 +87,41 @@ weak_sym:
// CHECK-NEXT: 0x2D R_X86_64_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
// CHECK-NEXT: 0x35 R_X86_64_CODE_4_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
// CHECK-NEXT: 0x3D R_X86_64_CODE_4_GOTTPOFF foo 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0x44 R_X86_64_TLSGD foo 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0x4B R_X86_64_TPOFF32 foo 0x0
-// CHECK-NEXT: 0x52 R_X86_64_TLSLD foo 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0x59 R_X86_64_DTPOFF32 foo 0x0
-// CHECK-NEXT: 0x5F R_X86_64_GOT64 foo 0x0
-// CHECK-NEXT: 0x69 R_X86_64_GOTOFF64 foo 0x0
-// CHECK-NEXT: 0x72 R_X86_64_32S .text 0x0
-// CHECK-NEXT: 0x79 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0x80 R_X86_64_PC32 foo 0x80
-// CHECK-NEXT: 0x87 R_X86_64_32S .text 0x0
-// CHECK-NEXT: 0x8B R_X86_64_DTPOFF64 foo 0x0
-// CHECK-NEXT: 0x95 R_X86_64_TPOFF64 baz 0x0
-// CHECK-NEXT: 0x9D R_X86_64_PC16 foo 0x9D
-// CHECK-NEXT: 0x9F R_X86_64_PC8 foo 0x9F
-// CHECK-NEXT: 0xA1 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0xA8 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
-// CHECK-NEXT: 0xAF R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x3
-// CHECK-NEXT: 0xB6 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0xFFFFFFFFFFFFFFFC
-// CHECK-NEXT: 0xBB R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
-// CHECK-NEXT: 0xC1 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
-// CHECK-NEXT: 0xC9 R_X86_64_SIZE64 blah 0x0
-// CHECK-NEXT: 0xD1 R_X86_64_SIZE64 blah 0x20
-// CHECK-NEXT: 0xD9 R_X86_64_SIZE64 blah 0xFFFFFFFFFFFFFFE0
-// CHECK-NEXT: 0xE4 R_X86_64_SIZE32 blah 0x0
-// CHECK-NEXT: 0xEB R_X86_64_SIZE32 blah 0x20
-// CHECK-NEXT: 0xF2 R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
-// CHECK-NEXT: 0xF6 R_X86_64_GOTPCREL foo 0x0
-// CHECK-NEXT: 0xFA R_X86_64_PLT32 foo 0x0
-// CHECK-NEXT: 0x10E R_X86_64_32 .text 0x10E
-// CHECK-NEXT: 0x113 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
-// CHECK-NEXT: 0x115 R_X86_64_PC32 pr23272 0x0
+// CHECK-NEXT: 0x47 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
+// CHECK-NEXT: 0x51 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
+// CHECK-NEXT: 0x5B R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
+// CHECK-NEXT: 0x65 R_X86_64_CODE_6_GOTTPOFF foo 0xFFFFFFFFFFFFFFFA
+// CHECK-NEXT: 0x6C R_X86_64_TLSGD foo 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: 0x73 R_X86_64_TPOFF32 foo 0x0
+// CHECK-NEXT: 0x7A R_X86_64_TLSLD foo 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: 0x81 R_X86_64_DTPOFF32 foo 0x0
+// CHECK-NEXT: 0x87 R_X86_64_GOT64 foo 0x0
+// CHECK-NEXT: 0x91 R_X86_64_GOTOFF64 foo 0x0
+// CHECK-NEXT: 0x9A R_X86_64_32S .text 0x0
+// CHECK-NEXT: 0xA1 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: 0xA8 R_X86_64_PC32 foo 0xA8
+// CHECK-NEXT: 0xAF R_X86_64_32S .text 0x0
+// CHECK-NEXT: 0xB3 R_X86_64_DTPOFF64 foo 0x0
+// CHECK-NEXT: 0xBD R_X86_64_TPOFF64 baz 0x0
+// CHECK-NEXT: 0xC5 R_X86_64_PC16 foo 0xC5
+// CHECK-NEXT: 0xC7 R_X86_64_PC8 foo 0xC7
+// CHECK-NEXT: 0xC9 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: 0xD0 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
+// CHECK-NEXT: 0xD7 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x3
+// CHECK-NEXT: 0xDE R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: 0xE3 R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
+// CHECK-NEXT: 0xE9 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
+// CHECK-NEXT: 0xF1 R_X86_64_SIZE64 blah 0x0
+// CHECK-NEXT: 0xF9 R_X86_64_SIZE64 blah 0x20
+// CHECK-NEXT: 0x101 R_X86_64_SIZE64 blah 0xFFFFFFFFFFFFFFE0
+// CHECK-NEXT: 0x10C R_X86_64_SIZE32 blah 0x0
+// CHECK-NEXT: 0x113 R_X86_64_SIZE32 blah 0x20
+// CHECK-NEXT: 0x11A R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
+// CHECK-NEXT: 0x11E R_X86_64_GOTPCREL foo 0x0
+// CHECK-NEXT: 0x122 R_X86_64_PLT32 foo 0x0
+// CHECK-NEXT: 0x136 R_X86_64_32 .text 0x136
+// CHECK-NEXT: 0x13B R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
+// CHECK-NEXT: 0x13D R_X86_64_PC32 pr23272 0x0
// CHECK-NEXT: ]
// CHECK-NEXT: }
``````````
</details>
https://github.com/llvm/llvm-project/pull/117277
More information about the llvm-commits
mailing list