mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 11:57:39 +08:00
[LLDB] - Improved DWARF5 support.
This patch improves the support of DWARF5. Particularly the reporting of source code locations. Differential revision: https://reviews.llvm.org/D51935 llvm-svn: 342153
This commit is contained in:
@@ -57,7 +57,7 @@ enum StateType {
|
|||||||
eStateSuspended, ///< Process or thread is in a suspended state as far
|
eStateSuspended, ///< Process or thread is in a suspended state as far
|
||||||
///< as the debugger is concerned while other processes
|
///< as the debugger is concerned while other processes
|
||||||
///< or threads get the chance to run.
|
///< or threads get the chance to run.
|
||||||
kLastStateType = eStateSuspended
|
kLastStateType = eStateSuspended
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -672,7 +672,8 @@ enum SectionType {
|
|||||||
eSectionTypeDWARFGNUDebugAltLink,
|
eSectionTypeDWARFGNUDebugAltLink,
|
||||||
eSectionTypeDWARFDebugTypes, // DWARF .debug_types section
|
eSectionTypeDWARFDebugTypes, // DWARF .debug_types section
|
||||||
eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names
|
eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names
|
||||||
eSectionTypeOther
|
eSectionTypeOther,
|
||||||
|
eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str
|
||||||
};
|
};
|
||||||
|
|
||||||
FLAGS_ENUM(EmulateInstructionOptions){
|
FLAGS_ENUM(EmulateInstructionOptions){
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import lldb
|
||||||
|
from lldbsuite.test.lldbtest import *
|
||||||
|
from lldbsuite.test.decorators import *
|
||||||
|
|
||||||
|
# This test checks that source code location is shown correctly
|
||||||
|
# when DWARF5 debug information is used.
|
||||||
|
|
||||||
|
class TestTargetSourceMap(TestBase):
|
||||||
|
|
||||||
|
mydir = TestBase.compute_mydir(__file__)
|
||||||
|
|
||||||
|
def test_source_map(self):
|
||||||
|
# Set the target soure map to map "./" to the current test directory.
|
||||||
|
yaml_path = os.path.join(self.getSourceDir(), "a.yaml")
|
||||||
|
yaml_base, ext = os.path.splitext(yaml_path)
|
||||||
|
obj_path = self.getBuildArtifact(yaml_base)
|
||||||
|
self.yaml2obj(yaml_path, obj_path)
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
if os.path.exists(obj_path):
|
||||||
|
os.unlink(obj_path)
|
||||||
|
|
||||||
|
# Execute the cleanup function during test case tear down.
|
||||||
|
self.addTearDownHook(cleanup)
|
||||||
|
|
||||||
|
# Create a target with the object file we just created from YAML
|
||||||
|
target = self.dbg.CreateTarget(obj_path)
|
||||||
|
|
||||||
|
# Check we are able to show the locations properly.
|
||||||
|
self.expect("b main", VALID_BREAKPOINT_LOCATION,
|
||||||
|
substrs=['main + 13 at test.cpp:2:3, address = 0x000000000040052d'])
|
||||||
|
|
||||||
|
self.expect("b foo", VALID_BREAKPOINT_LOCATION,
|
||||||
|
substrs=['foo() + 4 at test.cpp:6:1, address = 0x0000000000400534'])
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# This file is a shorten version of the output
|
||||||
|
# produced with the following invocations and input:
|
||||||
|
# ./clang test.cpp -g -gdwarf-5 -o test.exe
|
||||||
|
# ./obj2yaml test.exe > test.yaml
|
||||||
|
#
|
||||||
|
# // test.cpp
|
||||||
|
# int main() {
|
||||||
|
# return 0;
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# void foo() {
|
||||||
|
# }
|
||||||
|
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
Type: ET_EXEC
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Entry: 0x0000000000400440
|
||||||
|
Sections:
|
||||||
|
- Name: .text
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||||
|
Address: 0x0000000000400440
|
||||||
|
AddressAlign: 0x0000000000000010
|
||||||
|
Content: 31ED4989D15E4889E24883E4F0505449C7C0B005400048C7C14005400048C7C720054000E8B7FFFFFFF4660F1F44000055B820204000483D202040004889E57417B8000000004885C0740D5DBF20204000FFE00F1F4400005DC3660F1F440000BE20204000554881EE202040004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF20204000FFE00F1F005DC3660F1F440000803D391B0000007517554889E5E87EFFFFFFC605271B0000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89660F1F840000000000554889E531C0C745FC000000005DC390554889E55DC3662E0F1F840000000000415741564189FF415541544C8D25B618000055488D2DB6180000534989F64989D54C29E54883EC0848C1FD03E87FFEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3
|
||||||
|
- Name: .debug_str_offsets
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 200000000500000000000000230000002C0000004A0000004F000000530000005B000000
|
||||||
|
- Name: .debug_str
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
Flags: [ SHF_MERGE, SHF_STRINGS ]
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 636C616E672076657273696F6E20382E302E3020287472756E6B203334313935382900746573742E637070002F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E006D61696E00696E74005F5A33666F6F7600666F6F00
|
||||||
|
- Name: .debug_abbrev
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 011101252513050325721710171B25110112060000022E0011011206401803253A0B3B0B49133F190000032E001101120640186E2503253A0B3B0B3F19000004240003253E0B0B0B000000
|
||||||
|
- Name: .debug_info
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 50000000050001080000000001000400010800000000000000022005400000000000160000000220054000000000000F00000001560301014F000000033005400000000000060000000156050601050404050400
|
||||||
|
- Name: .debug_macinfo
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: '00'
|
||||||
|
- Name: .debug_line
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 70000000050008004C000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E021E00000000FD7C0F2E46BA561F7BDA351B04E677091E00000000FD7C0F2E46BA561F7BDA351B04E6770900090220054000000000000105030AC905003F05010A4B0202000101
|
||||||
|
- Name: .debug_line_str
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
Flags: [ SHF_MERGE, SHF_STRINGS ]
|
||||||
|
AddressAlign: 0x0000000000000001
|
||||||
|
Content: 2F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E00746573742E63707000
|
||||||
|
...
|
||||||
@@ -73,6 +73,8 @@ const char *Section::GetTypeAsCString() const {
|
|||||||
return "dwarf-info";
|
return "dwarf-info";
|
||||||
case eSectionTypeDWARFDebugLine:
|
case eSectionTypeDWARFDebugLine:
|
||||||
return "dwarf-line";
|
return "dwarf-line";
|
||||||
|
case eSectionTypeDWARFDebugLineStr:
|
||||||
|
return "dwarf-line-str";
|
||||||
case eSectionTypeDWARFDebugLoc:
|
case eSectionTypeDWARFDebugLoc:
|
||||||
return "dwarf-loc";
|
return "dwarf-loc";
|
||||||
case eSectionTypeDWARFDebugMacInfo:
|
case eSectionTypeDWARFDebugMacInfo:
|
||||||
|
|||||||
@@ -1788,6 +1788,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
|
|||||||
static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
|
static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
|
||||||
static ConstString g_sect_name_dwarf_debug_info(".debug_info");
|
static ConstString g_sect_name_dwarf_debug_info(".debug_info");
|
||||||
static ConstString g_sect_name_dwarf_debug_line(".debug_line");
|
static ConstString g_sect_name_dwarf_debug_line(".debug_line");
|
||||||
|
static ConstString g_sect_name_dwarf_debug_line_str(".debug_line_str");
|
||||||
static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
|
static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
|
||||||
static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
|
static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
|
||||||
static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
|
static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
|
||||||
@@ -1802,6 +1803,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
|
|||||||
".debug_abbrev.dwo");
|
".debug_abbrev.dwo");
|
||||||
static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
|
static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
|
||||||
static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
|
static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
|
||||||
|
static ConstString g_sect_name_dwarf_debug_line_str_dwo(".debug_line_str.dwo");
|
||||||
static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
|
static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
|
||||||
static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
|
static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
|
||||||
static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
|
static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
|
||||||
@@ -1861,6 +1863,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
|
|||||||
sect_type = eSectionTypeDWARFDebugInfo;
|
sect_type = eSectionTypeDWARFDebugInfo;
|
||||||
else if (name == g_sect_name_dwarf_debug_line)
|
else if (name == g_sect_name_dwarf_debug_line)
|
||||||
sect_type = eSectionTypeDWARFDebugLine;
|
sect_type = eSectionTypeDWARFDebugLine;
|
||||||
|
else if (name == g_sect_name_dwarf_debug_line_str)
|
||||||
|
sect_type = eSectionTypeDWARFDebugLineStr;
|
||||||
else if (name == g_sect_name_dwarf_debug_loc)
|
else if (name == g_sect_name_dwarf_debug_loc)
|
||||||
sect_type = eSectionTypeDWARFDebugLoc;
|
sect_type = eSectionTypeDWARFDebugLoc;
|
||||||
else if (name == g_sect_name_dwarf_debug_macinfo)
|
else if (name == g_sect_name_dwarf_debug_macinfo)
|
||||||
@@ -1887,6 +1891,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
|
|||||||
sect_type = eSectionTypeDWARFDebugInfo;
|
sect_type = eSectionTypeDWARFDebugInfo;
|
||||||
else if (name == g_sect_name_dwarf_debug_line_dwo)
|
else if (name == g_sect_name_dwarf_debug_line_dwo)
|
||||||
sect_type = eSectionTypeDWARFDebugLine;
|
sect_type = eSectionTypeDWARFDebugLine;
|
||||||
|
else if (name == g_sect_name_dwarf_debug_line_str_dwo)
|
||||||
|
sect_type = eSectionTypeDWARFDebugLineStr;
|
||||||
else if (name == g_sect_name_dwarf_debug_macro_dwo)
|
else if (name == g_sect_name_dwarf_debug_macro_dwo)
|
||||||
sect_type = eSectionTypeDWARFDebugMacro;
|
sect_type = eSectionTypeDWARFDebugMacro;
|
||||||
else if (name == g_sect_name_dwarf_debug_loc_dwo)
|
else if (name == g_sect_name_dwarf_debug_loc_dwo)
|
||||||
|
|||||||
@@ -1197,6 +1197,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
|
|||||||
case eSectionTypeDWARFDebugFrame:
|
case eSectionTypeDWARFDebugFrame:
|
||||||
case eSectionTypeDWARFDebugInfo:
|
case eSectionTypeDWARFDebugInfo:
|
||||||
case eSectionTypeDWARFDebugLine:
|
case eSectionTypeDWARFDebugLine:
|
||||||
|
case eSectionTypeDWARFDebugLineStr:
|
||||||
case eSectionTypeDWARFDebugLoc:
|
case eSectionTypeDWARFDebugLoc:
|
||||||
case eSectionTypeDWARFDebugMacInfo:
|
case eSectionTypeDWARFDebugMacInfo:
|
||||||
case eSectionTypeDWARFDebugMacro:
|
case eSectionTypeDWARFDebugMacro:
|
||||||
|
|||||||
@@ -34,8 +34,18 @@ DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
|
|||||||
cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
|
cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
|
||||||
cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
|
cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
|
||||||
cu_sp->m_version = debug_info.GetU16(offset_ptr);
|
cu_sp->m_version = debug_info.GetU16(offset_ptr);
|
||||||
abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
|
|
||||||
cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
|
if (cu_sp->m_version == 5) {
|
||||||
|
cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
|
||||||
|
cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
|
||||||
|
abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
|
||||||
|
|
||||||
|
if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
|
||||||
|
cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
|
||||||
|
} else {
|
||||||
|
abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
|
||||||
|
cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
bool length_OK =
|
bool length_OK =
|
||||||
debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
|
debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
|
||||||
@@ -65,6 +75,23 @@ void DWARFCompileUnit::Dump(Stream *s) const {
|
|||||||
GetNextCompileUnitOffset());
|
GetNextCompileUnitOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t DWARFCompileUnit::GetHeaderByteSize() const {
|
||||||
|
if (m_version < 5)
|
||||||
|
return m_is_dwarf64 ? 23 : 11;
|
||||||
|
|
||||||
|
switch (m_unit_type) {
|
||||||
|
case llvm::dwarf::DW_UT_compile:
|
||||||
|
case llvm::dwarf::DW_UT_partial:
|
||||||
|
return 12;
|
||||||
|
case llvm::dwarf::DW_UT_skeleton:
|
||||||
|
case llvm::dwarf::DW_UT_split_compile:
|
||||||
|
return 20;
|
||||||
|
case llvm::dwarf::DW_UT_type:
|
||||||
|
case llvm::dwarf::DW_UT_split_type:
|
||||||
|
return 24;
|
||||||
|
}
|
||||||
|
llvm_unreachable("invalid UnitType.");
|
||||||
|
}
|
||||||
|
|
||||||
const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
|
const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
|
||||||
return m_dwarf->get_debug_info_data();
|
return m_dwarf->get_debug_info_data();
|
||||||
|
|||||||
@@ -35,9 +35,7 @@ public:
|
|||||||
/// @return
|
/// @return
|
||||||
/// Byte size of the compile unit header
|
/// Byte size of the compile unit header
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
uint32_t GetHeaderByteSize() const override {
|
uint32_t GetHeaderByteSize() const override;
|
||||||
return m_is_dwarf64 ? 23 : 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
|
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
|
||||||
|
|||||||
@@ -122,18 +122,25 @@ bool DWARFDebugInfoEntry::FastExtract(
|
|||||||
case DW_FORM_data1:
|
case DW_FORM_data1:
|
||||||
case DW_FORM_flag:
|
case DW_FORM_flag:
|
||||||
case DW_FORM_ref1:
|
case DW_FORM_ref1:
|
||||||
|
case DW_FORM_strx1:
|
||||||
form_size = 1;
|
form_size = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 2 byte values
|
// 2 byte values
|
||||||
case DW_FORM_data2:
|
case DW_FORM_data2:
|
||||||
case DW_FORM_ref2:
|
case DW_FORM_ref2:
|
||||||
|
case DW_FORM_strx2:
|
||||||
form_size = 2;
|
form_size = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DW_FORM_strx3:
|
||||||
|
form_size = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
// 4 byte values
|
// 4 byte values
|
||||||
case DW_FORM_data4:
|
case DW_FORM_data4:
|
||||||
case DW_FORM_ref4:
|
case DW_FORM_ref4:
|
||||||
|
case DW_FORM_strx4:
|
||||||
form_size = 4;
|
form_size = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -150,6 +157,7 @@ bool DWARFDebugInfoEntry::FastExtract(
|
|||||||
case DW_FORM_ref_udata:
|
case DW_FORM_ref_udata:
|
||||||
case DW_FORM_GNU_addr_index:
|
case DW_FORM_GNU_addr_index:
|
||||||
case DW_FORM_GNU_str_index:
|
case DW_FORM_GNU_str_index:
|
||||||
|
case DW_FORM_strx:
|
||||||
debug_info_data.Skip_LEB128(&offset);
|
debug_info_data.Skip_LEB128(&offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
|
|||||||
if (line_table_sp.get() == NULL)
|
if (line_table_sp.get() == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
|
if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
|
||||||
// Make sure we don't don't loop infinitely
|
// Make sure we don't don't loop infinitely
|
||||||
if (offset <= debug_line_offset)
|
if (offset <= debug_line_offset)
|
||||||
break;
|
break;
|
||||||
@@ -127,7 +127,7 @@ DWARFDebugLine::DumpStatementTable(Log *log,
|
|||||||
"--------\n",
|
"--------\n",
|
||||||
debug_line_offset);
|
debug_line_offset);
|
||||||
|
|
||||||
if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
|
if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr))
|
||||||
return offset;
|
return offset;
|
||||||
else
|
else
|
||||||
return debug_line_offset + 1; // Skip to next byte in .debug_line section
|
return debug_line_offset + 1; // Skip to next byte in .debug_line section
|
||||||
@@ -366,17 +366,38 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
|
|||||||
void *userData) {
|
void *userData) {
|
||||||
lldb::offset_t offset = 0;
|
lldb::offset_t offset = 0;
|
||||||
if (debug_line_data.ValidOffset(offset)) {
|
if (debug_line_data.ValidOffset(offset)) {
|
||||||
if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
|
if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
|
||||||
++offset; // Skip to next byte in .debug_line section
|
++offset; // Skip to next byte in .debug_line section
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct EntryDescriptor {
|
||||||
|
dw_sleb128_t code;
|
||||||
|
dw_sleb128_t form;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<EntryDescriptor>
|
||||||
|
ReadDescriptors(const DWARFDataExtractor &debug_line_data,
|
||||||
|
lldb::offset_t *offset_ptr) {
|
||||||
|
std::vector<EntryDescriptor> ret;
|
||||||
|
uint8_t n = debug_line_data.GetU8(offset_ptr);
|
||||||
|
for (uint8_t i = 0; i < n; ++i) {
|
||||||
|
EntryDescriptor ent;
|
||||||
|
ent.code = debug_line_data.GetULEB128(offset_ptr);
|
||||||
|
ent.form = debug_line_data.GetULEB128(offset_ptr);
|
||||||
|
ret.push_back(ent);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// DWARFDebugLine::ParsePrologue
|
// DWARFDebugLine::ParsePrologue
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
|
bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
|
||||||
lldb::offset_t *offset_ptr,
|
lldb::offset_t *offset_ptr,
|
||||||
Prologue *prologue) {
|
Prologue *prologue, DWARFUnit *dwarf_cu) {
|
||||||
const lldb::offset_t prologue_offset = *offset_ptr;
|
const lldb::offset_t prologue_offset = *offset_ptr;
|
||||||
|
|
||||||
// DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
|
// DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
|
||||||
@@ -386,9 +407,14 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
|
|||||||
const char *s;
|
const char *s;
|
||||||
prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
|
prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
|
||||||
prologue->version = debug_line_data.GetU16(offset_ptr);
|
prologue->version = debug_line_data.GetU16(offset_ptr);
|
||||||
if (prologue->version < 2 || prologue->version > 4)
|
if (prologue->version < 2 || prologue->version > 5)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (prologue->version >= 5) {
|
||||||
|
prologue->address_size = debug_line_data.GetU8(offset_ptr);
|
||||||
|
prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
|
prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
|
||||||
const lldb::offset_t end_prologue_offset =
|
const lldb::offset_t end_prologue_offset =
|
||||||
prologue->prologue_length + *offset_ptr;
|
prologue->prologue_length + *offset_ptr;
|
||||||
@@ -410,25 +436,83 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
|
|||||||
prologue->standard_opcode_lengths.push_back(op_len);
|
prologue->standard_opcode_lengths.push_back(op_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*offset_ptr < end_prologue_offset) {
|
if (prologue->version >= 5) {
|
||||||
s = debug_line_data.GetCStr(offset_ptr);
|
std::vector<EntryDescriptor> dirEntryFormatV =
|
||||||
if (s && s[0])
|
ReadDescriptors(debug_line_data, offset_ptr);
|
||||||
prologue->include_directories.push_back(s);
|
uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
|
||||||
else
|
for (int i = 0; i < dirCount; ++i) {
|
||||||
break;
|
for (EntryDescriptor &ent : dirEntryFormatV) {
|
||||||
}
|
DWARFFormValue value(dwarf_cu, ent.form);
|
||||||
|
if (ent.code != DW_LNCT_path) {
|
||||||
|
if (!value.SkipValue(debug_line_data, offset_ptr))
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (*offset_ptr < end_prologue_offset) {
|
if (!value.ExtractValue(debug_line_data, offset_ptr))
|
||||||
const char *name = debug_line_data.GetCStr(offset_ptr);
|
return false;
|
||||||
if (name && name[0]) {
|
prologue->include_directories.push_back(value.AsCString());
|
||||||
FileNameEntry fileEntry;
|
}
|
||||||
fileEntry.name = name;
|
}
|
||||||
fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
|
|
||||||
fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
|
std::vector<EntryDescriptor> filesEntryFormatV =
|
||||||
fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
|
ReadDescriptors(debug_line_data, offset_ptr);
|
||||||
prologue->file_names.push_back(fileEntry);
|
llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
|
||||||
} else
|
uint8_t n = debug_line_data.GetULEB128(offset_ptr);
|
||||||
break;
|
for (int i = 0; i < n; ++i) {
|
||||||
|
FileNameEntry entry;
|
||||||
|
for (EntryDescriptor &ent : filesEntryFormatV) {
|
||||||
|
DWARFFormValue value(dwarf_cu, ent.form);
|
||||||
|
if (!value.ExtractValue(debug_line_data, offset_ptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (ent.code) {
|
||||||
|
case DW_LNCT_path:
|
||||||
|
entry.name = value.AsCString();
|
||||||
|
break;
|
||||||
|
case DW_LNCT_directory_index:
|
||||||
|
entry.dir_idx = value.Unsigned();
|
||||||
|
break;
|
||||||
|
case DW_LNCT_timestamp:
|
||||||
|
entry.mod_time = value.Unsigned();
|
||||||
|
break;
|
||||||
|
case DW_LNCT_size:
|
||||||
|
entry.length = value.Unsigned();
|
||||||
|
break;
|
||||||
|
case DW_LNCT_MD5:
|
||||||
|
assert(value.Unsigned() == 16);
|
||||||
|
std::uninitialized_copy_n(value.BlockData(), 16,
|
||||||
|
entry.checksum.Bytes.begin());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seen.insert(entry.checksum.words()).second)
|
||||||
|
prologue->file_names.push_back(entry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (*offset_ptr < end_prologue_offset) {
|
||||||
|
s = debug_line_data.GetCStr(offset_ptr);
|
||||||
|
if (s && s[0])
|
||||||
|
prologue->include_directories.push_back(s);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*offset_ptr < end_prologue_offset) {
|
||||||
|
const char *name = debug_line_data.GetCStr(offset_ptr);
|
||||||
|
if (name && name[0]) {
|
||||||
|
FileNameEntry fileEntry;
|
||||||
|
fileEntry.name = name;
|
||||||
|
fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
|
||||||
|
fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
|
||||||
|
fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
|
||||||
|
prologue->file_names.push_back(fileEntry);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX GNU as is broken for 64-Bit DWARF
|
// XXX GNU as is broken for 64-Bit DWARF
|
||||||
@@ -445,11 +529,11 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
|
|||||||
bool DWARFDebugLine::ParseSupportFiles(
|
bool DWARFDebugLine::ParseSupportFiles(
|
||||||
const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
|
const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
|
||||||
const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
|
const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
|
||||||
FileSpecList &support_files) {
|
FileSpecList &support_files, DWARFUnit *dwarf_cu) {
|
||||||
lldb::offset_t offset = stmt_list;
|
lldb::offset_t offset = stmt_list;
|
||||||
|
|
||||||
Prologue prologue;
|
Prologue prologue;
|
||||||
if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
|
if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
|
||||||
Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
|
Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
|
||||||
"at 0x%8.8x (parsing ended around "
|
"at 0x%8.8x (parsing ended around "
|
||||||
"0x%8.8" PRIx64 "\n",
|
"0x%8.8" PRIx64 "\n",
|
||||||
@@ -478,7 +562,7 @@ bool DWARFDebugLine::ParseSupportFiles(
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool DWARFDebugLine::ParseStatementTable(
|
bool DWARFDebugLine::ParseStatementTable(
|
||||||
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
|
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
|
||||||
DWARFDebugLine::State::Callback callback, void *userData) {
|
DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
|
||||||
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
|
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
|
||||||
Prologue::shared_ptr prologue(new Prologue());
|
Prologue::shared_ptr prologue(new Prologue());
|
||||||
|
|
||||||
@@ -489,7 +573,7 @@ bool DWARFDebugLine::ParseStatementTable(
|
|||||||
func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
|
func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
|
||||||
debug_line_offset);
|
debug_line_offset);
|
||||||
|
|
||||||
if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
|
if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
|
||||||
if (log)
|
if (log)
|
||||||
log->Error("failed to parse DWARF line table prologue");
|
log->Error("failed to parse DWARF line table prologue");
|
||||||
// Restore our offset and return false to indicate failure!
|
// Restore our offset and return false to indicate failure!
|
||||||
@@ -775,9 +859,9 @@ static void ParseStatementTableCallback(dw_offset_t offset,
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool DWARFDebugLine::ParseStatementTable(
|
bool DWARFDebugLine::ParseStatementTable(
|
||||||
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
|
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
|
||||||
LineTable *line_table) {
|
LineTable *line_table, DWARFUnit *dwarf_cu) {
|
||||||
return ParseStatementTable(debug_line_data, offset_ptr,
|
return ParseStatementTable(debug_line_data, offset_ptr,
|
||||||
ParseStatementTableCallback, line_table);
|
ParseStatementTableCallback, line_table, dwarf_cu);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DWARFDebugLine::Prologue::IsValid() const {
|
inline bool DWARFDebugLine::Prologue::IsValid() const {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
#include "DWARFDataExtractor.h"
|
#include "DWARFDataExtractor.h"
|
||||||
#include "DWARFDefines.h"
|
#include "DWARFDefines.h"
|
||||||
|
|
||||||
|
#include "llvm/Support/MD5.h"
|
||||||
|
|
||||||
|
class DWARFUnit;
|
||||||
class SymbolFileDWARF;
|
class SymbolFileDWARF;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -36,6 +39,7 @@ public:
|
|||||||
dw_sleb128_t dir_idx;
|
dw_sleb128_t dir_idx;
|
||||||
dw_sleb128_t mod_time;
|
dw_sleb128_t mod_time;
|
||||||
dw_sleb128_t length;
|
dw_sleb128_t length;
|
||||||
|
llvm::MD5::MD5Result checksum;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
@@ -55,6 +59,10 @@ public:
|
|||||||
// total_length field itself).
|
// total_length field itself).
|
||||||
uint16_t
|
uint16_t
|
||||||
version; // Version identifier for the statement information format.
|
version; // Version identifier for the statement information format.
|
||||||
|
|
||||||
|
uint8_t address_size;
|
||||||
|
uint8_t segment_selector_size;
|
||||||
|
|
||||||
uint32_t prologue_length; // The number of bytes following the
|
uint32_t prologue_length; // The number of bytes following the
|
||||||
// prologue_length field to the beginning of the
|
// prologue_length field to the beginning of the
|
||||||
// first byte of the statement program itself.
|
// first byte of the statement program itself.
|
||||||
@@ -201,14 +209,15 @@ public:
|
|||||||
const lldb_private::DWARFDataExtractor &debug_line_data,
|
const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
const lldb_private::FileSpec &cu_comp_dir,
|
const lldb_private::FileSpec &cu_comp_dir,
|
||||||
dw_offset_t stmt_list,
|
dw_offset_t stmt_list,
|
||||||
lldb_private::FileSpecList &support_files);
|
lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu);
|
||||||
static bool
|
static bool
|
||||||
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
|
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
lldb::offset_t *offset_ptr, Prologue *prologue);
|
lldb::offset_t *offset_ptr, Prologue *prologue,
|
||||||
|
DWARFUnit *dwarf_cu = nullptr);
|
||||||
static bool
|
static bool
|
||||||
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
lldb::offset_t *offset_ptr, State::Callback callback,
|
lldb::offset_t *offset_ptr, State::Callback callback,
|
||||||
void *userData);
|
void *userData, DWARFUnit *dwarf_cu);
|
||||||
static dw_offset_t
|
static dw_offset_t
|
||||||
DumpStatementTable(lldb_private::Log *log,
|
DumpStatementTable(lldb_private::Log *log,
|
||||||
const lldb_private::DWARFDataExtractor &debug_line_data,
|
const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
@@ -219,7 +228,8 @@ public:
|
|||||||
const dw_offset_t line_offset, uint32_t flags);
|
const dw_offset_t line_offset, uint32_t flags);
|
||||||
static bool
|
static bool
|
||||||
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
lldb::offset_t *offset_ptr, LineTable *line_table);
|
lldb::offset_t *offset_ptr, LineTable *line_table,
|
||||||
|
DWARFUnit *dwarf_cu);
|
||||||
static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
|
static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
|
||||||
DWARFDebugLine::State::Callback callback, void *userData);
|
DWARFDebugLine::State::Callback callback, void *userData);
|
||||||
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
|
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
|
||||||
|
|||||||
@@ -196,6 +196,10 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
|
|||||||
case DW_FORM_data8:
|
case DW_FORM_data8:
|
||||||
m_value.value.uval = data.GetU64(offset_ptr);
|
m_value.value.uval = data.GetU64(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
case DW_FORM_data16:
|
||||||
|
m_value.value.uval = 16;
|
||||||
|
is_block = true;
|
||||||
|
break;
|
||||||
case DW_FORM_string:
|
case DW_FORM_string:
|
||||||
m_value.value.cstr = data.GetCStr(offset_ptr);
|
m_value.value.cstr = data.GetCStr(offset_ptr);
|
||||||
break;
|
break;
|
||||||
@@ -218,10 +222,26 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
|
|||||||
m_value.value.sval = data.GetSLEB128(offset_ptr);
|
m_value.value.sval = data.GetSLEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
case DW_FORM_strp:
|
case DW_FORM_strp:
|
||||||
|
case DW_FORM_line_strp:
|
||||||
assert(m_cu);
|
assert(m_cu);
|
||||||
m_value.value.uval =
|
m_value.value.uval =
|
||||||
data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
|
data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
|
||||||
break;
|
break;
|
||||||
|
case DW_FORM_strx:
|
||||||
|
m_value.value.uval = data.GetULEB128(offset_ptr);
|
||||||
|
break;
|
||||||
|
case DW_FORM_strx1:
|
||||||
|
m_value.value.uval = data.GetU8(offset_ptr);
|
||||||
|
break;
|
||||||
|
case DW_FORM_strx2:
|
||||||
|
m_value.value.uval = data.GetU16(offset_ptr);
|
||||||
|
break;
|
||||||
|
case DW_FORM_strx3:
|
||||||
|
m_value.value.uval = data.GetMaxU64(offset_ptr, 3);
|
||||||
|
break;
|
||||||
|
case DW_FORM_strx4:
|
||||||
|
m_value.value.uval = data.GetU32(offset_ptr);
|
||||||
|
break;
|
||||||
// case DW_FORM_APPLE_db_str:
|
// case DW_FORM_APPLE_db_str:
|
||||||
case DW_FORM_udata:
|
case DW_FORM_udata:
|
||||||
m_value.value.uval = data.GetULEB128(offset_ptr);
|
m_value.value.uval = data.GetULEB128(offset_ptr);
|
||||||
@@ -348,47 +368,56 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
|
|||||||
case DW_FORM_flag_present:
|
case DW_FORM_flag_present:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// 1 byte values
|
// 1 byte values
|
||||||
case DW_FORM_data1:
|
case DW_FORM_data1:
|
||||||
case DW_FORM_flag:
|
case DW_FORM_flag:
|
||||||
case DW_FORM_ref1:
|
case DW_FORM_ref1:
|
||||||
*offset_ptr += 1;
|
case DW_FORM_strx1:
|
||||||
return true;
|
*offset_ptr += 1;
|
||||||
|
return true;
|
||||||
|
|
||||||
// 2 byte values
|
// 2 byte values
|
||||||
case DW_FORM_data2:
|
case DW_FORM_data2:
|
||||||
case DW_FORM_ref2:
|
case DW_FORM_ref2:
|
||||||
*offset_ptr += 2;
|
case DW_FORM_strx2:
|
||||||
return true;
|
*offset_ptr += 2;
|
||||||
|
return true;
|
||||||
|
|
||||||
// 32 bit for DWARF 32, 64 for DWARF 64
|
// 3 byte values
|
||||||
case DW_FORM_sec_offset:
|
case DW_FORM_strx3:
|
||||||
case DW_FORM_strp:
|
*offset_ptr += 3;
|
||||||
assert(cu);
|
return true;
|
||||||
*offset_ptr += (cu->IsDWARF64() ? 8 : 4);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// 4 byte values
|
// 32 bit for DWARF 32, 64 for DWARF 64
|
||||||
case DW_FORM_data4:
|
case DW_FORM_sec_offset:
|
||||||
case DW_FORM_ref4:
|
case DW_FORM_strp:
|
||||||
*offset_ptr += 4;
|
assert(cu);
|
||||||
return true;
|
*offset_ptr += (cu->IsDWARF64() ? 8 : 4);
|
||||||
|
return true;
|
||||||
|
|
||||||
// 8 byte values
|
// 4 byte values
|
||||||
case DW_FORM_data8:
|
case DW_FORM_data4:
|
||||||
case DW_FORM_ref8:
|
case DW_FORM_ref4:
|
||||||
case DW_FORM_ref_sig8:
|
case DW_FORM_strx4:
|
||||||
*offset_ptr += 8;
|
*offset_ptr += 4;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// signed or unsigned LEB 128 values
|
// 8 byte values
|
||||||
case DW_FORM_sdata:
|
case DW_FORM_data8:
|
||||||
case DW_FORM_udata:
|
case DW_FORM_ref8:
|
||||||
case DW_FORM_ref_udata:
|
case DW_FORM_ref_sig8:
|
||||||
case DW_FORM_GNU_addr_index:
|
*offset_ptr += 8;
|
||||||
case DW_FORM_GNU_str_index:
|
return true;
|
||||||
debug_info_data.Skip_LEB128(offset_ptr);
|
|
||||||
return true;
|
// signed or unsigned LEB 128 values
|
||||||
|
case DW_FORM_sdata:
|
||||||
|
case DW_FORM_udata:
|
||||||
|
case DW_FORM_ref_udata:
|
||||||
|
case DW_FORM_GNU_addr_index:
|
||||||
|
case DW_FORM_GNU_str_index:
|
||||||
|
case DW_FORM_strx:
|
||||||
|
debug_info_data.Skip_LEB128(offset_ptr);
|
||||||
|
return true;
|
||||||
|
|
||||||
case DW_FORM_indirect: {
|
case DW_FORM_indirect: {
|
||||||
dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
|
dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
|
||||||
@@ -546,6 +575,39 @@ const char *DWARFFormValue::AsCString() const {
|
|||||||
index_size);
|
index_size);
|
||||||
return symbol_file->get_debug_str_data().PeekCStr(str_offset);
|
return symbol_file->get_debug_str_data().PeekCStr(str_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
|
||||||
|
m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 ||
|
||||||
|
m_form == DW_FORM_strx4) {
|
||||||
|
|
||||||
|
// The same code as above.
|
||||||
|
if (!symbol_file)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
lldb::offset_t baseOffset = 0;
|
||||||
|
const DWARFDataExtractor &strOffsets =
|
||||||
|
symbol_file->get_debug_str_offsets_data();
|
||||||
|
uint64_t length = strOffsets.GetU32(&baseOffset);
|
||||||
|
if (length == 0xffffffff)
|
||||||
|
length = strOffsets.GetU64(&baseOffset);
|
||||||
|
|
||||||
|
// Check version.
|
||||||
|
if (strOffsets.GetU16(&baseOffset) < 5)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Skip padding.
|
||||||
|
baseOffset += 2;
|
||||||
|
|
||||||
|
uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4;
|
||||||
|
lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize;
|
||||||
|
dw_offset_t strOffset =
|
||||||
|
symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize);
|
||||||
|
return symbol_file->get_debug_str_data().PeekCStr(strOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_form == DW_FORM_line_strp)
|
||||||
|
return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,6 +803,11 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
|
|||||||
case DW_FORM_flag:
|
case DW_FORM_flag:
|
||||||
case DW_FORM_sdata:
|
case DW_FORM_sdata:
|
||||||
case DW_FORM_strp:
|
case DW_FORM_strp:
|
||||||
|
case DW_FORM_strx:
|
||||||
|
case DW_FORM_strx1:
|
||||||
|
case DW_FORM_strx2:
|
||||||
|
case DW_FORM_strx3:
|
||||||
|
case DW_FORM_strx4:
|
||||||
case DW_FORM_udata:
|
case DW_FORM_udata:
|
||||||
case DW_FORM_ref_addr:
|
case DW_FORM_ref_addr:
|
||||||
case DW_FORM_ref1:
|
case DW_FORM_ref1:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <stddef.h> // for NULL
|
#include <stddef.h> // for NULL
|
||||||
|
|
||||||
class DWARFUnit;
|
class DWARFUnit;
|
||||||
|
class SymbolFileDWARF;
|
||||||
|
|
||||||
class DWARFFormValue {
|
class DWARFFormValue {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -202,6 +202,8 @@ protected:
|
|||||||
dw_offset_t m_length = 0;
|
dw_offset_t m_length = 0;
|
||||||
uint16_t m_version = 0;
|
uint16_t m_version = 0;
|
||||||
uint8_t m_addr_size = 0;
|
uint8_t m_addr_size = 0;
|
||||||
|
uint8_t m_unit_type = 0;
|
||||||
|
uint64_t m_dwo_id = 0;
|
||||||
DWARFProducer m_producer = eProducerInvalid;
|
DWARFProducer m_producer = eProducerInvalid;
|
||||||
uint32_t m_producer_version_major = 0;
|
uint32_t m_producer_version_major = 0;
|
||||||
uint32_t m_producer_version_minor = 0;
|
uint32_t m_producer_version_minor = 0;
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ void DebugNamesDWARFIndex::GetFunctions(
|
|||||||
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
|
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
|
||||||
std::vector<DWARFDIE> &dies) {
|
std::vector<DWARFDIE> &dies) {
|
||||||
|
|
||||||
m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies);
|
std::vector<DWARFDIE> v;
|
||||||
|
m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v);
|
||||||
|
|
||||||
for (const DebugNames::Entry &entry :
|
for (const DebugNames::Entry &entry :
|
||||||
m_debug_names_up->equal_range(name.GetStringRef())) {
|
m_debug_names_up->equal_range(name.GetStringRef())) {
|
||||||
@@ -235,8 +236,13 @@ void DebugNamesDWARFIndex::GetFunctions(
|
|||||||
|
|
||||||
if (DIERef ref = ToDIERef(entry))
|
if (DIERef ref = ToDIERef(entry))
|
||||||
ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
|
ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
|
||||||
name_type_mask, dies);
|
name_type_mask, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<DWARFDebugInfoEntry *> seen;
|
||||||
|
for (DWARFDIE die : v)
|
||||||
|
if (seen.insert(die.GetDIE()).second)
|
||||||
|
dies.push_back(die);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex,
|
void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex,
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ void SymbolFileDWARF::InitializeObject() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
|
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
|
||||||
return version == 2 || version == 3 || version == 4;
|
return version >= 2 && version <= 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SymbolFileDWARF::CalculateAbilities() {
|
uint32_t SymbolFileDWARF::CalculateAbilities() {
|
||||||
@@ -645,6 +645,10 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
|
|||||||
return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
|
return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() {
|
||||||
|
return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str);
|
||||||
|
}
|
||||||
|
|
||||||
const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
|
const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
|
||||||
return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
|
return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
|
||||||
}
|
}
|
||||||
@@ -933,7 +937,7 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
|
|||||||
support_files.Append(*sc.comp_unit);
|
support_files.Append(*sc.comp_unit);
|
||||||
return DWARFDebugLine::ParseSupportFiles(
|
return DWARFDebugLine::ParseSupportFiles(
|
||||||
sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
|
sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
|
||||||
stmt_list, support_files);
|
stmt_list, support_files, dwarf_cu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1070,7 +1074,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
|
|||||||
lldb::offset_t offset = cu_line_offset;
|
lldb::offset_t offset = cu_line_offset;
|
||||||
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
|
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
|
||||||
ParseDWARFLineTableCallback,
|
ParseDWARFLineTableCallback,
|
||||||
&info);
|
&info, dwarf_cu);
|
||||||
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
|
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
|
||||||
if (debug_map_symfile) {
|
if (debug_map_symfile) {
|
||||||
// We have an object file that has a line table with addresses that
|
// We have an object file that has a line table with addresses that
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ public:
|
|||||||
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
|
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
|
||||||
const lldb_private::DWARFDataExtractor &get_debug_info_data();
|
const lldb_private::DWARFDataExtractor &get_debug_info_data();
|
||||||
const lldb_private::DWARFDataExtractor &get_debug_line_data();
|
const lldb_private::DWARFDataExtractor &get_debug_line_data();
|
||||||
|
const lldb_private::DWARFDataExtractor &get_debug_line_str_data();
|
||||||
const lldb_private::DWARFDataExtractor &get_debug_macro_data();
|
const lldb_private::DWARFDataExtractor &get_debug_macro_data();
|
||||||
const lldb_private::DWARFDataExtractor &get_debug_loc_data();
|
const lldb_private::DWARFDataExtractor &get_debug_loc_data();
|
||||||
const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
|
const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
|
||||||
@@ -466,6 +467,7 @@ protected:
|
|||||||
DWARFDataSegment m_data_debug_frame;
|
DWARFDataSegment m_data_debug_frame;
|
||||||
DWARFDataSegment m_data_debug_info;
|
DWARFDataSegment m_data_debug_info;
|
||||||
DWARFDataSegment m_data_debug_line;
|
DWARFDataSegment m_data_debug_line;
|
||||||
|
DWARFDataSegment m_data_debug_line_str;
|
||||||
DWARFDataSegment m_data_debug_macro;
|
DWARFDataSegment m_data_debug_macro;
|
||||||
DWARFDataSegment m_data_debug_loc;
|
DWARFDataSegment m_data_debug_loc;
|
||||||
DWARFDataSegment m_data_debug_ranges;
|
DWARFDataSegment m_data_debug_ranges;
|
||||||
|
|||||||
@@ -350,6 +350,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
|
|||||||
case eSectionTypeDWARFDebugFrame:
|
case eSectionTypeDWARFDebugFrame:
|
||||||
case eSectionTypeDWARFDebugInfo:
|
case eSectionTypeDWARFDebugInfo:
|
||||||
case eSectionTypeDWARFDebugLine:
|
case eSectionTypeDWARFDebugLine:
|
||||||
|
case eSectionTypeDWARFDebugLineStr:
|
||||||
case eSectionTypeDWARFDebugLoc:
|
case eSectionTypeDWARFDebugLoc:
|
||||||
case eSectionTypeDWARFDebugMacInfo:
|
case eSectionTypeDWARFDebugMacInfo:
|
||||||
case eSectionTypeDWARFDebugMacro:
|
case eSectionTypeDWARFDebugMacro:
|
||||||
|
|||||||
Reference in New Issue
Block a user