[Lldb-commits] [lldb] r226244 - Fixes to DNBArchImpl in debugserver to correctly get/set

Jason Molenda jmolenda at apple.com
Thu Jan 15 18:31:35 PST 2015


Author: jmolenda
Date: Thu Jan 15 20:31:35 2015
New Revision: 226244

URL: http://llvm.org/viewvc/llvm-project?rev=226244&view=rev
Log:
Fixes to DNBArchImpl in debugserver to correctly get/set
the register state when debugging AArch32 programs (armv7
programs running on an armv8 processor).  Most notably,
there is no "fpscr" register in the register context -
there is an fpsr and an fpcr.

Also fix a bug where the floating point values could not
be written in armv7 processes.
<rdar://problem/18977767> 

Modified:
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp?rev=226244&r1=226243&r2=226244&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp Thu Jan 15 20:31:35 2015
@@ -234,9 +234,62 @@ DNBArchMachARM::GetVFPState(bool force)
     if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
         return KERN_SUCCESS;
 
+    kern_return_t kret;
+
+#if defined (__arm64__) || defined (__aarch64__)
+    // Read the registers from our thread
+    mach_msg_type_number_t count = ARM_NEON_STATE_COUNT;
+    kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_NEON_STATE, (thread_state_t)&m_state.context.vfp, &count);
+    if (DNBLogEnabledForAny (LOG_THREAD))
+    {
+        DNBLogThreaded("thread_get_state(0x%4.4x, %u, &vfp, %u) => 0x%8.8x (count = %u) regs"
+                       "\n   q0  = 0x%16.16llx%16.16llx"
+                       "\n   q1  = 0x%16.16llx%16.16llx"
+                       "\n   q2  = 0x%16.16llx%16.16llx"
+                       "\n   q3  = 0x%16.16llx%16.16llx"
+                       "\n   q4  = 0x%16.16llx%16.16llx"
+                       "\n   q5  = 0x%16.16llx%16.16llx"
+                       "\n   q6  = 0x%16.16llx%16.16llx"
+                       "\n   q7  = 0x%16.16llx%16.16llx"
+                       "\n   q8  = 0x%16.16llx%16.16llx"
+                       "\n   q9  = 0x%16.16llx%16.16llx"
+                       "\n   q10 = 0x%16.16llx%16.16llx"
+                       "\n   q11 = 0x%16.16llx%16.16llx"
+                       "\n   q12 = 0x%16.16llx%16.16llx"
+                       "\n   q13 = 0x%16.16llx%16.16llx"
+                       "\n   q14 = 0x%16.16llx%16.16llx"
+                       "\n   q15 = 0x%16.16llx%16.16llx"
+                       "\n  fpsr = 0x%8.8x"
+                       "\n  fpcr = 0x%8.8x\n\n",
+                       m_thread->MachPortNumber(),
+                       ARM_NEON_STATE,
+                       ARM_NEON_STATE_COUNT,
+                       kret,
+                       count,
+                       ((uint64_t *)&m_state.context.vfp.__v[0])[0] , ((uint64_t *)&m_state.context.vfp.__v[0])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[1])[0] , ((uint64_t *)&m_state.context.vfp.__v[1])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[2])[0] , ((uint64_t *)&m_state.context.vfp.__v[2])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[3])[0] , ((uint64_t *)&m_state.context.vfp.__v[3])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[4])[0] , ((uint64_t *)&m_state.context.vfp.__v[4])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[5])[0] , ((uint64_t *)&m_state.context.vfp.__v[5])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[6])[0] , ((uint64_t *)&m_state.context.vfp.__v[6])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[7])[0] , ((uint64_t *)&m_state.context.vfp.__v[7])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[8])[0] , ((uint64_t *)&m_state.context.vfp.__v[8])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[9])[0] , ((uint64_t *)&m_state.context.vfp.__v[9])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[10])[0], ((uint64_t *)&m_state.context.vfp.__v[10])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[11])[0], ((uint64_t *)&m_state.context.vfp.__v[11])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[12])[0], ((uint64_t *)&m_state.context.vfp.__v[12])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[13])[0], ((uint64_t *)&m_state.context.vfp.__v[13])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[14])[0], ((uint64_t *)&m_state.context.vfp.__v[14])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[15])[0], ((uint64_t *)&m_state.context.vfp.__v[15])[1],
+                       m_state.context.vfp.__fpsr,
+                       m_state.context.vfp.__fpcr);
+
+    }
+#else
     // Read the registers from our thread
     mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
-    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
+    kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
     if (DNBLogEnabledForAny (LOG_THREAD))
     {
         uint32_t *r = &m_state.context.vfp.__r[0];
@@ -255,6 +308,7 @@ DNBArchMachARM::GetVFPState(bool force)
         DNBLogThreaded("  s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x s53=%8.8x s54=%8.8x s55=%8.8x",r[48],r[49],r[50],r[51],r[52],r[53],r[54],r[55]);
         DNBLogThreaded("  s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",r[56],r[57],r[58],r[59],r[60],r[61],r[62],r[63],r[64]);
     }
+#endif
     m_state.SetError(set, Read, kret);
     return kret;
 }
@@ -322,7 +376,64 @@ kern_return_t
 DNBArchMachARM::SetVFPState()
 {
     int set = e_regSetVFP;
-    kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
+    kern_return_t kret;
+    mach_msg_type_number_t count;
+
+#if defined (__arm64__) || defined (__aarch64__)
+    count = ARM_NEON_STATE_COUNT;
+    kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_NEON_STATE, (thread_state_t)&m_state.context.vfp, count);
+#else
+    count = ARM_VFP_STATE_COUNT;
+    kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, count);
+#endif
+
+#if defined (__arm64__) || defined (__aarch64__)
+    if (DNBLogEnabledForAny (LOG_THREAD))
+    {
+        DNBLogThreaded("thread_set_state(0x%4.4x, %u, &vfp, %u) => 0x%8.8x (count = %u) regs"
+                       "\n   q0  = 0x%16.16llx%16.16llx"
+                       "\n   q1  = 0x%16.16llx%16.16llx"
+                       "\n   q2  = 0x%16.16llx%16.16llx"
+                       "\n   q3  = 0x%16.16llx%16.16llx"
+                       "\n   q4  = 0x%16.16llx%16.16llx"
+                       "\n   q5  = 0x%16.16llx%16.16llx"
+                       "\n   q6  = 0x%16.16llx%16.16llx"
+                       "\n   q7  = 0x%16.16llx%16.16llx"
+                       "\n   q8  = 0x%16.16llx%16.16llx"
+                       "\n   q9  = 0x%16.16llx%16.16llx"
+                       "\n   q10 = 0x%16.16llx%16.16llx"
+                       "\n   q11 = 0x%16.16llx%16.16llx"
+                       "\n   q12 = 0x%16.16llx%16.16llx"
+                       "\n   q13 = 0x%16.16llx%16.16llx"
+                       "\n   q14 = 0x%16.16llx%16.16llx"
+                       "\n   q15 = 0x%16.16llx%16.16llx"
+                       "\n  fpsr = 0x%8.8x"
+                       "\n  fpcr = 0x%8.8x\n\n",
+                       m_thread->MachPortNumber(),
+                       ARM_NEON_STATE,
+                       ARM_NEON_STATE_COUNT,
+                       kret,
+                       count,
+                       ((uint64_t *)&m_state.context.vfp.__v[0])[0] , ((uint64_t *)&m_state.context.vfp.__v[0])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[1])[0] , ((uint64_t *)&m_state.context.vfp.__v[1])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[2])[0] , ((uint64_t *)&m_state.context.vfp.__v[2])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[3])[0] , ((uint64_t *)&m_state.context.vfp.__v[3])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[4])[0] , ((uint64_t *)&m_state.context.vfp.__v[4])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[5])[0] , ((uint64_t *)&m_state.context.vfp.__v[5])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[6])[0] , ((uint64_t *)&m_state.context.vfp.__v[6])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[7])[0] , ((uint64_t *)&m_state.context.vfp.__v[7])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[8])[0] , ((uint64_t *)&m_state.context.vfp.__v[8])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[9])[0] , ((uint64_t *)&m_state.context.vfp.__v[9])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[10])[0], ((uint64_t *)&m_state.context.vfp.__v[10])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[11])[0], ((uint64_t *)&m_state.context.vfp.__v[11])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[12])[0], ((uint64_t *)&m_state.context.vfp.__v[12])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[13])[0], ((uint64_t *)&m_state.context.vfp.__v[13])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[14])[0], ((uint64_t *)&m_state.context.vfp.__v[14])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[15])[0], ((uint64_t *)&m_state.context.vfp.__v[15])[1],
+                       m_state.context.vfp.__fpsr,
+                       m_state.context.vfp.__fpcr);
+    }
+#endif
     m_state.SetError(set, Write, kret);         // Set the current write error for this register set
     m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
     return kret;                                // Return the error code
@@ -1366,7 +1477,12 @@ enum
     vfp_q13,
     vfp_q14,
     vfp_q15,
+#if defined (__arm64__) || defined (__aarch64__)
+    vfp_fpsr,
+    vfp_fpcr,
+#else
     vfp_fpscr
+#endif
 };
 
 enum
@@ -1551,7 +1667,12 @@ DNBArchMachARM::g_vfp_registers[] =
     { DEFINE_VFP_Q_IDX (14),  NULL,           g_invalidate_q14 },
     { DEFINE_VFP_Q_IDX (15),  NULL,           g_invalidate_q15 },
 
+#if defined (__arm64__) || defined (__aarch64__)
+    { e_regSetVFP, vfp_fpsr, "fpsr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpsr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+    { e_regSetVFP, vfp_fpcr, "fpcr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpcr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
+#else
     { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
+#endif
 };
 
 // Exception registers
@@ -1654,28 +1775,55 @@ DNBArchMachARM::GetRegisterValue(int set
             // in the enumerated values for case statement below.
             if (reg >= vfp_s0 && reg <= vfp_s31)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                uint32_t *s_reg = ((uint32_t *) &m_state.context.vfp.__v[0]) + (reg - vfp_s0);
+                memcpy (&value->value.v_uint8, s_reg, 4);
+#else
                 value->value.uint32 = m_state.context.vfp.__r[reg];
+#endif
                 return true;
             }
             else if (reg >= vfp_d0 && reg <= vfp_d31)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                uint64_t *d_reg = ((uint64_t *) &m_state.context.vfp.__v[0]) + (reg - vfp_d0);
+                memcpy (&value->value.v_uint8, d_reg, 8);
+#else
                 uint32_t d_reg_idx = reg - vfp_d0;
                 uint32_t s_reg_idx = d_reg_idx * 2;
                 value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0];
                 value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1];
+#endif
                 return true;
             }
             else if (reg >= vfp_q0 && reg <= vfp_q15)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                memcpy (&value->value.v_uint8, (uint8_t *) &m_state.context.vfp.__v[reg - vfp_q0], 16);
+#else
                 uint32_t s_reg_idx = (reg - vfp_q0) * 4;
                 memcpy (&value->value.v_uint8, (uint8_t *) &m_state.context.vfp.__r[s_reg_idx], 16);
+#endif
+                return true;
+            }
+#if defined (__arm64__) || defined (__aarch64__)
+            else if (reg == vfp_fpsr)
+            {
+                value->value.uint32 = m_state.context.vfp.__fpsr;
+                return true;
+            }
+            else if (reg == vfp_fpcr)
+            {
+                value->value.uint32 = m_state.context.vfp.__fpcr;
                 return true;
             }
+#else
             else if (reg == vfp_fpscr)
             {
                 value->value.uint32 = m_state.context.vfp.__fpscr;
                 return true;
             }
+#endif
             break;
 
         case e_regSetEXC:
@@ -1750,28 +1898,55 @@ DNBArchMachARM::SetRegisterValue(int set
             // in the enumerated values for case statement below.
             if (reg >= vfp_s0 && reg <= vfp_s31)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                uint32_t *s_reg = ((uint32_t *) &m_state.context.vfp.__v[0]) + (reg - vfp_s0);
+                memcpy (s_reg, &value->value.v_uint8, 4);
+#else
                 m_state.context.vfp.__r[reg] = value->value.uint32;
+#endif
                 success = true;
             }
             else if (reg >= vfp_d0 && reg <= vfp_d31)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                uint64_t *d_reg = ((uint64_t *) &m_state.context.vfp.__v[0]) + (reg - vfp_d0);
+                memcpy (d_reg, &value->value.v_uint8, 8);
+#else
                 uint32_t d_reg_idx = reg - vfp_d0;
                 uint32_t s_reg_idx = d_reg_idx * 2;
                 m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0];
                 m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1];
+#endif
                 success = true;
             }
             else if (reg >= vfp_q0 && reg <= vfp_q15)
             {
+#if defined (__arm64__) || defined (__aarch64__)
+                memcpy ((uint8_t *) &m_state.context.vfp.__v[reg - vfp_q0], &value->value.v_uint8, 16);
+#else
                 uint32_t s_reg_idx = (reg - vfp_q0) * 4;
                 memcpy ((uint8_t *) &m_state.context.vfp.__r[s_reg_idx], &value->value.v_uint8, 16);
-                return true;
+#endif
+                success = true;
             }
+#if defined (__arm64__) || defined (__aarch64__)
+            else if (reg == vfp_fpsr)
+            {
+                m_state.context.vfp.__fpsr = value->value.uint32;
+                success = true;
+            }
+            else if (reg == vfp_fpcr)
+            {
+                m_state.context.vfp.__fpcr = value->value.uint32;
+                success = true;
+            }
+#else
             else if (reg == vfp_fpscr)
             {
                 m_state.context.vfp.__fpscr = value->value.uint32;
                 success = true;
             }
+#endif
             break;
 
         case e_regSetEXC:

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h?rev=226244&r1=226243&r2=226244&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h Thu Jan 15 20:31:35 2015
@@ -109,17 +109,14 @@ protected:
 #endif
     void                    EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, nub_addr_t *nextPC, bool *nextPCIsThumb);
 
+
     typedef enum RegisterSetTag
     {
         e_regSetALL = REGISTER_SET_ALL,
-        e_regSetGPR = ARM_THREAD_STATE,
-        e_regSetVFP = ARM_VFP_STATE,
-        e_regSetEXC = ARM_EXCEPTION_STATE,
-#if defined (ARM_DEBUG_STATE32) && (defined (__arm64__) || defined (__aarch64__))
-        e_regSetDBG = ARM_DEBUG_STATE32,
-#else
-        e_regSetDBG = ARM_DEBUG_STATE,
-#endif
+        e_regSetGPR, // ARM_THREAD_STATE
+        e_regSetVFP, // ARM_VFP_STATE (ARM_NEON_STATE if defined __arm64__)
+        e_regSetEXC, // ARM_EXCEPTION_STATE
+        e_regSetDBG, // ARM_DEBUG_STATE (ARM_DEBUG_STATE32 if defined __arm64__)
         kNumRegisterSets
     } RegisterSet;
 
@@ -131,7 +128,11 @@ protected:
     };
     
     typedef arm_thread_state_t GPR;
+#if defined (__arm64__) || defined (__aarch64__)
+    typedef arm_neon_state_t FPU;
+#else
     typedef arm_vfp_state_t FPU;
+#endif
     typedef arm_exception_state_t EXC;
 
     static const DNBRegisterInfo g_gpr_registers[];





More information about the lldb-commits mailing list