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

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


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

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

>From 5c0d068226bea8ff9cea7779b13cf02a1f2fdcbe Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ram.ramachandra at arm.com>
Date: Thu, 28 Mar 2024 18:02:29 +0000
Subject: [PATCH] lld/AArch64: handle more relocation addends

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
---
 lld/ELF/Arch/AArch64.cpp                      |  7 ++++
 lld/test/ELF/aarch64-reloc-abs16-addend.test  | 38 ++++++++++++++++++
 lld/test/ELF/aarch64-reloc-abs32-addend.test  | 38 ++++++++++++++++++
 lld/test/ELF/aarch64-reloc-call26-addend.test | 39 +++++++++++++++++++
 lld/test/ELF/aarch64-reloc-jump26-addend.test | 39 +++++++++++++++++++
 lld/test/ELF/aarch64-reloc-prel16-addend.test | 36 +++++++++++++++++
 6 files changed, 197 insertions(+)
 create mode 100644 lld/test/ELF/aarch64-reloc-abs16-addend.test
 create mode 100644 lld/test/ELF/aarch64-reloc-abs32-addend.test
 create mode 100644 lld/test/ELF/aarch64-reloc-call26-addend.test
 create mode 100644 lld/test/ELF/aarch64-reloc-jump26-addend.test
 create mode 100644 lld/test/ELF/aarch64-reloc-prel16-addend.test

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



More information about the llvm-commits mailing list