[Lldb-commits] [lldb] r131588 - in /lldb/trunk: include/lldb/Core/Address.h source/Core/Address.cpp source/Expression/ClangExpressionDeclMap.cpp source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp

Greg Clayton gclayton at apple.com
Wed May 18 15:01:49 PDT 2011


Author: gclayton
Date: Wed May 18 17:01:49 2011
New Revision: 131588

URL: http://llvm.org/viewvc/llvm-project?rev=131588&view=rev
Log:
Added a function to lldb_private::Address:

        addr_t
        Address::GetCallableLoadAddress (Target *target) const;
        
This will resolve the load address in the Address object and optionally
decorate the address up to be able to be called. For all non ARM targets, this
just essentially returns the result of "Address::GetLoadAddress (target)". But
for ARM targets, it checks if the address is Thumb, and if so, it returns
an address with bit zero set to indicate a mode switch to Thumb. This is how
we need function pointers to be for return addresses and when resolving 
function addresses for the JIT. It is also nice to centralize this in one spot
to avoid having multiple copies of this code.


Modified:
    lldb/trunk/include/lldb/Core/Address.h
    lldb/trunk/source/Core/Address.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp

Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=131588&r1=131587&r2=131588&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Wed May 18 17:01:49 2011
@@ -280,6 +280,23 @@
     //------------------------------------------------------------------
     lldb::addr_t
     GetLoadAddress (Target *target) const;
+    
+    //------------------------------------------------------------------
+    /// Get the load address as a callable code load address.
+    ///
+    /// This function will first resolve its address to a load address.
+    /// Then, if the address turns out to be in code address, return the
+    /// load address that would be required to call or return to. The
+    /// address might have extra bits set (bit zero will be set to Thumb
+    /// functions for an ARM target) that are required when changing the
+    /// program counter to setting a return address.
+    ///
+    /// @return
+    ///     The valid load virtual address, or LLDB_INVALID_ADDRESS if
+    ///     the address is currently not loaded.
+    //------------------------------------------------------------------
+    lldb::addr_t
+    GetCallableLoadAddress (Target *target) const;
 
     //------------------------------------------------------------------
     /// Get the section relative offset value.

Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=131588&r1=131587&r2=131588&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Wed May 18 17:01:49 2011
@@ -15,6 +15,8 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
+#include "llvm/ADT/Triple.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -294,6 +296,42 @@
     return LLDB_INVALID_ADDRESS;
 }
 
+addr_t
+Address::GetCallableLoadAddress (Target *target) const
+{
+    addr_t code_addr = GetLoadAddress (target);
+    
+    if (m_section && code_addr != LLDB_INVALID_ADDRESS)
+    {
+        switch (target->GetArchitecture().GetMachine())
+        {
+            case llvm::Triple::arm:
+            case llvm::Triple::thumb:
+                // Check if bit zero it no set?
+                if ((code_addr & 1ull) == 0)
+                {
+                    // Bit zero isn't set, check if the address is a multiple of 2?
+                    if (code_addr & 2ull)
+                    {
+                        // The address is a multiple of 2 so it must be thumb, set bit zero
+                        code_addr |= 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.
+                        code_addr |= 1ull;
+                    }
+                }
+                break;
+                
+            default:
+                break;
+        }
+    }
+    return code_addr;
+}
+
 bool
 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
 {

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=131588&r1=131587&r2=131588&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Wed May 18 17:01:49 2011
@@ -495,7 +495,7 @@
 ClangExpressionDeclMap::GetFunctionAddress 
 (
     const ConstString &name,
-    uint64_t &ptr
+    uint64_t &func_addr
 )
 {
     assert (m_parser_vars.get());
@@ -543,17 +543,17 @@
     SymbolContext sym_ctx;
     sc_list.GetContextAtIndex(0, sym_ctx);
     
-    const Address *fun_address;
+    const Address *func_so_addr = NULL;
     
     if (sym_ctx.function)
-        fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
+        func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress();
     else if (sym_ctx.symbol)
-        fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
+        func_so_addr = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
     else
         return false;
     
-    ptr = fun_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
-    
+    func_addr = func_so_addr->GetCallableLoadAddress (m_parser_vars->m_exe_ctx->target);
+
     return true;
 }
 
@@ -577,7 +577,7 @@
     
     const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
     
-    ptr = sym_address->GetLoadAddress(&target);
+    ptr = sym_address->GetCallableLoadAddress(&target);
     
     return true;
 }
@@ -2294,9 +2294,9 @@
 }
 
 void
-ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
-                                       Function* fun,
-                                       Symbol* symbol)
+ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
+                                        Function* fun,
+                                        Symbol* symbol)
 {
     assert (m_parser_vars.get());
     
@@ -2350,7 +2350,7 @@
         return;
     }
     
-    lldb::addr_t load_addr = fun_address->GetLoadAddress(m_parser_vars->m_exe_ctx->target);
+    lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(m_parser_vars->m_exe_ctx->target);
     fun_location->SetValueType(Value::eValueTypeLoadAddress);
     fun_location->GetScalar() = load_addr;
     

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=131588&r1=131587&r2=131588&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed May 18 17:01:49 2011
@@ -126,24 +126,16 @@
         }
     }
     
-    // Figure out if our return address is ARM or Thumb. We assume if we don't
-    // know about an address then it is ARM code.
 
     Target *target = &thread.GetProcess().GetTarget();
     Address so_addr;
-    bool ra_is_thumb = false;
-    if (return_addr & 3)
-        ra_is_thumb = true;
-    else if (so_addr.SetLoadAddress (return_addr, target))
-        ra_is_thumb = so_addr.GetAddressClass() == eAddressClassCodeAlternateISA;
-
-    // Set our clear bit zero for the return address if needed. We should never
-    // need to clear bit zero since the return address will either have bit zero
-    // or bit one (a thumb instruction on a two byte boundary) already set, or
-    // it won't and it will need it.
-    if (ra_is_thumb)
-        return_addr |= 1u;
-        
+
+    // Figure out if our return address is ARM or Thumb by using the 
+    // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
+    // thumb-ness and set the correct address bits for us.
+    so_addr.SetLoadAddress (return_addr, target);
+    return_addr = so_addr.GetCallableLoadAddress (target);
+
     // Set "lr" to the return address
     if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
         return false;
@@ -152,15 +144,10 @@
     if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
         return false;
     
-    bool pc_is_thumb = false;
-
     // If bit zero or 1 is set, this must be a thumb function, no need to figure
     // this out from the symbols.
-    if (function_addr & 3)
-        pc_is_thumb = true;
-    else if (so_addr.SetLoadAddress (function_addr, target))
-        pc_is_thumb = so_addr.GetAddressClass() == eAddressClassCodeAlternateISA;
-
+    so_addr.SetLoadAddress (function_addr, target);
+    function_addr = so_addr.GetCallableLoadAddress (target);
     
     const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
     const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
@@ -168,7 +155,7 @@
     // Make a new CPSR and mask out any Thumb IT (if/then) bits
     uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
     // If bit zero or 1 is set, this must be thumb...
-    if (pc_is_thumb)
+    if (function_addr & 1ull)
         new_cpsr |= MASK_CPSR_T;    // Set T bit in CPSR
     else
         new_cpsr &= ~MASK_CPSR_T;   // Clear T bit in CPSR
@@ -179,7 +166,7 @@
             return false;
     }
 
-    function_addr &= ~1u;   // clear bit zero since the CPSR will take care of the mode for us
+    function_addr &= ~1ull;   // clear bit zero since the CPSR will take care of the mode for us
     
     // Set "pc" to the address requested
     if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, function_addr))





More information about the lldb-commits mailing list