diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/Value.cpp | 78 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 190 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectList.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectVariable.cpp | 2 |
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) |