mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-08 17:11:33 +00:00
Add support for the ARM_THREAD_STATE64 and
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 llvm-svn: 285967
This commit is contained in:
parent
8e232573a8
commit
7747cb55dc
@ -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;
|
||||
@ -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;
|
||||
|
@ -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)
|
||||
|
BIN
llvm/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64
Normal file
BIN
llvm/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64
Normal file
Binary file not shown.
19
llvm/test/tools/llvm-objdump/AArch64/macho-print-thread.test
Normal file
19
llvm/test/tools/llvm-objdump/AArch64/macho-print-thread.test
Normal file
@ -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
|
@ -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)
|
||||
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user