]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
Update to bmake-201802222
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFDebugLine.cpp
1 //===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DWARFDebugLine.h"
11
12 //#define ENABLE_DEBUG_PRINTF   // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
13 #include <assert.h>
14
15 #include "lldb/Core/FileSpecList.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Host/Host.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/Timer.h"
20
21 #include "LogChannelDWARF.h"
22 #include "SymbolFileDWARF.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26 using namespace std;
27
28 //----------------------------------------------------------------------
29 // Parse
30 //
31 // Parse all information in the debug_line_data into an internal
32 // representation.
33 //----------------------------------------------------------------------
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;
40
41     if (line_table_sp.get() == NULL)
42       break;
43
44     if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
45       // Make sure we don't don't loop infinitely
46       if (offset <= debug_line_offset)
47         break;
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.reset(new LineTable);
52     } else
53       ++offset; // Try next byte in line table
54   }
55 }
56
57 void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
58   if (m_lineTableMap.empty())
59     Parse(debug_line_data);
60 }
61
62 //----------------------------------------------------------------------
63 // DWARFDebugLine::GetLineTable
64 //----------------------------------------------------------------------
65 DWARFDebugLine::LineTable::shared_ptr
66 DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
67   DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
68   LineTableConstIter pos = m_lineTableMap.find(offset);
69   if (pos != m_lineTableMap.end())
70     line_table_shared_ptr = pos->second;
71   return line_table_shared_ptr;
72 }
73
74 //----------------------------------------------------------------------
75 // DumpStateToFile
76 //----------------------------------------------------------------------
77 static void DumpStateToFile(dw_offset_t offset,
78                             const DWARFDebugLine::State &state,
79                             void *userData) {
80   Log *log = (Log *)userData;
81   if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
82     // If the row is zero we are being called with the prologue only
83     state.prologue->Dump(log);
84     log->PutCString("Address            Line   Column File");
85     log->PutCString("------------------ ------ ------ ------");
86   } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
87     // Done parsing line table
88   } else {
89     log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line,
90                 state.column, state.file, state.end_sequence ? " END" : "");
91   }
92 }
93
94 //----------------------------------------------------------------------
95 // DWARFDebugLine::DumpLineTableRows
96 //----------------------------------------------------------------------
97 bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data,
98                                        dw_offset_t debug_line_offset) {
99   const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
100
101   if (debug_line_offset == DW_INVALID_OFFSET) {
102     // Dump line table to a single file only
103     debug_line_offset = 0;
104     while (debug_line_data.ValidOffset(debug_line_offset))
105       debug_line_offset =
106           DumpStatementTable(log, debug_line_data, debug_line_offset);
107   } else {
108     // Dump line table to a single file only
109     DumpStatementTable(log, debug_line_data, debug_line_offset);
110   }
111   return false;
112 }
113
114 //----------------------------------------------------------------------
115 // DWARFDebugLine::DumpStatementTable
116 //----------------------------------------------------------------------
117 dw_offset_t
118 DWARFDebugLine::DumpStatementTable(Log *log,
119                                    const DWARFDataExtractor &debug_line_data,
120                                    const dw_offset_t debug_line_offset) {
121   if (debug_line_data.ValidOffset(debug_line_offset)) {
122     lldb::offset_t offset = debug_line_offset;
123     log->Printf("--------------------------------------------------------------"
124                 "--------\n"
125                 "debug_line[0x%8.8x]\n"
126                 "--------------------------------------------------------------"
127                 "--------\n",
128                 debug_line_offset);
129
130     if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
131       return offset;
132     else
133       return debug_line_offset + 1; // Skip to next byte in .debug_line section
134   }
135
136   return DW_INVALID_OFFSET;
137 }
138
139 //----------------------------------------------------------------------
140 // DumpOpcodes
141 //----------------------------------------------------------------------
142 bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data,
143                                  dw_offset_t debug_line_offset,
144                                  uint32_t dump_flags) {
145   const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
146
147   if (debug_line_data.GetByteSize() == 0) {
148     log->Printf("< EMPTY >\n");
149     return false;
150   }
151
152   if (debug_line_offset == DW_INVALID_OFFSET) {
153     // Dump line table to a single file only
154     debug_line_offset = 0;
155     while (debug_line_data.ValidOffset(debug_line_offset))
156       debug_line_offset = DumpStatementOpcodes(log, debug_line_data,
157                                                debug_line_offset, dump_flags);
158   } else {
159     // Dump line table to a single file only
160     DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags);
161   }
162   return false;
163 }
164
165 //----------------------------------------------------------------------
166 // DumpStatementOpcodes
167 //----------------------------------------------------------------------
168 dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
169     Log *log, const DWARFDataExtractor &debug_line_data,
170     const dw_offset_t debug_line_offset, uint32_t flags) {
171   lldb::offset_t offset = debug_line_offset;
172   if (debug_line_data.ValidOffset(offset)) {
173     Prologue prologue;
174
175     if (ParsePrologue(debug_line_data, &offset, &prologue)) {
176       log->PutCString("--------------------------------------------------------"
177                       "--------------");
178       log->Printf("debug_line[0x%8.8x]", debug_line_offset);
179       log->PutCString("--------------------------------------------------------"
180                       "--------------\n");
181       prologue.Dump(log);
182     } else {
183       offset = debug_line_offset;
184       log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset,
185                   debug_line_data.GetU8(&offset));
186       return offset;
187     }
188
189     Row row(prologue.default_is_stmt);
190     const dw_offset_t end_offset = debug_line_offset + prologue.total_length +
191                                    sizeof(prologue.total_length);
192
193     assert(debug_line_data.ValidOffset(end_offset - 1));
194
195     while (offset < end_offset) {
196       const uint32_t op_offset = offset;
197       uint8_t opcode = debug_line_data.GetU8(&offset);
198       switch (opcode) {
199       case 0: // Extended Opcodes always start with a zero opcode followed by
200       {       // a uleb128 length so you can skip ones you don't know about
201
202         dw_offset_t ext_offset = offset;
203         dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
204         dw_offset_t arg_size = len - (offset - ext_offset);
205         uint8_t sub_opcode = debug_line_data.GetU8(&offset);
206         //                    if (verbose)
207         //                        log->Printf( "Extended: <%u> %2.2x ", len,
208         //                        sub_opcode);
209
210         switch (sub_opcode) {
211         case DW_LNE_end_sequence:
212           log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset);
213           row.Dump(log);
214           row.Reset(prologue.default_is_stmt);
215           break;
216
217         case DW_LNE_set_address: {
218           row.address = debug_line_data.GetMaxU64(&offset, arg_size);
219           log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset,
220                       row.address);
221         } break;
222
223         case DW_LNE_define_file: {
224           FileNameEntry fileEntry;
225           fileEntry.name = debug_line_data.GetCStr(&offset);
226           fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
227           fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
228           fileEntry.length = debug_line_data.GetULEB128(&offset);
229           log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, "
230                       "mod_time=0x%8.8x, length=%i )",
231                       op_offset, fileEntry.name, fileEntry.dir_idx,
232                       fileEntry.mod_time, fileEntry.length);
233           prologue.file_names.push_back(fileEntry);
234         } break;
235
236         case DW_LNE_set_discriminator: {
237           uint64_t discriminator = debug_line_data.GetULEB128(&offset);
238           log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")",
239                       op_offset, discriminator);
240         } break;
241         default:
242           log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode",
243                       op_offset, opcode);
244           // Length doesn't include the zero opcode byte or the length itself,
245           // but
246           // it does include the sub_opcode, so we have to adjust for that below
247           offset += arg_size;
248           break;
249         }
250       } break;
251
252       // Standard Opcodes
253       case DW_LNS_copy:
254         log->Printf("0x%8.8x: DW_LNS_copy", op_offset);
255         row.Dump(log);
256         break;
257
258       case DW_LNS_advance_pc: {
259         dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
260         dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
261         log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset,
262                     addr_offset);
263         row.address += addr_offset;
264       } break;
265
266       case DW_LNS_advance_line: {
267         dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
268         log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset,
269                     line_offset);
270         row.line += line_offset;
271       } break;
272
273       case DW_LNS_set_file:
274         row.file = debug_line_data.GetULEB128(&offset);
275         log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
276         break;
277
278       case DW_LNS_set_column:
279         row.column = debug_line_data.GetULEB128(&offset);
280         log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
281         break;
282
283       case DW_LNS_negate_stmt:
284         row.is_stmt = !row.is_stmt;
285         log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset);
286         break;
287
288       case DW_LNS_set_basic_block:
289         row.basic_block = true;
290         log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset);
291         break;
292
293       case DW_LNS_const_add_pc: {
294         uint8_t adjust_opcode = 255 - prologue.opcode_base;
295         dw_addr_t addr_offset =
296             (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
297         log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")",
298                     op_offset, addr_offset);
299         row.address += addr_offset;
300       } break;
301
302       case DW_LNS_fixed_advance_pc: {
303         uint16_t pc_offset = debug_line_data.GetU16(&offset);
304         log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset,
305                     pc_offset);
306         row.address += pc_offset;
307       } break;
308
309       case DW_LNS_set_prologue_end:
310         row.prologue_end = true;
311         log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset);
312         break;
313
314       case DW_LNS_set_epilogue_begin:
315         row.epilogue_begin = true;
316         log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
317         break;
318
319       case DW_LNS_set_isa:
320         row.isa = debug_line_data.GetULEB128(&offset);
321         log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
322         break;
323
324       // Special Opcodes
325       default:
326         if (opcode < prologue.opcode_base) {
327           // We have an opcode that this parser doesn't know about, skip
328           // the number of ULEB128 numbers that is says to skip in the
329           // prologue's standard_opcode_lengths array
330           uint8_t n = prologue.standard_opcode_lengths[opcode - 1];
331           log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.",
332                       op_offset, n);
333           while (n > 0) {
334             debug_line_data.GetULEB128(&offset);
335             --n;
336           }
337         } else {
338           uint8_t adjust_opcode = opcode - prologue.opcode_base;
339           dw_addr_t addr_offset =
340               (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
341           int32_t line_offset =
342               prologue.line_base + (adjust_opcode % prologue.line_range);
343           log->Printf("0x%8.8x: address += 0x%" PRIx64 ",  line += %i\n",
344                       op_offset, (uint64_t)addr_offset, line_offset);
345           row.address += addr_offset;
346           row.line += line_offset;
347           row.Dump(log);
348         }
349         break;
350       }
351     }
352     return end_offset;
353   }
354   return DW_INVALID_OFFSET;
355 }
356
357 //----------------------------------------------------------------------
358 // Parse
359 //
360 // Parse the entire line table contents calling callback each time a
361 // new prologue is parsed and every time a new row is to be added to
362 // the line table.
363 //----------------------------------------------------------------------
364 void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
365                            DWARFDebugLine::State::Callback callback,
366                            void *userData) {
367   lldb::offset_t offset = 0;
368   if (debug_line_data.ValidOffset(offset)) {
369     if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
370       ++offset; // Skip to next byte in .debug_line section
371   }
372 }
373
374 //----------------------------------------------------------------------
375 // DWARFDebugLine::ParsePrologue
376 //----------------------------------------------------------------------
377 bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
378                                    lldb::offset_t *offset_ptr,
379                                    Prologue *prologue) {
380   const lldb::offset_t prologue_offset = *offset_ptr;
381
382   // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
383
384   prologue->Clear();
385   uint32_t i;
386   const char *s;
387   prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
388   prologue->version = debug_line_data.GetU16(offset_ptr);
389   if (prologue->version < 2 || prologue->version > 4)
390     return false;
391
392   prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
393   const lldb::offset_t end_prologue_offset =
394       prologue->prologue_length + *offset_ptr;
395   prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
396   if (prologue->version >= 4)
397     prologue->maximum_operations_per_instruction =
398         debug_line_data.GetU8(offset_ptr);
399   else
400     prologue->maximum_operations_per_instruction = 1;
401   prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
402   prologue->line_base = debug_line_data.GetU8(offset_ptr);
403   prologue->line_range = debug_line_data.GetU8(offset_ptr);
404   prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
405
406   prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
407
408   for (i = 1; i < prologue->opcode_base; ++i) {
409     uint8_t op_len = debug_line_data.GetU8(offset_ptr);
410     prologue->standard_opcode_lengths.push_back(op_len);
411   }
412
413   while (*offset_ptr < end_prologue_offset) {
414     s = debug_line_data.GetCStr(offset_ptr);
415     if (s && s[0])
416       prologue->include_directories.push_back(s);
417     else
418       break;
419   }
420
421   while (*offset_ptr < end_prologue_offset) {
422     const char *name = debug_line_data.GetCStr(offset_ptr);
423     if (name && name[0]) {
424       FileNameEntry fileEntry;
425       fileEntry.name = name;
426       fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
427       fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
428       fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
429       prologue->file_names.push_back(fileEntry);
430     } else
431       break;
432   }
433
434   // XXX GNU as is broken for 64-Bit DWARF
435   if (*offset_ptr != end_prologue_offset) {
436     Host::SystemLog(Host::eSystemLogWarning,
437                     "warning: parsing line table prologue at 0x%8.8" PRIx64
438                     " should have ended at 0x%8.8" PRIx64
439                     " but it ended at 0x%8.8" PRIx64 "\n",
440                     prologue_offset, end_prologue_offset, *offset_ptr);
441   }
442   return end_prologue_offset;
443 }
444
445 bool DWARFDebugLine::ParseSupportFiles(
446     const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
447     const char *cu_comp_dir, dw_offset_t stmt_list,
448     FileSpecList &support_files) {
449   lldb::offset_t offset = stmt_list;
450
451   Prologue prologue;
452   if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
453     Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
454                                            "at 0x%8.8x (parsing ended around "
455                                            "0x%8.8" PRIx64 "\n",
456                     stmt_list, offset);
457     return false;
458   }
459
460   FileSpec file_spec;
461   std::string remapped_file;
462
463   for (uint32_t file_idx = 1;
464        prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) {
465     if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
466       file_spec.SetFile(remapped_file, false);
467     support_files.Append(file_spec);
468   }
469   return true;
470 }
471
472 //----------------------------------------------------------------------
473 // ParseStatementTable
474 //
475 // Parse a single line table (prologue and all rows) and call the
476 // callback function once for the prologue (row in state will be zero)
477 // and each time a row is to be added to the line table.
478 //----------------------------------------------------------------------
479 bool DWARFDebugLine::ParseStatementTable(
480     const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
481     DWARFDebugLine::State::Callback callback, void *userData) {
482   Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
483   Prologue::shared_ptr prologue(new Prologue());
484
485   const dw_offset_t debug_line_offset = *offset_ptr;
486
487   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
488   Timer scoped_timer(
489       func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
490       debug_line_offset);
491
492   if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
493     if (log)
494       log->Error("failed to parse DWARF line table prologue");
495     // Restore our offset and return false to indicate failure!
496     *offset_ptr = debug_line_offset;
497     return false;
498   }
499
500   if (log)
501     prologue->Dump(log);
502
503   const dw_offset_t end_offset =
504       debug_line_offset + prologue->total_length +
505       (debug_line_data.GetDWARFSizeofInitialLength());
506
507   State state(prologue, log, callback, userData);
508
509   while (*offset_ptr < end_offset) {
510     // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
511     uint8_t opcode = debug_line_data.GetU8(offset_ptr);
512
513     if (opcode == 0) {
514       // Extended Opcodes always start with a zero opcode followed by
515       // a uleb128 length so you can skip ones you don't know about
516       lldb::offset_t ext_offset = *offset_ptr;
517       dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
518       dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
519
520       // DEBUG_PRINTF("Extended: <%2u> ", len);
521       uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
522       switch (sub_opcode) {
523       case DW_LNE_end_sequence:
524         // Set the end_sequence register of the state machine to true and
525         // append a row to the matrix using the current values of the
526         // state-machine registers. Then reset the registers to the initial
527         // values specified above. Every statement program sequence must end
528         // with a DW_LNE_end_sequence instruction which creates a row whose
529         // address is that of the byte after the last target machine instruction
530         // of the sequence.
531         state.end_sequence = true;
532         state.AppendRowToMatrix(*offset_ptr);
533         state.Reset();
534         break;
535
536       case DW_LNE_set_address:
537         // Takes a single relocatable address as an operand. The size of the
538         // operand is the size appropriate to hold an address on the target
539         // machine. Set the address register to the value given by the
540         // relocatable address. All of the other statement program opcodes
541         // that affect the address register add a delta to it. This instruction
542         // stores a relocatable value into it instead.
543         if (arg_size == 4)
544           state.address = debug_line_data.GetU32(offset_ptr);
545         else // arg_size == 8
546           state.address = debug_line_data.GetU64(offset_ptr);
547         break;
548
549       case DW_LNE_define_file:
550         // Takes 4 arguments. The first is a null terminated string containing
551         // a source file name. The second is an unsigned LEB128 number
552         // representing
553         // the directory index of the directory in which the file was found. The
554         // third is an unsigned LEB128 number representing the time of last
555         // modification of the file. The fourth is an unsigned LEB128 number
556         // representing the length in bytes of the file. The time and length
557         // fields may contain LEB128(0) if the information is not available.
558         //
559         // The directory index represents an entry in the include_directories
560         // section of the statement program prologue. The index is LEB128(0)
561         // if the file was found in the current directory of the compilation,
562         // LEB128(1) if it was found in the first directory in the
563         // include_directories section, and so on. The directory index is
564         // ignored for file names that represent full path names.
565         //
566         // The files are numbered, starting at 1, in the order in which they
567         // appear; the names in the prologue come before names defined by
568         // the DW_LNE_define_file instruction. These numbers are used in the
569         // file register of the state machine.
570         {
571           FileNameEntry fileEntry;
572           fileEntry.name = debug_line_data.GetCStr(offset_ptr);
573           fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
574           fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
575           fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
576           state.prologue->file_names.push_back(fileEntry);
577         }
578         break;
579
580       default:
581         // Length doesn't include the zero opcode byte or the length itself, but
582         // it does include the sub_opcode, so we have to adjust for that below
583         (*offset_ptr) += arg_size;
584         break;
585       }
586     } else if (opcode < prologue->opcode_base) {
587       switch (opcode) {
588       // Standard Opcodes
589       case DW_LNS_copy:
590         // Takes no arguments. Append a row to the matrix using the
591         // current values of the state-machine registers. Then set
592         // the basic_block register to false.
593         state.AppendRowToMatrix(*offset_ptr);
594         break;
595
596       case DW_LNS_advance_pc:
597         // Takes a single unsigned LEB128 operand, multiplies it by the
598         // min_inst_length field of the prologue, and adds the
599         // result to the address register of the state machine.
600         state.address +=
601             debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
602         break;
603
604       case DW_LNS_advance_line:
605         // Takes a single signed LEB128 operand and adds that value to
606         // the line register of the state machine.
607         state.line += debug_line_data.GetSLEB128(offset_ptr);
608         break;
609
610       case DW_LNS_set_file:
611         // Takes a single unsigned LEB128 operand and stores it in the file
612         // register of the state machine.
613         state.file = debug_line_data.GetULEB128(offset_ptr);
614         break;
615
616       case DW_LNS_set_column:
617         // Takes a single unsigned LEB128 operand and stores it in the
618         // column register of the state machine.
619         state.column = debug_line_data.GetULEB128(offset_ptr);
620         break;
621
622       case DW_LNS_negate_stmt:
623         // Takes no arguments. Set the is_stmt register of the state
624         // machine to the logical negation of its current value.
625         state.is_stmt = !state.is_stmt;
626         break;
627
628       case DW_LNS_set_basic_block:
629         // Takes no arguments. Set the basic_block register of the
630         // state machine to true
631         state.basic_block = true;
632         break;
633
634       case DW_LNS_const_add_pc:
635         // Takes no arguments. Add to the address register of the state
636         // machine the address increment value corresponding to special
637         // opcode 255. The motivation for DW_LNS_const_add_pc is this:
638         // when the statement program needs to advance the address by a
639         // small amount, it can use a single special opcode, which occupies
640         // a single byte. When it needs to advance the address by up to
641         // twice the range of the last special opcode, it can use
642         // DW_LNS_const_add_pc followed by a special opcode, for a total
643         // of two bytes. Only if it needs to advance the address by more
644         // than twice that range will it need to use both DW_LNS_advance_pc
645         // and a special opcode, requiring three or more bytes.
646         {
647           uint8_t adjust_opcode = 255 - prologue->opcode_base;
648           dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
649                                   prologue->min_inst_length;
650           state.address += addr_offset;
651         }
652         break;
653
654       case DW_LNS_fixed_advance_pc:
655         // Takes a single uhalf operand. Add to the address register of
656         // the state machine the value of the (unencoded) operand. This
657         // is the only extended opcode that takes an argument that is not
658         // a variable length number. The motivation for DW_LNS_fixed_advance_pc
659         // is this: existing assemblers cannot emit DW_LNS_advance_pc or
660         // special opcodes because they cannot encode LEB128 numbers or
661         // judge when the computation of a special opcode overflows and
662         // requires the use of DW_LNS_advance_pc. Such assemblers, however,
663         // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
664         state.address += debug_line_data.GetU16(offset_ptr);
665         break;
666
667       case DW_LNS_set_prologue_end:
668         // Takes no arguments. Set the prologue_end register of the
669         // state machine to true
670         state.prologue_end = true;
671         break;
672
673       case DW_LNS_set_epilogue_begin:
674         // Takes no arguments. Set the basic_block register of the
675         // state machine to true
676         state.epilogue_begin = true;
677         break;
678
679       case DW_LNS_set_isa:
680         // Takes a single unsigned LEB128 operand and stores it in the
681         // column register of the state machine.
682         state.isa = debug_line_data.GetULEB128(offset_ptr);
683         break;
684
685       default:
686         // Handle any unknown standard opcodes here. We know the lengths
687         // of such opcodes because they are specified in the prologue
688         // as a multiple of LEB128 operands for each opcode.
689         {
690           uint8_t i;
691           assert(static_cast<size_t>(opcode - 1) <
692                  prologue->standard_opcode_lengths.size());
693           const uint8_t opcode_length =
694               prologue->standard_opcode_lengths[opcode - 1];
695           for (i = 0; i < opcode_length; ++i)
696             debug_line_data.Skip_LEB128(offset_ptr);
697         }
698         break;
699       }
700     } else {
701       // Special Opcodes
702
703       // A special opcode value is chosen based on the amount that needs
704       // to be added to the line and address registers. The maximum line
705       // increment for a special opcode is the value of the line_base
706       // field in the header, plus the value of the line_range field,
707       // minus 1 (line base + line range - 1). If the desired line
708       // increment is greater than the maximum line increment, a standard
709       // opcode must be used instead of a special opcode. The "address
710       // advance" is calculated by dividing the desired address increment
711       // by the minimum_instruction_length field from the header. The
712       // special opcode is then calculated using the following formula:
713       //
714       //  opcode = (desired line increment - line_base) + (line_range * address
715       //  advance) + opcode_base
716       //
717       // If the resulting opcode is greater than 255, a standard opcode
718       // must be used instead.
719       //
720       // To decode a special opcode, subtract the opcode_base from the
721       // opcode itself to give the adjusted opcode. The amount to
722       // increment the address register is the result of the adjusted
723       // opcode divided by the line_range multiplied by the
724       // minimum_instruction_length field from the header. That is:
725       //
726       //  address increment = (adjusted opcode / line_range) *
727       //  minimum_instruction_length
728       //
729       // The amount to increment the line register is the line_base plus
730       // the result of the adjusted opcode modulo the line_range. That is:
731       //
732       // line increment = line_base + (adjusted opcode % line_range)
733
734       uint8_t adjust_opcode = opcode - prologue->opcode_base;
735       dw_addr_t addr_offset =
736           (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
737       int32_t line_offset =
738           prologue->line_base + (adjust_opcode % prologue->line_range);
739       state.line += line_offset;
740       state.address += addr_offset;
741       state.AppendRowToMatrix(*offset_ptr);
742     }
743   }
744
745   state.Finalize(*offset_ptr);
746
747   return end_offset;
748 }
749
750 //----------------------------------------------------------------------
751 // ParseStatementTableCallback
752 //----------------------------------------------------------------------
753 static void ParseStatementTableCallback(dw_offset_t offset,
754                                         const DWARFDebugLine::State &state,
755                                         void *userData) {
756   DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
757   if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
758     // Just started parsing the line table, so lets keep a reference to
759     // the prologue using the supplied shared pointer
760     line_table->prologue = state.prologue;
761   } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
762     // Done parsing line table, nothing to do for the cleanup
763   } else {
764     // We have a new row, lets append it
765     line_table->AppendRow(state);
766   }
767 }
768
769 //----------------------------------------------------------------------
770 // ParseStatementTable
771 //
772 // Parse a line table at offset and populate the LineTable class with
773 // the prologue and all rows.
774 //----------------------------------------------------------------------
775 bool DWARFDebugLine::ParseStatementTable(
776     const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
777     LineTable *line_table) {
778   return ParseStatementTable(debug_line_data, offset_ptr,
779                              ParseStatementTableCallback, line_table);
780 }
781
782 inline bool DWARFDebugLine::Prologue::IsValid() const {
783   return SymbolFileDWARF::SupportedVersion(version);
784 }
785
786 //----------------------------------------------------------------------
787 // DWARFDebugLine::Prologue::Dump
788 //----------------------------------------------------------------------
789 void DWARFDebugLine::Prologue::Dump(Log *log) {
790   uint32_t i;
791
792   log->Printf("Line table prologue:");
793   log->Printf("   total_length: 0x%8.8x", total_length);
794   log->Printf("        version: %u", version);
795   log->Printf("prologue_length: 0x%8.8x", prologue_length);
796   log->Printf("min_inst_length: %u", min_inst_length);
797   log->Printf("default_is_stmt: %u", default_is_stmt);
798   log->Printf("      line_base: %i", line_base);
799   log->Printf("     line_range: %u", line_range);
800   log->Printf("    opcode_base: %u", opcode_base);
801
802   for (i = 0; i < standard_opcode_lengths.size(); ++i) {
803     log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
804                 standard_opcode_lengths[i]);
805   }
806
807   if (!include_directories.empty()) {
808     for (i = 0; i < include_directories.size(); ++i) {
809       log->Printf("include_directories[%3u] = '%s'", i + 1,
810                   include_directories[i]);
811     }
812   }
813
814   if (!file_names.empty()) {
815     log->PutCString("                Dir  Mod Time   File Len   File Name");
816     log->PutCString("                ---- ---------- ---------- "
817                     "---------------------------");
818     for (i = 0; i < file_names.size(); ++i) {
819       const FileNameEntry &fileEntry = file_names[i];
820       log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
821                   fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
822                   fileEntry.name);
823     }
824   }
825 }
826
827 //----------------------------------------------------------------------
828 // DWARFDebugLine::ParsePrologue::Append
829 //
830 // Append the contents of the prologue to the binary stream buffer
831 //----------------------------------------------------------------------
832 // void
833 // DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
834 //{
835 //  uint32_t i;
836 //
837 //  buff.Append32(total_length);
838 //  buff.Append16(version);
839 //  buff.Append32(prologue_length);
840 //  buff.Append8(min_inst_length);
841 //  buff.Append8(default_is_stmt);
842 //  buff.Append8(line_base);
843 //  buff.Append8(line_range);
844 //  buff.Append8(opcode_base);
845 //
846 //  for (i=0; i<standard_opcode_lengths.size(); ++i)
847 //      buff.Append8(standard_opcode_lengths[i]);
848 //
849 //  for (i=0; i<include_directories.size(); ++i)
850 //      buff.AppendCStr(include_directories[i].c_str());
851 //  buff.Append8(0);    // Terminate the include directory section with empty
852 //  string
853 //
854 //  for (i=0; i<file_names.size(); ++i)
855 //  {
856 //      buff.AppendCStr(file_names[i].name.c_str());
857 //      buff.Append32_as_ULEB128(file_names[i].dir_idx);
858 //      buff.Append32_as_ULEB128(file_names[i].mod_time);
859 //      buff.Append32_as_ULEB128(file_names[i].length);
860 //  }
861 //  buff.Append8(0);    // Terminate the file names section with empty string
862 //}
863
864 bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir,
865                                        FileSpec &file) const {
866   uint32_t idx = file_idx - 1; // File indexes are 1 based...
867   if (idx < file_names.size()) {
868     file.SetFile(file_names[idx].name, false);
869     if (file.IsRelative()) {
870       if (file_names[idx].dir_idx > 0) {
871         const uint32_t dir_idx = file_names[idx].dir_idx - 1;
872         if (dir_idx < include_directories.size()) {
873           file.PrependPathComponent(include_directories[dir_idx]);
874           if (!file.IsRelative())
875             return true;
876         }
877       }
878
879       if (comp_dir && comp_dir[0])
880         file.PrependPathComponent(comp_dir);
881     }
882     return true;
883   }
884   return false;
885 }
886
887 //----------------------------------------------------------------------
888 // DWARFDebugLine::LineTable::Dump
889 //----------------------------------------------------------------------
890 void DWARFDebugLine::LineTable::Dump(Log *log) const {
891   if (prologue.get())
892     prologue->Dump(log);
893
894   if (!rows.empty()) {
895     log->PutCString("Address            Line   Column File   ISA Flags");
896     log->PutCString(
897         "------------------ ------ ------ ------ --- -------------");
898     Row::const_iterator pos = rows.begin();
899     Row::const_iterator end = rows.end();
900     while (pos != end) {
901       (*pos).Dump(log);
902       ++pos;
903     }
904   }
905 }
906
907 void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
908   rows.push_back(state);
909 }
910
911 //----------------------------------------------------------------------
912 // Compare function for the binary search in
913 // DWARFDebugLine::LineTable::LookupAddress()
914 //----------------------------------------------------------------------
915 static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
916                                 const DWARFDebugLine::Row &row2) {
917   return row1.address < row2.address;
918 }
919
920 //----------------------------------------------------------------------
921 // DWARFDebugLine::LineTable::LookupAddress
922 //----------------------------------------------------------------------
923 uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
924                                                   dw_addr_t cu_high_pc) const {
925   uint32_t index = UINT32_MAX;
926   if (!rows.empty()) {
927     // Use the lower_bound algorithm to perform a binary search since we know
928     // that our line table data is ordered by address.
929     DWARFDebugLine::Row row;
930     row.address = address;
931     Row::const_iterator begin_pos = rows.begin();
932     Row::const_iterator end_pos = rows.end();
933     Row::const_iterator pos =
934         lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
935     if (pos == end_pos) {
936       if (address < cu_high_pc)
937         return rows.size() - 1;
938     } else {
939       // Rely on fact that we are using a std::vector and we can do
940       // pointer arithmetic to find the row index (which will be one less
941       // that what we found since it will find the first position after
942       // the current address) since std::vector iterators are just
943       // pointers to the container type.
944       index = pos - begin_pos;
945       if (pos->address > address) {
946         if (index > 0)
947           --index;
948         else
949           index = UINT32_MAX;
950       }
951     }
952   }
953   return index; // Failed to find address
954 }
955
956 //----------------------------------------------------------------------
957 // DWARFDebugLine::Row::Row
958 //----------------------------------------------------------------------
959 DWARFDebugLine::Row::Row(bool default_is_stmt)
960     : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
961       basic_block(false), end_sequence(false), prologue_end(false),
962       epilogue_begin(false), isa(0) {}
963
964 //----------------------------------------------------------------------
965 // Called after a row is appended to the matrix
966 //----------------------------------------------------------------------
967 void DWARFDebugLine::Row::PostAppend() {
968   basic_block = false;
969   prologue_end = false;
970   epilogue_begin = false;
971 }
972
973 //----------------------------------------------------------------------
974 // DWARFDebugLine::Row::Reset
975 //----------------------------------------------------------------------
976 void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
977   address = 0;
978   line = 1;
979   column = 0;
980   file = 1;
981   is_stmt = default_is_stmt;
982   basic_block = false;
983   end_sequence = false;
984   prologue_end = false;
985   epilogue_begin = false;
986   isa = 0;
987 }
988 //----------------------------------------------------------------------
989 // DWARFDebugLine::Row::Dump
990 //----------------------------------------------------------------------
991 void DWARFDebugLine::Row::Dump(Log *log) const {
992   log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
993               column, file, isa, is_stmt ? " is_stmt" : "",
994               basic_block ? " basic_block" : "",
995               prologue_end ? " prologue_end" : "",
996               epilogue_begin ? " epilogue_begin" : "",
997               end_sequence ? " end_sequence" : "");
998 }
999
1000 //----------------------------------------------------------------------
1001 // Compare function LineTable structures
1002 //----------------------------------------------------------------------
1003 static bool AddressLessThan(const DWARFDebugLine::Row &a,
1004                             const DWARFDebugLine::Row &b) {
1005   return a.address < b.address;
1006 }
1007
1008 // Insert a row at the correct address if the addresses can be out of
1009 // order which can only happen when we are linking a line table that
1010 // may have had it's contents rearranged.
1011 void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
1012                                  const Row &state) {
1013   // If we don't have anything yet, or if the address of the last state in our
1014   // line table is less than the current one, just append the current state
1015   if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
1016     state_coll.push_back(state);
1017   } else {
1018     // Do a binary search for the correct entry
1019     pair<Row::iterator, Row::iterator> range(equal_range(
1020         state_coll.begin(), state_coll.end(), state, AddressLessThan));
1021
1022     // If the addresses are equal, we can safely replace the previous entry
1023     // with the current one if the one it is replacing is an end_sequence entry.
1024     // We currently always place an extra end sequence when ever we exit a valid
1025     // address range for a function in case the functions get rearranged by
1026     // optimizations or by order specifications. These extra end sequences will
1027     // disappear by getting replaced with valid consecutive entries within a
1028     // compile unit if there are no gaps.
1029     if (range.first == range.second) {
1030       state_coll.insert(range.first, state);
1031     } else {
1032       if ((distance(range.first, range.second) == 1) &&
1033           range.first->end_sequence == true) {
1034         *range.first = state;
1035       } else {
1036         state_coll.insert(range.second, state);
1037       }
1038     }
1039   }
1040 }
1041
1042 void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) {
1043   std::for_each(state_coll.begin(), state_coll.end(),
1044                 bind2nd(std::mem_fun_ref(&Row::Dump), log));
1045 }
1046
1047 //----------------------------------------------------------------------
1048 // DWARFDebugLine::State::State
1049 //----------------------------------------------------------------------
1050 DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
1051                              DWARFDebugLine::State::Callback cb, void *userData)
1052     : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
1053       callbackUserData(userData), row(StartParsingLineTable) {
1054   // Call the callback with the initial row state of zero for the prologue
1055   if (callback)
1056     callback(0, *this, callbackUserData);
1057 }
1058
1059 //----------------------------------------------------------------------
1060 // DWARFDebugLine::State::Reset
1061 //----------------------------------------------------------------------
1062 void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
1063
1064 //----------------------------------------------------------------------
1065 // DWARFDebugLine::State::AppendRowToMatrix
1066 //----------------------------------------------------------------------
1067 void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
1068   // Each time we are to add an entry into the line table matrix
1069   // call the callback function so that someone can do something with
1070   // the current state of the state machine (like build a line table
1071   // or dump the line table!)
1072   if (log) {
1073     if (row == 0) {
1074       log->PutCString("Address            Line   Column File   ISA Flags");
1075       log->PutCString(
1076           "------------------ ------ ------ ------ --- -------------");
1077     }
1078     Dump(log);
1079   }
1080
1081   ++row; // Increase the row number before we call our callback for a real row
1082   if (callback)
1083     callback(offset, *this, callbackUserData);
1084   PostAppend();
1085 }
1086
1087 //----------------------------------------------------------------------
1088 // DWARFDebugLine::State::Finalize
1089 //----------------------------------------------------------------------
1090 void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
1091   // Call the callback with a special row state when we are done parsing a
1092   // line table
1093   row = DoneParsingLineTable;
1094   if (callback)
1095     callback(offset, *this, callbackUserData);
1096 }
1097
1098 // void
1099 // DWARFDebugLine::AppendLineTableData
1100 //(
1101 //  const DWARFDebugLine::Prologue* prologue,
1102 //  const DWARFDebugLine::Row::collection& state_coll,
1103 //  const uint32_t addr_size,
1104 //  BinaryStreamBuf &debug_line_data
1105 //)
1106 //{
1107 //  if (state_coll.empty())
1108 //  {
1109 //      // We have no entries, just make an empty line table
1110 //      debug_line_data.Append8(0);
1111 //      debug_line_data.Append8(1);
1112 //      debug_line_data.Append8(DW_LNE_end_sequence);
1113 //  }
1114 //  else
1115 //  {
1116 //      DWARFDebugLine::Row::const_iterator pos;
1117 //      Row::const_iterator end = state_coll.end();
1118 //      bool default_is_stmt = prologue->default_is_stmt;
1119 //      const DWARFDebugLine::Row reset_state(default_is_stmt);
1120 //      const DWARFDebugLine::Row* prev_state = &reset_state;
1121 //      const int32_t max_line_increment_for_special_opcode =
1122 //      prologue->MaxLineIncrementForSpecialOpcode();
1123 //      for (pos = state_coll.begin(); pos != end; ++pos)
1124 //      {
1125 //          const DWARFDebugLine::Row& curr_state = *pos;
1126 //          int32_t line_increment  = 0;
1127 //          dw_addr_t addr_offset   = curr_state.address - prev_state->address;
1128 //          dw_addr_t addr_advance  = (addr_offset) / prologue->min_inst_length;
1129 //          line_increment = (int32_t)(curr_state.line - prev_state->line);
1130 //
1131 //          // If our previous state was the reset state, then let's emit the
1132 //          // address to keep GDB's DWARF parser happy. If we don't start each
1133 //          // sequence with a DW_LNE_set_address opcode, the line table won't
1134 //          // get slid properly in GDB.
1135 //
1136 //          if (prev_state == &reset_state)
1137 //          {
1138 //              debug_line_data.Append8(0); // Extended opcode
1139 //              debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
1140 //              opcode bytes
1141 //              debug_line_data.Append8(DW_LNE_set_address);
1142 //              debug_line_data.AppendMax64(curr_state.address, addr_size);
1143 //              addr_advance = 0;
1144 //          }
1145 //
1146 //          if (prev_state->file != curr_state.file)
1147 //          {
1148 //              debug_line_data.Append8(DW_LNS_set_file);
1149 //              debug_line_data.Append32_as_ULEB128(curr_state.file);
1150 //          }
1151 //
1152 //          if (prev_state->column != curr_state.column)
1153 //          {
1154 //              debug_line_data.Append8(DW_LNS_set_column);
1155 //              debug_line_data.Append32_as_ULEB128(curr_state.column);
1156 //          }
1157 //
1158 //          // Don't do anything fancy if we are at the end of a sequence
1159 //          // as we don't want to push any extra rows since the
1160 //          DW_LNE_end_sequence
1161 //          // will push a row itself!
1162 //          if (curr_state.end_sequence)
1163 //          {
1164 //              if (line_increment != 0)
1165 //              {
1166 //                  debug_line_data.Append8(DW_LNS_advance_line);
1167 //                  debug_line_data.Append32_as_SLEB128(line_increment);
1168 //              }
1169 //
1170 //              if (addr_advance > 0)
1171 //              {
1172 //                  debug_line_data.Append8(DW_LNS_advance_pc);
1173 //                  debug_line_data.Append32_as_ULEB128(addr_advance);
1174 //              }
1175 //
1176 //              // Now push the end sequence on!
1177 //              debug_line_data.Append8(0);
1178 //              debug_line_data.Append8(1);
1179 //              debug_line_data.Append8(DW_LNE_end_sequence);
1180 //
1181 //              prev_state = &reset_state;
1182 //          }
1183 //          else
1184 //          {
1185 //              if (line_increment || addr_advance)
1186 //              {
1187 //                  if (line_increment > max_line_increment_for_special_opcode)
1188 //                  {
1189 //                      debug_line_data.Append8(DW_LNS_advance_line);
1190 //                      debug_line_data.Append32_as_SLEB128(line_increment);
1191 //                      line_increment = 0;
1192 //                  }
1193 //
1194 //                  uint32_t special_opcode = (line_increment >=
1195 //                  prologue->line_base) ? ((line_increment -
1196 //                  prologue->line_base) + (prologue->line_range * addr_advance)
1197 //                  + prologue->opcode_base) : 256;
1198 //                  if (special_opcode > 255)
1199 //                  {
1200 //                      // Both the address and line won't fit in one special
1201 //                      opcode
1202 //                      // check to see if just the line advance will?
1203 //                      uint32_t special_opcode_line = ((line_increment >=
1204 //                      prologue->line_base) && (line_increment != 0)) ?
1205 //                              ((line_increment - prologue->line_base) +
1206 //                              prologue->opcode_base) : 256;
1207 //
1208 //
1209 //                      if (special_opcode_line > 255)
1210 //                      {
1211 //                          // Nope, the line advance won't fit by itself, check
1212 //                          the address increment by itself
1213 //                          uint32_t special_opcode_addr = addr_advance ?
1214 //                              ((0 - prologue->line_base) +
1215 //                              (prologue->line_range * addr_advance) +
1216 //                              prologue->opcode_base) : 256;
1217 //
1218 //                          if (special_opcode_addr > 255)
1219 //                          {
1220 //                              // Neither the address nor the line will fit in
1221 //                              a
1222 //                              // special opcode, we must manually enter both
1223 //                              then
1224 //                              // do a DW_LNS_copy to push a row (special
1225 //                              opcode
1226 //                              // automatically imply a new row is pushed)
1227 //                              if (line_increment != 0)
1228 //                              {
1229 //                                  debug_line_data.Append8(DW_LNS_advance_line);
1230 //                                  debug_line_data.Append32_as_SLEB128(line_increment);
1231 //                              }
1232 //
1233 //                              if (addr_advance > 0)
1234 //                              {
1235 //                                  debug_line_data.Append8(DW_LNS_advance_pc);
1236 //                                  debug_line_data.Append32_as_ULEB128(addr_advance);
1237 //                              }
1238 //
1239 //                              // Now push a row onto the line table manually
1240 //                              debug_line_data.Append8(DW_LNS_copy);
1241 //
1242 //                          }
1243 //                          else
1244 //                          {
1245 //                              // The address increment alone will fit into a
1246 //                              special opcode
1247 //                              // so modify our line change, then issue a
1248 //                              special opcode
1249 //                              // for the address increment and it will push a
1250 //                              row into the
1251 //                              // line table
1252 //                              if (line_increment != 0)
1253 //                              {
1254 //                                  debug_line_data.Append8(DW_LNS_advance_line);
1255 //                                  debug_line_data.Append32_as_SLEB128(line_increment);
1256 //                              }
1257 //
1258 //                              // Advance of line and address will fit into a
1259 //                              single byte special opcode
1260 //                              // and this will also push a row onto the line
1261 //                              table
1262 //                              debug_line_data.Append8(special_opcode_addr);
1263 //                          }
1264 //                      }
1265 //                      else
1266 //                      {
1267 //                          // The line change alone will fit into a special
1268 //                          opcode
1269 //                          // so modify our address increment first, then issue
1270 //                          a
1271 //                          // special opcode for the line change and it will
1272 //                          push
1273 //                          // a row into the line table
1274 //                          if (addr_advance > 0)
1275 //                          {
1276 //                              debug_line_data.Append8(DW_LNS_advance_pc);
1277 //                              debug_line_data.Append32_as_ULEB128(addr_advance);
1278 //                          }
1279 //
1280 //                          // Advance of line and address will fit into a
1281 //                          single byte special opcode
1282 //                          // and this will also push a row onto the line table
1283 //                          debug_line_data.Append8(special_opcode_line);
1284 //                      }
1285 //                  }
1286 //                  else
1287 //                  {
1288 //                      // Advance of line and address will fit into a single
1289 //                      byte special opcode
1290 //                      // and this will also push a row onto the line table
1291 //                      debug_line_data.Append8(special_opcode);
1292 //                  }
1293 //              }
1294 //              prev_state = &curr_state;
1295 //          }
1296 //      }
1297 //  }
1298 //}