CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
};
+ struct x86_thread_state32_t {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t eflags;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ };
+
struct x86_thread_state64_t {
uint64_t rax;
uint64_t rbx;
uint64_t faultvaddr;
};
+ inline void swapStruct(x86_thread_state32_t &x) {
+ sys::swapByteOrder(x.eax);
+ sys::swapByteOrder(x.ebx);
+ sys::swapByteOrder(x.ecx);
+ sys::swapByteOrder(x.edx);
+ sys::swapByteOrder(x.edi);
+ sys::swapByteOrder(x.esi);
+ sys::swapByteOrder(x.ebp);
+ sys::swapByteOrder(x.esp);
+ sys::swapByteOrder(x.ss);
+ sys::swapByteOrder(x.eflags);
+ sys::swapByteOrder(x.eip);
+ sys::swapByteOrder(x.cs);
+ sys::swapByteOrder(x.ds);
+ sys::swapByteOrder(x.es);
+ sys::swapByteOrder(x.fs);
+ sys::swapByteOrder(x.gs);
+ }
+
inline void swapStruct(x86_thread_state64_t &x) {
sys::swapByteOrder(x.rax);
sys::swapByteOrder(x.rbx);
x86_state_hdr_t tsh;
union {
x86_thread_state64_t ts64;
+ x86_thread_state32_t ts32;
} uts;
};
swapStruct(x.ues.es64);
}
+ const uint32_t x86_THREAD_STATE32_COUNT =
+ sizeof(x86_thread_state32_t) / sizeof(uint32_t);
+
const uint32_t x86_THREAD_STATE64_COUNT =
sizeof(x86_thread_state64_t) / sizeof(uint32_t);
const uint32_t x86_FLOAT_STATE64_COUNT =
sys::swapByteOrder(count);
state += sizeof(uint32_t);
- if (cputype == MachO::CPU_TYPE_X86_64) {
+ if (cputype == MachO::CPU_TYPE_I386) {
+ if (flavor == MachO::x86_THREAD_STATE32) {
+ if (count != MachO::x86_THREAD_STATE32_COUNT)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " count not x86_THREAD_STATE32_COUNT for "
+ "flavor number " + Twine(nflavor) + " which is "
+ "a x86_THREAD_STATE32 flavor in " + CmdName +
+ " command");
+ if (state + sizeof(MachO::x86_thread_state32_t) > end)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " x86_THREAD_STATE32 extends past end of "
+ "command in " + CmdName + " command");
+ state += sizeof(MachO::x86_thread_state32_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_X86_64) {
if (flavor == MachO::x86_THREAD_STATE64) {
if (count != MachO::x86_THREAD_STATE64_COUNT)
return malformedError("load command " + Twine(LoadCommandIndex) +
outs() << " reserved6 " << r.reserved6 << "\n";
}
+static void Print_x86_thread_state32_t(MachO::x86_thread_state32_t &cpu32) {
+ outs() << "\t eax " << format("0x%08" PRIx32, cpu32.eax);
+ outs() << " ebx " << format("0x%08" PRIx32, cpu32.ebx);
+ outs() << " ecx " << format("0x%08" PRIx32, cpu32.ecx);
+ outs() << " edx " << format("0x%08" PRIx32, cpu32.edx) << "\n";
+ outs() << "\t edi " << format("0x%08" PRIx32, cpu32.edi);
+ outs() << " esi " << format("0x%08" PRIx32, cpu32.esi);
+ outs() << " ebp " << format("0x%08" PRIx32, cpu32.ebp);
+ outs() << " esp " << format("0x%08" PRIx32, cpu32.esp) << "\n";
+ outs() << "\t ss " << format("0x%08" PRIx32, cpu32.ss);
+ outs() << " eflags " << format("0x%08" PRIx32, cpu32.eflags);
+ outs() << " eip " << format("0x%08" PRIx32, cpu32.eip);
+ outs() << " cs " << format("0x%08" PRIx32, cpu32.cs) << "\n";
+ outs() << "\t ds " << format("0x%08" PRIx32, cpu32.ds);
+ outs() << " es " << format("0x%08" PRIx32, cpu32.es);
+ outs() << " fs " << format("0x%08" PRIx32, cpu32.fs);
+ outs() << " gs " << format("0x%08" PRIx32, cpu32.gs) << "\n";
+}
+
static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
outs() << " rax " << format("0x%016" PRIx64, cpu64.rax);
outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
const char *begin = Ptr + sizeof(struct MachO::thread_command);
const char *end = Ptr + t.cmdsize;
uint32_t flavor, count, left;
- if (cputype == MachO::CPU_TYPE_X86_64) {
+ if (cputype == MachO::CPU_TYPE_I386) {
+ 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::x86_THREAD_STATE32) {
+ outs() << " flavor i386_THREAD_STATE\n";
+ if (count == MachO::x86_THREAD_STATE32_COUNT)
+ outs() << " count i386_THREAD_STATE_COUNT\n";
+ else
+ outs() << " count " << count
+ << " (not x86_THREAD_STATE32_COUNT)\n";
+ MachO::x86_thread_state32_t cpu32;
+ left = end - begin;
+ if (left >= sizeof(MachO::x86_thread_state32_t)) {
+ memcpy(&cpu32, begin, sizeof(MachO::x86_thread_state32_t));
+ begin += sizeof(MachO::x86_thread_state32_t);
+ } else {
+ memset(&cpu32, '\0', sizeof(MachO::x86_thread_state32_t));
+ memcpy(&cpu32, begin, left);
+ begin += left;
+ }
+ if (isLittleEndian != sys::IsLittleEndianHost)
+ swapStruct(cpu32);
+ Print_x86_thread_state32_t(cpu32);
+ } else if (flavor == MachO::x86_THREAD_STATE) {
+ outs() << " flavor x86_THREAD_STATE\n";
+ if (count == MachO::x86_THREAD_STATE_COUNT)
+ outs() << " count x86_THREAD_STATE_COUNT\n";
+ else
+ outs() << " count " << count
+ << " (not x86_THREAD_STATE_COUNT)\n";
+ struct MachO::x86_thread_state_t ts;
+ left = end - begin;
+ if (left >= sizeof(MachO::x86_thread_state_t)) {
+ memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
+ begin += sizeof(MachO::x86_thread_state_t);
+ } else {
+ memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
+ memcpy(&ts, begin, left);
+ begin += left;
+ }
+ if (isLittleEndian != sys::IsLittleEndianHost)
+ swapStruct(ts);
+ if (ts.tsh.flavor == MachO::x86_THREAD_STATE32) {
+ outs() << "\t tsh.flavor x86_THREAD_STATE32 ";
+ if (ts.tsh.count == MachO::x86_THREAD_STATE32_COUNT)
+ outs() << "tsh.count x86_THREAD_STATE32_COUNT\n";
+ else
+ outs() << "tsh.count " << ts.tsh.count
+ << " (not x86_THREAD_STATE32_COUNT\n";
+ Print_x86_thread_state32_t(ts.uts.ts32);
+ } else {
+ outs() << "\t tsh.flavor " << ts.tsh.flavor << " tsh.count "
+ << ts.tsh.count << "\n";
+ }
+ } else {
+ outs() << " flavor " << flavor << " (unknown)\n";
+ outs() << " count " << count << "\n";
+ outs() << " state (unknown)\n";
+ begin += count * sizeof(uint32_t);
+ }
+ }
+ } else if (cputype == MachO::CPU_TYPE_X86_64) {
while (begin < end) {
if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
memcpy((char *)&flavor, begin, sizeof(uint32_t));