[Lldb-commits] [lldb] r143065 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRInterpreter.cpp
Sean Callanan
scallanan at apple.com
Wed Oct 26 14:20:01 PDT 2011
Author: spyffe
Date: Wed Oct 26 16:20:00 2011
New Revision: 143065
URL: http://llvm.org/viewvc/llvm-project?rev=143065&view=rev
Log:
Extended the IR interpreter to handle the variables
"_cmd", "this", and "self". These variables are handled
differently from all other external variables used by
the expression. Other variables are used indirectly
through the $__lldb_arg operand; only _cmd, this, and
self are passed directly through the ABI.
There are two modifications:
- I added a function to ClangExpressionDeclMap that
retrives the value of one of these variables by name;
and
- I made IRInterpreter fetch these values when needed,
and ensured that the proper level of indirection is
used.
Modified:
lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
lldb/trunk/source/Expression/IRInterpreter.cpp
Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Wed Oct 26 16:20:00 2011
@@ -441,6 +441,19 @@
LookupDecl (clang::NamedDecl *decl);
//------------------------------------------------------------------
+ /// [Used by IRInterpreter] Get the Value for "this", "self", or
+ /// "_cmd".
+ ///
+ /// @param[in] name
+ /// The name of the entity to be found.
+ ///
+ /// @return
+ /// The value, or NULL.
+ //------------------------------------------------------------------
+ lldb_private::Value
+ GetSpecialValue (const ConstString &name);
+
+ //------------------------------------------------------------------
/// [Used by IRInterpreter] Returns true if the result is a
/// reference to data in the target, meaning it must be
/// dereferenced once more to get its data.
Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Wed Oct 26 16:20:00 2011
@@ -959,7 +959,12 @@
if (!expr_var_sp->m_parser_vars.get() || !expr_var_sp->m_parser_vars->m_lldb_var)
return Value();
- return *GetVariableValue(exe_ctx, expr_var_sp->m_parser_vars->m_lldb_var, NULL);
+ std::auto_ptr<Value> value(GetVariableValue(exe_ctx, expr_var_sp->m_parser_vars->m_lldb_var, NULL));
+
+ if (value.get())
+ return *value;
+ else
+ return Value();
}
else if (persistent_var_sp)
{
@@ -969,7 +974,7 @@
m_parser_vars->m_exe_ctx->GetProcessSP() &&
m_parser_vars->m_exe_ctx->GetProcessSP()->IsAlive())
{
- return persistent_var_sp->m_live_sp->GetValue();
+ return persistent_var_sp->m_live_sp->GetValue();
}
else
{
@@ -986,6 +991,39 @@
}
}
+Value
+ClangExpressionDeclMap::GetSpecialValue (const ConstString &name)
+{
+ assert(m_parser_vars.get());
+
+ if (!m_parser_vars->m_exe_ctx)
+ return Value();
+
+ StackFrame *frame = m_parser_vars->m_exe_ctx->GetFramePtr();
+
+ if (!frame)
+ return Value();
+
+ VariableList *vars = frame->GetVariableList(false);
+
+ if (!vars)
+ return Value();
+
+ lldb::VariableSP var = vars->FindVariable(name);
+
+ if (!var ||
+ !var->IsInScope(frame) ||
+ !var->LocationIsValidForFrame (frame))
+ return Value();
+
+ std::auto_ptr<Value> value(GetVariableValue(*m_parser_vars->m_exe_ctx, var, NULL));
+
+ if (value.get())
+ return *value;
+ else
+ return Value();
+}
+
// Interface for CommandObjectExpression
bool
@@ -1535,8 +1573,8 @@
Error allocate_error;
mem = process->AllocateMemory(pvar_byte_size,
- lldb::ePermissionsReadable | lldb::ePermissionsWritable,
- allocate_error);
+ lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ allocate_error);
if (mem == LLDB_INVALID_ADDRESS)
{
@@ -1577,9 +1615,9 @@
// Now write the location of the area into the struct.
Error write_error;
if (!process->WriteScalarToMemory (addr,
- var_sp->m_live_sp->GetValue().GetScalar(),
- process->GetAddressByteSize(),
- write_error))
+ var_sp->m_live_sp->GetValue().GetScalar(),
+ process->GetAddressByteSize(),
+ write_error))
{
err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString());
return false;
Modified: lldb/trunk/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRInterpreter.cpp?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRInterpreter.cpp (original)
+++ lldb/trunk/source/Expression/IRInterpreter.cpp Wed Oct 26 16:20:00 2011
@@ -576,6 +576,12 @@
const GlobalValue *global_value = dyn_cast<GlobalValue>(value);
+ // If the variable is indirected through the argument
+ // array then we need to build an extra level of indirection
+ // for it. This is the default; only magic arguments like
+ // "this", "self", and "_cmd" are direct.
+ bool indirect_variable = true;
+
// Attempt to resolve the value using the program's data.
// If it is, the values to be created are:
//
@@ -586,17 +592,40 @@
// resides. This is an IR-level variable.
do
{
- if (!global_value)
- break;
-
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ lldb_private::Value resolved_value;
- clang::NamedDecl *decl = IRForTarget::DeclForGlobal(global_value, &module);
-
- if (!decl)
- break;
-
- lldb_private::Value resolved_value = m_decl_map.LookupDecl(decl);
+ if (global_value)
+ {
+ clang::NamedDecl *decl = IRForTarget::DeclForGlobal(global_value, &module);
+
+ if (!decl)
+ break;
+
+ if (isa<clang::FunctionDecl>(decl))
+ {
+ if (log)
+ log->Printf("The interpreter does not handle function pointers at the moment");
+
+ return Memory::Region();
+ }
+
+ resolved_value = m_decl_map.LookupDecl(decl);
+ }
+ else
+ {
+ // Special-case "this", "self", and "_cmd"
+
+ std::string name_str = value->getNameStr();
+
+ if (name_str == "this" ||
+ name_str == "self" ||
+ name_str == "_cmd")
+ resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
+
+ indirect_variable = false;
+ }
if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
{
@@ -605,7 +634,10 @@
Memory::Region data_region = m_memory.Malloc(value->getType());
data_region.m_allocation->m_origin = resolved_value;
Memory::Region ref_region = m_memory.Malloc(value->getType());
- Memory::Region pointer_region = m_memory.Malloc(value->getType());
+ Memory::Region pointer_region;
+
+ if (indirect_variable)
+ pointer_region = m_memory.Malloc(value->getType());
if (!Cache(data_region.m_allocation, value->getType()))
return Memory::Region();
@@ -613,7 +645,7 @@
if (ref_region.IsInvalid())
return Memory::Region();
- if (pointer_region.IsInvalid())
+ if (pointer_region.IsInvalid() && indirect_variable)
return Memory::Region();
DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -621,31 +653,35 @@
if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
return Memory::Region();
- DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-
- if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
- return Memory::Region();
-
- m_values[value] = pointer_region;
- return pointer_region;
- }
- else if (isa<clang::FunctionDecl>(decl))
- {
- if (log)
- log->Printf("The interpreter does not handle function pointers at the moment");
-
- return Memory::Region();
+ if (indirect_variable)
+ {
+ DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+
+ if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
+ return Memory::Region();
+
+ m_values[value] = pointer_region;
+ return pointer_region;
+ }
+ else
+ {
+ m_values[value] = ref_region;
+ return ref_region;
+ }
}
else
{
Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
Memory::Region ref_region = m_memory.Malloc(value->getType());
- Memory::Region pointer_region = m_memory.Malloc(value->getType());
+ Memory::Region pointer_region;
+
+ if (indirect_variable)
+ pointer_region = m_memory.Malloc(value->getType());
if (ref_region.IsInvalid())
return Memory::Region();
- if (pointer_region.IsInvalid())
+ if (pointer_region.IsInvalid() && indirect_variable)
return Memory::Region();
DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -653,23 +689,30 @@
if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
return Memory::Region();
- DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-
- if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
- return Memory::Region();
+ if (indirect_variable)
+ {
+ DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
- m_values[value] = pointer_region;
+ if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
+ return Memory::Region();
+
+ m_values[value] = pointer_region;
+ }
if (log)
{
- log->Printf("Made an allocation for %s", PrintValue(global_value).c_str());
+ log->Printf("Made an allocation for %s", PrintValue(value).c_str());
log->Printf(" Data contents : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
- log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
+ if (indirect_variable)
+ log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
}
- return pointer_region;
+ if (indirect_variable)
+ return pointer_region;
+ else
+ return ref_region;
}
}
}
More information about the lldb-commits
mailing list