summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
commit12bd4897ff0678fa663e09d78ebc22dd255ceb86 (patch)
treea8f4b3abea3e6937e60728991c736e6e3d322fc1 /source/Plugins/SymbolFile
parent205afe679855a4ce8149cdaa94d3f0868ce796dc (diff)
Notes
Diffstat (limited to 'source/Plugins/SymbolFile')
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp147
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h7
4 files changed, 146 insertions, 47 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 067449a289be..8935f7143e48 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -992,11 +993,11 @@ DWARFCompileUnit::ParseProducerInfo ()
{
std::string str;
if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
- m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
- m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
- m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 10b51ffe0a8a..6a8c4e6d57b9 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -2294,22 +2294,26 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
if (dwarf2Data)
{
offset = GetOffset();
-
- const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
+
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set)
{
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
+ const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
+ if (abbrev_decl)
+ {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
+ GetOffset(),
+ (uint32_t)abbrev_decl->Code(),
+ (uint32_t)abbrev_code);
+ }
}
}
offset = DW_INVALID_OFFSET;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b3a5476227f4..7ba4f52ac297 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -893,13 +893,22 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
// only 1 compile unit which is at offset zero in the DWARF.
// TODO: modify to support LTO .o files where each .o file might
// have multiple DW_TAG_compile_unit tags.
- return info->GetCompileUnit(0).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
else
{
// Just a normal DWARF file whose user ID for the compile unit is
// the DWARF offset itself
- return info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
+
}
}
return NULL;
@@ -1037,23 +1046,6 @@ SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
return cu_sp;
}
-static void
-AddRangesToBlock (Block& block,
- DWARFDebugRanges::RangeList& ranges,
- addr_t block_base_addr)
-{
- const size_t num_ranges = ranges.GetSize();
- for (size_t i = 0; i<num_ranges; ++i)
- {
- const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
- const addr_t range_base = range.GetRangeBase();
- assert (range_base >= block_base_addr);
- block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
- }
- block.FinalizeRanges ();
-}
-
-
Function *
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
{
@@ -1397,8 +1389,24 @@ SymbolFileDWARF::ParseFunctionBlocks
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
}
-
- AddRangesToBlock (*block, ranges, subprogram_low_pc);
+
+ const size_t num_ranges = ranges.GetSize();
+ for (size_t i = 0; i<num_ranges; ++i)
+ {
+ const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
+ const addr_t range_base = range.GetRangeBase();
+ if (range_base >= subprogram_low_pc)
+ block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
+ block->GetID(),
+ range_base,
+ range.GetRangeEnd(),
+ subprogram_low_pc);
+ }
+ }
+ block->FinalizeRanges ();
if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
{
@@ -2786,6 +2794,59 @@ SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEn
return false;
}
+
+
+SymbolFileDWARF::GlobalVariableMap &
+SymbolFileDWARF::GetGlobalAranges()
+{
+ if (!m_global_aranges_ap)
+ {
+ m_global_aranges_ap.reset (new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp)
+ {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i)
+ {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp)
+ {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp)
+ {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g)
+ {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData())
+ {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ {
+ if (location_result.GetValueType() == Value::eValueTypeFileAddress)
+ {
+ lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
+}
+
+
uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
@@ -2794,10 +2855,11 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
static_cast<void*>(so_addr.GetSection().get()),
so_addr.GetOffset(), resolve_scope);
uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry))
+ if (resolve_scope & ( eSymbolContextCompUnit |
+ eSymbolContextFunction |
+ eSymbolContextBlock |
+ eSymbolContextLineEntry |
+ eSymbolContextVariable ))
{
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
@@ -2805,7 +2867,30 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
if (debug_info)
{
const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset != DW_INVALID_OFFSET)
+ if (cu_offset == DW_INVALID_OFFSET)
+ {
+ // Global variables are not in the compile unit address ranges. The only way to
+ // currently find global variables is to iterate over the .debug_pubnames or the
+ // __apple_names table and find all items in there that point to DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable)
+ {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data)
+ {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc)
+ {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ }
+ else
{
uint32_t cu_idx = DW_INVALID_INDEX;
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
@@ -3409,9 +3494,11 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
// Parse all blocks if needed
if (inlined_die)
{
- sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
- assert (sc.block != NULL);
- if (sc.block->GetStartAddress (addr) == false)
+ Block &function_block = sc.function->GetBlock (true);
+ sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
+ if (sc.block == NULL)
+ sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
+ if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
addr.Clear();
}
else
@@ -6906,7 +6993,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
- byte_size = clang_type.GetByteSize();
+ byte_size = clang_type.GetByteSize(nullptr);
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
this,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 230e1a5d3984..d8efdbcb38a4 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -29,6 +29,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -557,6 +558,11 @@ protected:
uint32_t type_mask,
TypeSet &type_set);
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
+
+ GlobalVariableMap &
+ GetGlobalAranges();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
@@ -584,6 +590,7 @@ protected:
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
NameToDIE m_function_basename_index; // All concrete functions
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions