DWARFDebugLine.cpp revision c4547c59f2e8390bdbf92484c851be06395b8e77
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDebugLine.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!! 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <assert.h> 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/FileSpecList.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "SymbolFileDWARF.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "LogChannelDWARF.h" 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace std; 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse all information in the debug_line_data into an internal 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// representation. 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Parse(const DataExtractor& debug_line_data) 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_lineTableMap.clear(); 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t offset = 0; 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner LineTable::shared_ptr line_table_sp(new LineTable); 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (debug_line_data.ValidOffset(offset)) 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t debug_line_offset = offset; 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (line_table_sp.get() == NULL) 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure we don't don't loop infinitely 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (offset <= debug_line_offset) 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", debug_line_offset); 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_lineTableMap[debug_line_offset] = line_table_sp; 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line_table_sp.reset(new LineTable); 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++offset; // Try next byte in line table 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::ParseIfNeeded(const DataExtractor& debug_line_data) 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_lineTableMap.empty()) 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Parse(debug_line_data); 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::GetLineTable 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::LineTable::shared_ptr 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::GetLineTable(const dw_offset_t offset) const 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr; 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner LineTableConstIter pos = m_lineTableMap.find(offset); 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos != m_lineTableMap.end()) 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line_table_shared_ptr = pos->second; 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return line_table_shared_ptr; 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DumpStateToFile 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDumpStateToFile (dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Log *log = (Log *)userData; 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (state.row == DWARFDebugLine::State::StartParsingLineTable) 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the row is zero we are being called with the prologue only 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.prologue->Dump (log); 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("Address Line Column File"); 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("------------------ ------ ------ ------"); 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Done parsing line table 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%16.16llx %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : ""); 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::DumpLineTableRows 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset) 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DataExtractor& debug_line_data = dwarf2Data->get_debug_line_data(); 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_offset == DW_INVALID_OFFSET) 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Dump line table to a single file only 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_offset = 0; 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (debug_line_data.ValidOffset(debug_line_offset)) 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_offset = DumpStatementTable (log, debug_line_data, debug_line_offset); 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Dump line table to a single file only 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DumpStatementTable (log, debug_line_data, debug_line_offset); 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::DumpStatementTable 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_offset_t 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::DumpStatementTable(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset) 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_data.ValidOffset(debug_line_offset)) 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t offset = debug_line_offset; 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "----------------------------------------------------------------------\n" 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "debug_line[0x%8.8x]\n" 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "----------------------------------------------------------------------\n", debug_line_offset); 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return offset; 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return debug_line_offset + 1; // Skip to next byte in .debug_line section 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return DW_INVALID_OFFSET; 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DumpOpcodes 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset, uint32_t dump_flags) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DataExtractor& debug_line_data = dwarf2Data->get_debug_line_data(); 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_data.GetByteSize() == 0) 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "< EMPTY >\n"); 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_offset == DW_INVALID_OFFSET) 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Dump line table to a single file only 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_offset = 0; 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (debug_line_data.ValidOffset(debug_line_offset)) 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_offset = DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags); 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Dump line table to a single file only 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags); 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DumpStatementOpcodes 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_offset_t 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::DumpStatementOpcodes(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags) 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t offset = debug_line_offset; 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_data.ValidOffset(offset)) 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Prologue prologue; 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ParsePrologue(debug_line_data, &offset, &prologue)) 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("----------------------------------------------------------------------"); 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("debug_line[0x%8.8x]", debug_line_offset); 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("----------------------------------------------------------------------\n"); 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue.Dump (log); 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner offset = debug_line_offset; 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset)); 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return offset; 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row row(prologue.default_is_stmt); 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const dw_offset_t end_offset = debug_line_offset + prologue.total_length + sizeof(prologue.total_length); 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(debug_line_data.ValidOffset(end_offset-1)); 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (offset < end_offset) 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t op_offset = offset; 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t opcode = debug_line_data.GetU8(&offset); 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (opcode) 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case 0: // Extended Opcodes always start with a zero opcode followed by 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { // a uleb128 length so you can skip ones you don't know about 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t ext_offset = offset; 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_uleb128_t len = debug_line_data.GetULEB128(&offset); 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t arg_size = len - (offset - ext_offset); 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t sub_opcode = debug_line_data.GetU8(&offset); 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (verbose) 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// log->Printf( "Extended: <%u> %2.2x ", len, sub_opcode); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (sub_opcode) 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_end_sequence : 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNE_end_sequence", op_offset); 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.Dump(log); 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.Reset(prologue.default_is_stmt); 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_set_address : 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address = debug_line_data.GetMaxU64(&offset, arg_size); 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNE_set_address (0x%llx)", op_offset, row.address); 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_define_file: 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileNameEntry fileEntry; 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.name = debug_line_data.GetCStr(&offset); 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.dir_idx = debug_line_data.GetULEB128(&offset); 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.mod_time = debug_line_data.GetULEB128(&offset); 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.length = debug_line_data.GetULEB128(&offset); 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNE_define_file('%s', dir=%i, mod_time=0x%8.8x, length=%i )", 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner op_offset, 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.name.c_str(), 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.dir_idx, 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.mod_time, 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.length); 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue.file_names.push_back(fileEntry); 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", op_offset, opcode); 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Length doesn't include the zero opcode byte or the length itself, but 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // it does include the sub_opcode, so we have to adjust for that below 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner offset += arg_size; 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Standard Opcodes 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_copy: 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_copy", op_offset); 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.Dump (log); 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_advance_pc: 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset); 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length; 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_advance_pc (0x%llx)", op_offset, addr_offset); 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address += addr_offset; 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_advance_line: 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset); 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_advance_line (%i)", op_offset, line_offset); 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.line += line_offset; 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_file: 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.file = debug_line_data.GetULEB128(&offset); 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file); 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_column: 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.column = debug_line_data.GetULEB128(&offset); 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column); 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_negate_stmt: 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.is_stmt = !row.is_stmt; 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_negate_stmt", op_offset); 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_basic_block: 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.basic_block = true; 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_basic_block", op_offset); 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_const_add_pc: 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t adjust_opcode = 255 - prologue.opcode_base; 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length; 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8llx)", op_offset, addr_offset); 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address += addr_offset; 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_fixed_advance_pc: 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint16_t pc_offset = debug_line_data.GetU16(&offset); 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, pc_offset); 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address += pc_offset; 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_prologue_end: 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.prologue_end = true; 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_prologue_end", op_offset); 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_epilogue_begin: 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.epilogue_begin = true; 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_epilogue_begin", op_offset); 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_isa: 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.isa = debug_line_data.GetULEB128(&offset); 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa); 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Special Opcodes 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (opcode < prologue.opcode_base) 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We have an opcode that this parser doesn't know about, skip 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the number of ULEB128 numbers that is says to skip in the 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // prologue's standard_opcode_lengths array 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t n = prologue.standard_opcode_lengths[opcode-1]; 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%8.8x: Special : Unknown skipping %u ULEB128 values.", op_offset, n); 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (n > 0) 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_data.GetULEB128(&offset); 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner --n; 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t adjust_opcode = opcode - prologue.opcode_base; 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length; 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range); 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf("0x%8.8x: address += 0x%llx, line += %i\n", op_offset, (uint64_t)addr_offset, line_offset); 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address += addr_offset; 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.line += line_offset; 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.Dump (log); 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return end_offset; 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return DW_INVALID_OFFSET; 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse the entire line table contents calling callback each time a 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// new prologue is parsed and every time a new row is to be added to 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the line table. 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Parse(const DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData) 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t offset = 0; 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (debug_line_data.ValidOffset(offset)) 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++offset; // Skip to next byte in .debug_line section 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::ParsePrologue 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue) 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const uint32_t prologue_offset = *offset_ptr; 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->Clear(); 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char * s; 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->total_length = debug_line_data.GetU32(offset_ptr); 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->version = debug_line_data.GetU16(offset_ptr); 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (prologue->version != 2) 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->prologue_length = debug_line_data.GetU32(offset_ptr); 41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const dw_offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; 41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->min_inst_length = debug_line_data.GetU8(offset_ptr); 41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr); 41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->line_base = debug_line_data.GetU8(offset_ptr); 42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->line_range = debug_line_data.GetU8(offset_ptr); 42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->opcode_base = debug_line_data.GetU8(offset_ptr); 42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1); 42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=1; i<prologue->opcode_base; ++i) 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t op_len = debug_line_data.GetU8(offset_ptr); 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->standard_opcode_lengths.push_back(op_len); 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (*offset_ptr < end_prologue_offset) 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s = debug_line_data.GetCStr(offset_ptr); 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (s && s[0]) 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->include_directories.push_back(s); 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (*offset_ptr < end_prologue_offset) 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char* name = debug_line_data.GetCStr( offset_ptr ); 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (name && name[0]) 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileNameEntry fileEntry; 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.name = name; 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.dir_idx = debug_line_data.GetULEB128( offset_ptr ); 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.mod_time = debug_line_data.GetULEB128( offset_ptr ); 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.length = debug_line_data.GetULEB128( offset_ptr ); 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->file_names.push_back(fileEntry); 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(*offset_ptr == end_prologue_offset); 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return end_prologue_offset; 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::ParseSupportFiles(const DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, FileSpecList &support_files) 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t offset = stmt_list + 4; // Skip the total length 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char * s; 46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t version = debug_line_data.GetU16(&offset); 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (version != 2) 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const dw_offset_t end_prologue_offset = debug_line_data.GetU32(&offset) + offset; 47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Skip instruction length, default is stmt, line base, line range and 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode base, and all opcode lengths 47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner offset += 4; 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint8_t opcode_base = debug_line_data.GetU8(&offset); 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner offset += opcode_base - 1; 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<std::string> include_directories; 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner include_directories.push_back(""); // Directory at index zero doesn't exist 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (offset < end_prologue_offset) 47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s = debug_line_data.GetCStr(&offset); 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (s && s[0]) 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner include_directories.push_back(s); 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string fullpath; 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (offset < end_prologue_offset) 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char* path = debug_line_data.GetCStr( &offset ); 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (path && path[0]) 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t dir_idx = debug_line_data.GetULEB128( &offset ); 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_data.Skip_LEB128(&offset); // Skip mod_time 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_data.Skip_LEB128(&offset); // Skip length 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (path[0] == '/') 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The path starts with a directory delimiter, so we are done. 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath = path; 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dir_idx > 0 && dir_idx < include_directories.size()) 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cu_comp_dir && include_directories[dir_idx][0] != '/') 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath = cu_comp_dir; 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*fullpath.rbegin() != '/') 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath += '/'; 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath += include_directories[dir_idx]; 51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath = include_directories[dir_idx]; 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (cu_comp_dir && cu_comp_dir[0]) 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath = cu_comp_dir; 51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!fullpath.empty()) 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*fullpath.rbegin() != '/') 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath += '/'; 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fullpath += path; 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 528c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham 529c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham // We don't need to realpath files in the debug_line tables. 530c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham FileSpec file_spec(fullpath.c_str(), false); 53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner support_files.Append(file_spec); 53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(offset == end_prologue_offset); 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return end_prologue_offset; 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ParseStatementTable 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse a single line table (prologue and all rows) and call the 54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// callback function once for the prologue (row in state will be zero) 54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// and each time a row is to be added to the line table. 54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::ParseStatementTable 54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DataExtractor& debug_line_data, 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t* offset_ptr, 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DWARFDebugLine::State::Callback callback, 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void* userData 55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE); 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Prologue::shared_ptr prologue(new Prologue()); 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const dw_offset_t debug_line_offset = *offset_ptr; 56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_offset); 56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) 56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Error ("failed to parse DWARF line table prologue"); 56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Restore our offset and return false to indicate failure! 57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *offset_ptr = debug_line_offset; 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->Dump (log); 57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const dw_offset_t end_offset = debug_line_offset + prologue->total_length + sizeof(prologue->total_length); 57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 57924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert(debug_line_data.ValidOffset(end_offset-1)); 58024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner State state(prologue, log, callback, userData); 58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (*offset_ptr < end_offset) 58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr); 58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t opcode = debug_line_data.GetU8(offset_ptr); 58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (opcode == 0) 58924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Extended Opcodes always start with a zero opcode followed by 59124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a uleb128 length so you can skip ones you don't know about 59224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t ext_offset = *offset_ptr; 59324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr); 59424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_offset_t arg_size = len - (*offset_ptr - ext_offset); 59524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //DEBUG_PRINTF("Extended: <%2u> ", len); 59724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr); 59824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (sub_opcode) 59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_end_sequence: 60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Set the end_sequence register of the state machine to true and 60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // append a row to the matrix using the current values of the 60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // state-machine registers. Then reset the registers to the initial 60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // values specified above. Every statement program sequence must end 60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // with a DW_LNE_end_sequence instruction which creates a row whose 60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // address is that of the byte after the last target machine instruction 60724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // of the sequence. 60824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.end_sequence = true; 60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.AppendRowToMatrix(*offset_ptr); 61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.Reset(); 61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_set_address: 61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single relocatable address as an operand. The size of the 61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // operand is the size appropriate to hold an address on the target 61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // machine. Set the address register to the value given by the 61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // relocatable address. All of the other statement program opcodes 61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // that affect the address register add a delta to it. This instruction 61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // stores a relocatable value into it instead. 62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.address = debug_line_data.GetAddress(offset_ptr); 62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 62224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 62324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNE_define_file: 62424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes 4 arguments. The first is a null terminated string containing 62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a source file name. The second is an unsigned LEB128 number representing 62624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the directory index of the directory in which the file was found. The 62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // third is an unsigned LEB128 number representing the time of last 62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // modification of the file. The fourth is an unsigned LEB128 number 62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // representing the length in bytes of the file. The time and length 63024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // fields may contain LEB128(0) if the information is not available. 63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The directory index represents an entry in the include_directories 63324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // section of the statement program prologue. The index is LEB128(0) 63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // if the file was found in the current directory of the compilation, 63524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // LEB128(1) if it was found in the first directory in the 63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // include_directories section, and so on. The directory index is 63724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // ignored for file names that represent full path names. 63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The files are numbered, starting at 1, in the order in which they 64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // appear; the names in the prologue come before names defined by 64124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the DW_LNE_define_file instruction. These numbers are used in the 64224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the file register of the state machine. 64324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 64424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FileNameEntry fileEntry; 64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.name = debug_line_data.GetCStr(offset_ptr); 64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); 64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); 64824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.length = debug_line_data.GetULEB128(offset_ptr); 64924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.prologue->file_names.push_back(fileEntry); 65024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 65124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 65224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 65424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Length doesn't include the zero opcode byte or the length itself, but 65524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // it does include the sub_opcode, so we have to adjust for that below 65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (*offset_ptr) += arg_size; 65724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (opcode < prologue->opcode_base) 66124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 66224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (opcode) 66324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 66424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Standard Opcodes 66524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_copy: 66624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Append a row to the matrix using the 66724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // current values of the state-machine registers. Then set 66824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the basic_block register to false. 66924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.AppendRowToMatrix(*offset_ptr); 67024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 67124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 67224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_advance_pc: 67324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single unsigned LEB128 operand, multiplies it by the 67424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // min_inst_length field of the prologue, and adds the 67524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // result to the address register of the state machine. 67624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length; 67724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 67824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 67924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_advance_line: 68024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single signed LEB128 operand and adds that value to 68124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the line register of the state machine. 68224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.line += debug_line_data.GetSLEB128(offset_ptr); 68324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_file: 68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single unsigned LEB128 operand and stores it in the file 68724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // register of the state machine. 68824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.file = debug_line_data.GetULEB128(offset_ptr); 68924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 69024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 69124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_column: 69224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single unsigned LEB128 operand and stores it in the 69324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // column register of the state machine. 69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.column = debug_line_data.GetULEB128(offset_ptr); 69524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 69624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 69724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_negate_stmt: 69824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Set the is_stmt register of the state 69924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // machine to the logical negation of its current value. 70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.is_stmt = !state.is_stmt; 70124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 70324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_basic_block: 70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Set the basic_block register of the 70524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // state machine to true 70624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.basic_block = true; 70724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 70824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 70924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_const_add_pc: 71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Add to the address register of the state 71124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // machine the address increment value corresponding to special 71224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode 255. The motivation for DW_LNS_const_add_pc is this: 71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // when the statement program needs to advance the address by a 71424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // small amount, it can use a single special opcode, which occupies 71524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a single byte. When it needs to advance the address by up to 71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // twice the range of the last special opcode, it can use 71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // DW_LNS_const_add_pc followed by a special opcode, for a total 71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // of two bytes. Only if it needs to advance the address by more 71924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // than twice that range will it need to use both DW_LNS_advance_pc 72024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // and a special opcode, requiring three or more bytes. 72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 72224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t adjust_opcode = 255 - prologue->opcode_base; 72324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length; 72424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.address += addr_offset; 72524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 72624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 72724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 72824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_fixed_advance_pc: 72924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single uhalf operand. Add to the address register of 73024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the state machine the value of the (unencoded) operand. This 73124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // is the only extended opcode that takes an argument that is not 73224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a variable length number. The motivation for DW_LNS_fixed_advance_pc 73324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // is this: existing assemblers cannot emit DW_LNS_advance_pc or 73424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // special opcodes because they cannot encode LEB128 numbers or 73524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // judge when the computation of a special opcode overflows and 73624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // requires the use of DW_LNS_advance_pc. Such assemblers, however, 73724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. 73824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.address += debug_line_data.GetU16(offset_ptr); 73924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 74024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 74124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_prologue_end: 74224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Set the prologue_end register of the 74324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // state machine to true 74424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.prologue_end = true; 74524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 74624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 74724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_epilogue_begin: 74824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes no arguments. Set the basic_block register of the 74924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // state machine to true 75024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.epilogue_begin = true; 75124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 75224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 75324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case DW_LNS_set_isa: 75424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Takes a single unsigned LEB128 operand and stores it in the 75524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // column register of the state machine. 75624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.isa = debug_line_data.GetULEB128(offset_ptr); 75724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 75824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 75924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 76024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Handle any unknown standard opcodes here. We know the lengths 76124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // of such opcodes because they are specified in the prologue 76224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // as a multiple of LEB128 operands for each opcode. 76324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 76424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t i; 76524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (opcode - 1 < prologue->standard_opcode_lengths.size()); 76624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1]; 76724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<opcode_length; ++i) 76824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner debug_line_data.Skip_LEB128(offset_ptr); 76924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 77024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 77124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 77224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 77324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 77424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 77524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Special Opcodes 77624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 77724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // A special opcode value is chosen based on the amount that needs 77824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // to be added to the line and address registers. The maximum line 77924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // increment for a special opcode is the value of the line_base 78024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // field in the header, plus the value of the line_range field, 78124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // minus 1 (line base + line range - 1). If the desired line 78224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // increment is greater than the maximum line increment, a standard 78324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode must be used instead of a special opcode. The “address 78424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // advance” is calculated by dividing the desired address increment 78524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // by the minimum_instruction_length field from the header. The 78624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // special opcode is then calculated using the following formula: 78724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 78824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base 78924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 79024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the resulting opcode is greater than 255, a standard opcode 79124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // must be used instead. 79224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 79324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // To decode a special opcode, subtract the opcode_base from the 79424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode itself to give the adjusted opcode. The amount to 79524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // increment the address register is the result of the adjusted 79624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // opcode divided by the line_range multiplied by the 79724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // minimum_instruction_length field from the header. That is: 79824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 79924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // address increment = (adjusted opcode / line_range) * minimim_instruction_length 80024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 80124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The amount to increment the line register is the line_base plus 80224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the result of the adjusted opcode modulo the line_range. That is: 80324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 80424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // line increment = line_base + (adjusted opcode % line_range) 80524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 80624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t adjust_opcode = opcode - prologue->opcode_base; 80724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length; 80824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range); 80924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.line += line_offset; 81024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.address += addr_offset; 81124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.AppendRowToMatrix(*offset_ptr); 81224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 81324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 81424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 81524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state.Finalize( *offset_ptr ); 81624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 81724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return end_offset; 81824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 81924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 82024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 82124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 82224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ParseStatementTableCallback 82324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 82424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void 82524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 82624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 82724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData; 82824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (state.row == DWARFDebugLine::State::StartParsingLineTable) 82924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 83024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Just started parsing the line table, so lets keep a reference to 83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the prologue using the supplied shared pointer 83224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line_table->prologue = state.prologue; 83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 83424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 83524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 83624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Done parsing line table, nothing to do for the cleanup 83724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 83824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 83924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 84024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We have a new row, lets append it 84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line_table->AppendRow(state); 84224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 84324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 84524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 84624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ParseStatementTable 84724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 84824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Parse a line table at offset and populate the LineTable class with 84924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the prologue and all rows. 85024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 85124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 85224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table) 85324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 85424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table); 85524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 85624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 85724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 85824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerinline bool 85924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Prologue::IsValid() const 86024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 86124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SymbolFileDWARF::SupportedVersion(version); 86224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 86324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 86424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 86524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::Prologue::Dump 86624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 86724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 86824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Prologue::Dump(Log *log) 86924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 87024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 87124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 87224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "Line table prologue:"); 87324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( " total_length: 0x%8.8x", total_length); 87424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( " version: %u", version); 87524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "prologue_length: 0x%8.8x", prologue_length); 87624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "min_inst_length: %u", min_inst_length); 87724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "default_is_stmt: %u", default_is_stmt); 87824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( " line_base: %i", line_base); 87924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( " line_range: %u", line_range); 88024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( " opcode_base: %u", opcode_base); 88124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 88224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<standard_opcode_lengths.size(); ++i) 88324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 88424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]); 88524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 88624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 88724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!include_directories.empty()) 88824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 88924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<include_directories.size(); ++i) 89024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 89124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i].c_str()); 89224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 89324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 89424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 89524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!file_names.empty()) 89624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 89724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString (" Dir Mod Time File Len File Name"); 89824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString (" ---- ---------- ---------- ---------------------------"); 89924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<file_names.size(); ++i) 90024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 90124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const FileNameEntry& fileEntry = file_names[i]; 90224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", 90324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner i+1, 90424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.dir_idx, 90524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.mod_time, 90624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.length, 90724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fileEntry.name.c_str()); 90824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 90924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 91024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 91124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::ParsePrologue::Append 91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Append the contents of the prologue to the binary stream buffer 91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//void 91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const 92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{ 92124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// uint32_t i; 92224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 92324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append32(total_length); 92424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append16(version); 92524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append32(prologue_length); 92624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(min_inst_length); 92724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(default_is_stmt); 92824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(line_base); 92924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(line_range); 93024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(opcode_base); 93124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 93224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// for (i=0; i<standard_opcode_lengths.size(); ++i) 93324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(standard_opcode_lengths[i]); 93424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 93524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// for (i=0; i<include_directories.size(); ++i) 93624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.AppendCStr(include_directories[i].c_str()); 93724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(0); // Terminate the include directory section with empty string 93824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 93924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// for (i=0; i<file_names.size(); ++i) 94024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 94124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.AppendCStr(file_names[i].name.c_str()); 94224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append32_as_ULEB128(file_names[i].dir_idx); 94324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append32_as_ULEB128(file_names[i].mod_time); 94424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append32_as_ULEB128(file_names[i].length); 94524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 94624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buff.Append8(0); // Terminate the file names section with empty string 94724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//} 94824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 94924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 95024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, std::string& path, std::string& directory) const 95124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 95224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t idx = file_idx - 1; // File indexes are 1 based... 95324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (idx < file_names.size()) 95424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 95524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner path = file_names[idx].name; 95624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t dir_idx = file_names[idx].dir_idx - 1; 95724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dir_idx < include_directories.size()) 95824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner directory = include_directories[dir_idx]; 95924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 96024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner directory.clear(); 96124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 96224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 96324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 96424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 96524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 96624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 96724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::LineTable::Dump 96824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 96924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 97024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::LineTable::Dump(Log *log) const 97124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 97224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (prologue.get()) 97324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue->Dump (log); 97424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 97524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!rows.empty()) 97624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 97724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("Address Line Column File ISA Flags"); 97824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("------------------ ------ ------ ------ --- -------------"); 97924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::const_iterator pos = rows.begin(); 98024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::const_iterator end = rows.end(); 98124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (pos != end) 98224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 98324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (*pos).Dump (log); 98424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++pos; 98524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 98624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 98724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 98824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 98924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 99024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 99124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state) 99224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 99324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner rows.push_back(state); 99424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 99524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 99624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 99724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 99824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 99924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress() 100024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 100124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2) 100224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 100324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return row1.address < row2.address; 100424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 100524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 100624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 100724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 100824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::LineTable::LookupAddress 100924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 101024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 101124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const 101224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 1013178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton uint32_t index = UINT32_MAX; 101424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!rows.empty()) 101524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 101624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Use the lower_bound algorithm to perform a binary search since we know 101724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // that our line table data is ordered by address. 101824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DWARFDebugLine::Row row; 101924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row.address = address; 102024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::const_iterator begin_pos = rows.begin(); 102124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::const_iterator end_pos = rows.end(); 102224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress); 102324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos == end_pos) 102424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 102524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (address < cu_high_pc) 102624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return rows.size()-1; 102724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 102824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 102924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 103024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Rely on fact that we are using a std::vector and we can do 103124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pointer arithmetic to find the row index (which will be one less 103224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // that what we found since it will find the first position after 103324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the current address) since std::vector iterators are just 103424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pointers to the container type. 103524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner index = pos - begin_pos; 103624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos->address > address) 103724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 103824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (index > 0) 103924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner --index; 104024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 1041178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton index = UINT32_MAX; 104224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 104324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 104424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 104524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return index; // Failed to find address 104624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 104724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 104824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 104924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 105024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::Row::Row 105124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 105224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::Row(bool default_is_stmt) : 105324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner address(0), 105424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line(1), 105524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner column(0), 105624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file(1), 105724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner is_stmt(default_is_stmt), 105824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner basic_block(false), 105924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end_sequence(false), 106024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue_end(false), 106124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner epilogue_begin(false), 106224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner isa(0) 106324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 106424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 106524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 106624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 106724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Called after a row is appended to the matrix 106824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 106924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 107024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::PostAppend() 107124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 107224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner basic_block = false; 107324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue_end = false; 107424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner epilogue_begin = false; 107524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 107624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 107724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 107824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 107924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::Row::Reset 108024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 108124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 108224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::Reset(bool default_is_stmt) 108324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 108424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner address = 0; 108524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line = 1; 108624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner column = 0; 108724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file = 1; 108824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner is_stmt = default_is_stmt; 108924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner basic_block = false; 109024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end_sequence = false; 109124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue_end = false; 109224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner epilogue_begin = false; 109324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner isa = 0; 109424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 109524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 109624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::Row::Dump 109724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 109824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 109924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::Dump(Log *log) const 110024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 110124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf( "0x%16.16llx %6u %6u %6u %3u %s%s%s%s%s", 110224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner address, 110324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line, 110424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner column, 110524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file, 110624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner isa, 110724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner is_stmt ? " is_stmt" : "", 110824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner basic_block ? " basic_block" : "", 110924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue_end ? " prologue_end" : "", 111024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner epilogue_begin ? " epilogue_begin" : "", 111124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end_sequence ? " end_sequence" : ""); 111224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 111324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 111424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 111524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Compare function LineTable structures 111624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 111724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b) 111824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 111924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return a.address < b.address; 112024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 112124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 112224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 112324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 112424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Insert a row at the correct address if the addresses can be out of 112524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// order which can only happen when we are linking a line table that 112624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// may have had it's contents rearranged. 112724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 112824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state) 112924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 113024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we don't have anything yet, or if the address of the last state in our 113124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // line table is less than the current one, just append the current state 113224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) 113324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 113424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state_coll.push_back(state); 113524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 113624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 113724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 113824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Do a binary search for the correct entry 113924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan)); 114024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 114124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the addresses are equal, we can safely replace the previous entry 114224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // with the current one if the one it is replacing is an end_sequence entry. 114324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We currently always place an extra end sequence when ever we exit a valid 114424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // address range for a function in case the functions get rearranged by 114524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // optmimizations or by order specifications. These extra end sequences will 114624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // disappear by getting replaced with valid consecutive entries within a 114724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // compile unit if there are no gaps. 114824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (range.first == range.second) 114924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 115024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state_coll.insert(range.first, state); 115124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 115224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 115324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 115424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true) 115524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 115624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *range.first = state; 115724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 115824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 115924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 116024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner state_coll.insert(range.second, state); 116124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 116224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 116324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 116424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 116524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 116624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 116724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll) 116824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 116924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log)); 117024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 117124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 117224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 117324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 117424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::State::State 117524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 117624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) : 117724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row (p->default_is_stmt), 117824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner prologue (p), 117924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log (l), 118024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner callback (cb), 118124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner callbackUserData (userData), 118224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row (StartParsingLineTable) 118324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 118424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Call the callback with the initial row state of zero for the prologue 118524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (callback) 118624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner callback(0, *this, callbackUserData); 118724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 118824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 118924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 119024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::State::Reset 119124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 119224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 119324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::State::Reset() 119424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 119524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Row::Reset(prologue->default_is_stmt); 119624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 119724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 119824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 119924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::State::AppendRowToMatrix 120024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 120124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 120224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) 120324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 120424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Each time we are to add an entry into the line table matrix 120524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // call the callback funtion so that someone can do something with 120624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the current state of the state machine (like build a line table 120724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // or dump the line table!) 120824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 120924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 121024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (row == 0) 121124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 121224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("Address Line Column File ISA Flags"); 121324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->PutCString ("------------------ ------ ------ ------ --- -------------"); 121424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 121524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Dump (log); 121624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 121724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 121824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++row; // Increase the row number before we call our callback for a real row 121924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (callback) 122024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner callback(offset, *this, callbackUserData); 122124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PostAppend(); 122224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 122324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 122424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 122524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::State::Finalize 122624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 122724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 122824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugLine::State::Finalize(dw_offset_t offset) 122924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 123024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Call the callback with a special row state when we are done parsing a 123124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // line table 123224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner row = DoneParsingLineTable; 123324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (callback) 123424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner callback(offset, *this, callbackUserData); 123524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 123624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 123724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//void 123824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//DWARFDebugLine::AppendLineTableData 123924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//( 124024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const DWARFDebugLine::Prologue* prologue, 124124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const DWARFDebugLine::Row::collection& state_coll, 124224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const uint32_t addr_size, 124324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// BinaryStreamBuf &debug_line_data 124424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//) 124524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{ 124624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (state_coll.empty()) 124724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 124824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // We have no entries, just make an empty line table 124924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(0); 125024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(1); 125124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNE_end_sequence); 125224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 125324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// else 125424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 125524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugLine::Row::const_iterator pos; 125624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Row::const_iterator end = state_coll.end(); 125724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// bool default_is_stmt = prologue->default_is_stmt; 125824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const DWARFDebugLine::Row reset_state(default_is_stmt); 125924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const DWARFDebugLine::Row* prev_state = &reset_state; 126024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode(); 126124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// for (pos = state_coll.begin(); pos != end; ++pos) 126224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 126324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// const DWARFDebugLine::Row& curr_state = *pos; 126424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// int32_t line_increment = 0; 126524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// dw_addr_t addr_offset = curr_state.address - prev_state->address; 126624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// dw_addr_t addr_advance = (addr_offset) / prologue->min_inst_length; 126724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// line_increment = (int32_t)(curr_state.line - prev_state->line); 126824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 126924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // If our previous state was the reset state, then let's emit the 127024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // address to keep GDB's DWARF parser happy. If we don't start each 127124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // sequence with a DW_LNE_set_address opcode, the line table won't 127224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // get slid properly in GDB. 127324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 127424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (prev_state == &reset_state) 127524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 127624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(0); // Extended opcode 127724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes 127824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNE_set_address); 127924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.AppendMax64(curr_state.address, addr_size); 128024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// addr_advance = 0; 128124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 128224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 128324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (prev_state->file != curr_state.file) 128424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 128524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_set_file); 128624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(curr_state.file); 128724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 128824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 128924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (prev_state->column != curr_state.column) 129024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 129124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_set_column); 129224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(curr_state.column); 129324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 129424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 129524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Don't do anything fancy if we are at the end of a sequence 129624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // as we don't want to push any extra rows since the DW_LNE_end_sequence 129724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // will push a row itself! 129824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (curr_state.end_sequence) 129924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 130024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (line_increment != 0) 130124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 130224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_line); 130324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_SLEB128(line_increment); 130424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 130524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 130624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (addr_advance > 0) 130724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 130824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_pc); 130924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(addr_advance); 131024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 131124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 131224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Now push the end sequence on! 131324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(0); 131424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(1); 131524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNE_end_sequence); 131624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 131724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// prev_state = &reset_state; 131824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 131924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// else 132024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 132124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (line_increment || addr_advance) 132224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 132324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (line_increment > max_line_increment_for_special_opcode) 132424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 132524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_line); 132624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_SLEB128(line_increment); 132724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// line_increment = 0; 132824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 132924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 133024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256; 133124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (special_opcode > 255) 133224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 133324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Both the address and line won't fit in one special opcode 133424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // check to see if just the line advance will? 133524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ? 133624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ((line_increment - prologue->line_base) + prologue->opcode_base) : 256; 133724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 133824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 133924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (special_opcode_line > 255) 134024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 134124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Nope, the line advance won't fit by itself, check the address increment by itself 134224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// uint32_t special_opcode_addr = addr_advance ? 134324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256; 134424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 134524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (special_opcode_addr > 255) 134624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 134724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Neither the address nor the line will fit in a 134824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // special opcode, we must manually enter both then 134924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // do a DW_LNS_copy to push a row (special opcode 135024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // automatically imply a new row is pushed) 135124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (line_increment != 0) 135224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 135324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_line); 135424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_SLEB128(line_increment); 135524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 135624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 135724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (addr_advance > 0) 135824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 135924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_pc); 136024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(addr_advance); 136124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 136224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 136324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Now push a row onto the line table manually 136424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_copy); 136524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 136624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 136724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// else 136824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 136924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // The address increment alone will fit into a special opcode 137024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // so modify our line change, then issue a special opcode 137124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // for the address increment and it will push a row into the 137224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // line table 137324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (line_increment != 0) 137424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 137524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_line); 137624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_SLEB128(line_increment); 137724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 137824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 137924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Advance of line and address will fit into a single byte special opcode 138024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // and this will also push a row onto the line table 138124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(special_opcode_addr); 138224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 138324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 138424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// else 138524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 138624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // The line change alone will fit into a special opcode 138724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // so modify our address increment first, then issue a 138824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // special opcode for the line change and it will push 138924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // a row into the line table 139024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (addr_advance > 0) 139124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 139224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(DW_LNS_advance_pc); 139324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append32_as_ULEB128(addr_advance); 139424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 139524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 139624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Advance of line and address will fit into a single byte special opcode 139724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // and this will also push a row onto the line table 139824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(special_opcode_line); 139924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 140024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 140124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// else 140224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// { 140324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // Advance of line and address will fit into a single byte special opcode 140424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// // and this will also push a row onto the line table 140524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug_line_data.Append8(special_opcode); 140624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 140724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 140824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// prev_state = &curr_state; 140924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 141024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 141124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// } 141224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//} 1413