mstorsjo updated this revision to Diff 231517.
mstorsjo edited the summary of this revision.
mstorsjo added a comment.

Converted the test to .s form, using lld, split out the ObjectFile changes to 
D70848 <https://reviews.llvm.org/D70848> (which this change now depends on for 
the tests).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70840/new/

https://reviews.llvm.org/D70840

Files:
  lldb/include/lldb/Symbol/LineTable.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Symbol/LineTable.cpp
  lldb/test/Shell/SymbolFile/DWARF/thumb-windows.s

Index: lldb/test/Shell/SymbolFile/DWARF/thumb-windows.s
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/thumb-windows.s
@@ -0,0 +1,183 @@
+# Test that a linked windows executable, with a thumb bit in many address
+# fields, gets the thumb bit stripped out from addresses.
+
+# If the thumb bit isn't stripped out from subprogram ranges, 0x401006 is
+# associated with the function "entry", while it actually is the start of
+# the function "other".
+# If the thumb bit isn't stripped out from line tables, the LineEntry
+# points to the wrong line.
+
+# REQUIRES: lld, arm
+
+# RUN: llvm-mc -triple armv7-windows-gnu %s -filetype=obj > %t.o
+# RUN: lld-link %t.o -out:%t.exe -debug:dwarf -entry:entry -subsystem:console -lldmingw
+# RUN: %lldb %t.exe -o "image lookup -v -a 0x401006" -b | FileCheck %s
+
+# CHECK-LABEL: image lookup -v -a 0x401006
+# CHECK: Function: {{.*}}, name = "other", range = [0x00401006-0x0040100c)
+# CHECK: LineEntry: [0x00401006-0x0040100a): /path/to/src/dwarf-thumb.c:7:12
+
+        .text
+        .syntax unified
+        .file   "dwarf-thumb.c"
+        .file   1 "" "dwarf-thumb.c"
+        .def     entry;
+        .scl    2;
+        .type   32;
+        .endef
+        .globl  entry                   @ -- Begin function entry
+        .p2align        1
+        .code   16                      @ @entry
+        .thumb_func
+entry:
+.Lfunc_begin0:
+        .loc    1 2 0                   @ dwarf-thumb.c:2:0
+        .cfi_sections .debug_frame
+        .cfi_startproc
+        .loc    1 4 9 prologue_end      @ dwarf-thumb.c:4:9
+        mov     r1, r0
+.Ltmp0:
+        b       other
+.Ltmp1:
+.Lfunc_end0:
+        .cfi_endproc
+                                        @ -- End function
+        .def     other;
+        .scl    2;
+        .type   32;
+        .endef
+        .globl  other                   @ -- Begin function other
+        .p2align        1
+        .code   16                      @ @other
+        .thumb_func
+other:
+.Lfunc_begin1:
+        .loc    1 6 0                   @ dwarf-thumb.c:6:0
+        .cfi_startproc
+        .loc    1 7 12 prologue_end     @ dwarf-thumb.c:7:12
+        add.w   r0, r1, r1, lsl #1
+        .loc    1 7 2 is_stmt 0         @ dwarf-thumb.c:7:2
+        bx      lr
+.Ltmp2:
+.Lfunc_end1:
+        .cfi_endproc
+                                        @ -- End function
+        .section        .debug_str,"dr"
+.Linfo_string:
+.Linfo_string1:
+        .asciz  "dwarf-thumb.c"
+.Linfo_string2:
+        .asciz  "/path/to/src"
+.Linfo_string3:
+        .asciz  "other"
+.Linfo_string6:
+        .asciz  "entry"
+        .section        .debug_loc,"dr"
+.Lsection_debug_loc:
+.Ldebug_loc0:
+        .long   .Lfunc_begin0-.Lfunc_begin0
+        .long   .Ltmp0-.Lfunc_begin0
+        .short  1                       @ Loc expr size
+        .byte   80                      @ DW_OP_reg0
+        .long   .Ltmp0-.Lfunc_begin0
+        .long   .Lfunc_end0-.Lfunc_begin0
+        .short  1                       @ Loc expr size
+        .byte   81                      @ DW_OP_reg1
+        .long   0
+        .long   0
+        .section        .debug_abbrev,"dr"
+.Lsection_abbrev:
+        .byte   1                       @ Abbreviation Code
+        .byte   17                      @ DW_TAG_compile_unit
+        .byte   1                       @ DW_CHILDREN_yes
+        .byte   37                      @ DW_AT_producer
+        .byte   37                      @ DW_FORM_strx1
+        .byte   19                      @ DW_AT_language
+        .byte   5                       @ DW_FORM_data2
+        .byte   3                       @ DW_AT_name
+        .byte   14                      @ DW_FORM_strp
+        .byte   16                      @ DW_AT_stmt_list
+        .byte   23                      @ DW_FORM_sec_offset
+        .byte   27                      @ DW_AT_comp_dir
+        .byte   14                      @ DW_FORM_strp
+        .byte   17                      @ DW_AT_low_pc
+        .byte   1                       @ DW_FORM_addr
+        .byte   18                      @ DW_AT_high_pc
+        .byte   6                       @ DW_FORM_data4
+        .byte   0                       @ EOM(1)
+        .byte   0                       @ EOM(2)
+
+        .byte   6                       @ Abbreviation Code
+        .byte   46                      @ DW_TAG_subprogram
+        .byte   1                       @ DW_CHILDREN_yes
+        .byte   17                      @ DW_AT_low_pc
+        .byte   1                       @ DW_FORM_addr
+        .byte   18                      @ DW_AT_high_pc
+        .byte   6                       @ DW_FORM_data4
+        .byte   64                      @ DW_AT_frame_base
+        .byte   24                      @ DW_FORM_exprloc
+        .ascii  "\227B"                 @ DW_AT_GNU_all_call_sites
+        .byte   25                      @ DW_FORM_flag_present
+        .byte   3                       @ DW_AT_name
+        .byte   14                      @ DW_FORM_strp
+        .byte   58                      @ DW_AT_decl_file
+        .byte   11                      @ DW_FORM_data1
+        .byte   59                      @ DW_AT_decl_line
+        .byte   11                      @ DW_FORM_data1
+        .byte   39                      @ DW_AT_prototyped
+        .byte   25                      @ DW_FORM_flag_present
+        .byte   73                      @ DW_AT_type
+        .byte   19                      @ DW_FORM_ref4
+        .byte   63                      @ DW_AT_external
+        .byte   25                      @ DW_FORM_flag_present
+        .byte   0                       @ EOM(1)
+        .byte   0                       @ EOM(2)
+        .byte   0                       @ EOM(3)
+        .section        .debug_info,"dr"
+.Lsection_info:
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 @ Length of Unit
+.Ldebug_info_start0:
+        .short  4                       @ DWARF version number
+        .secrel32       .Lsection_abbrev @ Offset Into Abbrev. Section
+        .byte   4                       @ Address Size (in bytes)
+        .byte   1                       @ Abbrev [1] 0xb:0xbf DW_TAG_compile_unit
+        .byte   0                       @ DW_AT_producer
+        .short  12                      @ DW_AT_language
+        .secrel32       .Linfo_string1  @ DW_AT_name
+        .secrel32       .Lline_table_start0 @ DW_AT_stmt_list
+        .secrel32       .Linfo_string2  @ DW_AT_comp_dir
+        .long   .Lfunc_begin0           @ DW_AT_low_pc
+        .long   .Lfunc_end1-.Lfunc_begin0 @ DW_AT_high_pc
+
+        .byte   6                       @ Abbrev [6] 0x4f:0x39 DW_TAG_subprogram
+        .long   .Lfunc_begin0           @ DW_AT_low_pc
+        .long   .Lfunc_end0-.Lfunc_begin0 @ DW_AT_high_pc
+        .byte   1                       @ DW_AT_frame_base
+        .byte   91
+                                        @ DW_AT_GNU_all_call_sites
+        .secrel32       .Linfo_string6  @ DW_AT_name
+        .byte   1                       @ DW_AT_decl_file
+        .byte   2                       @ DW_AT_decl_line
+                                        @ DW_AT_prototyped
+        .long   60                      @ DW_AT_type
+                                        @ DW_AT_external
+        .byte   0                       @ End Of Children Mark
+        .byte   6                       @ Abbrev [6] 0x88:0x2e DW_TAG_subprogram
+        .long   .Lfunc_begin1           @ DW_AT_low_pc
+        .long   .Lfunc_end1-.Lfunc_begin1 @ DW_AT_high_pc
+        .byte   1                       @ DW_AT_frame_base
+        .byte   91
+                                        @ DW_AT_GNU_all_call_sites
+        .secrel32       .Linfo_string3  @ DW_AT_name
+        .byte   1                       @ DW_AT_decl_file
+        .byte   6                       @ DW_AT_decl_line
+                                        @ DW_AT_prototyped
+        .long   60                      @ DW_AT_type
+                                        @ DW_AT_external
+        .byte   0                       @ End Of Children Mark
+.Ldebug_info_end0:
+        .addrsig
+        .section        .debug_line,"dr"
+.Lsection_line:
+.Lline_table_start0:
Index: lldb/source/Symbol/LineTable.cpp
===================================================================
--- lldb/source/Symbol/LineTable.cpp
+++ lldb/source/Symbol/LineTable.cpp
@@ -19,7 +19,13 @@
 
 // LineTable constructor
 LineTable::LineTable(CompileUnit *comp_unit)
-    : m_comp_unit(comp_unit), m_entries() {}
+    : m_comp_unit(comp_unit), m_entries() {
+  if (ArchSpec arch = m_comp_unit->GetModule()->GetArchitecture()) {
+    if (arch.GetTriple().getArch() == llvm::Triple::arm ||
+        arch.GetTriple().getArch() == llvm::Triple::thumb)
+      m_clear_address_zeroth_bit = true;
+  }
+}
 
 // Destructor
 LineTable::~LineTable() {}
@@ -30,6 +36,8 @@
                                 bool is_start_of_basic_block,
                                 bool is_prologue_end, bool is_epilogue_begin,
                                 bool is_terminal_entry) {
+  if (m_clear_address_zeroth_bit)
+    file_addr &= ~1ull;
   Entry entry(file_addr, line, column, file_idx, is_start_of_statement,
               is_start_of_basic_block, is_prologue_end, is_epilogue_begin,
               is_terminal_entry);
@@ -63,6 +71,8 @@
     bool is_terminal_entry) {
   assert(sequence != nullptr);
   LineSequenceImpl *seq = reinterpret_cast<LineSequenceImpl *>(sequence);
+  if (m_clear_address_zeroth_bit)
+    file_addr &= ~1ull;
   Entry entry(file_addr, line, column, file_idx, is_start_of_statement,
               is_start_of_basic_block, is_prologue_end, is_epilogue_begin,
               is_terminal_entry);
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -318,6 +318,8 @@
 
   lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
 
+  dw_addr_t GetAddressMask() const;
+
 protected:
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
       DIEToTypePtr;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4003,3 +4003,12 @@
   });
   return m_dwp_symfile.get();
 }
+
+dw_addr_t SymbolFileDWARF::GetAddressMask() const {
+  if (ArchSpec arch = m_objfile_sp->GetArchitecture()) {
+    if (arch.GetTriple().getArch() == llvm::Triple::arm ||
+        arch.GetTriple().getArch() == llvm::Triple::thumb)
+      return ~1ull;
+  }
+  return ~0ull;
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -59,6 +59,7 @@
 
   // We are in our compile unit, parse starting at the offset we were told to
   // parse
+  m_first_die.SetAddrMask(m_dwarf.GetAddressMask());
   const DWARFDataExtractor &data = GetData();
   if (offset < GetNextUnitOffset() &&
       m_first_die.Extract(data, this, &offset)) {
@@ -155,6 +156,7 @@
   lldb::offset_t next_cu_offset = GetNextUnitOffset();
 
   DWARFDebugInfoEntry die;
+  die.SetAddrMask(m_dwarf.GetAddressMask());
 
   uint32_t depth = 0;
   // We are in our compile unit, parse starting at the offset we were told to
@@ -721,7 +723,7 @@
 
 const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
   if (m_func_aranges_up == nullptr) {
-    m_func_aranges_up.reset(new DWARFDebugAranges());
+    m_func_aranges_up.reset(new DWARFDebugAranges(m_dwarf.GetAddressMask()));
     const DWARFDebugInfoEntry *die = DIEPtr();
     if (die)
       die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get());
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -41,6 +41,8 @@
   bool operator==(const DWARFDebugInfoEntry &rhs) const;
   bool operator!=(const DWARFDebugInfoEntry &rhs) const;
 
+  void SetAddrMask(dw_addr_t addr_mask) { m_addr_mask = addr_mask; }
+
   void BuildAddressRangeTable(const DWARFUnit *cu,
                               DWARFDebugAranges *debug_aranges) const;
 
@@ -185,6 +187,7 @@
   /// A copy of the DW_TAG value so we don't have to go through the compile
   /// unit abbrev table
   dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
+  dw_addr_t m_addr_mask = ~0ull;
 };
 
 #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -255,7 +255,7 @@
       if (form_value.ExtractValue(data, &offset)) {
         switch (attr) {
         case DW_AT_low_pc:
-          lo_pc = form_value.Address();
+          lo_pc = form_value.Address() & m_addr_mask;
 
           if (do_offset)
             hi_pc += lo_pc;
@@ -270,7 +270,7 @@
           if (form_value.Form() == DW_FORM_addr ||
               form_value.Form() == DW_FORM_addrx ||
               form_value.Form() == DW_FORM_GNU_addr_index) {
-            hi_pc = form_value.Address();
+            hi_pc = form_value.Address() & m_addr_mask;
           } else {
             hi_pc = form_value.Unsigned();
             if (lo_pc == LLDB_INVALID_ADDRESS)
@@ -735,7 +735,7 @@
     dw_form_t form = form_value.Form();
     if (form == DW_FORM_addr || form == DW_FORM_addrx ||
         form == DW_FORM_GNU_addr_index)
-      return form_value.Address();
+      return form_value.Address() & m_addr_mask;
 
     // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
     return lo_pc + form_value.Unsigned();
@@ -755,6 +755,7 @@
   lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
                                      check_specification_or_abstract_origin);
   if (lo_pc != fail_value) {
+    lo_pc &= m_addr_mask;
     hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
                                check_specification_or_abstract_origin);
     if (hi_pc != fail_value)
@@ -1125,8 +1126,10 @@
       dw_addr_t lo_pc =
           GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
       if (lo_pc != LLDB_INVALID_ADDRESS) {
+        lo_pc &= m_addr_mask;
         dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
         if (hi_pc != LLDB_INVALID_ADDRESS) {
+          hi_pc &= m_addr_mask;
           //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ",
           //  m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
           if ((lo_pc <= address) && (address < hi_pc)) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -38,7 +38,8 @@
   if (m_cu_aranges_up)
     return *m_cu_aranges_up;
 
-  m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
+  m_cu_aranges_up =
+      std::make_unique<DWARFDebugAranges>(m_dwarf.GetAddressMask());
   const DWARFDataExtractor &debug_aranges_data =
       m_context.getOrLoadArangesData();
   if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -22,7 +22,7 @@
   typedef RangeToDIE::Entry Range;
   typedef std::vector<RangeToDIE::Entry> RangeColl;
 
-  DWARFDebugAranges();
+  DWARFDebugAranges(dw_addr_t addr_mask);
 
   void Clear() { m_aranges.Clear(); }
 
@@ -50,6 +50,7 @@
 
 protected:
   RangeToDIE m_aranges;
+  dw_addr_t m_addr_mask;
 };
 
 #endif // SymbolFileDWARF_DWARFDebugAranges_h_
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -16,7 +16,8 @@
 using namespace lldb_private;
 
 // Constructor
-DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}
+DWARFDebugAranges::DWARFDebugAranges(dw_addr_t addr_mask)
+    : m_aranges(), m_addr_mask(addr_mask) {}
 
 // CountArangeDescriptors
 class CountArangeDescriptors {
@@ -74,7 +75,8 @@
 void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc,
                                     dw_addr_t high_pc) {
   if (high_pc > low_pc)
-    m_aranges.Append(RangeToDIE::Entry(low_pc, high_pc - low_pc, offset));
+    m_aranges.Append(
+        RangeToDIE::Entry(low_pc & m_addr_mask, high_pc - low_pc, offset));
 }
 
 void DWARFDebugAranges::Sort(bool minimize) {
Index: lldb/include/lldb/Symbol/LineTable.h
===================================================================
--- lldb/include/lldb/Symbol/LineTable.h
+++ lldb/include/lldb/Symbol/LineTable.h
@@ -329,6 +329,8 @@
 
 private:
   DISALLOW_COPY_AND_ASSIGN(LineTable);
+
+  bool m_clear_address_zeroth_bit = false;
 };
 
 } // namespace lldb_private
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to