]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
MFV r276568:
[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/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.c_str(),
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 > 3)
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     prologue->default_is_stmt   = debug_line_data.GetU8(offset_ptr);
428     prologue->line_base         = debug_line_data.GetU8(offset_ptr);
429     prologue->line_range        = debug_line_data.GetU8(offset_ptr);
430     prologue->opcode_base       = debug_line_data.GetU8(offset_ptr);
431
432     prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1);
433
434     for (i=1; i<prologue->opcode_base; ++i)
435     {
436         uint8_t op_len = debug_line_data.GetU8(offset_ptr);
437         prologue->standard_opcode_lengths.push_back(op_len);
438     }
439
440     while (*offset_ptr < end_prologue_offset)
441     {
442         s = debug_line_data.GetCStr(offset_ptr);
443         if (s && s[0])
444             prologue->include_directories.push_back(s);
445         else
446             break;
447     }
448
449     while (*offset_ptr < end_prologue_offset)
450     {
451         const char* name = debug_line_data.GetCStr( offset_ptr );
452         if (name && name[0])
453         {
454             FileNameEntry fileEntry;
455             fileEntry.name      = name;
456             fileEntry.dir_idx   = debug_line_data.GetULEB128( offset_ptr );
457             fileEntry.mod_time  = debug_line_data.GetULEB128( offset_ptr );
458             fileEntry.length    = debug_line_data.GetULEB128( offset_ptr );
459             prologue->file_names.push_back(fileEntry);
460         }
461         else
462             break;
463     }
464
465     // XXX GNU as is broken for 64-Bit DWARF
466     if (*offset_ptr != end_prologue_offset)
467     {
468         Host::SystemLog (Host::eSystemLogWarning, 
469                          "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",
470                          prologue_offset,
471                          end_prologue_offset, 
472                          *offset_ptr);
473     }
474     return end_prologue_offset;
475 }
476
477 bool
478 DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp,
479                                    const DWARFDataExtractor& debug_line_data,
480                                    const char *cu_comp_dir,
481                                    dw_offset_t stmt_list,
482                                    FileSpecList &support_files)
483 {
484     lldb::offset_t offset = stmt_list;
485     // Skip the total length
486     (void)debug_line_data.GetDWARFInitialLength(&offset);
487     const char * s;
488     uint32_t version = debug_line_data.GetU16(&offset);
489     if (version < 2 || version > 3)
490       return false;
491
492     const dw_offset_t end_prologue_offset = debug_line_data.GetDWARFOffset(&offset) + offset;
493     // Skip instruction length, default is stmt, line base, line range and
494     // opcode base, and all opcode lengths
495     offset += 4;
496     const uint8_t opcode_base = debug_line_data.GetU8(&offset);
497     offset += opcode_base - 1;
498     std::vector<std::string> include_directories;
499     include_directories.push_back("");  // Directory at index zero doesn't exist
500     while (offset < end_prologue_offset)
501     {
502         s = debug_line_data.GetCStr(&offset);
503         if (s && s[0])
504             include_directories.push_back(s);
505         else
506             break;
507     }
508     std::string fullpath;
509     std::string remapped_fullpath;
510     while (offset < end_prologue_offset)
511     {
512         const char* path = debug_line_data.GetCStr( &offset );
513         if (path && path[0])
514         {
515             uint32_t dir_idx    = debug_line_data.GetULEB128( &offset );
516             debug_line_data.Skip_LEB128(&offset); // Skip mod_time
517             debug_line_data.Skip_LEB128(&offset); // Skip length
518
519             if (path[0] == '/')
520             {
521                 // The path starts with a directory delimiter, so we are done.
522                 if (module_sp->RemapSourceFile (path, fullpath))
523                     support_files.Append(FileSpec (fullpath.c_str(), false));
524                 else
525                     support_files.Append(FileSpec (path, false));
526             }
527             else
528             {
529                 if (dir_idx > 0 && dir_idx < include_directories.size())
530                 {
531                     if (cu_comp_dir && include_directories[dir_idx][0] != '/')
532                     {
533                         fullpath = cu_comp_dir;
534
535                         if (*fullpath.rbegin() != '/')
536                             fullpath += '/';
537                         fullpath += include_directories[dir_idx];
538
539                     }
540                     else
541                         fullpath = include_directories[dir_idx];
542                 }
543                 else if (cu_comp_dir && cu_comp_dir[0])
544                 {
545                     fullpath = cu_comp_dir;
546                 }
547
548                 if (!fullpath.empty())
549                 {
550                    if (*fullpath.rbegin() != '/')
551                         fullpath += '/';
552                 }
553                 fullpath += path;
554                 if (module_sp->RemapSourceFile (fullpath.c_str(), remapped_fullpath))
555                     support_files.Append(FileSpec (remapped_fullpath.c_str(), false));
556                 else
557                     support_files.Append(FileSpec (fullpath.c_str(), false));
558             }
559             
560         }
561     }
562
563     if (offset != end_prologue_offset)
564     {
565         Host::SystemLog (Host::eSystemLogError, 
566                          "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended at 0x%8.8" PRIx64 "\n",
567                          stmt_list, 
568                          end_prologue_offset, 
569                          offset);
570     }
571     return end_prologue_offset;
572 }
573
574 //----------------------------------------------------------------------
575 // ParseStatementTable
576 //
577 // Parse a single line table (prologue and all rows) and call the
578 // callback function once for the prologue (row in state will be zero)
579 // and each time a row is to be added to the line table.
580 //----------------------------------------------------------------------
581 bool
582 DWARFDebugLine::ParseStatementTable
583 (
584     const DWARFDataExtractor& debug_line_data,
585     lldb::offset_t* offset_ptr,
586     DWARFDebugLine::State::Callback callback,
587     void* userData
588 )
589 {
590     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
591     Prologue::shared_ptr prologue(new Prologue());
592
593
594     const dw_offset_t debug_line_offset = *offset_ptr;
595
596     Timer scoped_timer (__PRETTY_FUNCTION__,
597                         "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
598                         debug_line_offset);
599
600     if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get()))
601     {
602         if (log)
603             log->Error ("failed to parse DWARF line table prologue");
604         // Restore our offset and return false to indicate failure!
605         *offset_ptr = debug_line_offset;
606         return false;
607     }
608
609     if (log)
610         prologue->Dump (log);
611
612     const dw_offset_t end_offset = debug_line_offset + prologue->total_length + (debug_line_data.GetDWARFSizeofInitialLength());
613
614     State state(prologue, log, callback, userData);
615
616     while (*offset_ptr < end_offset)
617     {
618         //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
619         uint8_t opcode = debug_line_data.GetU8(offset_ptr);
620
621         if (opcode == 0)
622         {
623             // Extended Opcodes always start with a zero opcode followed by
624             // a uleb128 length so you can skip ones you don't know about
625             lldb::offset_t ext_offset = *offset_ptr;
626             dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
627             dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
628
629             //DEBUG_PRINTF("Extended: <%2u> ", len);
630             uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
631             switch (sub_opcode)
632             {
633             case DW_LNE_end_sequence:
634                 // Set the end_sequence register of the state machine to true and
635                 // append a row to the matrix using the current values of the
636                 // state-machine registers. Then reset the registers to the initial
637                 // values specified above. Every statement program sequence must end
638                 // with a DW_LNE_end_sequence instruction which creates a row whose
639                 // address is that of the byte after the last target machine instruction
640                 // of the sequence.
641                 state.end_sequence = true;
642                 state.AppendRowToMatrix(*offset_ptr);
643                 state.Reset();
644                 break;
645
646             case DW_LNE_set_address:
647                 // Takes a single relocatable address as an operand. The size of the
648                 // operand is the size appropriate to hold an address on the target
649                 // machine. Set the address register to the value given by the
650                 // relocatable address. All of the other statement program opcodes
651                 // that affect the address register add a delta to it. This instruction
652                 // stores a relocatable value into it instead.
653                 state.address = debug_line_data.GetAddress(offset_ptr);
654                 break;
655
656             case DW_LNE_define_file:
657                 // Takes 4 arguments. The first is a null terminated string containing
658                 // a source file name. The second is an unsigned LEB128 number representing
659                 // the directory index of the directory in which the file was found. The
660                 // third is an unsigned LEB128 number representing the time of last
661                 // modification of the file. The fourth is an unsigned LEB128 number
662                 // representing the length in bytes of the file. The time and length
663                 // fields may contain LEB128(0) if the information is not available.
664                 //
665                 // The directory index represents an entry in the include_directories
666                 // section of the statement program prologue. The index is LEB128(0)
667                 // if the file was found in the current directory of the compilation,
668                 // LEB128(1) if it was found in the first directory in the
669                 // include_directories section, and so on. The directory index is
670                 // ignored for file names that represent full path names.
671                 //
672                 // The files are numbered, starting at 1, in the order in which they
673                 // appear; the names in the prologue come before names defined by
674                 // the DW_LNE_define_file instruction. These numbers are used in the
675                 // file register of the state machine.
676                 {
677                     FileNameEntry fileEntry;
678                     fileEntry.name      = debug_line_data.GetCStr(offset_ptr);
679                     fileEntry.dir_idx   = debug_line_data.GetULEB128(offset_ptr);
680                     fileEntry.mod_time  = debug_line_data.GetULEB128(offset_ptr);
681                     fileEntry.length    = debug_line_data.GetULEB128(offset_ptr);
682                     state.prologue->file_names.push_back(fileEntry);
683                 }
684                 break;
685
686             default:
687                 // Length doesn't include the zero opcode byte or the length itself, but
688                 // it does include the sub_opcode, so we have to adjust for that below
689                 (*offset_ptr) += arg_size;
690                 break;
691             }
692         }
693         else if (opcode < prologue->opcode_base)
694         {
695             switch (opcode)
696             {
697             // Standard Opcodes
698             case DW_LNS_copy:
699                 // Takes no arguments. Append a row to the matrix using the
700                 // current values of the state-machine registers. Then set
701                 // the basic_block register to false.
702                 state.AppendRowToMatrix(*offset_ptr);
703                 break;
704
705             case DW_LNS_advance_pc:
706                 // Takes a single unsigned LEB128 operand, multiplies it by the
707                 // min_inst_length field of the prologue, and adds the
708                 // result to the address register of the state machine.
709                 state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
710                 break;
711
712             case DW_LNS_advance_line:
713                 // Takes a single signed LEB128 operand and adds that value to
714                 // the line register of the state machine.
715                 state.line += debug_line_data.GetSLEB128(offset_ptr);
716                 break;
717
718             case DW_LNS_set_file:
719                 // Takes a single unsigned LEB128 operand and stores it in the file
720                 // register of the state machine.
721                 state.file = debug_line_data.GetULEB128(offset_ptr);
722                 break;
723
724             case DW_LNS_set_column:
725                 // Takes a single unsigned LEB128 operand and stores it in the
726                 // column register of the state machine.
727                 state.column = debug_line_data.GetULEB128(offset_ptr);
728                 break;
729
730             case DW_LNS_negate_stmt:
731                 // Takes no arguments. Set the is_stmt register of the state
732                 // machine to the logical negation of its current value.
733                 state.is_stmt = !state.is_stmt;
734                 break;
735
736             case DW_LNS_set_basic_block:
737                 // Takes no arguments. Set the basic_block register of the
738                 // state machine to true
739                 state.basic_block = true;
740                 break;
741
742             case DW_LNS_const_add_pc:
743                 // Takes no arguments. Add to the address register of the state
744                 // machine the address increment value corresponding to special
745                 // opcode 255. The motivation for DW_LNS_const_add_pc is this:
746                 // when the statement program needs to advance the address by a
747                 // small amount, it can use a single special opcode, which occupies
748                 // a single byte. When it needs to advance the address by up to
749                 // twice the range of the last special opcode, it can use
750                 // DW_LNS_const_add_pc followed by a special opcode, for a total
751                 // of two bytes. Only if it needs to advance the address by more
752                 // than twice that range will it need to use both DW_LNS_advance_pc
753                 // and a special opcode, requiring three or more bytes.
754                 {
755                     uint8_t adjust_opcode = 255 - prologue->opcode_base;
756                     dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
757                     state.address += addr_offset;
758                 }
759                 break;
760
761             case DW_LNS_fixed_advance_pc:
762                 // Takes a single uhalf operand. Add to the address register of
763                 // the state machine the value of the (unencoded) operand. This
764                 // is the only extended opcode that takes an argument that is not
765                 // a variable length number. The motivation for DW_LNS_fixed_advance_pc
766                 // is this: existing assemblers cannot emit DW_LNS_advance_pc or
767                 // special opcodes because they cannot encode LEB128 numbers or
768                 // judge when the computation of a special opcode overflows and
769                 // requires the use of DW_LNS_advance_pc. Such assemblers, however,
770                 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
771                 state.address += debug_line_data.GetU16(offset_ptr);
772                 break;
773
774             case DW_LNS_set_prologue_end:
775                 // Takes no arguments. Set the prologue_end register of the
776                 // state machine to true
777                 state.prologue_end = true;
778                 break;
779
780             case DW_LNS_set_epilogue_begin:
781                 // Takes no arguments. Set the basic_block register of the
782                 // state machine to true
783                 state.epilogue_begin = true;
784                 break;
785
786             case DW_LNS_set_isa:
787                 // Takes a single unsigned LEB128 operand and stores it in the
788                 // column register of the state machine.
789                 state.isa = debug_line_data.GetULEB128(offset_ptr);
790                 break;
791
792             default:
793                 // Handle any unknown standard opcodes here. We know the lengths
794                 // of such opcodes because they are specified in the prologue
795                 // as a multiple of LEB128 operands for each opcode.
796                 {
797                     uint8_t i;
798                     assert (static_cast<size_t>(opcode - 1) < prologue->standard_opcode_lengths.size());
799                     const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1];
800                     for (i=0; i<opcode_length; ++i)
801                         debug_line_data.Skip_LEB128(offset_ptr);
802                 }
803                 break;
804             }
805         }
806         else
807         {
808             // Special Opcodes
809
810             // A special opcode value is chosen based on the amount that needs
811             // to be added to the line and address registers. The maximum line
812             // increment for a special opcode is the value of the line_base
813             // field in the header, plus the value of the line_range field,
814             // minus 1 (line base + line range - 1). If the desired line
815             // increment is greater than the maximum line increment, a standard
816             // opcode must be used instead of a special opcode. The "address
817             // advance" is calculated by dividing the desired address increment
818             // by the minimum_instruction_length field from the header. The
819             // special opcode is then calculated using the following formula:
820             //
821             //  opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base
822             //
823             // If the resulting opcode is greater than 255, a standard opcode
824             // must be used instead.
825             //
826             // To decode a special opcode, subtract the opcode_base from the
827             // opcode itself to give the adjusted opcode. The amount to
828             // increment the address register is the result of the adjusted
829             // opcode divided by the line_range multiplied by the
830             // minimum_instruction_length field from the header. That is:
831             //
832             //  address increment = (adjusted opcode / line_range) * minimum_instruction_length
833             //
834             // The amount to increment the line register is the line_base plus
835             // the result of the adjusted opcode modulo the line_range. That is:
836             //
837             // line increment = line_base + (adjusted opcode % line_range)
838
839             uint8_t adjust_opcode = opcode - prologue->opcode_base;
840             dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
841             int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range);
842             state.line += line_offset;
843             state.address += addr_offset;
844             state.AppendRowToMatrix(*offset_ptr);
845         }
846     }
847
848     state.Finalize( *offset_ptr );
849
850     return end_offset;
851 }
852
853
854 //----------------------------------------------------------------------
855 // ParseStatementTableCallback
856 //----------------------------------------------------------------------
857 static void
858 ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
859 {
860     DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData;
861     if (state.row == DWARFDebugLine::State::StartParsingLineTable)
862     {
863         // Just started parsing the line table, so lets keep a reference to
864         // the prologue using the supplied shared pointer
865         line_table->prologue = state.prologue;
866     }
867     else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
868     {
869         // Done parsing line table, nothing to do for the cleanup
870     }
871     else
872     {
873         // We have a new row, lets append it
874         line_table->AppendRow(state);
875     }
876 }
877
878 //----------------------------------------------------------------------
879 // ParseStatementTable
880 //
881 // Parse a line table at offset and populate the LineTable class with
882 // the prologue and all rows.
883 //----------------------------------------------------------------------
884 bool
885 DWARFDebugLine::ParseStatementTable(const DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table)
886 {
887     return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
888 }
889
890
891 inline bool
892 DWARFDebugLine::Prologue::IsValid() const
893 {
894     return SymbolFileDWARF::SupportedVersion(version);
895 }
896
897 //----------------------------------------------------------------------
898 // DWARFDebugLine::Prologue::Dump
899 //----------------------------------------------------------------------
900 void
901 DWARFDebugLine::Prologue::Dump(Log *log)
902 {
903     uint32_t i;
904
905     log->Printf( "Line table prologue:");
906     log->Printf( "   total_length: 0x%8.8x", total_length);
907     log->Printf( "        version: %u", version);
908     log->Printf( "prologue_length: 0x%8.8x", prologue_length);
909     log->Printf( "min_inst_length: %u", min_inst_length);
910     log->Printf( "default_is_stmt: %u", default_is_stmt);
911     log->Printf( "      line_base: %i", line_base);
912     log->Printf( "     line_range: %u", line_range);
913     log->Printf( "    opcode_base: %u", opcode_base);
914
915     for (i=0; i<standard_opcode_lengths.size(); ++i)
916     {
917         log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]);
918     }
919
920     if (!include_directories.empty())
921     {
922         for (i=0; i<include_directories.size(); ++i)
923         {
924             log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i].c_str());
925         }
926     }
927
928     if (!file_names.empty())
929     {
930         log->PutCString ("                Dir  Mod Time   File Len   File Name");
931         log->PutCString ("                ---- ---------- ---------- ---------------------------");
932         for (i=0; i<file_names.size(); ++i)
933         {
934             const FileNameEntry& fileEntry = file_names[i];
935             log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s",
936                 i+1,
937                 fileEntry.dir_idx,
938                 fileEntry.mod_time,
939                 fileEntry.length,
940                 fileEntry.name.c_str());
941         }
942     }
943 }
944
945
946 //----------------------------------------------------------------------
947 // DWARFDebugLine::ParsePrologue::Append
948 //
949 // Append the contents of the prologue to the binary stream buffer
950 //----------------------------------------------------------------------
951 //void
952 //DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
953 //{
954 //  uint32_t i;
955 //
956 //  buff.Append32(total_length);
957 //  buff.Append16(version);
958 //  buff.Append32(prologue_length);
959 //  buff.Append8(min_inst_length);
960 //  buff.Append8(default_is_stmt);
961 //  buff.Append8(line_base);
962 //  buff.Append8(line_range);
963 //  buff.Append8(opcode_base);
964 //
965 //  for (i=0; i<standard_opcode_lengths.size(); ++i)
966 //      buff.Append8(standard_opcode_lengths[i]);
967 //
968 //  for (i=0; i<include_directories.size(); ++i)
969 //      buff.AppendCStr(include_directories[i].c_str());
970 //  buff.Append8(0);    // Terminate the include directory section with empty string
971 //
972 //  for (i=0; i<file_names.size(); ++i)
973 //  {
974 //      buff.AppendCStr(file_names[i].name.c_str());
975 //      buff.Append32_as_ULEB128(file_names[i].dir_idx);
976 //      buff.Append32_as_ULEB128(file_names[i].mod_time);
977 //      buff.Append32_as_ULEB128(file_names[i].length);
978 //  }
979 //  buff.Append8(0);    // Terminate the file names section with empty string
980 //}
981
982
983 bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, std::string& path, std::string& directory) const
984 {
985     uint32_t idx = file_idx - 1;    // File indexes are 1 based...
986     if (idx < file_names.size())
987     {
988         path = file_names[idx].name;
989         uint32_t dir_idx = file_names[idx].dir_idx - 1;
990         if (dir_idx < include_directories.size())
991             directory = include_directories[dir_idx];
992         else
993             directory.clear();
994         return true;
995     }
996     return false;
997 }
998
999 //----------------------------------------------------------------------
1000 // DWARFDebugLine::LineTable::Dump
1001 //----------------------------------------------------------------------
1002 void
1003 DWARFDebugLine::LineTable::Dump(Log *log) const
1004 {
1005     if (prologue.get())
1006         prologue->Dump (log);
1007
1008     if (!rows.empty())
1009     {
1010         log->PutCString ("Address            Line   Column File   ISA Flags");
1011         log->PutCString ("------------------ ------ ------ ------ --- -------------");
1012         Row::const_iterator pos = rows.begin();
1013         Row::const_iterator end = rows.end();
1014         while (pos != end)
1015         {
1016             (*pos).Dump (log);
1017             ++pos;
1018         }
1019     }
1020 }
1021
1022
1023 void
1024 DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state)
1025 {
1026     rows.push_back(state);
1027 }
1028
1029
1030
1031 //----------------------------------------------------------------------
1032 // Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress()
1033 //----------------------------------------------------------------------
1034 static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2)
1035 {
1036     return row1.address < row2.address;
1037 }
1038
1039
1040 //----------------------------------------------------------------------
1041 // DWARFDebugLine::LineTable::LookupAddress
1042 //----------------------------------------------------------------------
1043 uint32_t
1044 DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const
1045 {
1046     uint32_t index = UINT32_MAX;
1047     if (!rows.empty())
1048     {
1049         // Use the lower_bound algorithm to perform a binary search since we know
1050         // that our line table data is ordered by address.
1051         DWARFDebugLine::Row row;
1052         row.address = address;
1053         Row::const_iterator begin_pos = rows.begin();
1054         Row::const_iterator end_pos = rows.end();
1055         Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
1056         if (pos == end_pos)
1057         {
1058             if (address < cu_high_pc)
1059                 return rows.size()-1;
1060         }
1061         else
1062         {
1063             // Rely on fact that we are using a std::vector and we can do
1064             // pointer arithmetic to find the row index (which will be one less
1065             // that what we found since it will find the first position after
1066             // the current address) since std::vector iterators are just
1067             // pointers to the container type.
1068             index = pos - begin_pos;
1069             if (pos->address > address)
1070             {
1071                 if (index > 0)
1072                     --index;
1073                 else
1074                     index = UINT32_MAX;
1075             }
1076         }
1077     }
1078     return index;   // Failed to find address
1079 }
1080
1081
1082 //----------------------------------------------------------------------
1083 // DWARFDebugLine::Row::Row
1084 //----------------------------------------------------------------------
1085 DWARFDebugLine::Row::Row(bool default_is_stmt) :
1086     address(0),
1087     line(1),
1088     column(0),
1089     file(1),
1090     is_stmt(default_is_stmt),
1091     basic_block(false),
1092     end_sequence(false),
1093     prologue_end(false),
1094     epilogue_begin(false),
1095     isa(0)
1096 {
1097 }
1098
1099 //----------------------------------------------------------------------
1100 // Called after a row is appended to the matrix
1101 //----------------------------------------------------------------------
1102 void
1103 DWARFDebugLine::Row::PostAppend()
1104 {
1105     basic_block = false;
1106     prologue_end = false;
1107     epilogue_begin = false;
1108 }
1109
1110
1111 //----------------------------------------------------------------------
1112 // DWARFDebugLine::Row::Reset
1113 //----------------------------------------------------------------------
1114 void
1115 DWARFDebugLine::Row::Reset(bool default_is_stmt)
1116 {
1117     address = 0;
1118     line = 1;
1119     column = 0;
1120     file = 1;
1121     is_stmt = default_is_stmt;
1122     basic_block = false;
1123     end_sequence = false;
1124     prologue_end = false;
1125     epilogue_begin = false;
1126     isa = 0;
1127 }
1128 //----------------------------------------------------------------------
1129 // DWARFDebugLine::Row::Dump
1130 //----------------------------------------------------------------------
1131 void
1132 DWARFDebugLine::Row::Dump(Log *log) const
1133 {
1134     log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s",
1135                 address,
1136                 line,
1137                 column,
1138                 file,
1139                 isa,
1140                 is_stmt ? " is_stmt" : "",
1141                 basic_block ? " basic_block" : "",
1142                 prologue_end ? " prologue_end" : "",
1143                 epilogue_begin ? " epilogue_begin" : "",
1144                 end_sequence ? " end_sequence" : "");
1145 }
1146
1147 //----------------------------------------------------------------------
1148 // Compare function LineTable structures
1149 //----------------------------------------------------------------------
1150 static bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b)
1151 {
1152     return a.address < b.address;
1153 }
1154
1155
1156
1157 // Insert a row at the correct address if the addresses can be out of
1158 // order which can only happen when we are linking a line table that
1159 // may have had it's contents rearranged.
1160 void
1161 DWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state)
1162 {
1163     // If we don't have anything yet, or if the address of the last state in our
1164     // line table is less than the current one, just append the current state
1165     if (state_coll.empty() || AddressLessThan(state_coll.back(), state))
1166     {
1167         state_coll.push_back(state);
1168     }
1169     else
1170     {
1171         // Do a binary search for the correct entry
1172         pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan));
1173
1174         // If the addresses are equal, we can safely replace the previous entry
1175         // with the current one if the one it is replacing is an end_sequence entry.
1176         // We currently always place an extra end sequence when ever we exit a valid
1177         // address range for a function in case the functions get rearranged by
1178         // optimizations or by order specifications. These extra end sequences will
1179         // disappear by getting replaced with valid consecutive entries within a
1180         // compile unit if there are no gaps.
1181         if (range.first == range.second)
1182         {
1183             state_coll.insert(range.first, state);
1184         }
1185         else
1186         {
1187             if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true)
1188             {
1189                 *range.first = state;
1190             }
1191             else
1192             {
1193                 state_coll.insert(range.second, state);
1194             }
1195         }
1196     }
1197 }
1198
1199 void
1200 DWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll)
1201 {
1202     std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log));
1203 }
1204
1205
1206 //----------------------------------------------------------------------
1207 // DWARFDebugLine::State::State
1208 //----------------------------------------------------------------------
1209 DWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) :
1210     Row (p->default_is_stmt),
1211     prologue (p),
1212     log (l),
1213     callback (cb),
1214     callbackUserData (userData),
1215     row (StartParsingLineTable)
1216 {
1217     // Call the callback with the initial row state of zero for the prologue
1218     if (callback)
1219         callback(0, *this, callbackUserData);
1220 }
1221
1222 //----------------------------------------------------------------------
1223 // DWARFDebugLine::State::Reset
1224 //----------------------------------------------------------------------
1225 void
1226 DWARFDebugLine::State::Reset()
1227 {
1228     Row::Reset(prologue->default_is_stmt);
1229 }
1230
1231 //----------------------------------------------------------------------
1232 // DWARFDebugLine::State::AppendRowToMatrix
1233 //----------------------------------------------------------------------
1234 void
1235 DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset)
1236 {
1237     // Each time we are to add an entry into the line table matrix
1238     // call the callback function so that someone can do something with
1239     // the current state of the state machine (like build a line table
1240     // or dump the line table!)
1241     if (log)
1242     {
1243         if (row == 0)
1244         {
1245             log->PutCString ("Address            Line   Column File   ISA Flags");
1246             log->PutCString ("------------------ ------ ------ ------ --- -------------");
1247         }
1248         Dump (log);
1249     }
1250
1251     ++row;  // Increase the row number before we call our callback for a real row
1252     if (callback)
1253         callback(offset, *this, callbackUserData);
1254     PostAppend();
1255 }
1256
1257 //----------------------------------------------------------------------
1258 // DWARFDebugLine::State::Finalize
1259 //----------------------------------------------------------------------
1260 void
1261 DWARFDebugLine::State::Finalize(dw_offset_t offset)
1262 {
1263     // Call the callback with a special row state when we are done parsing a
1264     // line table
1265     row = DoneParsingLineTable;
1266     if (callback)
1267         callback(offset, *this, callbackUserData);
1268 }
1269
1270 //void
1271 //DWARFDebugLine::AppendLineTableData
1272 //(
1273 //  const DWARFDebugLine::Prologue* prologue,
1274 //  const DWARFDebugLine::Row::collection& state_coll,
1275 //  const uint32_t addr_size,
1276 //  BinaryStreamBuf &debug_line_data
1277 //)
1278 //{
1279 //  if (state_coll.empty())
1280 //  {
1281 //      // We have no entries, just make an empty line table
1282 //      debug_line_data.Append8(0);
1283 //      debug_line_data.Append8(1);
1284 //      debug_line_data.Append8(DW_LNE_end_sequence);
1285 //  }
1286 //  else
1287 //  {
1288 //      DWARFDebugLine::Row::const_iterator pos;
1289 //      Row::const_iterator end = state_coll.end();
1290 //      bool default_is_stmt = prologue->default_is_stmt;
1291 //      const DWARFDebugLine::Row reset_state(default_is_stmt);
1292 //      const DWARFDebugLine::Row* prev_state = &reset_state;
1293 //      const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode();
1294 //      for (pos = state_coll.begin(); pos != end; ++pos)
1295 //      {
1296 //          const DWARFDebugLine::Row& curr_state = *pos;
1297 //          int32_t line_increment  = 0;
1298 //          dw_addr_t addr_offset   = curr_state.address - prev_state->address;
1299 //          dw_addr_t addr_advance  = (addr_offset) / prologue->min_inst_length;
1300 //          line_increment = (int32_t)(curr_state.line - prev_state->line);
1301 //
1302 //          // If our previous state was the reset state, then let's emit the
1303 //          // address to keep GDB's DWARF parser happy. If we don't start each
1304 //          // sequence with a DW_LNE_set_address opcode, the line table won't
1305 //          // get slid properly in GDB.
1306 //
1307 //          if (prev_state == &reset_state)
1308 //          {
1309 //              debug_line_data.Append8(0); // Extended opcode
1310 //              debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes
1311 //              debug_line_data.Append8(DW_LNE_set_address);
1312 //              debug_line_data.AppendMax64(curr_state.address, addr_size);
1313 //              addr_advance = 0;
1314 //          }
1315 //
1316 //          if (prev_state->file != curr_state.file)
1317 //          {
1318 //              debug_line_data.Append8(DW_LNS_set_file);
1319 //              debug_line_data.Append32_as_ULEB128(curr_state.file);
1320 //          }
1321 //
1322 //          if (prev_state->column != curr_state.column)
1323 //          {
1324 //              debug_line_data.Append8(DW_LNS_set_column);
1325 //              debug_line_data.Append32_as_ULEB128(curr_state.column);
1326 //          }
1327 //
1328 //          // Don't do anything fancy if we are at the end of a sequence
1329 //          // as we don't want to push any extra rows since the DW_LNE_end_sequence
1330 //          // will push a row itself!
1331 //          if (curr_state.end_sequence)
1332 //          {
1333 //              if (line_increment != 0)
1334 //              {
1335 //                  debug_line_data.Append8(DW_LNS_advance_line);
1336 //                  debug_line_data.Append32_as_SLEB128(line_increment);
1337 //              }
1338 //
1339 //              if (addr_advance > 0)
1340 //              {
1341 //                  debug_line_data.Append8(DW_LNS_advance_pc);
1342 //                  debug_line_data.Append32_as_ULEB128(addr_advance);
1343 //              }
1344 //
1345 //              // Now push the end sequence on!
1346 //              debug_line_data.Append8(0);
1347 //              debug_line_data.Append8(1);
1348 //              debug_line_data.Append8(DW_LNE_end_sequence);
1349 //
1350 //              prev_state = &reset_state;
1351 //          }
1352 //          else
1353 //          {
1354 //              if (line_increment || addr_advance)
1355 //              {
1356 //                  if (line_increment > max_line_increment_for_special_opcode)
1357 //                  {
1358 //                      debug_line_data.Append8(DW_LNS_advance_line);
1359 //                      debug_line_data.Append32_as_SLEB128(line_increment);
1360 //                      line_increment = 0;
1361 //                  }
1362 //
1363 //                  uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
1364 //                  if (special_opcode > 255)
1365 //                  {
1366 //                      // Both the address and line won't fit in one special opcode
1367 //                      // check to see if just the line advance will?
1368 //                      uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ?
1369 //                              ((line_increment - prologue->line_base) + prologue->opcode_base) : 256;
1370 //
1371 //
1372 //                      if (special_opcode_line > 255)
1373 //                      {
1374 //                          // Nope, the line advance won't fit by itself, check the address increment by itself
1375 //                          uint32_t special_opcode_addr = addr_advance ?
1376 //                              ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
1377 //
1378 //                          if (special_opcode_addr > 255)
1379 //                          {
1380 //                              // Neither the address nor the line will fit in a
1381 //                              // special opcode, we must manually enter both then
1382 //                              // do a DW_LNS_copy to push a row (special opcode
1383 //                              // automatically imply a new row is pushed)
1384 //                              if (line_increment != 0)
1385 //                              {
1386 //                                  debug_line_data.Append8(DW_LNS_advance_line);
1387 //                                  debug_line_data.Append32_as_SLEB128(line_increment);
1388 //                              }
1389 //
1390 //                              if (addr_advance > 0)
1391 //                              {
1392 //                                  debug_line_data.Append8(DW_LNS_advance_pc);
1393 //                                  debug_line_data.Append32_as_ULEB128(addr_advance);
1394 //                              }
1395 //
1396 //                              // Now push a row onto the line table manually
1397 //                              debug_line_data.Append8(DW_LNS_copy);
1398 //
1399 //                          }
1400 //                          else
1401 //                          {
1402 //                              // The address increment alone will fit into a special opcode
1403 //                              // so modify our line change, then issue a special opcode
1404 //                              // for the address increment and it will push a row into the
1405 //                              // line table
1406 //                              if (line_increment != 0)
1407 //                              {
1408 //                                  debug_line_data.Append8(DW_LNS_advance_line);
1409 //                                  debug_line_data.Append32_as_SLEB128(line_increment);
1410 //                              }
1411 //
1412 //                              // Advance of line and address will fit into a single byte special opcode
1413 //                              // and this will also push a row onto the line table
1414 //                              debug_line_data.Append8(special_opcode_addr);
1415 //                          }
1416 //                      }
1417 //                      else
1418 //                      {
1419 //                          // The line change alone will fit into a special opcode
1420 //                          // so modify our address increment first, then issue a
1421 //                          // special opcode for the line change and it will push
1422 //                          // a row into the line table
1423 //                          if (addr_advance > 0)
1424 //                          {
1425 //                              debug_line_data.Append8(DW_LNS_advance_pc);
1426 //                              debug_line_data.Append32_as_ULEB128(addr_advance);
1427 //                          }
1428 //
1429 //                          // Advance of line and address will fit into a single byte special opcode
1430 //                          // and this will also push a row onto the line table
1431 //                          debug_line_data.Append8(special_opcode_line);
1432 //                      }
1433 //                  }
1434 //                  else
1435 //                  {
1436 //                      // Advance of line and address will fit into a single byte special opcode
1437 //                      // and this will also push a row onto the line table
1438 //                      debug_line_data.Append8(special_opcode);
1439 //                  }
1440 //              }
1441 //              prev_state = &curr_state;
1442 //          }
1443 //      }
1444 //  }
1445 //}