[lld] lld/AArch64: handle more relocation addends (PR #87328)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 2 02:39:38 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-elf

Author: Ramkumar Ramachandra (artagnon)

<details>
<summary>Changes</summary>

The function getImplicitAddend() is woefully incomplete, as it is possible to cook up object files with ABS16, PREL16, ABS32, CALL26, and JUMP26 relocation addends. Although using llvm-mc does not produce such object files, other assemblers theoretically could. Although this patch doesn't aim to comprehensively cover all possible relocation addends, it does extend lld to work with the five mentioned relocation addends, using the canonical aaelf64 document as a reference:

  https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst

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


6 Files Affected:

- (modified) lld/ELF/Arch/AArch64.cpp (+7) 
- (added) lld/test/ELF/aarch64-reloc-abs16-addend.test (+38) 
- (added) lld/test/ELF/aarch64-reloc-abs32-addend.test (+38) 
- (added) lld/test/ELF/aarch64-reloc-call26-addend.test (+39) 
- (added) lld/test/ELF/aarch64-reloc-jump26-addend.test (+39) 
- (added) lld/test/ELF/aarch64-reloc-prel16-addend.test (+36) 


``````````diff
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 30ccd68f7b7506..0786b15d47c86d 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -217,6 +217,10 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_AARCH64_GLOB_DAT:
   case R_AARCH64_JUMP_SLOT:
     return 0;
+  case R_AARCH64_ABS16:
+  case R_AARCH64_PREL16:
+    return SignExtend64<16>(read16(buf));
+  case R_AARCH64_ABS32:
   case R_AARCH64_PREL32:
     return SignExtend64<32>(read32(buf));
   case R_AARCH64_ABS64:
@@ -225,6 +229,9 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_AARCH64_IRELATIVE:
   case R_AARCH64_TLS_TPREL64:
     return read64(buf);
+  case R_AARCH64_JUMP26:
+  case R_AARCH64_CALL26:
+    return read32(buf) & 0x0FFFFFFC >> 2;
   default:
     internalLinkerError(getErrorLocation(buf),
                         "cannot read addend for relocation " + toString(type));
diff --git a/lld/test/ELF/aarch64-reloc-abs16-addend.test b/lld/test/ELF/aarch64-reloc-abs16-addend.test
new file mode 100644
index 00000000000000..48023a970ac33e
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-abs16-addend.test
@@ -0,0 +1,38 @@
+# REQUIRES: aarch64
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t.out
+# RUN: llvm-objdump -t %t.out | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000000000210120 g     F bar	0000000000000000 _start
+---
+!ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_AARCH64
+Sections:
+  - Name: bar
+    Type: SHT_PROGBITS
+    Flags: [SHF_ALLOC, SHF_EXECINSTR]
+  - Name: .debug_frame
+    Type: SHT_PROGBITS
+  - Name: .rel.debug_frame
+    Type: SHT_REL
+    Link: .symtab
+    Info: .debug_frame
+    Relocations:
+      - Symbol: .debug_frame
+        Type: R_AARCH64_ABS16
+Symbols:
+  - Name: .debug_frame
+    Type: STT_SECTION
+    Section: .debug_frame
+  - Name: bar
+    Type: STT_SECTION
+    Section: bar
+  - Name: _start
+    Type: STT_FUNC
+    Section: bar
+    Binding: STB_GLOBAL
diff --git a/lld/test/ELF/aarch64-reloc-abs32-addend.test b/lld/test/ELF/aarch64-reloc-abs32-addend.test
new file mode 100644
index 00000000000000..21627bb83a029a
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-abs32-addend.test
@@ -0,0 +1,38 @@
+# REQUIRES: aarch64
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t.out
+# RUN: llvm-objdump -t %t.out | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000000000210120 g     F bar	0000000000000000 _start
+---
+!ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_AARCH64
+Sections:
+  - Name: bar
+    Type: SHT_PROGBITS
+    Flags: [SHF_ALLOC, SHF_EXECINSTR]
+  - Name: .debug_frame
+    Type: SHT_PROGBITS
+  - Name: .rel.debug_frame
+    Type: SHT_REL
+    Link: .symtab
+    Info: .debug_frame
+    Relocations:
+      - Symbol: .debug_frame
+        Type: R_AARCH64_ABS32
+Symbols:
+  - Name: .debug_frame
+    Type: STT_SECTION
+    Section: .debug_frame
+  - Name: bar
+    Type: STT_SECTION
+    Section: bar
+  - Name: _start
+    Type: STT_FUNC
+    Section: bar
+    Binding: STB_GLOBAL
diff --git a/lld/test/ELF/aarch64-reloc-call26-addend.test b/lld/test/ELF/aarch64-reloc-call26-addend.test
new file mode 100644
index 00000000000000..94f4f13511bcfa
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-call26-addend.test
@@ -0,0 +1,39 @@
+# REQUIRES: aarch64
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t.out
+# RUN: llvm-objdump -t %t.out | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000000000210120 g     F foo	0000000000000000 _start
+---
+!ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_AARCH64
+Sections:
+  - Name: bar
+    Type: SHT_PROGBITS
+    Flags: [SHF_ALLOC, SHF_EXECINSTR]
+  - Name: foo
+    Type: SHT_PROGBITS
+    Flags: [SHF_ALLOC, SHF_EXECINSTR]
+  - Name: .relfoo
+    Type: SHT_REL
+    Link: .symtab
+    Info: foo
+    Relocations:
+      - Symbol: bar
+        Type: R_AARCH64_CALL26
+Symbols:
+  - Name: bar
+    Type: STT_SECTION
+    Section: bar
+  - Name: foo
+    Type: STT_SECTION
+    Section: bar
+  - Name: _start
+    Type: STT_FUNC
+    Section: foo
+    Binding: STB_GLOBAL
diff --git a/lld/test/ELF/aarch64-reloc-jump26-addend.test b/lld/test/ELF/aarch64-reloc-jump26-addend.test
new file mode 100644
index 00000000000000..ae1a13786e5603
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-jump26-addend.test
@@ -0,0 +1,39 @@
+# REQUIRES: aarch64
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t.out
+# RUN: llvm-objdump -t %t.out | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000000000210120 g     F foo	0000000000000000 _start
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_AARCH64
+Sections:
+  - Name:            bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:            foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:            .relfoo
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            foo
+    Relocations:
+      - Symbol:        bar
+        Type:          R_AARCH64_JUMP26
+Symbols:
+  - Name:            bar
+    Type:            STT_SECTION
+    Section:         bar
+  - Name:            foo
+    Type:            STT_SECTION
+    Section:         bar
+  - Name:            _start
+    Type:            STT_FUNC
+    Section:         foo
+    Binding:         STB_GLOBAL
diff --git a/lld/test/ELF/aarch64-reloc-prel16-addend.test b/lld/test/ELF/aarch64-reloc-prel16-addend.test
new file mode 100644
index 00000000000000..e129268276541a
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-prel16-addend.test
@@ -0,0 +1,36 @@
+# REQUIRES: aarch64
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t.out
+# RUN: llvm-objdump -t %t.out | FileCheck %s
+
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000000000210158 g     F .text	0000000000000000 _start
+---
+!ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_AARCH64
+Sections:
+  - Name: .text
+    Type: SHT_PROGBITS
+    Flags: [SHF_ALLOC, SHF_EXECINSTR]
+  - Name: .data
+    Type: SHT_PROGBITS
+    Flags: [SHF_WRITE, SHF_ALLOC]
+  - Name: .rel.text
+    Type: SHT_REL
+    Info: .text
+    Relocations:
+      - Symbol: .data
+        Offset: 4
+        Type: R_AARCH64_PREL16
+Symbols:
+  - Name: .data
+    Type: STT_SECTION
+    Section: .data
+  - Name: _start
+    Type: STT_FUNC
+    Section: .text
+    Binding: STB_GLOBAL

``````````

</details>


https://github.com/llvm/llvm-project/pull/87328


More information about the llvm-commits mailing list