From 41c9c00bf07e979e1fb643312a1490bde0e314f3 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Fri, 21 Oct 2016 18:22:35 +0000 Subject: [PATCH] For llvm-objdump for Mach-O files add printing of the ARM_THREAD_STATE in the same format as otool-classic(1) on darwin. Also remove an extra space in printing the initprot to make the output match otool-classic(1) on darwin. rdar://28851457 llvm-svn: 284852 --- .../tools/llvm-objdump/ARM/Inputs/thumb.armv7m | Bin 0 -> 4288 bytes .../llvm-objdump/ARM/macho-private-headers.test | 13 ++++ llvm/tools/llvm-objdump/MachODump.cpp | 71 ++++++++++++++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100755 llvm/test/tools/llvm-objdump/ARM/Inputs/thumb.armv7m diff --git a/llvm/test/tools/llvm-objdump/ARM/Inputs/thumb.armv7m b/llvm/test/tools/llvm-objdump/ARM/Inputs/thumb.armv7m new file mode 100755 index 0000000000000000000000000000000000000000..785ab997bc4a8f567dfa8f02b47e0e34c4fd771b GIT binary patch literal 4288 zcmX^2>+L@t1_lOxAZ7w$b|7wGWMBXyFtz~F@$mtU?yga;LHulZUwRAJDNdJz&)=3=J?{AaRJB zeLVfVU0pn3_A3A-p!OdCGC}H)%>emb0*FCsxPVjzkoEx5(m)InPY4RxT6Dtv_S}e# z2dZmV9?}AefsBIzkUv0Hfy@+y36e?w2l{gqjE2By2#kinXb6mkz-S1JhQMeDjE2By z2#kinXb6mk0QEwkz#Y`@O@SK7jl>oPveWn(8I+X`!a;pnJs<(%Qj1_xK=S}>YC;kK literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-objdump/ARM/macho-private-headers.test b/llvm/test/tools/llvm-objdump/ARM/macho-private-headers.test index 4ab3043..53004c7 100644 --- a/llvm/test/tools/llvm-objdump/ARM/macho-private-headers.test +++ b/llvm/test/tools/llvm-objdump/ARM/macho-private-headers.test @@ -1,6 +1,8 @@ // RUN: llvm-objdump -p %p/Inputs/hello.obj.macho-arm | FileCheck %s // RUN: llvm-objdump -p %p/Inputs/hello.exe.macho-arm \ // RUN: | FileCheck %s -check-prefix=EXE +// RUN: llvm-objdump -macho -private-headers %p/Inputs/thumb.armv7m \ +// RUN: | FileCheck %s -check-prefix=THREAD CHECK: Mach header CHECK: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags @@ -343,3 +345,14 @@ EXE: cmd LC_DYLIB_CODE_SIGN_DRS EXE: cmdsize 16 EXE: dataoff 49244 EXE: datasize 20 + +THREAD: Load command 6 +THREAD: cmd LC_UNIXTHREAD +THREAD: cmdsize 84 +THREAD: flavor ARM_THREAD_STATE +THREAD: count ARM_THREAD_STATE_COUNT +THREAD: r0 0x00000000 r1 0x00000000 r2 0x00000000 r3 0x00000000 +THREAD: r4 0x00000000 r5 0x00000000 r6 0x00000000 r7 0x00000000 +THREAD: r8 0x00000000 r9 0x00000000 r10 0x00000000 r11 0x00000000 +THREAD: r12 0x00000000 sp 0x00000000 lr 0x00000000 pc 0x00001fff +THREAD: cpsr 0x00000000 diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index a2f0e8d..2c101f6 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -7745,9 +7745,9 @@ static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize, if ((initprot & ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE)) != 0) - outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n"; + outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n"; else { - outs() << " initprot "; + outs() << " initprot "; outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-"); outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-"); outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n"); @@ -8640,6 +8640,26 @@ static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) { outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n"; } +static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) { + outs() << "\t r0 " << format("0x%08" PRIx32, cpu32.r[0]); + outs() << " r1 " << format("0x%08" PRIx32, cpu32.r[1]); + outs() << " r2 " << format("0x%08" PRIx32, cpu32.r[2]); + outs() << " r3 " << format("0x%08" PRIx32, cpu32.r[3]) << "\n"; + outs() << "\t r4 " << format("0x%08" PRIx32, cpu32.r[4]); + outs() << " r5 " << format("0x%08" PRIx32, cpu32.r[5]); + outs() << " r6 " << format("0x%08" PRIx32, cpu32.r[6]); + outs() << " r7 " << format("0x%08" PRIx32, cpu32.r[7]) << "\n"; + outs() << "\t r8 " << format("0x%08" PRIx32, cpu32.r[8]); + outs() << " r9 " << format("0x%08" PRIx32, cpu32.r[9]); + outs() << " r10 " << format("0x%08" PRIx32, cpu32.r[10]); + outs() << " r11 " << format("0x%08" PRIx32, cpu32.r[11]) << "\n"; + outs() << "\t r12 " << format("0x%08" PRIx32, cpu32.r[12]); + outs() << " sp " << format("0x%08" PRIx32, cpu32.sp); + outs() << " lr " << format("0x%08" PRIx32, cpu32.lr); + outs() << " pc " << format("0x%08" PRIx32, cpu32.pc) << "\n"; + outs() << "\t cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n"; +} + static void PrintThreadCommand(MachO::thread_command t, const char *Ptr, bool isLittleEndian, uint32_t cputype) { if (t.cmd == MachO::LC_THREAD) @@ -8796,6 +8816,53 @@ static void PrintThreadCommand(MachO::thread_command t, const char *Ptr, begin += count * sizeof(uint32_t); } } + } else if (cputype == MachO::CPU_TYPE_ARM) { + while (begin < end) { + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&flavor, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + flavor = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(flavor); + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&count, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + count = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(count); + if (flavor == MachO::ARM_THREAD_STATE) { + outs() << " flavor ARM_THREAD_STATE\n"; + if (count == MachO::ARM_THREAD_STATE_COUNT) + outs() << " count ARM_THREAD_STATE_COUNT\n"; + else + outs() << " count " << count + << " (not ARM_THREAD_STATE_COUNT)\n"; + MachO::arm_thread_state32_t cpu32; + left = end - begin; + if (left >= sizeof(MachO::arm_thread_state32_t)) { + memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t)); + begin += sizeof(MachO::arm_thread_state32_t); + } else { + memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t)); + memcpy(&cpu32, begin, left); + begin += left; + } + if (isLittleEndian != sys::IsLittleEndianHost) + swapStruct(cpu32); + Print_arm_thread_state32_t(cpu32); + } else { + outs() << " flavor " << flavor << " (unknown)\n"; + outs() << " count " << count << "\n"; + outs() << " state (unknown)\n"; + begin += count * sizeof(uint32_t); + } + } } else { while (begin < end) { if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { -- 2.7.4