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