[Lldb-commits] [lldb] r131834 - in /lldb/trunk: include/lldb/Core/Address.h source/Core/Address.cpp source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp tools/debugserver/source/RNBRemote.cpp

Greg Clayton gclayton at apple.com
Sat May 21 21:32:55 PDT 2011


Author: gclayton
Date: Sat May 21 23:32:55 2011
New Revision: 131834

URL: http://llvm.org/viewvc/llvm-project?rev=131834&view=rev
Log:
Added functions to lldb_private::Address to set an address from a load address
and set the address as an opcode address or as a callable address. This is
needed in various places in the thread plans to make sure that addresses that
might be found in symbols or runtime might already have extra bits set (ARM/Thumb).
The new functions are:

bool
Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target);

bool
Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target);

SetCallableLoadAddress will initialize a section offset address if it can,
and if so it might possibly set some bits in the address to make the address
callable (bit zero might get set for ARM for Thumb functions).

SetOpcodeLoadAddress will initialize a section offset address using the
specified target and it will strip any special address bits if needed 
depending on the target.

Fixed the ABIMacOSX_arm::GetArgumentValues() function to require arguments
1-4 to be in the needed registers (previously this would incorrectly fallback
to the stack) and return false if unable to get the register values. The
function was also modified to first look for the generic argument registers
and then fall back to finding the registers by name.

Fixed the objective trampoline handler to use the new Address::SetOpcodeLoadAddress
function when needed to avoid address mismatches when trying to complete 
steps into objective C methods. Make similar fixes inside the
AppleThreadPlanStepThroughObjCTrampoline::ShouldStop() function.

Modified ProcessGDBRemote::BuildDynamicRegisterInfo(...) to be able to deal with
the new generic argument registers.

Modified RNBRemote::HandlePacket_qRegisterInfo() to handle the new generic
argument registers on the debugserver side.

Modified DNBArchMachARM::NumSupportedHardwareBreakpoints() to be able to 
detect how many hardware breakpoint registers there are using a darwin sysctl.
Did the same for hardware watchpoints in 
DNBArchMachARM::NumSupportedHardwareWatchpoints().



Modified:
    lldb/trunk/include/lldb/Core/Address.h
    lldb/trunk/source/Core/Address.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp

Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Sat May 21 23:32:55 2011
@@ -419,6 +419,12 @@
     //------------------------------------------------------------------
     bool
     SetLoadAddress (lldb::addr_t load_addr, Target *target);
+    
+    bool
+    SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target);
+
+    bool
+    SetCallableLoadAddress (lldb::addr_t load_addr, Target *target);
 
     //------------------------------------------------------------------
     /// Get accessor for the module for this address.

Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Sat May 21 23:32:55 2011
@@ -334,6 +334,43 @@
     return code_addr;
 }
 
+bool
+Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target)
+{
+    if (SetLoadAddress (load_addr, target))
+    {
+        switch (target->GetArchitecture().GetMachine())
+        {
+            case llvm::Triple::arm:
+            case llvm::Triple::thumb:
+                // Check if bit zero it no set?
+                if ((m_offset & 1ull) == 0)
+                {
+                    // Bit zero isn't set, check if the address is a multiple of 2?
+                    if (m_offset & 2ull)
+                    {
+                        // The address is a multiple of 2 so it must be thumb, set bit zero
+                        m_offset |= 1ull;
+                    }
+                    else if (GetAddressClass() == eAddressClassCodeAlternateISA)
+                    {
+                        // We checked the address and the address claims to be the alternate ISA
+                        // which means thumb, so set bit zero.
+                        m_offset |= 1ull;
+                    }
+                }
+                break;
+                
+            default:
+                break;
+        }
+        return true;
+    }
+    return false;
+}
+
+
+
 addr_t
 Address::GetOpcodeLoadAddress (Target *target) const
 {
@@ -357,6 +394,27 @@
 }
 
 bool
+Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target)
+{
+    if (SetLoadAddress (load_addr, target))
+    {
+        switch (target->GetArchitecture().GetMachine())
+        {
+            case llvm::Triple::arm:
+            case llvm::Triple::thumb:
+                // Make sure bit zero is clear
+                m_offset &= ~(1ull);
+                break;
+                
+            default:
+                break;
+        }
+        return true;
+    }
+    return false;
+}
+
+bool
 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
 {
     // If the section was NULL, only load address is going to work.

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Sat May 21 23:32:55 2011
@@ -194,8 +194,6 @@
     if (!reg_ctx)
         return false;
         
-    bool arg_regs_exceeded = false;
-    
     addr_t sp = reg_ctx->GetSP(0);
     
     if (!sp)
@@ -231,16 +229,29 @@
             
             if (bit_width <= (thread.GetProcess().GetAddressByteSize() * 8))
             {
-                if (!arg_regs_exceeded)
+                if (value_idx < 4)
                 {
+                    // Arguments 1-4 are in r0-r3...
+                    const RegisterInfo *arg_reg_info = NULL;
+                    // Search by generic ID first, then fall back to by name
                     uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
-                    if (arg_reg_num == LLDB_INVALID_REGNUM)
+                    if (arg_reg_num != LLDB_INVALID_REGNUM)
                     {
-                        arg_regs_exceeded = true;
+                        arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
                     }
                     else
                     {
-                        const RegisterInfo *arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+                        switch (value_idx)
+                        {
+                            case 0: arg_reg_info = reg_ctx->GetRegisterInfoByName("r0"); break;
+                            case 1: arg_reg_info = reg_ctx->GetRegisterInfoByName("r1"); break;
+                            case 2: arg_reg_info = reg_ctx->GetRegisterInfoByName("r2"); break;
+                            case 3: arg_reg_info = reg_ctx->GetRegisterInfoByName("r3"); break;
+                        }
+                    }
+
+                    if (arg_reg_info)
+                    {
                         RegisterValue reg_value;
                         
                         if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
@@ -251,37 +262,36 @@
                                 return false;
                             continue;
                         }
-                        else
-                        {
-                            return false;
-                        }
                     }
+                    return false;
                 }
-                
-                
-                const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
-                if (arg_byte_size <= sizeof(uint64_t))
+                else
                 {
-                    uint8_t arg_data[sizeof(uint64_t)];
-                    Error error;
-                    thread.GetProcess().ReadMemory(sp, arg_data, sizeof(arg_data), error);
-                    DataExtractor arg_data_extractor (arg_data, sizeof(arg_data), 
-                                                      thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(), 
-                                                      thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
-                    uint32_t offset = 0;
-                    if (arg_byte_size <= 4)
-                        value->GetScalar() = arg_data_extractor.GetMaxU32 (&offset, arg_byte_size);
-                    else if (arg_byte_size <= 8)
-                        value->GetScalar() = arg_data_extractor.GetMaxU64 (&offset, arg_byte_size);
-                    else
-                        return false;
+                    // Arguments 5 on up are on the stack
+                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
+                    if (arg_byte_size <= sizeof(uint64_t))
+                    {
+                        uint8_t arg_data[sizeof(uint64_t)];
+                        Error error;
+                        thread.GetProcess().ReadMemory(sp, arg_data, sizeof(arg_data), error);
+                        DataExtractor arg_data_extractor (arg_data, sizeof(arg_data), 
+                                                          thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(), 
+                                                          thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
+                        uint32_t offset = 0;
+                        if (arg_byte_size <= 4)
+                            value->GetScalar() = arg_data_extractor.GetMaxU32 (&offset, arg_byte_size);
+                        else if (arg_byte_size <= 8)
+                            value->GetScalar() = arg_data_extractor.GetMaxU64 (&offset, arg_byte_size);
+                        else
+                            return false;
 
-                    if (offset == 0 || offset == UINT32_MAX)
-                        return false;
+                        if (offset == 0 || offset == UINT32_MAX)
+                            return false;
 
-                    if (is_signed)
-                        value->GetScalar().SignExtend (bit_width);
-                    sp += arg_byte_size;
+                        if (is_signed)
+                            value->GetScalar().SignExtend (bit_width);
+                        sp += arg_byte_size;
+                    }
                 }
             }
         }

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Sat May 21 23:32:55 2011
@@ -562,7 +562,7 @@
             // Problem is we also need to lookup the dispatch function.  For now we could have a side table of stret & non-stret
             // dispatch functions.  If that's as complex as it gets, we're fine.
             
-            lldb::addr_t sym_addr = msgSend_symbol->GetValue().GetLoadAddress(target);
+            lldb::addr_t sym_addr = msgSend_symbol->GetValue().GetOpcodeLoadAddress(target);
             
             m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i));
         }
@@ -854,7 +854,7 @@
                 flag_value.GetScalar() = 1;
             else
                 flag_value.GetScalar() = 0;  // FIXME - Set to 0 when debugging is done.
-                 dispatch_values.PushValue (flag_value);
+            dispatch_values.PushValue (flag_value);
 
             // Now, if we haven't already, make and insert the function as a ClangUtilityFunction, and make and insert 
             // it's runner ClangFunction.
@@ -880,7 +880,7 @@
                         if (sc.symbol != NULL)
                             impl_code_address = sc.symbol->GetValue();
                             
-                        //lldb::addr_t addr = impl_code_address.GetLoadAddress (exe_ctx.target);
+                        //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.target);
                         //printf ("Getting address for our_utility_function: 0x%llx.\n", addr);
                     }
                     else

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Sat May 21 23:32:55 2011
@@ -74,7 +74,7 @@
 
 void
 AppleThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s,
-                lldb::DescriptionLevel level)
+                                                          lldb::DescriptionLevel level)
 {
     if (level == lldb::eDescriptionLevelBrief)
         s->Printf("Step through ObjC trampoline");
@@ -119,7 +119,8 @@
             m_impl_function->FetchFunctionResults (exc_context, m_args_addr, target_addr_value);
             m_impl_function->DeallocateFunctionResults(exc_context, m_args_addr);
             lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
-            Address target_address(NULL, target_addr);
+            Address target_so_addr;
+            target_so_addr.SetOpcodeLoadAddress(target_addr, exc_context.target);
             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
             if (target_addr == 0)
             {
@@ -153,11 +154,11 @@
             assert (objc_runtime != NULL);
             objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr);
             if (log)
-                log->Printf("Adding {0x%llx, 0x%llx} = 0x%llx to cache.", m_isa_addr, m_sel_addr, target_addr);
+                log->Printf("Adding {isa-addr=0x%llx, sel-addr=0x%llx} = addr=0x%llx to cache.", m_isa_addr, m_sel_addr, target_addr);
 
             // Extract the target address from the value:
             
-            m_run_to_sp.reset(new ThreadPlanRunToAddress(m_thread, target_address, m_stop_others));
+            m_run_to_sp.reset(new ThreadPlanRunToAddress(m_thread, target_so_addr, m_stop_others));
             m_thread.QueueThreadPlan(m_run_to_sp, false);
             m_run_to_sp->SetPrivate(true);
             return false;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sat May 21 23:32:55 2011
@@ -302,6 +302,23 @@
                             reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
                         else if (value.compare("flags") == 0)
                             reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+                        else if (value.find("arg") == 0)
+                        {
+                            if (value.size() == 4)
+                            {
+                                switch (value[3])
+                                {
+                                    case '1': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1; break;
+                                    case '2': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2; break;
+                                    case '3': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3; break;
+                                    case '4': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4; break;
+                                    case '5': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5; break;
+                                    case '6': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6; break;
+                                    case '7': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7; break;
+                                    case '8': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8; break;
+                                }
+                            }
+                        }
                     }
                 }
 

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=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp Sat May 21 23:32:55 2011
@@ -2058,39 +2058,48 @@
         // Set this to zero in case we can't tell if there are any HW breakpoints
         g_num_supported_hw_breakpoints = 0;
 
-        // Read the DBGDIDR to get the number of available hardware breakpoints
-        // However, in some of our current armv7 processors, hardware
-        // breakpoints/watchpoints were not properly connected. So detect those
-        // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
-        // field to distinguish CPU architectures. This is a hack until we can
-        // get <rdar://problem/6372672> fixed, at which point we will switch to
-        // using a different sysctl string that will tell us how many BRPs
-        // are available to us directly without having to read DBGDIDR.
-        uint32_t register_DBGDIDR;
-
-        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
-        uint32_t numBRPs = bits(register_DBGDIDR, 27, 24);
-        // Zero is reserved for the BRP count, so don't increment it if it is zero
-        if (numBRPs > 0)
-            numBRPs++;
-        DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs);
-
-        if (numBRPs > 0)
-        {
-            uint32_t cpusubtype;
-            size_t len;
-            len = sizeof(cpusubtype);
-            // TODO: remove this hack and change to using hw.optional.xx when implmented
-            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
-            {
-                DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
-                if (cpusubtype == CPU_SUBTYPE_ARM_V7)
-                    DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)");
-                else
-                    g_num_supported_hw_breakpoints = numBRPs;
+        size_t len;
+        uint32_t n = 0;
+        len = sizeof (n);
+        if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0)
+        {
+            g_num_supported_hw_breakpoints = n;
+            DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n);
+        }
+        else
+        {
+            // Read the DBGDIDR to get the number of available hardware breakpoints
+            // However, in some of our current armv7 processors, hardware
+            // breakpoints/watchpoints were not properly connected. So detect those
+            // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
+            // field to distinguish CPU architectures. This is a hack until we can
+            // get <rdar://problem/6372672> fixed, at which point we will switch to
+            // using a different sysctl string that will tell us how many BRPs
+            // are available to us directly without having to read DBGDIDR.
+            uint32_t register_DBGDIDR;
+
+            asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
+            uint32_t numBRPs = bits(register_DBGDIDR, 27, 24);
+            // Zero is reserved for the BRP count, so don't increment it if it is zero
+            if (numBRPs > 0)
+                numBRPs++;
+            DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs);
+
+            if (numBRPs > 0)
+            {
+                uint32_t cpusubtype;
+                len = sizeof(cpusubtype);
+                // TODO: remove this hack and change to using hw.optional.xx when implmented
+                if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
+                {
+                    DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=%d", cpusubtype);
+                    if (cpusubtype == CPU_SUBTYPE_ARM_V7)
+                        DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)");
+                    else
+                        g_num_supported_hw_breakpoints = numBRPs;
+                }
             }
         }
-
     }
     return g_num_supported_hw_breakpoints;
 }
@@ -2106,37 +2115,49 @@
     {
         // Set this to zero in case we can't tell if there are any HW breakpoints
         g_num_supported_hw_watchpoints = 0;
-        // Read the DBGDIDR to get the number of available hardware breakpoints
-        // However, in some of our current armv7 processors, hardware
-        // breakpoints/watchpoints were not properly connected. So detect those
-        // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
-        // field to distinguish CPU architectures. This is a hack until we can
-        // get <rdar://problem/6372672> fixed, at which point we will switch to
-        // using a different sysctl string that will tell us how many WRPs
-        // are available to us directly without having to read DBGDIDR.
-
-        uint32_t register_DBGDIDR;
-        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
-        uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1;
-        DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs);
-
-        if (numWRPs > 0)
-        {
-            uint32_t cpusubtype;
-            size_t len;
-            len = sizeof(cpusubtype);
-            // TODO: remove this hack and change to using hw.optional.xx when implmented
-            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
-            {
-                DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
-
-                if (cpusubtype == CPU_SUBTYPE_ARM_V7)
-                    DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)");
-                else
-                    g_num_supported_hw_watchpoints = numWRPs;
+        
+        
+        size_t len;
+        uint32_t n = 0;
+        len = sizeof (n);
+        if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
+        {
+            g_num_supported_hw_watchpoints = n;
+            DNBLogThreadedIf(LOG_THREAD, "hw.optional.watchpoint=%u", n);
+        }
+        else
+        {
+            // Read the DBGDIDR to get the number of available hardware breakpoints
+            // However, in some of our current armv7 processors, hardware
+            // breakpoints/watchpoints were not properly connected. So detect those
+            // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
+            // field to distinguish CPU architectures. This is a hack until we can
+            // get <rdar://problem/6372672> fixed, at which point we will switch to
+            // using a different sysctl string that will tell us how many WRPs
+            // are available to us directly without having to read DBGDIDR.
+
+            uint32_t register_DBGDIDR;
+            asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
+            uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1;
+            DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs);
+
+            if (numWRPs > 0)
+            {
+                uint32_t cpusubtype;
+                size_t len;
+                len = sizeof(cpusubtype);
+                // TODO: remove this hack and change to using hw.optional.xx when implmented
+                if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
+                {
+                    DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
+
+                    if (cpusubtype == CPU_SUBTYPE_ARM_V7)
+                        DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)");
+                    else
+                        g_num_supported_hw_watchpoints = numWRPs;
+                }
             }
         }
-
     }
     return g_num_supported_hw_watchpoints;
 }

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=131834&r1=131833&r2=131834&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Sat May 21 23:32:55 2011
@@ -1453,6 +1453,14 @@
             case GENERIC_REGNUM_SP:     ostrm << "generic:sp;"; break;
             case GENERIC_REGNUM_RA:     ostrm << "generic:ra;"; break;
             case GENERIC_REGNUM_FLAGS:  ostrm << "generic:flags;"; break;
+            case GENERIC_REGNUM_ARG1:   ostrm << "generic:arg1;"; break;
+            case GENERIC_REGNUM_ARG2:   ostrm << "generic:arg2;"; break;
+            case GENERIC_REGNUM_ARG3:   ostrm << "generic:arg3;"; break;
+            case GENERIC_REGNUM_ARG4:   ostrm << "generic:arg4;"; break;
+            case GENERIC_REGNUM_ARG5:   ostrm << "generic:arg5;"; break;
+            case GENERIC_REGNUM_ARG6:   ostrm << "generic:arg6;"; break;
+            case GENERIC_REGNUM_ARG7:   ostrm << "generic:arg7;"; break;
+            case GENERIC_REGNUM_ARG8:   ostrm << "generic:arg8;"; break;
             default: break;
         }
 





More information about the lldb-commits mailing list