[llvm] r285967 - Add support for the ARM_THREAD_STATE64 and

Kevin Enderby via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 3 13:51:28 PDT 2016


Author: enderby
Date: Thu Nov  3 15:51:28 2016
New Revision: 285967

URL: http://llvm.org/viewvc/llvm-project?rev=285967&view=rev
Log:
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

Added:
    llvm/trunk/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64   (with props)
    llvm/trunk/test/tools/llvm-objdump/AArch64/macho-print-thread.test
Modified:
    llvm/trunk/include/llvm/Support/MachO.h
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/tools/llvm-objdump/MachODump.cpp

Modified: llvm/trunk/include/llvm/Support/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MachO.h?rev=285967&r1=285966&r2=285967&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/MachO.h (original)
+++ llvm/trunk/include/llvm/Support/MachO.h Thu Nov  3 15:51:28 2016
@@ -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;

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=285967&r1=285966&r2=285967&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Nov  3 15:51:28 2016
@@ -970,6 +970,25 @@ static Error checkThreadCommand(const Ma
                               "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)

Added: llvm/trunk/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64?rev=285967&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-aarch64
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/AArch64/macho-print-thread.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/AArch64/macho-print-thread.test?rev=285967&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/AArch64/macho-print-thread.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/AArch64/macho-print-thread.test Thu Nov  3 15:51:28 2016
@@ -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

Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=285967&r1=285966&r2=285967&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Thu Nov  3 15:51:28 2016
@@ -8656,6 +8656,43 @@ static void Print_arm_thread_state32_t(M
   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)
@@ -8855,6 +8892,53 @@ static void PrintThreadCommand(MachO::th
       } 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_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);
       }




More information about the llvm-commits mailing list