[Lldb-commits] [lldb] r180803 - <rdar://problem/13695846>

Enrico Granata egranata at apple.com
Tue Apr 30 13:45:04 PDT 2013


Author: enrico
Date: Tue Apr 30 15:45:04 2013
New Revision: 180803

URL: http://llvm.org/viewvc/llvm-project?rev=180803&view=rev
Log:
<rdar://problem/13695846>

Enabling LLDB to write to variables that are stored in registers
Previously, this would not work since the Value's Context loses the notion of the data being in a register
We now store an "original" context that comes out of DWARF parsing, and use that context's data when attempting a write


Modified:
    lldb/trunk/include/lldb/Core/Value.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectVariable.h
    lldb/trunk/source/Core/Value.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectVariable.cpp

Modified: lldb/trunk/include/lldb/Core/Value.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Value.h?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Value.h (original)
+++ lldb/trunk/include/lldb/Core/Value.h Tue Apr 30 15:45:04 2013
@@ -165,7 +165,7 @@ public:
     }
 
     RegisterInfo *
-    GetRegisterInfo();
+    GetRegisterInfo() const;
 
     Type *
     GetType();
@@ -173,6 +173,18 @@ public:
     Scalar &
     ResolveValue (ExecutionContext *exe_ctx, clang::ASTContext *ast_context);
 
+    const Scalar &
+    GetScalar() const
+    {
+        return m_value;
+    }
+    
+    const Vector &
+    GetVector() const
+    {
+        return m_vector;
+    }
+    
     Scalar &
     GetScalar()
     {

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Tue Apr 30 15:45:04 2013
@@ -794,7 +794,7 @@ public:
     virtual bool
     ResolveValue (Scalar &scalar);
     
-    const char *
+    virtual const char *
     GetLocationAsCString ();
 
     const char *
@@ -1340,6 +1340,10 @@ protected:
     virtual lldb::clang_type_t
     GetClangTypeImpl () = 0;
     
+    const char *
+    GetLocationAsCStringImpl (const Value& value,
+                              const DataExtractor& data);
+    
 private:
     //------------------------------------------------------------------
     // For ValueObject only

Modified: lldb/trunk/include/lldb/Core/ValueObjectVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectVariable.h?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectVariable.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectVariable.h Tue Apr 30 15:45:04 2013
@@ -57,7 +57,16 @@ public:
 
     virtual bool
     GetDeclaration (Declaration &decl);
+    
+    virtual const char *
+    GetLocationAsCString ();
+    
+    virtual bool
+    SetValueFromCString (const char *value_str, Error& error);
 
+    virtual bool
+    SetData (DataExtractor &data, Error &error);
+    
 protected:
     virtual bool
     UpdateValue ();
@@ -69,6 +78,7 @@ protected:
     GetClangTypeImpl ();
 
     lldb::VariableSP  m_variable_sp;  ///< The variable that this value object is based upon
+    Value m_resolved_value;           ///< The value that DWARFExpression resolves this variable to before we patch it up
 
 private:
     ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp);

Modified: lldb/trunk/source/Core/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Value.cpp?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/source/Core/Value.cpp (original)
+++ lldb/trunk/source/Core/Value.cpp Tue Apr 30 15:45:04 2013
@@ -128,7 +128,7 @@ Value::GetValueAddressType () const
 }
 
 RegisterInfo *
-Value::GetRegisterInfo()
+Value::GetRegisterInfo() const
 {
     if (m_context_type == eContextTypeRegisterInfo)
         return static_cast<RegisterInfo *> (m_context);

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Apr 30 15:45:04 2013
@@ -401,37 +401,49 @@ ValueObject::GetName() const
 const char *
 ValueObject::GetLocationAsCString ()
 {
+    return GetLocationAsCStringImpl(m_value,
+                                    m_data);
+}
+
+const char *
+ValueObject::GetLocationAsCStringImpl (const Value& value,
+                                       const DataExtractor& data)
+{
     if (UpdateValueIfNeeded(false))
     {
         if (m_location_str.empty())
         {
             StreamString sstr;
-
-            switch (m_value.GetValueType())
+            
+            Value::ValueType value_type = value.GetValueType();
+            
+            switch (value_type)
             {
             case Value::eValueTypeScalar:
             case Value::eValueTypeVector:
-                if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
+                if (value.GetContextType() == Value::eContextTypeRegisterInfo)
                 {
-                    RegisterInfo *reg_info = m_value.GetRegisterInfo();
+                    RegisterInfo *reg_info = value.GetRegisterInfo();
                     if (reg_info)
                     {
                         if (reg_info->name)
                             m_location_str = reg_info->name;
                         else if (reg_info->alt_name)
                             m_location_str = reg_info->alt_name;
-
-                        m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar";
+                        if (m_location_str.empty())
+                            m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar";
                     }
                 }
+                if (m_location_str.empty())
+                    m_location_str = (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
                 break;
 
             case Value::eValueTypeLoadAddress:
             case Value::eValueTypeFileAddress:
             case Value::eValueTypeHostAddress:
                 {
-                    uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
-                    sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
+                    uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
+                    sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
                     m_location_str.swap(sstr.GetString());
                 }
                 break;

Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=180803&r1=180802&r2=180803&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectVariable.cpp Tue Apr 30 15:45:04 2013
@@ -15,6 +15,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/Module.h"
+#include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/ValueObjectList.h"
 #include "lldb/Core/Value.h"
 
@@ -138,6 +139,8 @@ ValueObjectVariable::UpdateValue ()
             m_value.SetContext(Value::eContextTypeVariable, variable);
         else
             m_error.SetErrorString ("empty constant data");
+        // constant bytes can't be edited - sorry
+        m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
     }
     else
     {
@@ -161,6 +164,7 @@ ValueObjectVariable::UpdateValue ()
         Value old_value(m_value);
         if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
         {
+            m_resolved_value = m_value;
             m_value.SetContext(Value::eContextTypeVariable, variable);
 
             Value::ValueType value_type = m_value.GetValueType();
@@ -249,6 +253,11 @@ ValueObjectVariable::UpdateValue ()
 
             SetValueIsValid (m_error.Success());
         }
+        else
+        {
+            // could not find location, won't allow editing
+            m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
+        }
     }
     return m_error.Success();
 }
@@ -313,3 +322,74 @@ ValueObjectVariable::GetDeclaration (Dec
     }
     return false;
 }
+
+const char *
+ValueObjectVariable::GetLocationAsCString ()
+{
+    return GetLocationAsCStringImpl(m_resolved_value,
+                                    m_data);
+}
+
+bool
+ValueObjectVariable::SetValueFromCString (const char *value_str, Error& error)
+{
+    if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
+    {
+        RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
+        ExecutionContext exe_ctx(GetExecutionContextRef());
+        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
+        RegisterValue reg_value;
+        if (!reg_info || !reg_ctx)
+        {
+            error.SetErrorString("unable to retrieve register info");
+            return false;
+        }
+        error = reg_value.SetValueFromCString(reg_info, value_str);
+        if (error.Fail())
+            return false;
+        if (reg_ctx->WriteRegister (reg_info, reg_value))
+        {
+            SetNeedsUpdate();
+            return true;
+        }
+        else
+        {
+            error.SetErrorString("unable to write back to register");
+            return false;
+        }
+    }
+    else
+        return ValueObject::SetValueFromCString(value_str, error);
+}
+
+bool
+ValueObjectVariable::SetData (DataExtractor &data, Error &error)
+{
+    if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
+    {
+        RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
+        ExecutionContext exe_ctx(GetExecutionContextRef());
+        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
+        RegisterValue reg_value;
+        if (!reg_info || !reg_ctx)
+        {
+            error.SetErrorString("unable to retrieve register info");
+            return false;
+        }
+        error = reg_value.SetValueFromData(reg_info, data, 0, false);
+        if (error.Fail())
+            return false;
+        if (reg_ctx->WriteRegister (reg_info, reg_value))
+        {
+            SetNeedsUpdate();
+            return true;
+        }
+        else
+        {
+            error.SetErrorString("unable to write back to register");
+            return false;
+        }
+    }
+    else
+        return ValueObject::SetData(data, error);
+}





More information about the lldb-commits mailing list