summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
authorTim Corringham <tcorring@amd.com>2018-03-26 17:06:33 +0000
committerTim Corringham <tcorring@amd.com>2018-03-26 17:06:33 +0000
commit7116e8963df0f3507b86c36953b22d4958b299f1 (patch)
tree00d507be627881c4f6efcdaf189a7d6cd639d7f6 /llvm/tools/llvm-objdump/llvm-objdump.cpp
parentfbfba29d74748b8fffd2f7cc654fb4c3659c8f67 (diff)
downloadbcm5719-llvm-7116e8963df0f3507b86c36953b22d4958b299f1.tar.gz
bcm5719-llvm-7116e8963df0f3507b86c36953b22d4958b299f1.zip
[AMDGPU] Improve disassembler error handling
Summary: llvm-objdump now disassembles unrecognised opcodes as data, using the .long directive. We treat unrecognised opcodes as being 32 bit values, so move along 4 bytes rather than the single byte which previously resulted in a cascade of bogus disassembly following an unrecognised opcode. While no solution can always disassemble code that contains embedded data correctly this provides a significant improvement. The disassembler will now cope with an arbitrary length section as it no longer truncates it to a multiple of 4 bytes, and will use the .byte directive for trailing bytes. Subscribers: arsenm, kzhuravl, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, llvm-commits Differential Revision: https://reviews.llvm.org/D44685 llvm-svn: 328553
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp49
1 files changed, 33 insertions, 16 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 7764c1d6e10..53b720e3a1b 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -595,23 +595,42 @@ public:
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address);
- if (!MI) {
- OS << " <unknown>";
- return;
- }
+ typedef support::ulittle32_t U32;
- SmallString<40> InstStr;
- raw_svector_ostream IS(InstStr);
+ if (MI) {
+ SmallString<40> InstStr;
+ raw_svector_ostream IS(InstStr);
- IP.printInst(MI, IS, "", STI);
+ IP.printInst(MI, IS, "", STI);
- OS << left_justify(IS.str(), 60) << format("// %012" PRIX64 ": ", Address);
- typedef support::ulittle32_t U32;
- for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
- Bytes.size() / sizeof(U32)))
- // D should be explicitly casted to uint32_t here as it is passed
- // by format to snprintf as vararg.
- OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
+ OS << left_justify(IS.str(), 60);
+ } else {
+ // an unrecognized encoding - this is probably data so represent it
+ // using the .long directive, or .byte directive if fewer than 4 bytes
+ // remaining
+ if (Bytes.size() >= 4) {
+ OS << format("\t.long 0x%08" PRIx32 " ",
+ static_cast<uint32_t>(*reinterpret_cast<const U32*>(Bytes.data())));
+ OS.indent(42);
+ } else {
+ OS << format("\t.byte 0x%02" PRIx8, Bytes[0]);
+ for (unsigned int i = 1; i < Bytes.size(); i++)
+ OS << format(", 0x%02" PRIx8, Bytes[i]);
+ OS.indent(55 - (6 * Bytes.size()));
+ }
+ }
+
+ OS << format("// %012" PRIX64 ": ", Address);
+ if (Bytes.size() >=4) {
+ for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
+ Bytes.size() / sizeof(U32)))
+ // D should be explicitly casted to uint32_t here as it is passed
+ // by format to snprintf as vararg.
+ OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
+ } else {
+ for (unsigned int i = 0; i < Bytes.size(); i++)
+ OS << format("%02" PRIX8 " ", Bytes[i]);
+ }
if (!Annot.empty())
OS << "// " << Annot;
@@ -1459,8 +1478,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
End = StopAddress - SectionAddr;
if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
- // make size 4 bytes folded
- End = Start + ((End - Start) & ~0x3ull);
if (std::get<2>(Symbols[si]) == ELF::STT_AMDGPU_HSA_KERNEL) {
// skip amd_kernel_code_t at the begining of kernel symbol (256 bytes)
Start += 256;
OpenPOWER on IntegriCloud