summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
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