[llvm-objdump,ARM] Fix big-endian AArch32 disassembly.
authorSimon Tatham <simon.tatham@arm.com>
Mon, 1 Aug 2022 12:40:32 +0000 (13:40 +0100)
committerSimon Tatham <simon.tatham@arm.com>
Mon, 8 Aug 2022 09:49:51 +0000 (10:49 +0100)
commit72017e9b16b737c5bd7c1dd33abff36f368fa724
tree493cbdf0631efa94878df0f5310c8baaa7c8f9fa
parent1eee6de873974f55538df976bf7802f019eac70a
[llvm-objdump,ARM] Fix big-endian AArch32 disassembly.

The ABI for big-endian AArch32, as specified by AAELF32, is above-
averagely complicated. Relocatable object files are expected to store
instruction encodings in byte order matching the ELF file's endianness
(so, big-endian for a BE ELF file). But executable images can
//either// do that //or// store instructions little-endian regardless
of data and ELF endianness (to support BE32 and BE8 platforms
respectively). They signal the latter by setting the EF_ARM_BE8 flag
in the ELF header.

(In the case of the Thumb instruction set, this all means that each
16-bit halfword of a Thumb instruction is stored in one or other
endianness. The two halfwords of a 32-bit Thumb instruction must
appear in the same order no matter what, because the first halfword is
the one that must avoid overlapping the encoding of any 16-bit Thumb
instruction.)

llvm-objdump was unconditionally expecting Arm instructions to be
stored little-endian. So it would correctly disassemble a BE8 image,
but if you gave it a BE32 image or a BE object file, it would retrieve
every instruction in byte-swapped form and disassemble it to
nonsense. (Even an object file output by LLVM itself, because
ARMMCCodeEmitter outputs instructions big-endian in big-endian mode,
which is correct for writing an object file.)

This patch allows llvm-objdump to correctly disassemble all three of
those classes of Arm ELF file. It does it by introducing a new
SubtargetFeature for big-endian instructions, setting it from the ELF
image type and flags during llvm-objdump setup, and teaching both
ARMDisassembler and llvm-objdump itself to pay attention to it when
retrieving instruction data from a section being disassembled.

Differential Revision: https://reviews.llvm.org/D130902
llvm/include/llvm/BinaryFormat/ELF.h
llvm/lib/ObjectYAML/ELFYAML.cpp
llvm/lib/Target/ARM/ARM.td
llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
llvm/test/tools/llvm-objdump/ELF/ARM/be-disasm.test [new file with mode: 0644]
llvm/tools/llvm-objdump/llvm-objdump.cpp