Skip to content

Commit

Permalink
Add support for the ARM_THREAD_STATE64 and
Browse files Browse the repository at this point in the history
in llvm-objdump for Mach-O files add the printing of the
ARM_THREAD_STATE64 in the same format as
otool-classic(1) on darwin.

To do this the 64-bit ARM general tread state
needed to be defined in include/llvm/Support/MachO.h .

rdar://28985800


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285967 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
enderby committed Nov 3, 2016
1 parent e8078b2 commit 00b62fb
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 0 deletions.
22 changes: 22 additions & 0 deletions include/llvm/Support/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,25 @@ namespace llvm {
sys::swapByteOrder(x.cpsr);
}

struct arm_thread_state64_t {
uint64_t x[29];
uint64_t fp;
uint64_t lr;
uint64_t sp;
uint64_t pc;
uint32_t cpsr;
};

inline void swapStruct(arm_thread_state64_t &x) {
for (int i = 0; i < 29; i++)
sys::swapByteOrder(x.x[i]);
sys::swapByteOrder(x.fp);
sys::swapByteOrder(x.lr);
sys::swapByteOrder(x.sp);
sys::swapByteOrder(x.pc);
sys::swapByteOrder(x.cpsr);
}

struct arm_state_hdr_t {
uint32_t flavor;
uint32_t count;
Expand Down Expand Up @@ -1778,6 +1797,9 @@ namespace llvm {
const uint32_t ARM_THREAD_STATE_COUNT =
sizeof(arm_thread_state32_t) / sizeof(uint32_t);

const uint32_t ARM_THREAD_STATE64_COUNT =
sizeof(arm_thread_state64_t) / sizeof(uint32_t);

struct ppc_thread_state32_t {
uint32_t srr0;
uint32_t srr1;
Expand Down
19 changes: 19 additions & 0 deletions lib/Object/MachOObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,25 @@ static Error checkThreadCommand(const MachOObjectFile *Obj,
"flavor number " + Twine(nflavor) + " in " +
CmdName + " command");
}
} else if (cputype == MachO::CPU_TYPE_ARM64) {
if (flavor == MachO::ARM_THREAD_STATE64) {
if (count != MachO::ARM_THREAD_STATE64_COUNT)
return malformedError("load command " + Twine(LoadCommandIndex) +
" count not ARM_THREAD_STATE64_COUNT for "
"flavor number " + Twine(nflavor) + " which is "
"a ARM_THREAD_STATE64 flavor in " + CmdName +
" command");
if (state + sizeof(MachO::arm_thread_state64_t) > end)
return malformedError("load command " + Twine(LoadCommandIndex) +
" ARM_THREAD_STATE64 extends past end of "
"command in " + CmdName + " command");
state += sizeof(MachO::arm_thread_state64_t);
} else {
return malformedError("load command " + Twine(LoadCommandIndex) +
" unknown flavor (" + Twine(flavor) + ") for "
"flavor number " + Twine(nflavor) + " in " +
CmdName + " command");
}
} else if (cputype == MachO::CPU_TYPE_POWERPC) {
if (flavor == MachO::PPC_THREAD_STATE) {
if (count != MachO::PPC_THREAD_STATE_COUNT)
Expand Down
Binary file not shown.
19 changes: 19 additions & 0 deletions test/tools/llvm-objdump/AArch64/macho-print-thread.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
RUN: llvm-objdump -macho -private-headers %p/Inputs/thread.macho-aarch64 | FileCheck %s

CHECK: Load command 0
CHECK: cmd LC_THREAD
CHECK: cmdsize 288
CHECK: flavor ARM_THREAD_STATE64
CHECK: count ARM_THREAD_STATE64_COUNT
CHECK: x0 0x0000000000000000 x1 0x0000000000000000 x2 0x0000000000000000
CHECK: x3 0x0000000000000000 x4 0x0000000000000000 x5 0x0000000000000000
CHECK: x6 0x0000000000000000 x7 0x0000000000000000 x8 0x0000000000000000
CHECK: x9 0x0000000000000000 x10 0x0000000000000000 x11 0x0000000000000000
CHECK: x12 0x0000000000000000 x13 0x0000000000000000 x14 0x0000000000000000
CHECK: x15 0x0000000000000000 x16 0x0000000000000000 x17 0x0000000000000000
CHECK: x18 0x0000000000000000 x19 0x0000000000000000 x20 0x0000000000000000
CHECK: x21 0x0000000000000000 x22 0x0000000000000000 x23 0x0000000000000000
CHECK: x24 0x0000000000000000 x25 0x0000000000000000 x26 0x0000000000000000
CHECK: x27 0x0000000000000000 x28 0x0000000000000000 fp 0x0000000000000000
CHECK: lr 0x0000000000000000 sp 0x0000000000000000 pc 0x0000000000000000
CHECK: cpsr 0x00000000
84 changes: 84 additions & 0 deletions tools/llvm-objdump/MachODump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8656,6 +8656,43 @@ static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) {
outs() << "\t cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n";
}

static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) {
outs() << "\t x0 " << format("0x%016" PRIx64, cpu64.x[0]);
outs() << " x1 " << format("0x%016" PRIx64, cpu64.x[1]);
outs() << " x2 " << format("0x%016" PRIx64, cpu64.x[2]) << "\n";
outs() << "\t x3 " << format("0x%016" PRIx64, cpu64.x[3]);
outs() << " x4 " << format("0x%016" PRIx64, cpu64.x[4]);
outs() << " x5 " << format("0x%016" PRIx64, cpu64.x[5]) << "\n";
outs() << "\t x6 " << format("0x%016" PRIx64, cpu64.x[6]);
outs() << " x7 " << format("0x%016" PRIx64, cpu64.x[7]);
outs() << " x8 " << format("0x%016" PRIx64, cpu64.x[8]) << "\n";
outs() << "\t x9 " << format("0x%016" PRIx64, cpu64.x[9]);
outs() << " x10 " << format("0x%016" PRIx64, cpu64.x[10]);
outs() << " x11 " << format("0x%016" PRIx64, cpu64.x[11]) << "\n";
outs() << "\t x12 " << format("0x%016" PRIx64, cpu64.x[12]);
outs() << " x13 " << format("0x%016" PRIx64, cpu64.x[13]);
outs() << " x14 " << format("0x%016" PRIx64, cpu64.x[14]) << "\n";
outs() << "\t x15 " << format("0x%016" PRIx64, cpu64.x[15]);
outs() << " x16 " << format("0x%016" PRIx64, cpu64.x[16]);
outs() << " x17 " << format("0x%016" PRIx64, cpu64.x[17]) << "\n";
outs() << "\t x18 " << format("0x%016" PRIx64, cpu64.x[18]);
outs() << " x19 " << format("0x%016" PRIx64, cpu64.x[19]);
outs() << " x20 " << format("0x%016" PRIx64, cpu64.x[20]) << "\n";
outs() << "\t x21 " << format("0x%016" PRIx64, cpu64.x[21]);
outs() << " x22 " << format("0x%016" PRIx64, cpu64.x[22]);
outs() << " x23 " << format("0x%016" PRIx64, cpu64.x[23]) << "\n";
outs() << "\t x24 " << format("0x%016" PRIx64, cpu64.x[24]);
outs() << " x25 " << format("0x%016" PRIx64, cpu64.x[25]);
outs() << " x26 " << format("0x%016" PRIx64, cpu64.x[26]) << "\n";
outs() << "\t x27 " << format("0x%016" PRIx64, cpu64.x[27]);
outs() << " x28 " << format("0x%016" PRIx64, cpu64.x[28]);
outs() << " fp " << format("0x%016" PRIx64, cpu64.fp) << "\n";
outs() << "\t lr " << format("0x%016" PRIx64, cpu64.lr);
outs() << " sp " << format("0x%016" PRIx64, cpu64.sp);
outs() << " pc " << format("0x%016" PRIx64, cpu64.pc) << "\n";
outs() << "\t cpsr " << format("0x%08" PRIx32, cpu64.cpsr) << "\n";
}

static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
bool isLittleEndian, uint32_t cputype) {
if (t.cmd == MachO::LC_THREAD)
Expand Down Expand Up @@ -8859,6 +8896,53 @@ static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
begin += count * sizeof(uint32_t);
}
}
} else if (cputype == MachO::CPU_TYPE_ARM64) {
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_STATE64) {
outs() << " flavor ARM_THREAD_STATE64\n";
if (count == MachO::ARM_THREAD_STATE64_COUNT)
outs() << " count ARM_THREAD_STATE64_COUNT\n";
else
outs() << " count " << count
<< " (not ARM_THREAD_STATE64_COUNT)\n";
MachO::arm_thread_state64_t cpu64;
left = end - begin;
if (left >= sizeof(MachO::arm_thread_state64_t)) {
memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t));
begin += sizeof(MachO::arm_thread_state64_t);
} else {
memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t));
memcpy(&cpu64, begin, left);
begin += left;
}
if (isLittleEndian != sys::IsLittleEndianHost)
swapStruct(cpu64);
Print_arm_thread_state64_t(cpu64);
} 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)) {
Expand Down

0 comments on commit 00b62fb

Please sign in to comment.