summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-06-29 22:09:02 +0000
committerGreg Clayton <gclayton@apple.com>2011-06-29 22:09:02 +0000
commitdea8cb4fe314fb772706e033e50c3258210007f5 (patch)
treef48ad3ccc7229cc40cccc815e20e1b64fd8c01ea /lldb/source/Core
parent1c2d4f2feaf680df14b0a6a2f23e2d96589ac598 (diff)
downloadbcm5719-llvm-dea8cb4fe314fb772706e033e50c3258210007f5.tar.gz
bcm5719-llvm-dea8cb4fe314fb772706e033e50c3258210007f5.zip
Added support for finding and global variables in the SBTarget and SBModule
level in the public API. Also modified the ValueObject values to be able to display global variables without having a valid running process. The globals will read themselves from the object file section data if there is no process, and from the process if there is one. Also fixed an issue where modifications for dynamic types could cause child values of ValueObjects to not show up if the value was unable to evaluate itself (children of NULL pointer objects). llvm-svn: 134102
Diffstat (limited to 'lldb/source/Core')
-rw-r--r--lldb/source/Core/Value.cpp78
-rw-r--r--lldb/source/Core/ValueObject.cpp190
-rw-r--r--lldb/source/Core/ValueObjectList.cpp10
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp2
4 files changed, 167 insertions, 113 deletions
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index 2d8ac9147ce..2ba490ebb0a 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -516,6 +516,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
Error error;
lldb::addr_t address = LLDB_INVALID_ADDRESS;
AddressType address_type = eAddressTypeFile;
+ Address file_so_addr;
switch (m_value_type)
{
default:
@@ -541,11 +542,11 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
case eValueTypeLoadAddress:
if (exe_ctx == NULL)
{
- error.SetErrorString ("can't read memory (no execution context)");
+ error.SetErrorString ("can't read load address (no execution context)");
}
else if (exe_ctx->process == NULL)
{
- error.SetErrorString ("can't read memory (invalid process)");
+ error.SetErrorString ("can't read load address (invalid process)");
}
else
{
@@ -557,6 +558,15 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
break;
case eValueTypeFileAddress:
+ if (exe_ctx == NULL)
+ {
+ error.SetErrorString ("can't read file address (no execution context)");
+ }
+ else if (exe_ctx->target == NULL)
+ {
+ error.SetErrorString ("can't read file address (invalid target)");
+ }
+ else
{
// The only thing we can currently lock down to a module so that
// we can resolve a file address, is a variable.
@@ -564,9 +574,10 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
if (GetVariable())
{
- lldb::addr_t file_addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS)
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (address != LLDB_INVALID_ADDRESS)
{
+ bool resolved = false;
SymbolContext var_sc;
variable->CalculateSymbolContext(&var_sc);
if (var_sc.module_sp)
@@ -574,31 +585,46 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
if (objfile)
{
- Address so_addr(file_addr, objfile->GetSectionList());
- address = so_addr.GetLoadAddress (exe_ctx->target);
- if (address != LLDB_INVALID_ADDRESS)
+ Address so_addr(address, objfile->GetSectionList());
+ addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
+ if (load_address != LLDB_INVALID_ADDRESS)
{
+ resolved = true;
+ address = load_address;
address_type = eAddressTypeLoad;
data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
}
else
{
- data.SetByteOrder(objfile->GetByteOrder());
- data.SetAddressByteSize(objfile->GetAddressByteSize());
+ if (so_addr.IsSectionOffset())
+ {
+ resolved = true;
+ file_so_addr = so_addr;
+ data.SetByteOrder(objfile->GetByteOrder());
+ data.SetAddressByteSize(objfile->GetAddressByteSize());
+ }
}
}
- if (address_type == eAddressTypeFile)
- error.SetErrorStringWithFormat ("%s is not loaded.\n", var_sc.module_sp->GetFileSpec().GetFilename().AsCString());
}
- else
+ if (!resolved)
{
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", file_addr, variable->GetName().AsCString(""));
+ if (var_sc.module_sp)
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
+ address,
+ variable->GetName().AsCString(""),
+ var_sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
+ var_sc.module_sp->GetFileSpec().GetDirectory() ? "/" : "",
+ var_sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ else
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
+ address,
+ variable->GetName().AsCString(""));
}
}
else
{
- error.SetErrorString ("Invalid file address.");
+ error.SetErrorString ("invalid file address");
}
}
else
@@ -651,14 +677,28 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
// The address is an address in this process, so just copy it
memcpy (dst, (uint8_t*)NULL + address, byte_size);
}
- else if (address_type == eAddressTypeLoad)
+ else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
{
- if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
+ if (file_so_addr.IsValid())
{
- if (error.Success())
- error.SetErrorStringWithFormat("read %u bytes of memory from 0x%llx failed", (uint64_t)address, byte_size);
- else
+ // We have a file address that we were able to translate into a
+ // section offset address so we might be able to read this from
+ // the object files if we don't have a live process. Lets always
+ // try and read from the process if we have one though since we
+ // want to read the actual value by setting "prefer_file_cache"
+ // to false.
+ const bool prefer_file_cache = false;
+ if (exe_ctx->target->ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
+ {
+ error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ }
+ }
+ else
+ {
+ if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
+ {
error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ }
}
}
else
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 6471972ad99..c4bfc3c126c 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -285,21 +285,21 @@ ValueObjectSP
ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
{
ValueObjectSP child_sp;
- if (UpdateValueIfNeeded())
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType ())
+ UpdateValueIfNeeded();
+ if (idx < GetNumChildren())
{
- if (idx < GetNumChildren())
+ // Check if we have already made the child value object?
+ if (can_create && m_children[idx] == NULL)
{
- // Check if we have already made the child value object?
- if (can_create && m_children[idx] == NULL)
- {
- // No we haven't created the child at this index, so lets have our
- // subclass do it and cache the result for quick future access.
- m_children[idx] = CreateChildAtIndex (idx, false, 0);
- }
-
- if (m_children[idx] != NULL)
- return m_children[idx]->GetSP();
+ // No we haven't created the child at this index, so lets have our
+ // subclass do it and cache the result for quick future access.
+ m_children[idx] = CreateChildAtIndex (idx, false, 0);
}
+
+ if (m_children[idx] != NULL)
+ return m_children[idx]->GetSP();
}
return child_sp;
}
@@ -322,36 +322,37 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
// need a vector of indexes that can get us down to the correct child
ValueObjectSP child_sp;
- if (UpdateValueIfNeeded())
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType ())
+ UpdateValueIfNeeded();
+
+ std::vector<uint32_t> child_indexes;
+ clang::ASTContext *clang_ast = GetClangAST();
+ void *clang_type = GetClangType();
+ bool omit_empty_base_classes = true;
+ const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
+ clang_type,
+ name.GetCString(),
+ omit_empty_base_classes,
+ child_indexes);
+ if (num_child_indexes > 0)
{
- std::vector<uint32_t> child_indexes;
- clang::ASTContext *clang_ast = GetClangAST();
- void *clang_type = GetClangType();
- bool omit_empty_base_classes = true;
- const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
- clang_type,
- name.GetCString(),
- omit_empty_base_classes,
- child_indexes);
- if (num_child_indexes > 0)
- {
- std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
- std::vector<uint32_t>::const_iterator end = child_indexes.end ();
+ std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
+ std::vector<uint32_t>::const_iterator end = child_indexes.end ();
- child_sp = GetChildAtIndex(*pos, can_create);
- for (++pos; pos != end; ++pos)
+ child_sp = GetChildAtIndex(*pos, can_create);
+ for (++pos; pos != end; ++pos)
+ {
+ if (child_sp)
{
- if (child_sp)
- {
- ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
- child_sp = new_child_sp;
- }
- else
- {
- child_sp.reset();
- }
-
+ ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
+ child_sp = new_child_sp;
}
+ else
+ {
+ child_sp.reset();
+ }
+
}
}
return child_sp;
@@ -391,62 +392,59 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
{
ValueObject *valobj = NULL;
- if (UpdateValueIfNeeded())
- {
- bool omit_empty_base_classes = true;
-
- std::string child_name_str;
- uint32_t child_byte_size = 0;
- int32_t child_byte_offset = 0;
- uint32_t child_bitfield_bit_size = 0;
- uint32_t child_bitfield_bit_offset = 0;
- bool child_is_base_class = false;
- bool child_is_deref_of_parent = false;
-
- const bool transparent_pointers = synthetic_array_member == false;
- clang::ASTContext *clang_ast = GetClangAST();
- clang_type_t clang_type = GetClangType();
- clang_type_t child_clang_type;
-
- ExecutionContext exe_ctx;
- GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
-
- child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
- clang_ast,
- GetName().GetCString(),
- clang_type,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- child_name_str,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
- if (child_clang_type && child_byte_size)
- {
- if (synthetic_index)
- child_byte_offset += child_byte_size * synthetic_index;
-
- ConstString child_name;
- if (!child_name_str.empty())
- child_name.SetCString (child_name_str.c_str());
+ bool omit_empty_base_classes = true;
- valobj = new ValueObjectChild (*this,
- clang_ast,
- child_clang_type,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
- if (m_pointers_point_to_load_addrs)
- valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
- }
+ std::string child_name_str;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ uint32_t child_bitfield_bit_offset = 0;
+ bool child_is_base_class = false;
+ bool child_is_deref_of_parent = false;
+
+ const bool transparent_pointers = synthetic_array_member == false;
+ clang::ASTContext *clang_ast = GetClangAST();
+ clang_type_t clang_type = GetClangType();
+ clang_type_t child_clang_type;
+
+ ExecutionContext exe_ctx;
+ GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
+
+ child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
+ clang_ast,
+ GetName().GetCString(),
+ clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ child_name_str,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ if (child_clang_type && child_byte_size)
+ {
+ if (synthetic_index)
+ child_byte_offset += child_byte_size * synthetic_index;
+
+ ConstString child_name;
+ if (!child_name_str.empty())
+ child_name.SetCString (child_name_str.c_str());
+
+ valobj = new ValueObjectChild (*this,
+ clang_ast,
+ child_clang_type,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ if (m_pointers_point_to_load_addrs)
+ valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
}
return valobj;
@@ -994,6 +992,12 @@ ValueObject::IsPossibleCPlusPlusDynamicType ()
return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
}
+bool
+ValueObject::IsPossibleDynamicType ()
+{
+ return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
+}
+
ValueObjectSP
ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
{
diff --git a/lldb/source/Core/ValueObjectList.cpp b/lldb/source/Core/ValueObjectList.cpp
index 8913d4da18d..f732a698ee5 100644
--- a/lldb/source/Core/ValueObjectList.cpp
+++ b/lldb/source/Core/ValueObjectList.cpp
@@ -51,6 +51,16 @@ ValueObjectList::Append (const ValueObjectSP &val_obj_sp)
m_value_objects.push_back(val_obj_sp);
}
+void
+ValueObjectList::Append (const ValueObjectList &valobj_list)
+{
+ std::copy(valobj_list.m_value_objects.begin(), // source begin
+ valobj_list.m_value_objects.end(), // source end
+ back_inserter(m_value_objects)); // destination
+
+}
+
+
uint32_t
ValueObjectList::GetSize() const
{
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index e2a281b7f95..79692a023a8 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -169,7 +169,7 @@ ValueObjectVariable::UpdateValue ()
// Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
+ if (value_type == Value::eValueTypeFileAddress && exe_ctx.process && exe_ctx.process->IsAlive())
{
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (file_addr != LLDB_INVALID_ADDRESS)
OpenPOWER on IntegriCloud