aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index fd83dc1..efac3a8 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -690,14 +690,14 @@ public:
OS << ' '
<< format_hex_no_prefix(
llvm::support::endian::read<uint16_t>(
- Bytes.data() + Pos, llvm::support::little),
+ Bytes.data() + Pos, InstructionEndianness),
4);
} else {
for (; Pos + 4 <= End; Pos += 4)
OS << ' '
<< format_hex_no_prefix(
llvm::support::endian::read<uint32_t>(
- Bytes.data() + Pos, llvm::support::little),
+ Bytes.data() + Pos, InstructionEndianness),
8);
}
if (Pos < End) {
@@ -713,6 +713,13 @@ public:
} else
OS << "\t<unknown>";
}
+
+ void setInstructionEndianness(llvm::support::endianness Endianness) {
+ InstructionEndianness = Endianness;
+ }
+
+private:
+ llvm::support::endianness InstructionEndianness = llvm::support::little;
};
ARMPrettyPrinter ARMPrettyPrinterInst;
@@ -1852,6 +1859,29 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
if (MCPU.empty())
MCPU = Obj->tryGetCPUName().value_or("").str();
+ if (isArmElf(*Obj)) {
+ // When disassembling big-endian Arm ELF, the instruction endianness is
+ // determined in a complex way. In relocatable objects, AAELF32 mandates
+ // that instruction endianness matches the ELF file endianness; in
+ // executable images, that's true unless the file header has the EF_ARM_BE8
+ // flag, in which case instructions are little-endian regardless of data
+ // endianness.
+ //
+ // We must set the big-endian-instructions SubtargetFeature to make the
+ // disassembler read the instructions the right way round, and also tell
+ // our own prettyprinter to retrieve the encodings the same way to print in
+ // hex.
+ const auto *Elf32BE = dyn_cast<ELF32BEObjectFile>(Obj);
+
+ if (Elf32BE && (Elf32BE->isRelocatableObject() ||
+ !(Elf32BE->getPlatformFlags() & ELF::EF_ARM_BE8))) {
+ Features.AddFeature("+big-endian-instructions");
+ ARMPrettyPrinterInst.setInstructionEndianness(llvm::support::big);
+ } else {
+ ARMPrettyPrinterInst.setInstructionEndianness(llvm::support::little);
+ }
+ }
+
std::unique_ptr<const MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
if (!STI)