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