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

[llvm][lld] Support R_AARCH64_GOTPCREL32 #72584

Merged
merged 1 commit into from
Jan 10, 2024

Conversation

PiJoules
Copy link
Contributor

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 16, 2023

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

@llvm/pr-subscribers-mc

Author: None (PiJoules)

Changes

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.


Full diff: https://github.com/llvm/llvm-project/pull/72584.diff

5 Files Affected:

  • (modified) lld/ELF/Arch/AArch64.cpp (+3)
  • (added) lld/test/ELF/aarch64-reloc-gotpcrel32.s (+36)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (+2)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (+5-2)
  • (added) llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s (+14)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return R_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_GOTPCREL32:
+    return R_GOT_PC;
   case R_AARCH64_NONE:
     return R_NONE;
   default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     write32(loc, val);
     break;
   case R_AARCH64_PLT32:
+  case R_AARCH64_GOTPCREL32:
     checkInt(loc, val, 32, rel);
     write32(loc, val);
     break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x20350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 8
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK:  30358 f8fffeff f8fffeff ecfffeff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
 ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
 ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
 ELF_RELOC(R_AARCH64_PLT32,                           0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32,                      0x13b)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
 ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE,                0x01a)
 ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC,            0x01b)
 ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14,           0x01c)
 ELF_RELOC(R_AARCH64_P32_PLT32,                       0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32,                  0x01e)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21,            0x050)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21,            0x051)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC,           0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
 
   assert((!Target.getSymA() ||
           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
          "Should only be expression-level modifiers here");
 
   assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_Data_2:
       return R_CLS(ABS16);
     case FK_Data_4:
-      return R_CLS(ABS32);
+      return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+                 ? R_CLS(GOTPCREL32)
+                 : R_CLS(ABS32);
     case FK_Data_8:
       if (IsILP32) {
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+        .section .data
+this:
+        .word this@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@GOTPCREL-4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT:   0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT:   0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-backend-aarch64

Author: None (PiJoules)

Changes

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.


Full diff: https://github.com/llvm/llvm-project/pull/72584.diff

5 Files Affected:

  • (modified) lld/ELF/Arch/AArch64.cpp (+3)
  • (added) lld/test/ELF/aarch64-reloc-gotpcrel32.s (+36)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (+2)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (+5-2)
  • (added) llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s (+14)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return R_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_GOTPCREL32:
+    return R_GOT_PC;
   case R_AARCH64_NONE:
     return R_NONE;
   default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     write32(loc, val);
     break;
   case R_AARCH64_PLT32:
+  case R_AARCH64_GOTPCREL32:
     checkInt(loc, val, 32, rel);
     write32(loc, val);
     break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x20350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 8
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK:  30358 f8fffeff f8fffeff ecfffeff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
 ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
 ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
 ELF_RELOC(R_AARCH64_PLT32,                           0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32,                      0x13b)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
 ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE,                0x01a)
 ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC,            0x01b)
 ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14,           0x01c)
 ELF_RELOC(R_AARCH64_P32_PLT32,                       0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32,                  0x01e)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21,            0x050)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21,            0x051)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC,           0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
 
   assert((!Target.getSymA() ||
           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
          "Should only be expression-level modifiers here");
 
   assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_Data_2:
       return R_CLS(ABS16);
     case FK_Data_4:
-      return R_CLS(ABS32);
+      return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+                 ? R_CLS(GOTPCREL32)
+                 : R_CLS(ABS32);
     case FK_Data_8:
       if (IsILP32) {
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+        .section .data
+this:
+        .word this@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@GOTPCREL-4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT:   0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT:   0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }

@PiJoules
Copy link
Contributor Author

I only discovered the R_AARCH64_P32_* relocations just now. Not sure if I need another rfc for R_AARCH64_P32_GOTPCREL32.

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

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

Other than one line about the ILP32 code LGTM.

Please do tell us if you need ILP32 support and we can add the code to the ABI.

llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def Outdated Show resolved Hide resolved
@MaskRay MaskRay changed the title [llvm][lld] Support R_<CLS>_GOTREL32 [llvm][lld] Support R_AARCH64_GOTPCREL32 Nov 27, 2023
@@ -0,0 +1,11 @@
// REQUIRES: aarch64
Copy link
Member

Choose a reason for hiding this comment

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

Newer tests place overflow tests (RUN: not ld.lld ...) and regular tests (RUN: ld.lld ...) in one file so that the boundary is clearer.

aarch64-reloc-plt32.s is a good example

Copy link
Contributor Author

@PiJoules PiJoules Dec 5, 2023

Choose a reason for hiding this comment

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

For PLT32 I can put all the tests in one file since foo@PLT can be relaxed to foo if it's defined in one of the other input files, but I don't think the same can work for foo@GOTPCREL since this can't be relaxed to anything that could be defined in a separate input file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you perhaps have another example I can follow?

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps you can use more than one symbol in a test.

Since the error message contains the bounds (in [-2147483648, 2147483647]), I think we don't need to make an extreme test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated tests

@smithp35
Copy link
Collaborator

I don't have any more comments, thanks for making the earlier changes. Happy for MaskRay to approve when his comments have been addressed.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

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

I think this is mostly good, just needing some test changes.

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this
relocation in llvm and lld.
@PiJoules PiJoules merged commit 04a906e into llvm:main Jan 10, 2024
3 of 4 checks passed
@PiJoules PiJoules deleted the aarch64-gotpcrel32 branch January 10, 2024 23:12
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
This is the follopw implementation to
ARM-software/abi-aa#223 that supports this
relocation in llvm and lld.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants