diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp | 375 |
1 files changed, 16 insertions, 359 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index d9f50122bd6f..953089fee22b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -1,9 +1,8 @@ //===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -12,12 +11,15 @@ //#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!! #include <assert.h> +#include <memory> + #include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Host/Host.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" +#include "DWARFUnit.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" @@ -25,12 +27,10 @@ using namespace lldb; using namespace lldb_private; using namespace std; -//---------------------------------------------------------------------- // Parse // // Parse all information in the debug_line_data into an internal // representation. -//---------------------------------------------------------------------- void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { m_lineTableMap.clear(); lldb::offset_t offset = 0; @@ -38,7 +38,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { while (debug_line_data.ValidOffset(offset)) { const lldb::offset_t debug_line_offset = offset; - if (line_table_sp.get() == NULL) + if (line_table_sp.get() == nullptr) break; if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) { @@ -48,7 +48,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", // debug_line_offset); m_lineTableMap[debug_line_offset] = line_table_sp; - line_table_sp.reset(new LineTable); + line_table_sp = std::make_shared<LineTable>(); } else ++offset; // Try next byte in line table } @@ -59,9 +59,7 @@ void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) { Parse(debug_line_data); } -//---------------------------------------------------------------------- // DWARFDebugLine::GetLineTable -//---------------------------------------------------------------------- DWARFDebugLine::LineTable::shared_ptr DWARFDebugLine::GetLineTable(const dw_offset_t offset) const { DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr; @@ -71,296 +69,11 @@ DWARFDebugLine::GetLineTable(const dw_offset_t offset) const { return line_table_shared_ptr; } -//---------------------------------------------------------------------- -// DumpStateToFile -//---------------------------------------------------------------------- -static void DumpStateToFile(dw_offset_t offset, - const DWARFDebugLine::State &state, - void *userData) { - Log *log = (Log *)userData; - if (state.row == DWARFDebugLine::State::StartParsingLineTable) { - // If the row is zero we are being called with the prologue only - state.prologue->Dump(log); - log->PutCString("Address Line Column File"); - log->PutCString("------------------ ------ ------ ------"); - } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) { - // Done parsing line table - } else { - log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, - state.column, state.file, state.end_sequence ? " END" : ""); - } -} - -//---------------------------------------------------------------------- -// DWARFDebugLine::DumpLineTableRows -//---------------------------------------------------------------------- -bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data, - dw_offset_t debug_line_offset) { - const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data(); - - if (debug_line_offset == DW_INVALID_OFFSET) { - // Dump line table to a single file only - debug_line_offset = 0; - while (debug_line_data.ValidOffset(debug_line_offset)) - debug_line_offset = - DumpStatementTable(log, debug_line_data, debug_line_offset); - } else { - // Dump line table to a single file only - DumpStatementTable(log, debug_line_data, debug_line_offset); - } - return false; -} - -//---------------------------------------------------------------------- -// DWARFDebugLine::DumpStatementTable -//---------------------------------------------------------------------- -dw_offset_t -DWARFDebugLine::DumpStatementTable(Log *log, - const DWARFDataExtractor &debug_line_data, - const dw_offset_t debug_line_offset) { - if (debug_line_data.ValidOffset(debug_line_offset)) { - lldb::offset_t offset = debug_line_offset; - log->Printf("--------------------------------------------------------------" - "--------\n" - "debug_line[0x%8.8x]\n" - "--------------------------------------------------------------" - "--------\n", - debug_line_offset); - - if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr)) - return offset; - else - return debug_line_offset + 1; // Skip to next byte in .debug_line section - } - - return DW_INVALID_OFFSET; -} - -//---------------------------------------------------------------------- -// DumpOpcodes -//---------------------------------------------------------------------- -bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data, - dw_offset_t debug_line_offset, - uint32_t dump_flags) { - const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data(); - - if (debug_line_data.GetByteSize() == 0) { - log->Printf("< EMPTY >\n"); - return false; - } - - if (debug_line_offset == DW_INVALID_OFFSET) { - // Dump line table to a single file only - debug_line_offset = 0; - while (debug_line_data.ValidOffset(debug_line_offset)) - debug_line_offset = DumpStatementOpcodes(log, debug_line_data, - debug_line_offset, dump_flags); - } else { - // Dump line table to a single file only - DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags); - } - return false; -} - -//---------------------------------------------------------------------- -// DumpStatementOpcodes -//---------------------------------------------------------------------- -dw_offset_t DWARFDebugLine::DumpStatementOpcodes( - Log *log, const DWARFDataExtractor &debug_line_data, - const dw_offset_t debug_line_offset, uint32_t flags) { - lldb::offset_t offset = debug_line_offset; - if (debug_line_data.ValidOffset(offset)) { - Prologue prologue; - - if (ParsePrologue(debug_line_data, &offset, &prologue)) { - log->PutCString("--------------------------------------------------------" - "--------------"); - log->Printf("debug_line[0x%8.8x]", debug_line_offset); - log->PutCString("--------------------------------------------------------" - "--------------\n"); - prologue.Dump(log); - } else { - offset = debug_line_offset; - log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, - debug_line_data.GetU8(&offset)); - return offset; - } - - Row row(prologue.default_is_stmt); - const dw_offset_t end_offset = debug_line_offset + prologue.total_length + - sizeof(prologue.total_length); - - assert(debug_line_data.ValidOffset(end_offset - 1)); - - while (offset < end_offset) { - const uint32_t op_offset = offset; - uint8_t opcode = debug_line_data.GetU8(&offset); - switch (opcode) { - case 0: // Extended Opcodes always start with a zero opcode followed by - { // a uleb128 length so you can skip ones you don't know about - - dw_offset_t ext_offset = offset; - dw_uleb128_t len = debug_line_data.GetULEB128(&offset); - dw_offset_t arg_size = len - (offset - ext_offset); - uint8_t sub_opcode = debug_line_data.GetU8(&offset); - // if (verbose) - // log->Printf( "Extended: <%u> %2.2x ", len, - // sub_opcode); - - switch (sub_opcode) { - case DW_LNE_end_sequence: - log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset); - row.Dump(log); - row.Reset(prologue.default_is_stmt); - break; - - case DW_LNE_set_address: { - row.address = debug_line_data.GetMaxU64(&offset, arg_size); - log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, - row.address); - } break; - - case DW_LNE_define_file: { - FileNameEntry fileEntry; - fileEntry.name = debug_line_data.GetCStr(&offset); - fileEntry.dir_idx = debug_line_data.GetULEB128(&offset); - fileEntry.mod_time = debug_line_data.GetULEB128(&offset); - fileEntry.length = debug_line_data.GetULEB128(&offset); - log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, " - "mod_time=0x%8.8x, length=%i )", - op_offset, fileEntry.name, fileEntry.dir_idx, - fileEntry.mod_time, fileEntry.length); - prologue.file_names.push_back(fileEntry); - } break; - - case DW_LNE_set_discriminator: { - uint64_t discriminator = debug_line_data.GetULEB128(&offset); - log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")", - op_offset, discriminator); - } break; - default: - log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", - op_offset, opcode); - // Length doesn't include the zero opcode byte or the length itself, - // but it does include the sub_opcode, so we have to adjust for that - // below - offset += arg_size; - break; - } - } break; - - // Standard Opcodes - case DW_LNS_copy: - log->Printf("0x%8.8x: DW_LNS_copy", op_offset); - row.Dump(log); - break; - - case DW_LNS_advance_pc: { - dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset); - dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length; - log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset, - addr_offset); - row.address += addr_offset; - } break; - - case DW_LNS_advance_line: { - dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset); - log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset, - line_offset); - row.line += line_offset; - } break; - - case DW_LNS_set_file: - row.file = debug_line_data.GetULEB128(&offset); - log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file); - break; - - case DW_LNS_set_column: - row.column = debug_line_data.GetULEB128(&offset); - log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column); - break; - - case DW_LNS_negate_stmt: - row.is_stmt = !row.is_stmt; - log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset); - break; - - case DW_LNS_set_basic_block: - row.basic_block = true; - log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset); - break; - - case DW_LNS_const_add_pc: { - uint8_t adjust_opcode = 255 - prologue.opcode_base; - dw_addr_t addr_offset = - (adjust_opcode / prologue.line_range) * prologue.min_inst_length; - log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", - op_offset, addr_offset); - row.address += addr_offset; - } break; - - case DW_LNS_fixed_advance_pc: { - uint16_t pc_offset = debug_line_data.GetU16(&offset); - log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, - pc_offset); - row.address += pc_offset; - } break; - - case DW_LNS_set_prologue_end: - row.prologue_end = true; - log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset); - break; - - case DW_LNS_set_epilogue_begin: - row.epilogue_begin = true; - log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset); - break; - - case DW_LNS_set_isa: - row.isa = debug_line_data.GetULEB128(&offset); - log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa); - break; - - // Special Opcodes - default: - if (opcode < prologue.opcode_base) { - // We have an opcode that this parser doesn't know about, skip the - // number of ULEB128 numbers that is says to skip in the prologue's - // standard_opcode_lengths array - uint8_t n = prologue.standard_opcode_lengths[opcode - 1]; - log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.", - op_offset, n); - while (n > 0) { - debug_line_data.GetULEB128(&offset); - --n; - } - } else { - uint8_t adjust_opcode = opcode - prologue.opcode_base; - dw_addr_t addr_offset = - (adjust_opcode / prologue.line_range) * prologue.min_inst_length; - int32_t line_offset = - prologue.line_base + (adjust_opcode % prologue.line_range); - log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", - op_offset, (uint64_t)addr_offset, line_offset); - row.address += addr_offset; - row.line += line_offset; - row.Dump(log); - } - break; - } - } - return end_offset; - } - return DW_INVALID_OFFSET; -} - -//---------------------------------------------------------------------- // Parse // // Parse the entire line table contents calling callback each time a new // prologue is parsed and every time a new row is to be added to the line // table. -//---------------------------------------------------------------------- void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data, DWARFDebugLine::State::Callback callback, void *userData) { @@ -392,9 +105,7 @@ ReadDescriptors(const DWARFDataExtractor &debug_line_data, } } // namespace -//---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue -//---------------------------------------------------------------------- bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, Prologue *prologue, DWARFUnit *dwarf_cu) { @@ -528,8 +239,7 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, bool DWARFDebugLine::ParseSupportFiles( const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, - const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - FileSpecList &support_files, DWARFUnit *dwarf_cu) { + dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) { lldb::offset_t offset = stmt_list; Prologue prologue; @@ -545,7 +255,9 @@ bool DWARFDebugLine::ParseSupportFiles( std::string remapped_file; for (uint32_t file_idx = 1; - prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { + prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(), + dwarf_cu->GetPathStyle(), file_spec); + ++file_idx) { if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) file_spec.SetFile(remapped_file, FileSpec::Style::native); support_files.Append(file_spec); @@ -553,13 +265,11 @@ bool DWARFDebugLine::ParseSupportFiles( return true; } -//---------------------------------------------------------------------- // ParseStatementTable // // Parse a single line table (prologue and all rows) and call the callback // function once for the prologue (row in state will be zero) and each time a // row is to be added to the line table. -//---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) { @@ -832,9 +542,7 @@ bool DWARFDebugLine::ParseStatementTable( return end_offset; } -//---------------------------------------------------------------------- // ParseStatementTableCallback -//---------------------------------------------------------------------- static void ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State &state, void *userData) { @@ -851,12 +559,10 @@ static void ParseStatementTableCallback(dw_offset_t offset, } } -//---------------------------------------------------------------------- // ParseStatementTable // // Parse a line table at offset and populate the LineTable class with the // prologue and all rows. -//---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, LineTable *line_table, DWARFUnit *dwarf_cu) { @@ -868,9 +574,7 @@ inline bool DWARFDebugLine::Prologue::IsValid() const { return SymbolFileDWARF::SupportedVersion(version); } -//---------------------------------------------------------------------- // DWARFDebugLine::Prologue::Dump -//---------------------------------------------------------------------- void DWARFDebugLine::Prologue::Dump(Log *log) { uint32_t i; @@ -909,11 +613,9 @@ void DWARFDebugLine::Prologue::Dump(Log *log) { } } -//---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue::Append // // Append the contents of the prologue to the binary stream buffer -//---------------------------------------------------------------------- // void // DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const //{ @@ -947,10 +649,12 @@ void DWARFDebugLine::Prologue::Dump(Log *log) { //} bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, - const lldb_private::FileSpec &comp_dir, FileSpec &file) const { + const FileSpec &comp_dir, + FileSpec::Style style, + FileSpec &file) const { uint32_t idx = file_idx - 1; // File indexes are 1 based... if (idx < file_names.size()) { - file.SetFile(file_names[idx].name, FileSpec::Style::native); + file.SetFile(file_names[idx].name, style); if (file.IsRelative()) { if (file_names[idx].dir_idx > 0) { const uint32_t dir_idx = file_names[idx].dir_idx - 1; @@ -969,42 +673,18 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, return false; } -//---------------------------------------------------------------------- -// DWARFDebugLine::LineTable::Dump -//---------------------------------------------------------------------- -void DWARFDebugLine::LineTable::Dump(Log *log) const { - if (prologue.get()) - prologue->Dump(log); - - if (!rows.empty()) { - log->PutCString("Address Line Column File ISA Flags"); - log->PutCString( - "------------------ ------ ------ ------ --- -------------"); - Row::const_iterator pos = rows.begin(); - Row::const_iterator end = rows.end(); - while (pos != end) { - (*pos).Dump(log); - ++pos; - } - } -} - void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) { rows.push_back(state); } -//---------------------------------------------------------------------- // Compare function for the binary search in // DWARFDebugLine::LineTable::LookupAddress() -//---------------------------------------------------------------------- static bool FindMatchingAddress(const DWARFDebugLine::Row &row1, const DWARFDebugLine::Row &row2) { return row1.address < row2.address; } -//---------------------------------------------------------------------- // DWARFDebugLine::LineTable::LookupAddress -//---------------------------------------------------------------------- uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const { uint32_t index = UINT32_MAX; @@ -1037,26 +717,20 @@ uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, return index; // Failed to find address } -//---------------------------------------------------------------------- // DWARFDebugLine::Row::Row -//---------------------------------------------------------------------- DWARFDebugLine::Row::Row(bool default_is_stmt) : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt), basic_block(false), end_sequence(false), prologue_end(false), epilogue_begin(false), isa(0) {} -//---------------------------------------------------------------------- // Called after a row is appended to the matrix -//---------------------------------------------------------------------- void DWARFDebugLine::Row::PostAppend() { basic_block = false; prologue_end = false; epilogue_begin = false; } -//---------------------------------------------------------------------- // DWARFDebugLine::Row::Reset -//---------------------------------------------------------------------- void DWARFDebugLine::Row::Reset(bool default_is_stmt) { address = 0; line = 1; @@ -1069,9 +743,7 @@ void DWARFDebugLine::Row::Reset(bool default_is_stmt) { epilogue_begin = false; isa = 0; } -//---------------------------------------------------------------------- // DWARFDebugLine::Row::Dump -//---------------------------------------------------------------------- void DWARFDebugLine::Row::Dump(Log *log) const { log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line, column, file, isa, is_stmt ? " is_stmt" : "", @@ -1081,9 +753,7 @@ void DWARFDebugLine::Row::Dump(Log *log) const { end_sequence ? " end_sequence" : ""); } -//---------------------------------------------------------------------- // Compare function LineTable structures -//---------------------------------------------------------------------- static bool AddressLessThan(const DWARFDebugLine::Row &a, const DWARFDebugLine::Row &b) { return a.address < b.address; @@ -1123,14 +793,7 @@ void DWARFDebugLine::Row::Insert(Row::collection &state_coll, } } -void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) { - std::for_each(state_coll.begin(), state_coll.end(), - bind2nd(std::mem_fun_ref(&Row::Dump), log)); -} - -//---------------------------------------------------------------------- // DWARFDebugLine::State::State -//---------------------------------------------------------------------- DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l, DWARFDebugLine::State::Callback cb, void *userData) : Row(p->default_is_stmt), prologue(p), log(l), callback(cb), @@ -1140,14 +803,10 @@ DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l, callback(0, *this, callbackUserData); } -//---------------------------------------------------------------------- // DWARFDebugLine::State::Reset -//---------------------------------------------------------------------- void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); } -//---------------------------------------------------------------------- // DWARFDebugLine::State::AppendRowToMatrix -//---------------------------------------------------------------------- void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) { // Each time we are to add an entry into the line table matrix call the // callback function so that someone can do something with the current state @@ -1167,9 +826,7 @@ void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) { PostAppend(); } -//---------------------------------------------------------------------- // DWARFDebugLine::State::Finalize -//---------------------------------------------------------------------- void DWARFDebugLine::State::Finalize(dw_offset_t offset) { // Call the callback with a special row state when we are done parsing a line // table |