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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits