1 //===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "DWARFDebugLine.h"
11 //#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
16 #include "lldb/Core/FileSpecList.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Host/Host.h"
19 #include "lldb/Utility/Log.h"
20 #include "lldb/Utility/Timer.h"
22 #include "DWARFUnit.h"
23 #include "LogChannelDWARF.h"
24 #include "SymbolFileDWARF.h"
27 using namespace lldb_private;
32 // Parse all information in the debug_line_data into an internal
34 void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
35 m_lineTableMap.clear();
36 lldb::offset_t offset = 0;
37 LineTable::shared_ptr line_table_sp(new LineTable);
38 while (debug_line_data.ValidOffset(offset)) {
39 const lldb::offset_t debug_line_offset = offset;
41 if (line_table_sp.get() == nullptr)
44 if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
45 // Make sure we don't don't loop infinitely
46 if (offset <= debug_line_offset)
48 // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
49 // debug_line_offset);
50 m_lineTableMap[debug_line_offset] = line_table_sp;
51 line_table_sp = std::make_shared<LineTable>();
53 ++offset; // Try next byte in line table
57 void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
58 if (m_lineTableMap.empty())
59 Parse(debug_line_data);
62 // DWARFDebugLine::GetLineTable
63 DWARFDebugLine::LineTable::shared_ptr
64 DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
65 DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
66 LineTableConstIter pos = m_lineTableMap.find(offset);
67 if (pos != m_lineTableMap.end())
68 line_table_shared_ptr = pos->second;
69 return line_table_shared_ptr;
74 // Parse the entire line table contents calling callback each time a new
75 // prologue is parsed and every time a new row is to be added to the line
77 void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
78 DWARFDebugLine::State::Callback callback,
80 lldb::offset_t offset = 0;
81 if (debug_line_data.ValidOffset(offset)) {
82 if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
83 ++offset; // Skip to next byte in .debug_line section
88 struct EntryDescriptor {
93 static std::vector<EntryDescriptor>
94 ReadDescriptors(const DWARFDataExtractor &debug_line_data,
95 lldb::offset_t *offset_ptr) {
96 std::vector<EntryDescriptor> ret;
97 uint8_t n = debug_line_data.GetU8(offset_ptr);
98 for (uint8_t i = 0; i < n; ++i) {
100 ent.code = debug_line_data.GetULEB128(offset_ptr);
101 ent.form = debug_line_data.GetULEB128(offset_ptr);
108 // DWARFDebugLine::ParsePrologue
109 bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
110 lldb::offset_t *offset_ptr,
111 Prologue *prologue, DWARFUnit *dwarf_cu) {
112 const lldb::offset_t prologue_offset = *offset_ptr;
114 // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
119 prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
120 prologue->version = debug_line_data.GetU16(offset_ptr);
121 if (prologue->version < 2 || prologue->version > 5)
124 if (prologue->version >= 5) {
125 prologue->address_size = debug_line_data.GetU8(offset_ptr);
126 prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
129 prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
130 const lldb::offset_t end_prologue_offset =
131 prologue->prologue_length + *offset_ptr;
132 prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
133 if (prologue->version >= 4)
134 prologue->maximum_operations_per_instruction =
135 debug_line_data.GetU8(offset_ptr);
137 prologue->maximum_operations_per_instruction = 1;
138 prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
139 prologue->line_base = debug_line_data.GetU8(offset_ptr);
140 prologue->line_range = debug_line_data.GetU8(offset_ptr);
141 prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
143 prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
145 for (i = 1; i < prologue->opcode_base; ++i) {
146 uint8_t op_len = debug_line_data.GetU8(offset_ptr);
147 prologue->standard_opcode_lengths.push_back(op_len);
150 if (prologue->version >= 5) {
151 std::vector<EntryDescriptor> dirEntryFormatV =
152 ReadDescriptors(debug_line_data, offset_ptr);
153 uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
154 for (int i = 0; i < dirCount; ++i) {
155 for (EntryDescriptor &ent : dirEntryFormatV) {
156 DWARFFormValue value(dwarf_cu, ent.form);
157 if (ent.code != DW_LNCT_path) {
158 if (!value.SkipValue(debug_line_data, offset_ptr))
163 if (!value.ExtractValue(debug_line_data, offset_ptr))
165 prologue->include_directories.push_back(value.AsCString());
169 std::vector<EntryDescriptor> filesEntryFormatV =
170 ReadDescriptors(debug_line_data, offset_ptr);
171 llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
172 uint8_t n = debug_line_data.GetULEB128(offset_ptr);
173 for (int i = 0; i < n; ++i) {
175 for (EntryDescriptor &ent : filesEntryFormatV) {
176 DWARFFormValue value(dwarf_cu, ent.form);
177 if (!value.ExtractValue(debug_line_data, offset_ptr))
182 entry.name = value.AsCString();
184 case DW_LNCT_directory_index:
185 entry.dir_idx = value.Unsigned();
187 case DW_LNCT_timestamp:
188 entry.mod_time = value.Unsigned();
191 entry.length = value.Unsigned();
194 assert(value.Unsigned() == 16);
195 std::uninitialized_copy_n(value.BlockData(), 16,
196 entry.checksum.Bytes.begin());
203 if (seen.insert(entry.checksum.words()).second)
204 prologue->file_names.push_back(entry);
207 while (*offset_ptr < end_prologue_offset) {
208 s = debug_line_data.GetCStr(offset_ptr);
210 prologue->include_directories.push_back(s);
215 while (*offset_ptr < end_prologue_offset) {
216 const char *name = debug_line_data.GetCStr(offset_ptr);
217 if (name && name[0]) {
218 FileNameEntry fileEntry;
219 fileEntry.name = name;
220 fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
221 fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
222 fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
223 prologue->file_names.push_back(fileEntry);
229 // XXX GNU as is broken for 64-Bit DWARF
230 if (*offset_ptr != end_prologue_offset) {
231 Host::SystemLog(Host::eSystemLogWarning,
232 "warning: parsing line table prologue at 0x%8.8" PRIx64
233 " should have ended at 0x%8.8" PRIx64
234 " but it ended at 0x%8.8" PRIx64 "\n",
235 prologue_offset, end_prologue_offset, *offset_ptr);
237 return end_prologue_offset;
240 bool DWARFDebugLine::ParseSupportFiles(
241 const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
242 dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) {
243 lldb::offset_t offset = stmt_list;
246 if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
247 Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
248 "at 0x%8.8x (parsing ended around "
249 "0x%8.8" PRIx64 "\n",
255 std::string remapped_file;
257 for (uint32_t file_idx = 1;
258 prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(),
259 dwarf_cu->GetPathStyle(), file_spec);
261 if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
262 file_spec.SetFile(remapped_file, FileSpec::Style::native);
263 support_files.Append(file_spec);
268 // ParseStatementTable
270 // Parse a single line table (prologue and all rows) and call the callback
271 // function once for the prologue (row in state will be zero) and each time a
272 // row is to be added to the line table.
273 bool DWARFDebugLine::ParseStatementTable(
274 const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
275 DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
276 Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
277 Prologue::shared_ptr prologue(new Prologue());
279 const dw_offset_t debug_line_offset = *offset_ptr;
281 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
283 func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
286 if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
288 log->Error("failed to parse DWARF line table prologue");
289 // Restore our offset and return false to indicate failure!
290 *offset_ptr = debug_line_offset;
297 const dw_offset_t end_offset =
298 debug_line_offset + prologue->total_length +
299 (debug_line_data.GetDWARFSizeofInitialLength());
301 State state(prologue, log, callback, userData);
303 while (*offset_ptr < end_offset) {
304 // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
305 uint8_t opcode = debug_line_data.GetU8(offset_ptr);
308 // Extended Opcodes always start with a zero opcode followed by a uleb128
309 // length so you can skip ones you don't know about
310 lldb::offset_t ext_offset = *offset_ptr;
311 dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
312 dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
314 // DEBUG_PRINTF("Extended: <%2u> ", len);
315 uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
316 switch (sub_opcode) {
317 case DW_LNE_end_sequence:
318 // Set the end_sequence register of the state machine to true and
319 // append a row to the matrix using the current values of the state-
320 // machine registers. Then reset the registers to the initial values
321 // specified above. Every statement program sequence must end with a
322 // DW_LNE_end_sequence instruction which creates a row whose address is
323 // that of the byte after the last target machine instruction of the
325 state.end_sequence = true;
326 state.AppendRowToMatrix(*offset_ptr);
330 case DW_LNE_set_address:
331 // Takes a single relocatable address as an operand. The size of the
332 // operand is the size appropriate to hold an address on the target
333 // machine. Set the address register to the value given by the
334 // relocatable address. All of the other statement program opcodes that
335 // affect the address register add a delta to it. This instruction
336 // stores a relocatable value into it instead.
338 state.address = debug_line_data.GetU32(offset_ptr);
339 else // arg_size == 8
340 state.address = debug_line_data.GetU64(offset_ptr);
343 case DW_LNE_define_file:
344 // Takes 4 arguments. The first is a null terminated string containing
345 // a source file name. The second is an unsigned LEB128 number
346 // representing the directory index of the directory in which the file
347 // was found. The third is an unsigned LEB128 number representing the
348 // time of last modification of the file. The fourth is an unsigned
349 // LEB128 number representing the length in bytes of the file. The time
350 // and length fields may contain LEB128(0) if the information is not
353 // The directory index represents an entry in the include_directories
354 // section of the statement program prologue. The index is LEB128(0) if
355 // the file was found in the current directory of the compilation,
356 // LEB128(1) if it was found in the first directory in the
357 // include_directories section, and so on. The directory index is
358 // ignored for file names that represent full path names.
360 // The files are numbered, starting at 1, in the order in which they
361 // appear; the names in the prologue come before names defined by the
362 // DW_LNE_define_file instruction. These numbers are used in the file
363 // register of the state machine.
365 FileNameEntry fileEntry;
366 fileEntry.name = debug_line_data.GetCStr(offset_ptr);
367 fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
368 fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
369 fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
370 state.prologue->file_names.push_back(fileEntry);
375 // Length doesn't include the zero opcode byte or the length itself,
376 // but it does include the sub_opcode, so we have to adjust for that
378 (*offset_ptr) += arg_size;
381 } else if (opcode < prologue->opcode_base) {
385 // Takes no arguments. Append a row to the matrix using the current
386 // values of the state-machine registers. Then set the basic_block
387 // register to false.
388 state.AppendRowToMatrix(*offset_ptr);
391 case DW_LNS_advance_pc:
392 // Takes a single unsigned LEB128 operand, multiplies it by the
393 // min_inst_length field of the prologue, and adds the result to the
394 // address register of the state machine.
396 debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
399 case DW_LNS_advance_line:
400 // Takes a single signed LEB128 operand and adds that value to the line
401 // register of the state machine.
402 state.line += debug_line_data.GetSLEB128(offset_ptr);
405 case DW_LNS_set_file:
406 // Takes a single unsigned LEB128 operand and stores it in the file
407 // register of the state machine.
408 state.file = debug_line_data.GetULEB128(offset_ptr);
411 case DW_LNS_set_column:
412 // Takes a single unsigned LEB128 operand and stores it in the column
413 // register of the state machine.
414 state.column = debug_line_data.GetULEB128(offset_ptr);
417 case DW_LNS_negate_stmt:
418 // Takes no arguments. Set the is_stmt register of the state machine to
419 // the logical negation of its current value.
420 state.is_stmt = !state.is_stmt;
423 case DW_LNS_set_basic_block:
424 // Takes no arguments. Set the basic_block register of the state
426 state.basic_block = true;
429 case DW_LNS_const_add_pc:
430 // Takes no arguments. Add to the address register of the state machine
431 // the address increment value corresponding to special opcode 255. The
432 // motivation for DW_LNS_const_add_pc is this: when the statement
433 // program needs to advance the address by a small amount, it can use a
434 // single special opcode, which occupies a single byte. When it needs
435 // to advance the address by up to twice the range of the last special
436 // opcode, it can use DW_LNS_const_add_pc followed by a special opcode,
437 // for a total of two bytes. Only if it needs to advance the address by
438 // more than twice that range will it need to use both
439 // DW_LNS_advance_pc and a special opcode, requiring three or more
442 uint8_t adjust_opcode = 255 - prologue->opcode_base;
443 dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
444 prologue->min_inst_length;
445 state.address += addr_offset;
449 case DW_LNS_fixed_advance_pc:
450 // Takes a single uhalf operand. Add to the address register of the
451 // state machine the value of the (unencoded) operand. This is the only
452 // extended opcode that takes an argument that is not a variable length
453 // number. The motivation for DW_LNS_fixed_advance_pc is this: existing
454 // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
455 // they cannot encode LEB128 numbers or judge when the computation of a
456 // special opcode overflows and requires the use of DW_LNS_advance_pc.
457 // Such assemblers, however, can use DW_LNS_fixed_advance_pc instead,
458 // sacrificing compression.
459 state.address += debug_line_data.GetU16(offset_ptr);
462 case DW_LNS_set_prologue_end:
463 // Takes no arguments. Set the prologue_end register of the state
465 state.prologue_end = true;
468 case DW_LNS_set_epilogue_begin:
469 // Takes no arguments. Set the basic_block register of the state
471 state.epilogue_begin = true;
475 // Takes a single unsigned LEB128 operand and stores it in the column
476 // register of the state machine.
477 state.isa = debug_line_data.GetULEB128(offset_ptr);
481 // Handle any unknown standard opcodes here. We know the lengths of
482 // such opcodes because they are specified in the prologue as a
483 // multiple of LEB128 operands for each opcode.
486 assert(static_cast<size_t>(opcode - 1) <
487 prologue->standard_opcode_lengths.size());
488 const uint8_t opcode_length =
489 prologue->standard_opcode_lengths[opcode - 1];
490 for (i = 0; i < opcode_length; ++i)
491 debug_line_data.Skip_LEB128(offset_ptr);
498 // A special opcode value is chosen based on the amount that needs
499 // to be added to the line and address registers. The maximum line
500 // increment for a special opcode is the value of the line_base field in
501 // the header, plus the value of the line_range field, minus 1 (line base
502 // + line range - 1). If the desired line increment is greater than the
503 // maximum line increment, a standard opcode must be used instead of a
504 // special opcode. The "address advance" is calculated by dividing the
505 // desired address increment by the minimum_instruction_length field from
506 // the header. The special opcode is then calculated using the following
509 // opcode = (desired line increment - line_base) + (line_range * address
510 // advance) + opcode_base
512 // If the resulting opcode is greater than 255, a standard opcode must be
515 // To decode a special opcode, subtract the opcode_base from the opcode
516 // itself to give the adjusted opcode. The amount to increment the
517 // address register is the result of the adjusted opcode divided by the
518 // line_range multiplied by the minimum_instruction_length field from the
521 // address increment = (adjusted opcode / line_range) *
522 // minimum_instruction_length
524 // The amount to increment the line register is the line_base plus the
525 // result of the adjusted opcode modulo the line_range. That is:
527 // line increment = line_base + (adjusted opcode % line_range)
529 uint8_t adjust_opcode = opcode - prologue->opcode_base;
530 dw_addr_t addr_offset =
531 (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
532 int32_t line_offset =
533 prologue->line_base + (adjust_opcode % prologue->line_range);
534 state.line += line_offset;
535 state.address += addr_offset;
536 state.AppendRowToMatrix(*offset_ptr);
540 state.Finalize(*offset_ptr);
545 // ParseStatementTableCallback
546 static void ParseStatementTableCallback(dw_offset_t offset,
547 const DWARFDebugLine::State &state,
549 DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
550 if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
551 // Just started parsing the line table, so lets keep a reference to the
552 // prologue using the supplied shared pointer
553 line_table->prologue = state.prologue;
554 } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
555 // Done parsing line table, nothing to do for the cleanup
557 // We have a new row, lets append it
558 line_table->AppendRow(state);
562 // ParseStatementTable
564 // Parse a line table at offset and populate the LineTable class with the
565 // prologue and all rows.
566 bool DWARFDebugLine::ParseStatementTable(
567 const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
568 LineTable *line_table, DWARFUnit *dwarf_cu) {
569 return ParseStatementTable(debug_line_data, offset_ptr,
570 ParseStatementTableCallback, line_table, dwarf_cu);
573 inline bool DWARFDebugLine::Prologue::IsValid() const {
574 return SymbolFileDWARF::SupportedVersion(version);
577 // DWARFDebugLine::Prologue::Dump
578 void DWARFDebugLine::Prologue::Dump(Log *log) {
581 log->Printf("Line table prologue:");
582 log->Printf(" total_length: 0x%8.8x", total_length);
583 log->Printf(" version: %u", version);
584 log->Printf("prologue_length: 0x%8.8x", prologue_length);
585 log->Printf("min_inst_length: %u", min_inst_length);
586 log->Printf("default_is_stmt: %u", default_is_stmt);
587 log->Printf(" line_base: %i", line_base);
588 log->Printf(" line_range: %u", line_range);
589 log->Printf(" opcode_base: %u", opcode_base);
591 for (i = 0; i < standard_opcode_lengths.size(); ++i) {
592 log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
593 standard_opcode_lengths[i]);
596 if (!include_directories.empty()) {
597 for (i = 0; i < include_directories.size(); ++i) {
598 log->Printf("include_directories[%3u] = '%s'", i + 1,
599 include_directories[i]);
603 if (!file_names.empty()) {
604 log->PutCString(" Dir Mod Time File Len File Name");
605 log->PutCString(" ---- ---------- ---------- "
606 "---------------------------");
607 for (i = 0; i < file_names.size(); ++i) {
608 const FileNameEntry &fileEntry = file_names[i];
609 log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
610 fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
616 // DWARFDebugLine::ParsePrologue::Append
618 // Append the contents of the prologue to the binary stream buffer
620 // DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
624 // buff.Append32(total_length);
625 // buff.Append16(version);
626 // buff.Append32(prologue_length);
627 // buff.Append8(min_inst_length);
628 // buff.Append8(default_is_stmt);
629 // buff.Append8(line_base);
630 // buff.Append8(line_range);
631 // buff.Append8(opcode_base);
633 // for (i=0; i<standard_opcode_lengths.size(); ++i)
634 // buff.Append8(standard_opcode_lengths[i]);
636 // for (i=0; i<include_directories.size(); ++i)
637 // buff.AppendCStr(include_directories[i].c_str());
638 // buff.Append8(0); // Terminate the include directory section with empty
641 // for (i=0; i<file_names.size(); ++i)
643 // buff.AppendCStr(file_names[i].name.c_str());
644 // buff.Append32_as_ULEB128(file_names[i].dir_idx);
645 // buff.Append32_as_ULEB128(file_names[i].mod_time);
646 // buff.Append32_as_ULEB128(file_names[i].length);
648 // buff.Append8(0); // Terminate the file names section with empty string
651 bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
652 const FileSpec &comp_dir,
653 FileSpec::Style style,
654 FileSpec &file) const {
655 uint32_t idx = file_idx - 1; // File indexes are 1 based...
656 if (idx < file_names.size()) {
657 file.SetFile(file_names[idx].name, style);
658 if (file.IsRelative()) {
659 if (file_names[idx].dir_idx > 0) {
660 const uint32_t dir_idx = file_names[idx].dir_idx - 1;
661 if (dir_idx < include_directories.size()) {
662 file.PrependPathComponent(include_directories[dir_idx]);
663 if (!file.IsRelative())
669 file.PrependPathComponent(comp_dir);
676 void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
677 rows.push_back(state);
680 // Compare function for the binary search in
681 // DWARFDebugLine::LineTable::LookupAddress()
682 static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
683 const DWARFDebugLine::Row &row2) {
684 return row1.address < row2.address;
687 // DWARFDebugLine::LineTable::LookupAddress
688 uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
689 dw_addr_t cu_high_pc) const {
690 uint32_t index = UINT32_MAX;
692 // Use the lower_bound algorithm to perform a binary search since we know
693 // that our line table data is ordered by address.
694 DWARFDebugLine::Row row;
695 row.address = address;
696 Row::const_iterator begin_pos = rows.begin();
697 Row::const_iterator end_pos = rows.end();
698 Row::const_iterator pos =
699 lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
700 if (pos == end_pos) {
701 if (address < cu_high_pc)
702 return rows.size() - 1;
704 // Rely on fact that we are using a std::vector and we can do pointer
705 // arithmetic to find the row index (which will be one less that what we
706 // found since it will find the first position after the current address)
707 // since std::vector iterators are just pointers to the container type.
708 index = pos - begin_pos;
709 if (pos->address > address) {
717 return index; // Failed to find address
720 // DWARFDebugLine::Row::Row
721 DWARFDebugLine::Row::Row(bool default_is_stmt)
722 : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
723 basic_block(false), end_sequence(false), prologue_end(false),
724 epilogue_begin(false), isa(0) {}
726 // Called after a row is appended to the matrix
727 void DWARFDebugLine::Row::PostAppend() {
729 prologue_end = false;
730 epilogue_begin = false;
733 // DWARFDebugLine::Row::Reset
734 void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
739 is_stmt = default_is_stmt;
741 end_sequence = false;
742 prologue_end = false;
743 epilogue_begin = false;
746 // DWARFDebugLine::Row::Dump
747 void DWARFDebugLine::Row::Dump(Log *log) const {
748 log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
749 column, file, isa, is_stmt ? " is_stmt" : "",
750 basic_block ? " basic_block" : "",
751 prologue_end ? " prologue_end" : "",
752 epilogue_begin ? " epilogue_begin" : "",
753 end_sequence ? " end_sequence" : "");
756 // Compare function LineTable structures
757 static bool AddressLessThan(const DWARFDebugLine::Row &a,
758 const DWARFDebugLine::Row &b) {
759 return a.address < b.address;
762 // Insert a row at the correct address if the addresses can be out of order
763 // which can only happen when we are linking a line table that may have had
764 // it's contents rearranged.
765 void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
767 // If we don't have anything yet, or if the address of the last state in our
768 // line table is less than the current one, just append the current state
769 if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
770 state_coll.push_back(state);
772 // Do a binary search for the correct entry
773 pair<Row::iterator, Row::iterator> range(equal_range(
774 state_coll.begin(), state_coll.end(), state, AddressLessThan));
776 // If the addresses are equal, we can safely replace the previous entry
777 // with the current one if the one it is replacing is an end_sequence
778 // entry. We currently always place an extra end sequence when ever we exit
779 // a valid address range for a function in case the functions get
780 // rearranged by optimizations or by order specifications. These extra end
781 // sequences will disappear by getting replaced with valid consecutive
782 // entries within a compile unit if there are no gaps.
783 if (range.first == range.second) {
784 state_coll.insert(range.first, state);
786 if ((distance(range.first, range.second) == 1) &&
787 range.first->end_sequence == true) {
788 *range.first = state;
790 state_coll.insert(range.second, state);
796 // DWARFDebugLine::State::State
797 DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
798 DWARFDebugLine::State::Callback cb, void *userData)
799 : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
800 callbackUserData(userData), row(StartParsingLineTable) {
801 // Call the callback with the initial row state of zero for the prologue
803 callback(0, *this, callbackUserData);
806 // DWARFDebugLine::State::Reset
807 void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
809 // DWARFDebugLine::State::AppendRowToMatrix
810 void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
811 // Each time we are to add an entry into the line table matrix call the
812 // callback function so that someone can do something with the current state
813 // of the state machine (like build a line table or dump the line table!)
816 log->PutCString("Address Line Column File ISA Flags");
818 "------------------ ------ ------ ------ --- -------------");
823 ++row; // Increase the row number before we call our callback for a real row
825 callback(offset, *this, callbackUserData);
829 // DWARFDebugLine::State::Finalize
830 void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
831 // Call the callback with a special row state when we are done parsing a line
833 row = DoneParsingLineTable;
835 callback(offset, *this, callbackUserData);
839 // DWARFDebugLine::AppendLineTableData
841 // const DWARFDebugLine::Prologue* prologue,
842 // const DWARFDebugLine::Row::collection& state_coll,
843 // const uint32_t addr_size,
844 // BinaryStreamBuf &debug_line_data
847 // if (state_coll.empty())
849 // // We have no entries, just make an empty line table
850 // debug_line_data.Append8(0);
851 // debug_line_data.Append8(1);
852 // debug_line_data.Append8(DW_LNE_end_sequence);
856 // DWARFDebugLine::Row::const_iterator pos;
857 // Row::const_iterator end = state_coll.end();
858 // bool default_is_stmt = prologue->default_is_stmt;
859 // const DWARFDebugLine::Row reset_state(default_is_stmt);
860 // const DWARFDebugLine::Row* prev_state = &reset_state;
861 // const int32_t max_line_increment_for_special_opcode =
862 // prologue->MaxLineIncrementForSpecialOpcode();
863 // for (pos = state_coll.begin(); pos != end; ++pos)
865 // const DWARFDebugLine::Row& curr_state = *pos;
866 // int32_t line_increment = 0;
867 // dw_addr_t addr_offset = curr_state.address - prev_state->address;
868 // dw_addr_t addr_advance = (addr_offset) / prologue->min_inst_length;
869 // line_increment = (int32_t)(curr_state.line - prev_state->line);
871 // // If our previous state was the reset state, then let's emit the
872 // // address to keep GDB's DWARF parser happy. If we don't start each
873 // // sequence with a DW_LNE_set_address opcode, the line table won't
874 // // get slid properly in GDB.
876 // if (prev_state == &reset_state)
878 // debug_line_data.Append8(0); // Extended opcode
879 // debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
881 // debug_line_data.Append8(DW_LNE_set_address);
882 // debug_line_data.AppendMax64(curr_state.address, addr_size);
886 // if (prev_state->file != curr_state.file)
888 // debug_line_data.Append8(DW_LNS_set_file);
889 // debug_line_data.Append32_as_ULEB128(curr_state.file);
892 // if (prev_state->column != curr_state.column)
894 // debug_line_data.Append8(DW_LNS_set_column);
895 // debug_line_data.Append32_as_ULEB128(curr_state.column);
898 // // Don't do anything fancy if we are at the end of a sequence
899 // // as we don't want to push any extra rows since the
900 // DW_LNE_end_sequence
901 // // will push a row itself!
902 // if (curr_state.end_sequence)
904 // if (line_increment != 0)
906 // debug_line_data.Append8(DW_LNS_advance_line);
907 // debug_line_data.Append32_as_SLEB128(line_increment);
910 // if (addr_advance > 0)
912 // debug_line_data.Append8(DW_LNS_advance_pc);
913 // debug_line_data.Append32_as_ULEB128(addr_advance);
916 // // Now push the end sequence on!
917 // debug_line_data.Append8(0);
918 // debug_line_data.Append8(1);
919 // debug_line_data.Append8(DW_LNE_end_sequence);
921 // prev_state = &reset_state;
925 // if (line_increment || addr_advance)
927 // if (line_increment > max_line_increment_for_special_opcode)
929 // debug_line_data.Append8(DW_LNS_advance_line);
930 // debug_line_data.Append32_as_SLEB128(line_increment);
931 // line_increment = 0;
934 // uint32_t special_opcode = (line_increment >=
935 // prologue->line_base) ? ((line_increment -
936 // prologue->line_base) + (prologue->line_range * addr_advance)
937 // + prologue->opcode_base) : 256;
938 // if (special_opcode > 255)
940 // // Both the address and line won't fit in one special
942 // // check to see if just the line advance will?
943 // uint32_t special_opcode_line = ((line_increment >=
944 // prologue->line_base) && (line_increment != 0)) ?
945 // ((line_increment - prologue->line_base) +
946 // prologue->opcode_base) : 256;
949 // if (special_opcode_line > 255)
951 // // Nope, the line advance won't fit by itself, check
952 // the address increment by itself
953 // uint32_t special_opcode_addr = addr_advance ?
954 // ((0 - prologue->line_base) +
955 // (prologue->line_range * addr_advance) +
956 // prologue->opcode_base) : 256;
958 // if (special_opcode_addr > 255)
960 // // Neither the address nor the line will fit in
962 // // special opcode, we must manually enter both
964 // // do a DW_LNS_copy to push a row (special
966 // // automatically imply a new row is pushed)
967 // if (line_increment != 0)
969 // debug_line_data.Append8(DW_LNS_advance_line);
970 // debug_line_data.Append32_as_SLEB128(line_increment);
973 // if (addr_advance > 0)
975 // debug_line_data.Append8(DW_LNS_advance_pc);
976 // debug_line_data.Append32_as_ULEB128(addr_advance);
979 // // Now push a row onto the line table manually
980 // debug_line_data.Append8(DW_LNS_copy);
985 // // The address increment alone will fit into a
987 // // so modify our line change, then issue a
989 // // for the address increment and it will push a
992 // if (line_increment != 0)
994 // debug_line_data.Append8(DW_LNS_advance_line);
995 // debug_line_data.Append32_as_SLEB128(line_increment);
998 // // Advance of line and address will fit into a
999 // single byte special opcode
1000 // // and this will also push a row onto the line
1002 // debug_line_data.Append8(special_opcode_addr);
1007 // // The line change alone will fit into a special
1009 // // so modify our address increment first, then issue
1011 // // special opcode for the line change and it will
1013 // // a row into the line table
1014 // if (addr_advance > 0)
1016 // debug_line_data.Append8(DW_LNS_advance_pc);
1017 // debug_line_data.Append32_as_ULEB128(addr_advance);
1020 // // Advance of line and address will fit into a
1021 // single byte special opcode
1022 // // and this will also push a row onto the line table
1023 // debug_line_data.Append8(special_opcode_line);
1028 // // Advance of line and address will fit into a single
1029 // byte special opcode
1030 // // and this will also push a row onto the line table
1031 // debug_line_data.Append8(special_opcode);
1034 // prev_state = &curr_state;