diff options
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 34 |
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) |