Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86][MC] Add R_X86_64_CODE_6_GOTTPOFF #117277

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

fzou1
Copy link
Contributor

@fzou1 fzou1 commented Nov 22, 2024

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

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.
@llvmbot
Copy link
Member

llvmbot commented Nov 22, 2024

@llvm/pr-subscribers-backend-x86

Author: Feng Zou (fzou1)

Changes

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: 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/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 --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@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
         movq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
         addq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
+        # NDD
+        addq %r8, foo@GOTTPOFF(%rip), %r16
+        addq foo@GOTTPOFF(%rip), %rax, %r12
+        {nf} addq %r8, foo@GOTTPOFF(%rip), %r16
+        {nf} addq foo@GOTTPOFF(%rip), %rax, %r12
+
         leaq	foo@TLSGD(%rip), %rax    # R_X86_64_TLSGD
         leaq	foo@TPOFF(%rax), %rax    # R_X86_64_TPOFF32
         leaq	foo@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:   }
 

@llvmbot
Copy link
Member

llvmbot commented Nov 22, 2024

@llvm/pr-subscribers-mc

Author: Feng Zou (fzou1)

Changes

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: 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/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 --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@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
         movq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
         addq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
+        # NDD
+        addq %r8, foo@GOTTPOFF(%rip), %r16
+        addq foo@GOTTPOFF(%rip), %rax, %r12
+        {nf} addq %r8, foo@GOTTPOFF(%rip), %r16
+        {nf} addq foo@GOTTPOFF(%rip), %rax, %r12
+
         leaq	foo@TLSGD(%rip), %rax    # R_X86_64_TLSGD
         leaq	foo@TPOFF(%rax), %rax    # R_X86_64_TPOFF32
         leaq	foo@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:   }
 

@llvmbot
Copy link
Member

llvmbot commented Nov 22, 2024

@llvm/pr-subscribers-llvm-binary-utilities

Author: Feng Zou (fzou1)

Changes

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: 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/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 --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@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
         movq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
         addq    foo@GOTTPOFF(%rip), %r31 # R_X86_64_CODE_4_GOTTPOFF
+        # NDD
+        addq %r8, foo@GOTTPOFF(%rip), %r16
+        addq foo@GOTTPOFF(%rip), %rax, %r12
+        {nf} addq %r8, foo@GOTTPOFF(%rip), %r16
+        {nf} addq foo@GOTTPOFF(%rip), %rax, %r12
+
         leaq	foo@TLSGD(%rip), %rax    # R_X86_64_TLSGD
         leaq	foo@TPOFF(%rax), %rax    # R_X86_64_TPOFF32
         leaq	foo@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:   }
 

Comment on lines +675 to +679
case X86::ADD64rm_ND:
case X86::ADD64mr_ND:
case X86::ADD64mr_NF_ND:
case X86::ADD64rm_NF_ND:
return X86::reloc_riprel_6byte_relax;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to consider ADD64rm_NF too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

@KanRobert
Copy link
Contributor

The description needs to be updated. It doesn't mention NF.

@fzou1
Copy link
Contributor Author

fzou1 commented Nov 22, 2024

The description needs to be updated. It doesn't mention NF.

Done. Thanks.

Copy link
Contributor

@KanRobert KanRobert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants