grimar created this revision.
grimar added reviewers: LLDB, clayborg.
Herald added subscribers: JDevlieghere, aprantl.

Imagine the following code:

  void baz() {
  }
  
  int main() {
    baz();
    return 0;
  }

When compiling with with `-gdwarf-4 -gsplit-dwarf` LLDB is able to set the 
breakpoint correctly:

  clang test.cc -g -fno-rtti -c -gdwarf-4 -gsplit-dwarf
  clang test.o -g -fno-rtti -gdwarf-4 -o test -gsplit-dwarf
  lldb test
  (lldb) target create "test"
  Current executable set to 'test' (x86_64).
  (lldb) b baz
  Breakpoint 1: where = test`baz() + 4 at test.cc:4:1, address = 
0x0000000000400524

But not when -dwarf-5 is used. It thinks there are 2 locations:

  clang test.cc -g -fno-rtti -c -gdwarf-5 -gsplit-dwarf
  clang test.o -g -fno-rtti -gdwarf-5 -o test -gsplit-dwarf
  lldb test
  (lldb) target create "test"
  Current executable set to 'test' (x86_64).
  (lldb) b baz
  Breakpoint 1: 2 locations.

The issue happens because starting from DWARF v5 `DW_AT_addr_base` attribute 
should be used
instead of `DW_AT_GNU_addr_base`. LLDB does not do that and we end up reading 
the
`.debug_addr` header as section content (as addresses) instead of skipping it 
and reading the real addresses.
Then LLDB is unable to match 2 similar locations and thinks they are different.


https://reviews.llvm.org/D54751

Files:
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp


Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -306,9 +306,11 @@
 }
 
 // m_die_array_mutex must be already held as read/write.
-void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
-  SetAddrBase(
-      cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 0));
+void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {  
+  dw_addr_t addr_base =
+          cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 
0);
+  SetAddrBase(addr_base);
+
   SetRangesBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
                                                    DW_AT_rnglists_base, 0));
 
@@ -342,8 +344,12 @@
 
   m_dwo_symbol_file = std::move(dwo_symbol_file);
 
-  dw_addr_t addr_base =
-      cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 
0);
+  // Here we make DWO CU use address base set in the skeleton unit.
+  // DWO files in pre-DWARF v5 could use DW_AT_GNU_addr_base.
+  // Starting from DWARF v5, the DW_AT_addr_base is used instead.
+  if (!addr_base)
+    addr_base =
+       cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 
0);
   dwo_cu->SetAddrBase(addr_base);
 
   dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(


Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -306,9 +306,11 @@
 }
 
 // m_die_array_mutex must be already held as read/write.
-void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
-  SetAddrBase(
-      cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 0));
+void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {  
+  dw_addr_t addr_base =
+          cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 0);
+  SetAddrBase(addr_base);
+
   SetRangesBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
                                                    DW_AT_rnglists_base, 0));
 
@@ -342,8 +344,12 @@
 
   m_dwo_symbol_file = std::move(dwo_symbol_file);
 
-  dw_addr_t addr_base =
-      cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0);
+  // Here we make DWO CU use address base set in the skeleton unit.
+  // DWO files in pre-DWARF v5 could use DW_AT_GNU_addr_base.
+  // Starting from DWARF v5, the DW_AT_addr_base is used instead.
+  if (!addr_base)
+    addr_base =
+       cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0);
   dwo_cu->SetAddrBase(addr_base);
 
   dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to