[lld] 7605a9a - [ELF] Support aarch64_be

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 8 08:55:36 PST 2021


Author: Fangrui Song
Date: 2021-02-08T08:55:29-08:00
New Revision: 7605a9a009b5fa3bdac07e3131c8d82f6d08feb7

URL: https://github.com/llvm/llvm-project/commit/7605a9a009b5fa3bdac07e3131c8d82f6d08feb7
DIFF: https://github.com/llvm/llvm-project/commit/7605a9a009b5fa3bdac07e3131c8d82f6d08feb7.diff

LOG: [ELF] Support aarch64_be

This patch adds

* Big-endian values for `R_AARCH64_{ABS,PREL}{16,32,64}` and `R_AARCH64_PLT32`
* aarch64elfb & aarch64linuxb BFD emulations
* elf64-bigaarch64 output format (bfdname)

Link: https://github.com/ClangBuiltLinux/linux/issues/1288

Differential Revision: https://reviews.llvm.org/D96188

Added: 
    lld/test/ELF/lto/aarch64.ll

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/Driver.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/ScriptParser.cpp
    lld/test/ELF/aarch64-abs16.s
    lld/test/ELF/aarch64-abs32.s
    lld/test/ELF/aarch64-data-relocs.s
    lld/test/ELF/aarch64-gnu-ifunc-plt.s
    lld/test/ELF/aarch64-prel16.s
    lld/test/ELF/aarch64-prel32.s
    lld/test/ELF/aarch64-reloc-plt32.s
    lld/test/ELF/emulation-aarch64.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 6fa860ef0b8b..58da44a86f65 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -195,7 +195,7 @@ RelType AArch64::getDynRel(RelType type) const {
 }
 
 void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const {
-  write64le(buf, in.plt->getVA());
+  write64(buf, in.plt->getVA());
 }
 
 void AArch64::writePltHeader(uint8_t *buf) const {
@@ -323,20 +323,20 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
   case R_AARCH64_ABS16:
   case R_AARCH64_PREL16:
     checkIntUInt(loc, val, 16, rel);
-    write16le(loc, val);
+    write16(loc, val);
     break;
   case R_AARCH64_ABS32:
   case R_AARCH64_PREL32:
     checkIntUInt(loc, val, 32, rel);
-    write32le(loc, val);
+    write32(loc, val);
     break;
   case R_AARCH64_PLT32:
     checkInt(loc, val, 32, rel);
-    write32le(loc, val);
+    write32(loc, val);
     break;
   case R_AARCH64_ABS64:
   case R_AARCH64_PREL64:
-    write64le(loc, val);
+    write64(loc, val);
     break;
   case R_AARCH64_ADD_ABS_LO12_NC:
     or32AArch64Imm(loc, val);

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index dce0a9c0f318..09c2c17de9b2 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -146,6 +146,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
       StringSwitch<std::pair<ELFKind, uint16_t>>(s)
           .Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec",
                  {ELF64LEKind, EM_AARCH64})
+          .Cases("aarch64elfb", "aarch64linuxb", {ELF64BEKind, EM_AARCH64})
           .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
           .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
           .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 0f6afadd9bff..caca4bc37f4e 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1608,6 +1608,7 @@ static ELFKind getBitcodeELFKind(const Triple &t) {
 static uint16_t getBitcodeMachineKind(StringRef path, const Triple &t) {
   switch (t.getArch()) {
   case Triple::aarch64:
+  case Triple::aarch64_be:
     return EM_AARCH64;
   case Triple::amdgcn:
   case Triple::r600:

diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index b81812d11821..3af63830f9c0 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -412,6 +412,7 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
       .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
+      .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64})
       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
       .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})

diff  --git a/lld/test/ELF/aarch64-abs16.s b/lld/test/ELF/aarch64-abs16.s
index a0abe0fa79d7..530492141262 100644
--- a/lld/test/ELF/aarch64-abs16.s
+++ b/lld/test/ELF/aarch64-abs16.s
@@ -3,6 +3,8 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
 
 .globl _start
 _start:
@@ -12,6 +14,8 @@ _start:
 
 // RUN: ld.lld %t.o %t256.o -o %t
 // RUN: llvm-objdump -s --section=.data %t | FileCheck %s --check-prefixes=CHECK,LE
+// RUN: ld.lld %t.be.o %t256.be.o -o %t.be
+// RUN: llvm-objdump -s --section=.data %t.be | FileCheck %s --check-prefixes=CHECK,BE
 
 // CHECK: Contents of section .data:
 // 220158: S = 0x100, A = 0xfeff
@@ -19,6 +23,7 @@ _start:
 // 22015c: S = 0x100, A = -0x8100
 //         S + A = 0x8000
 // LE-NEXT: 220158 ffff0080
+// BE-NEXT: 220158 ffff8000
 
 // RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
 // OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 65535]; references foo

diff  --git a/lld/test/ELF/aarch64-abs32.s b/lld/test/ELF/aarch64-abs32.s
index 42a7ca803e8e..8bbacd9d6ca8 100644
--- a/lld/test/ELF/aarch64-abs32.s
+++ b/lld/test/ELF/aarch64-abs32.s
@@ -3,6 +3,8 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
 
 .globl _start
 _start:
@@ -12,6 +14,8 @@ _start:
 
 // RUN: ld.lld %t.o %t256.o -o %t
 // RUN: llvm-objdump -s --section=.data %t | FileCheck %s --check-prefixes=CHECK,LE
+// RUN: ld.lld %t.be.o %t256.be.o -o %t.be
+// RUN: llvm-objdump -s --section=.data %t.be | FileCheck %s --check-prefixes=CHECK,BE
 
 // CHECK: Contents of section .data:
 // 220158: S = 0x100, A = 0xfffffeff
@@ -19,6 +23,7 @@ _start:
 // 22015c: S = 0x100, A = -0x80000100
 //         S + A = 0x80000000
 // LE-NEXT: 220158 ffffffff 00000080
+// BE-NEXT: 220158 ffffffff 80000000
 
 // RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
 // OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 4294967295]; references foo

diff  --git a/lld/test/ELF/aarch64-data-relocs.s b/lld/test/ELF/aarch64-data-relocs.s
index aa55cce4b7aa..438740c11c97 100644
--- a/lld/test/ELF/aarch64-data-relocs.s
+++ b/lld/test/ELF/aarch64-data-relocs.s
@@ -4,6 +4,11 @@
 // RUN: ld.lld %t.o %t256.o -o %t
 // RUN: llvm-objdump -s %t | FileCheck %s --check-prefixes=CHECK,LE
 
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
+// RUN: ld.lld %t.be.o %t256.be.o -o %t.be
+// RUN: llvm-objdump -s %t.be | FileCheck %s --check-prefixes=CHECK,BE
+
 .globl _start
 _start:
 .section .R_AARCH64_ABS64, "ax", at progbits
@@ -13,6 +18,7 @@ _start:
 // S + A = 0x124
 // CHECK: Contents of section .R_AARCH64_ABS64:
 // LE-NEXT: 210120 24010000 00000000
+// BE-NEXT: 210120 00000000 00000124
 
 .section .R_AARCH64_PREL64, "ax", at progbits
   .xword foo - . + 0x24
@@ -20,3 +26,4 @@ _start:
 // S + A - P = 0x100 + 0x24 - 0x210128 = 0xffffffffffdefffc
 // CHECK: Contents of section .R_AARCH64_PREL64:
 // LE-NEXT: 210128 fcffdeff ffffffff
+// BE-NEXT: 210128 ffffffff ffdefffc

diff  --git a/lld/test/ELF/aarch64-gnu-ifunc-plt.s b/lld/test/ELF/aarch64-gnu-ifunc-plt.s
index fdd8e6ee09aa..31b494228e14 100644
--- a/lld/test/ELF/aarch64-gnu-ifunc-plt.s
+++ b/lld/test/ELF/aarch64-gnu-ifunc-plt.s
@@ -7,6 +7,14 @@
 // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
 // RUN: llvm-readobj --dynamic-table -r %tout | FileCheck %s
 
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/shared2.s -o %t1.be.o
+// RUN: ld.lld %t1.be.o --shared --soname=t.so -o %t.be.so
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: ld.lld --hash-style=sysv %t.be.so %t.be.o -o %t.be
+// RUN: llvm-objdump -d --no-show-raw-insn %t.be | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-objdump -s %t.be | FileCheck %s --check-prefix=GOTPLT_BE
+// RUN: llvm-readobj --dynamic-table -r %t.be | FileCheck %s
+
 // Check that the PLTRELSZ tag does not include the IRELATIVE relocations
 // CHECK: DynamicSection [
 // CHECK:   0x0000000000000008 RELASZ               48 (bytes)
@@ -31,6 +39,12 @@
 // GOTPLT-NEXT:  230460 f0022100 00000000 00000000 00000000
 // GOTPLT-NEXT:  230470 00000000 00000000
 
+// GOTPLT_BE: Contents of section .got.plt:
+// GOTPLT_BE-NEXT:  230440 00000000 00000000 00000000 00000000
+// GOTPLT_BE-NEXT:  230450 00000000 00000000 00000000 002102f0
+// GOTPLT_BE-NEXT:  230460 00000000 002102f0 00000000 00000000
+// GOTPLT_BE-NEXT:  230470 00000000 00000000
+
 // Check that a PLT header is written and the ifunc entries appear last
 // DISASM: Disassembly of section .text:
 // DISASM-EMPTY:

diff  --git a/lld/test/ELF/aarch64-prel16.s b/lld/test/ELF/aarch64-prel16.s
index cdebd2dabee5..a18f0798432b 100644
--- a/lld/test/ELF/aarch64-prel16.s
+++ b/lld/test/ELF/aarch64-prel16.s
@@ -3,6 +3,8 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
 
 .globl _start
 _start:
@@ -16,6 +18,8 @@ _start:
 //       if it is already fixed. Then, update addends accordingly.
 // RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t
 // RUN: llvm-objdump -s --section=.data %t | FileCheck %s --check-prefixes=CHECK,LE
+// RUN: ld.lld -z max-page-size=4096 %t.be.o %t256.be.o -o %t.be
+// RUN: llvm-objdump -s --section=.data %t.be | FileCheck %s --check-prefixes=CHECK,BE
 
 // CHECK: Contents of section .data:
 // 202158: S = 0x100, A = 0x212157, P = 0x202158

diff  --git a/lld/test/ELF/aarch64-prel32.s b/lld/test/ELF/aarch64-prel32.s
index 0fd72b96dcb5..ce9f0596eb27 100644
--- a/lld/test/ELF/aarch64-prel32.s
+++ b/lld/test/ELF/aarch64-prel32.s
@@ -3,6 +3,8 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
 
 .globl _start
 _start:
@@ -16,6 +18,8 @@ _start:
 //       if it is already fixed. Then, update addends accordingly.
 // RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t
 // RUN: llvm-objdump -s --section=.data %t | FileCheck %s --check-prefixes=CHECK,LE
+// RUN: ld.lld -z max-page-size=4096 %t.be.o %t256.be.o -o %t.be
+// RUN: llvm-objdump -s --section=.data %t.be | FileCheck %s --check-prefixes=CHECK,BE
 
 // CHECK: Contents of section .data:
 // 202158: S = 0x100, A = 0x100202057, P = 0x202158
@@ -23,6 +27,7 @@ _start:
 // 20215c: S = 0x100, A = -0x7fdfdfa4, P = 0x20215c
 //         S + A - P = 0x80000000
 // LE-NEXT: 202158 ffffffff 00000080
+// BE-NEXT: 202158 ffffffff 80000000
 
 // RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
 // OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 4294967295]; references foo

diff  --git a/lld/test/ELF/aarch64-reloc-plt32.s b/lld/test/ELF/aarch64-reloc-plt32.s
index a7467562b2db..2e56dfd1986f 100644
--- a/lld/test/ELF/aarch64-reloc-plt32.s
+++ b/lld/test/ELF/aarch64-reloc-plt32.s
@@ -3,11 +3,15 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/abs256.s -o %t256.be.o
 
 /// Check for overflow with a R_AACH64_PLT32 relocation.
 
 // RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2
-// RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s
+// RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s --check-prefixes=CHECK,LE
+// RUN: ld.lld -z max-page-size=4096 %t.be.o %t256.be.o -o %t2.be
+// RUN: llvm-objdump -s --section=.data %t2.be | FileCheck %s --check-prefixes=CHECK,BE
 
 // CHECK: Contents of section .data:
 /// 202158: S = 0x100, A = 0x80202057, P = 0x202158
@@ -16,7 +20,8 @@
 ///         S + A - P = 0x80000000
 /// 202160: S = 0x100, A = 0, P = 0x202160
 ///         S + A - P = 0xffdfdfa0
-// CHECK-NEXT: 202158 ffffff7f 00000080 a0dfdfff
+// LE-NEXT: 202158 ffffff7f 00000080 a0dfdfff
+// BE-NEXT: 202158 7fffffff 80000000 ffdfdfa0
 
 // RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
 // OVERFLOW1: relocation R_AARCH64_PLT32 out of range: -2147483649 is not in [-2147483648, 2147483647]; references foo

diff  --git a/lld/test/ELF/emulation-aarch64.s b/lld/test/ELF/emulation-aarch64.s
index f7956f438690..e5ba733a5b8f 100644
--- a/lld/test/ELF/emulation-aarch64.s
+++ b/lld/test/ELF/emulation-aarch64.s
@@ -12,11 +12,23 @@
 # RUN: ld.lld -m aarch64_elf64_le_vec %t.o -o %taosp
 # RUN: llvm-readobj --file-headers %taosp | FileCheck --check-prefixes=AARCH64,LE %s
 
+# RUN: llvm-mc -filetype=obj -triple=aarch64_be %s -o %t.be.o
+# RUN: ld.lld %t.be.o -o %t
+# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefixes=AARCH64,BE %s
+# RUN: ld.lld -m aarch64linuxb %t.be.o -o %t1.be
+# RUN: llvm-readobj --file-headers %t1.be | FileCheck --check-prefixes=AARCH64,BE %s
+# RUN: ld.lld -m aarch64elfb %t.be.o -o %t2.be
+# RUN: llvm-readobj --file-headers %t2.be | FileCheck --check-prefixes=AARCH64,BE %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-bigaarch64)' > %t.script
+# RUN: ld.lld %t.script %t.be.o -o %t3.be
+# RUN: llvm-readobj --file-headers %t3.be | FileCheck --check-prefixes=AARCH64,BE %s
+
 # AARCH64:      ElfHeader {
 # AARCH64-NEXT:   Ident {
 # AARCH64-NEXT:     Magic: (7F 45 4C 46)
 # AARCH64-NEXT:     Class: 64-bit (0x2)
 # LE-NEXT:          DataEncoding: LittleEndian (0x1)
+# BE-NEXT:          DataEncoding: BigEndian (0x2)
 # AARCH64-NEXT:     FileVersion: 1
 # AARCH64-NEXT:     OS/ABI: SystemV (0x0)
 # AARCH64-NEXT:     ABIVersion: 0

diff  --git a/lld/test/ELF/lto/aarch64.ll b/lld/test/ELF/lto/aarch64.ll
new file mode 100644
index 000000000000..a6f6ceeb3860
--- /dev/null
+++ b/lld/test/ELF/lto/aarch64.ll
@@ -0,0 +1,33 @@
+; REQUIRES: aarch64
+;; Test we can infer the e_machine value EM_AARCH64 from a bitcode file.
+
+; RUN: split-file %s %t
+; RUN: llvm-as %t/le.s -o %t/le.o
+; RUN: ld.lld %t/le.o -o %t/le
+; RUN: llvm-readobj -h %t/le | FileCheck %s --check-prefixes=CHECK,LE
+
+; RUN: llvm-as %t/be.s -o %t/be.o
+; RUN: ld.lld %t/be.o -o %t/be
+; RUN: llvm-readobj -h %t/be | FileCheck %s --check-prefixes=CHECK,BE
+
+; LE:      DataEncoding: LittleEndian
+; BE:      DataEncoding: BigEndian
+; CHECK: Machine: EM_AARCH64
+
+;--- le.s
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+define void @_start() {
+entry:
+  ret void
+}
+
+;--- be.s
+target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64_be-unknown-linux-gnu"
+
+define void @_start() {
+entry:
+  ret void
+}


        


More information about the llvm-commits mailing list