[lld][Arm] Big Endian - Byte invariant support.
authorSimi Pallipurath <simi.pallipurath@arm.com>
Thu, 18 May 2023 11:29:07 +0000 (12:29 +0100)
committerSimi Pallipurath <simi.pallipurath@arm.com>
Tue, 20 Jun 2023 13:08:21 +0000 (14:08 +0100)
commit8cf8956897ce9bca3176c6339077b1ca17b27abc
treef547eeca9b1890b1b7b7a58d2583f30f9b2d4f1a
parentefacdfc235e327341d2b8a733d9963fb526cf17b
[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
32 files changed:
lld/ELF/Arch/ARM.cpp
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/Options.td
lld/ELF/OutputSections.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/Target.h
lld/ELF/Thunks.cpp
lld/ELF/Writer.cpp
lld/docs/ld.lld.1
lld/test/ELF/arm-bl-v6.s
lld/test/ELF/arm-data-relocs.s
lld/test/ELF/arm-exidx-emit-relocs.s
lld/test/ELF/arm-exidx-relocatable.s
lld/test/ELF/arm-exidx-sentinel-norelocatable.s
lld/test/ELF/arm-header.s
lld/test/ELF/arm-mov-relocs.s
lld/test/ELF/arm-plt-reloc.s
lld/test/ELF/arm-thumb-plt-reloc.s
lld/test/ELF/arm-thunk-arm-thumb-reuse.s
lld/test/ELF/arm-thunk-edgecase.s
lld/test/ELF/arm-thunk-largesection.s
lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
lld/test/ELF/arm-thunk-linkerscript.s
lld/test/ELF/arm-thunk-nosuitable.s
lld/test/ELF/arm-thunk-re-add.s
lld/test/ELF/arm-thunk-reuse.s
lld/test/ELF/arm-thunk-section-too-large.s
lld/test/ELF/arm-thunk-toolargesection.s
lld/test/ELF/arm-v5-reloc-error.s
lld/test/ELF/emulation-arm.s
lld/test/ELF/target-specific-options.s