llvm-project/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
Simi Pallipurath 8cf8956897 [lld][Arm] Big Endian - Byte invariant support.
Arm has BE8 big endian configuration called a byte-invariant(every byte has the same address on little and big-endian systems).

When in BE8 mode:
  1. Instructions are big-endian in relocatable objects but
     little-endian in executables and shared objects.
  2. Data is big-endian.
  3. The data encoding of the ELF file is ELFDATA2MSB.

To support BE8 without an ABI break for relocatable objects,the linker takes on the responsibility of changing the endianness of instructions. At a high level the only difference between BE32 and BE8 in the linker is that for BE8:
  1. The linker sets the flag EF_ARM_BE8 in the ELF header.
  2. The linker endian reverses the instructions, but not data.

This patch adds BE8 big endian support for Arm. To endian reverse the instructions we'll need access to the mapping symbols. Code sections can contain a mix of Arm, Thumb and literal data. We need to endian reverse Arm instructions as words, Thumb instructions
as half-words and ignore literal data.The only way to find these transitions precisely is by using mapping symbols. The instruction reversal will need to take place after relocation. For Arm BE8 code sections (Section has SHF_EXECINSTR flag ) we inserted a step after relocation to endian reverse the instructions. The implementation strategy i have used here is to write all sections BE32  including SyntheticSections then endian reverse all code in InputSections via mapping symbols.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D150870
2023-06-20 14:08:21 +01:00

88 lines
4.0 KiB
ArmAsm

// REQUIRES: arm
// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: echo "SECTIONS { \
// RUN: . = SIZEOF_HEADERS; \
// RUN: .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \
// RUN: } " > %t.script
// RUN: ld.lld --no-rosegment --script %t.script %t -o %t2
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x94 --stop-address=0xbc | FileCheck --check-prefix=CHECK1 %s
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x20000bc --stop-address=0x20000de | FileCheck --check-prefix=CHECK2 %s
// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %s -o %t
// RUN: ld.lld --no-rosegment --script %t.script %t -o %t2
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x94 --stop-address=0xbc | FileCheck --check-prefix=CHECK1 %s
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x20000bc --stop-address=0x20000de | FileCheck --check-prefix=CHECK2 %s
// RUN: ld.lld --be8 --no-rosegment --script %t.script %t -o %t2
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x94 --stop-address=0xbc | FileCheck --check-prefix=CHECK1 %s
// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x20000bc --stop-address=0x20000de | FileCheck --check-prefix=CHECK2 %s
// Test that range extension thunks can handle location expressions within
// a Section Description
.syntax unified
.section .text_low, "ax", %progbits
.thumb
.globl _start
_start: bx lr
.globl low_target
.type low_target, %function
low_target:
bl high_target
bl high_target2
.section .text_low2, "ax", %progbits
.thumb
.globl low_target2
.type low_target2, %function
low_target2:
bl high_target
bl high_target2
// CHECK1: Disassembly of section .text_low:
// CHECK1-EMPTY:
// CHECK1-NEXT: <_start>:
// CHECK1-NEXT: 94: 4770 bx lr
// CHECK1: <low_target>:
// CHECK1-NEXT: 96: f000 f803 bl 0xa0 <__Thumbv7ABSLongThunk_high_target>
// CHECK1-NEXT: 9a: f000 f806 bl 0xaa <__Thumbv7ABSLongThunk_high_target2>
// CHECK1: <__Thumbv7ABSLongThunk_high_target>:
// CHECK1-NEXT: a0: f240 0cbd movw r12, #189
// CHECK1-NEXT: a4: f2c0 2c00 movt r12, #512
// CHECK1-NEXT: a8: 4760 bx r12
// CHECK1: <__Thumbv7ABSLongThunk_high_target2>:
// CHECK1-NEXT: aa: f240 0cd9 movw r12, #217
// CHECK1-NEXT: ae: f2c0 2c00 movt r12, #512
// CHECK1-NEXT: b2: 4760 bx r12
// CHECK1: <low_target2>:
// CHECK1-NEXT: b4: f7ff fff4 bl 0xa0 <__Thumbv7ABSLongThunk_high_target>
// CHECK1-NEXT: b8: f7ff fff7 bl 0xaa <__Thumbv7ABSLongThunk_high_target2>
.section .text_high, "ax", %progbits
.thumb
.globl high_target
.type high_target, %function
high_target:
bl low_target
bl low_target2
.section .text_high2, "ax", %progbits
.thumb
.globl high_target2
.type high_target2, %function
high_target2:
bl low_target
bl low_target2
// CHECK2: <high_target>:
// CHECK2-NEXT: 20000bc: f000 f802 bl 0x20000c4 <__Thumbv7ABSLongThunk_low_target>
// CHECK2-NEXT: 20000c0: f000 f805 bl 0x20000ce <__Thumbv7ABSLongThunk_low_target2>
// CHECK2: <__Thumbv7ABSLongThunk_low_target>:
// CHECK2-NEXT: 20000c4: f240 0c97 movw r12, #151
// CHECK2-NEXT: 20000c8: f2c0 0c00 movt r12, #0
// CHECK2-NEXT: 20000cc: 4760 bx r12
// CHECK2: <__Thumbv7ABSLongThunk_low_target2>:
// CHECK2-NEXT: 20000ce: f240 0cb5 movw r12, #181
// CHECK2-NEXT: 20000d2: f2c0 0c00 movt r12, #0
// CHECK2-NEXT: 20000d6: 4760 bx r12
// CHECK2: <high_target2>:
// CHECK2-NEXT: 20000d8: f7ff fff4 bl 0x20000c4 <__Thumbv7ABSLongThunk_low_target>
// CHECK2-NEXT: 20000dc: f7ff fff7 bl 0x20000ce <__Thumbv7ABSLongThunk_low_target2>