summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp99
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();
+}