diff options
| author | Adrian Prantl <aprantl@apple.com> | 2019-11-14 13:57:49 -0800 |
|---|---|---|
| committer | Adrian Prantl <aprantl@apple.com> | 2019-11-15 11:52:13 -0800 |
| commit | 1cbe0038944a39ba79078997f9c65ba8abf6fbdd (patch) | |
| tree | 56f59d50075a7e99c26c27829c5c36a2e134cf4c /lldb/source/Plugins | |
| parent | 7d71dd928d1dcc838dc4dbe5cf294f557609f271 (diff) | |
| download | bcm5719-llvm-1cbe0038944a39ba79078997f9c65ba8abf6fbdd.tar.gz bcm5719-llvm-1cbe0038944a39ba79078997f9c65ba8abf6fbdd.zip | |
[-gmodules] Let LLDB log a warning if the Clang module hash mismatches.
This feature is mostly there to aid debugging of Clang module issues,
since the only useful actual the end-user can to is to recompile their
program.
Differential Revision: https://reviews.llvm.org/D70272
Diffstat (limited to 'lldb/source/Plugins')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 79 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 3 |
2 files changed, 70 insertions, 12 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 5b508181406..08dcfa57ffe 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1555,6 +1555,40 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) { return DWARFDIE(); } +/// Return the DW_AT_(GNU_)dwo_name. +static const char *GetDWOName(DWARFCompileUnit &dwarf_cu, + const DWARFDebugInfoEntry &cu_die) { + const char *dwo_name = + cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + if (!dwo_name) + dwo_name = + cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr); + return dwo_name; +} + +/// Return the DW_AT_(GNU_)dwo_id. +/// FIXME: Technically 0 is a valid hash. +static uint64_t GetDWOId(DWARFCompileUnit &dwarf_cu, + const DWARFDebugInfoEntry &cu_die) { + uint64_t dwo_id = + cu_die.GetAttributeValueAsUnsigned(&dwarf_cu, DW_AT_GNU_dwo_id, 0); + if (!dwo_id) + dwo_id = cu_die.GetAttributeValueAsUnsigned(&dwarf_cu, DW_AT_dwo_id, 0); + return dwo_id; +} + +llvm::Optional<uint64_t> SymbolFileDWARF::GetDWOId() { + if (GetNumCompileUnits() == 1) { + if (auto comp_unit = GetCompileUnitAtIndex(0)) + if (DWARFCompileUnit *cu = llvm::dyn_cast_or_null<DWARFCompileUnit>( + GetDWARFCompileUnit(comp_unit.get()))) + if (DWARFDebugInfoEntry *cu_die = cu->DIE().GetDIE()) + if (uint64_t dwo_id = ::GetDWOId(*cu, *cu_die)) + return dwo_id; + } + return {}; +} + std::unique_ptr<SymbolFileDWARFDwo> SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { @@ -1571,15 +1605,13 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (!dwarf_cu) return nullptr; - const char *dwo_name = - cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + const char *dwo_name = GetDWOName(*dwarf_cu, cu_die); if (!dwo_name) return nullptr; SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); if (dwp_symfile) { - uint64_t dwo_id = - cu_die.GetAttributeValueAsUnsigned(dwarf_cu, DW_AT_GNU_dwo_id, 0); + uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die); std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile = dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id); if (dwo_symfile) @@ -1619,15 +1651,18 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { if (m_fetched_external_modules) return; m_fetched_external_modules = true; - DWARFDebugInfo *debug_info = DebugInfo(); // Follow DWO skeleton unit breadcrumbs. const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx); + auto *dwarf_cu = + llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(cu_idx)); + if (!dwarf_cu) + continue; + const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); - if (!die || die.HasChildren()) + if (!die || die.HasChildren() || !die.GetDIE()) continue; const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); @@ -1639,10 +1674,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { if (module_sp) continue; - const char *dwo_path = - die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); - if (!dwo_path) - dwo_path = die.GetAttributeValueAsString(DW_AT_dwo_name, nullptr); + const char *dwo_path = GetDWOName(*dwarf_cu, *die.GetDIE()); if (!dwo_path) continue; @@ -1685,12 +1717,35 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { GetObjectFile()->GetModule()->ReportWarning( "0x%8.8x: unable to locate module needed for external types: " "%s\nerror: %s\nDebugging will be degraded due to missing " - "types. Rebuilding your project will regenerate the needed " + "types. Rebuilding the project will regenerate the needed " "module files.", die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str(), error.AsCString("unknown error")); continue; } + + // Verify the DWO hash. + // FIXME: Technically "0" is a valid hash. + uint64_t dwo_id = ::GetDWOId(*dwarf_cu, *die.GetDIE()); + if (!dwo_id) + continue; + + auto *dwo_symfile = + llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile()); + if (!dwo_symfile) + continue; + llvm::Optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId(); + if (!dwo_dwo_id) + continue; + + if (dwo_id != dwo_dwo_id) { + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8x: Module %s is out-of-date (hash mismatch). Type information " + "from this module may be incomplete or inconsistent with the rest of " + "the program. Rebuilding the project will regenerate the needed " + "module files.", + die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str()); + } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 1b8633ad1f1..a86350844ef 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -300,6 +300,9 @@ public: virtual llvm::Optional<uint32_t> GetDwoNum() { return llvm::None; } + /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id. + llvm::Optional<uint64_t> GetDWOId(); + static bool DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, const DWARFDIE &die); |

