diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-02-09 01:44:09 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-02-09 01:44:09 +0000 |
commit | 12bd4897ff0678fa663e09d78ebc22dd255ceb86 (patch) | |
tree | a8f4b3abea3e6937e60728991c736e6e3d322fc1 /source/Plugins/SymbolFile | |
parent | 205afe679855a4ce8149cdaa94d3f0868ce796dc (diff) |
Notes
Diffstat (limited to 'source/Plugins/SymbolFile')
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 |