diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index ef18c2b5d3bab..f149ec354f08c 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -13,7 +13,6 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Threading.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" @@ -22,6 +21,7 @@ #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" +#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -30,6 +30,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/Symbols.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" @@ -53,7 +54,7 @@ #include "lldb/Target/Language.h" -#include "lldb/Utility/TaskPool.h" +#include "lldb/Host/TaskPool.h" #include "DWARFASTParser.h" #include "DWARFASTParserClang.h" @@ -71,6 +72,7 @@ #include "LogChannelDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" +#include "SymbolFileDWARFDwp.h" #include "llvm/Support/FileSystem.h" @@ -207,6 +209,10 @@ static const char *resolveCompDir(const char *path_from_dwarf) { return nullptr; } +DWARFCompileUnit *SymbolFileDWARF::GetBaseCompileUnit() { + return nullptr; +} + void SymbolFileDWARF::Initialize() { LogChannelDWARF::Initialize(); PluginManager::RegisterPlugin(GetPluginNameStatic(), @@ -435,13 +441,11 @@ void SymbolFileDWARF::InitializeObject() { ModuleSP module_sp(m_obj_file->GetModule()); if (module_sp) { const SectionList *section_list = module_sp->GetSectionList(); - const Section *section = + Section *section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get(); - // Memory map the DWARF mach-o segment so we have everything mmap'ed - // to keep our heap memory usage down. if (section) - m_obj_file->MemoryMapSectionData(section, m_dwarf_data); + m_obj_file->ReadSectionData(section, m_dwarf_data); } get_apple_names_data(); @@ -497,6 +501,21 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { if (section_list == NULL) return 0; + // On non Apple platforms we might have .debug_types debug info that + // is created by using "-fdebug-types-section". LLDB currently will try + // to load this debug info, but it causes crashes during debugging when + // types are missing since it doesn't know how to parse the info in + // the .debug_types type units. This causes all complex debug info + // types to be unresolved. Because this causes LLDB to crash and since + // it really doesn't provide a solid debuggiung experience, we should + // disable trying to debug this kind of DWARF until support gets + // added or deprecated. + if (section_list->FindSectionByName(ConstString(".debug_types"))) { + m_obj_file->GetModule()->ReportWarning( + "lldb doesn’t support .debug_types debug info"); + return 0; + } + uint64_t debug_abbrev_file_size = 0; uint64_t debug_info_file_size = 0; uint64_t debug_line_file_size = 0; @@ -517,6 +536,20 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { if (section) debug_abbrev_file_size = section->GetFileSize(); + DWARFDebugAbbrev *abbrev = DebugAbbrev(); + if (abbrev) { + std::set<dw_form_t> invalid_forms; + abbrev->GetUnsupportedForms(invalid_forms); + if (!invalid_forms.empty()) { + StreamString error; + error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : ""); + for (auto form : invalid_forms) + error.Printf(" %#x", form); + m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str()); + return 0; + } + } + section = section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true) .get(); @@ -1539,6 +1572,16 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (!dwo_name) return nullptr; + SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); + if (dwp_symfile) { + uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu, + DW_AT_GNU_dwo_id, 0); + std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile = + dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id); + if (dwo_symfile) + return dwo_symfile; + } + FileSpec dwo_file(dwo_name, true); if (dwo_file.IsRelative()) { const char *comp_dir = cu_die.GetAttributeValueAsString( @@ -1600,7 +1643,29 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { } dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); - // printf ("Loading dwo = '%s'\n", dwo_path); + + // When LLDB loads "external" modules it looks at the + // presence of DW_AT_GNU_dwo_name. + // However, when the already created module + // (corresponding to .dwo itself) is being processed, + // it will see the presence of DW_AT_GNU_dwo_name + // (which contains the name of dwo file) and + // will try to call ModuleList::GetSharedModule again. + // In some cases (i.e. for empty files) Clang 4.0 + // generates a *.dwo file which has DW_AT_GNU_dwo_name, + // but no DW_AT_comp_dir. In this case the method + // ModuleList::GetSharedModule will fail and + // the warning will be printed. However, as one can notice + // in this case we don't actually need to try to load the already + // loaded module (corresponding to .dwo) so we simply skip it. + if (m_obj_file->GetFileSpec() + .GetFileNameExtension() + .GetStringRef() == "dwo" && + llvm::StringRef(m_obj_file->GetFileSpec().GetPath()) + .endswith(dwo_module_spec.GetFileSpec().GetPath())) { + continue; + } + Status error = ModuleList::GetSharedModule( dwo_module_spec, module_sp, NULL, NULL, NULL); if (!module_sp) { @@ -1640,9 +1705,8 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { const DWARFExpression &location = var_sp->LocationExpression(); Value location_result; Status error; - if (location.Evaluate(nullptr, nullptr, nullptr, - LLDB_INVALID_ADDRESS, nullptr, nullptr, - location_result, &error)) { + if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr, + nullptr, location_result, &error)) { if (location_result.GetValueType() == Value::eValueTypeFileAddress) { lldb::addr_t file_addr = @@ -4288,3 +4352,18 @@ DWARFExpression::LocationListFormat SymbolFileDWARF::GetLocationListFormat() const { return DWARFExpression::RegularLocationList; } + +SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { + llvm::call_once(m_dwp_symfile_once_flag, [this]() { + ModuleSpec module_spec; + module_spec.GetFileSpec() = m_obj_file->GetFileSpec(); + module_spec.GetSymbolFileSpec() = + FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false); + FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec); + if (dwp_filespec.Exists()) { + m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), + dwp_filespec); + } + }); + return m_dwp_symfile.get(); +} |