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 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 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/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(); + m_cu_aranges_up = + std::make_unique(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/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 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/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/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 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/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(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/Symbol/ObjectFile.cpp =================================================================== --- lldb/source/Symbol/ObjectFile.cpp +++ lldb/source/Symbol/ObjectFile.cpp @@ -477,7 +477,13 @@ DataExtractor &data) const { // The entire file has already been mmap'ed into m_data, so just copy from // there as the back mmap buffer will be shared with shared pointers. - return data.SetData(m_data, offset, length); + size_t ret = data.SetData(m_data, offset, length); + // DataExtractor::SetData copies the address byte size from m_data, but + // m_data's address byte size is only set from sizeof(void*), and we can't + // access subclasses GetAddressByteSize() when setting up m_data in the + // constructor. + data.SetAddressByteSize(GetAddressByteSize()); + return ret; } size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length, Index: lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg +++ lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg @@ -1 +1 @@ -config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll'] +config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll', '.yaml'] Index: lldb/test/Shell/SymbolFile/DWARF/thumb-windows.yaml =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/thumb-windows.yaml @@ -0,0 +1,125 @@ +# 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. + +# RUN: yaml2obj %s > %t.exe +# 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 + +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4097 + ImageBase: 4194304 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 0 + Size: 0 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 + Debug: + RelativeVirtualAddress: 8192 + Size: 28 + Architecture: + RelativeVirtualAddress: 0 + Size: 0 + GlobalPtr: + RelativeVirtualAddress: 0 + Size: 0 + TlsTable: + RelativeVirtualAddress: 0 + Size: 0 + LoadConfigTable: + RelativeVirtualAddress: 0 + Size: 0 + BoundImport: + RelativeVirtualAddress: 0 + Size: 0 + IAT: + RelativeVirtualAddress: 0 + Size: 0 + DelayImportDescriptor: + RelativeVirtualAddress: 0 + Size: 0 + ClrRuntimeHeader: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_ARMNT + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 12 + SectionData: 014600F000B801EB41007047 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 8192 + VirtualSize: 53 + SectionData: 00000000D7D2DF5D0000000002000000190000001C2000001C06000000000000000000000000000000000000000000000000000000 + - Name: .debug_abbrev + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 12288 + VirtualSize: 46 + SectionData: 01110125251305030E10171B0E110112060000062E01110112064018974219030E3A0B3B0B271949133F19000000 + - Name: .debug_frame + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 16384 + VirtualSize: 52 + SectionData: 10000000FFFFFFFF04000400017C0E0C0D0000000C0000000000000001104000060000000C000000000000000710400006000000 + - Name: .debug_info + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 20480 + VirtualSize: 79 + SectionData: 4B0000000400000000000401000C0000000000000000000E000000011040000C000000060110400006000000015B2100000001023C00000000060710400006000000015B1B00000001063C00000000 + - Name: .debug_line + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 24576 + VirtualSize: 75 + SectionData: 47000000040025000000010101FB0E0D0001010101000000010000010064776172662D7468756D622E630000000000000502011040001305090A14050068050C0A130502064A0202000101 + - Name: .debug_loc + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 28672 + VirtualSize: 30 + SectionData: '000000000200000001005002000000060000000100510000000000000000' + - Name: .debug_str + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 32768 + VirtualSize: 39 + SectionData: 64776172662D7468756D622E63002F706174682F746F2F737263006F7468657200656E74727900 +symbols: +...