1b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//===-- DWARFDebugLine.cpp ------------------------------------------------===// 2b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// 3b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// The LLVM Compiler Infrastructure 4b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// 5b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// This file is distributed under the University of Illinois Open Source 6b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// License. See LICENSE.TXT for details. 7b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// 8b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//===----------------------------------------------------------------------===// 9b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 11b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/Dwarf.h" 12b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/Format.h" 1338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov#include "llvm/Support/Path.h" 14b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/raw_ostream.h" 157393c7f748acb10b143cab296ae98551b4c430f4Benjamin Kramer#include <algorithm> 16b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerusing namespace llvm; 17b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerusing namespace dwarf; 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Prologue::Prologue() { clear(); } 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::Prologue::clear() { 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TotalLength = Version = PrologueLength = 0; 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; 25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OpcodeBase = 0; 266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IsDWARF64 = false; 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StandardOpcodeLengths.clear(); 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IncludeDirectories.clear(); 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FileNames.clear(); 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 31b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 32b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { 33b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer OS << "Line table prologue:\n" 346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength) 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" version: %u\n", Version) 366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" min_inst_length: %u\n", MinInstLength) 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" default_is_stmt: %u\n", DefaultIsStmt) 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" line_base: %i\n", LineBase) 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" line_range: %u\n", LineRange) 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" opcode_base: %u\n", OpcodeBase); 43b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 44b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) 45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i + 1), 46b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer StandardOpcodeLengths[i]); 47b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 48b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer if (!IncludeDirectories.empty()) 49b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer for (uint32_t i = 0; i < IncludeDirectories.size(); ++i) 50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS << format("include_directories[%3u] = '", i + 1) 51b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer << IncludeDirectories[i] << "'\n"; 52b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 53b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer if (!FileNames.empty()) { 54b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer OS << " Dir Mod Time File Len File Name\n" 55b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer << " ---- ---------- ---------- -----------" 56b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer "----------------\n"; 57b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer for (uint32_t i = 0; i < FileNames.size(); ++i) { 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const FileNameEntry &fileEntry = FileNames[i]; 59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx) 60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime, 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar fileEntry.Length) 62b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer << fileEntry.Name << '\n'; 63b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 64b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 65b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 66b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t *offset_ptr) { 696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const uint64_t prologue_offset = *offset_ptr; 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines clear(); 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TotalLength = debug_line_data.getU32(offset_ptr); 736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (TotalLength == UINT32_MAX) { 746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IsDWARF64 = true; 756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar TotalLength = debug_line_data.getU64(offset_ptr); 766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (TotalLength > 0xffffff00) { 776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Version = debug_line_data.getU16(offset_ptr); 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Version < 2) 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar PrologueLength = 84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength()); 856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const uint64_t end_prologue_offset = PrologueLength + *offset_ptr; 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MinInstLength = debug_line_data.getU8(offset_ptr); 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Version >= 4) 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MaxOpsPerInst = debug_line_data.getU8(offset_ptr); 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DefaultIsStmt = debug_line_data.getU8(offset_ptr); 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LineBase = debug_line_data.getU8(offset_ptr); 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LineRange = debug_line_data.getU8(offset_ptr); 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OpcodeBase = debug_line_data.getU8(offset_ptr); 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StandardOpcodeLengths.reserve(OpcodeBase - 1); 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (uint32_t i = 1; i < OpcodeBase; ++i) { 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t op_len = debug_line_data.getU8(offset_ptr); 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StandardOpcodeLengths.push_back(op_len); 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (*offset_ptr < end_prologue_offset) { 101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *s = debug_line_data.getCStr(offset_ptr); 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (s && s[0]) 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IncludeDirectories.push_back(s); 104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (*offset_ptr < end_prologue_offset) { 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *name = debug_line_data.getCStr(offset_ptr); 110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (name && name[0]) { 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FileNameEntry fileEntry; 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fileEntry.Name = name; 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FileNames.push_back(fileEntry); 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (*offset_ptr != end_prologue_offset) { 1236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar " should have ended at 0x%8.8" PRIx64 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar " but it ended at 0x%8.8" PRIx64 "\n", 1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr); 127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); } 133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 134b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::postAppend() { 135b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer BasicBlock = false; 136b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer PrologueEnd = false; 137b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer EpilogueBegin = false; 138b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 139b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 140b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::reset(bool default_is_stmt) { 141b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer Address = 0; 142b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer Line = 1; 143b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer Column = 0; 144b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer File = 1; 145b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer Isa = 0; 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Discriminator = 0; 147b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer IsStmt = default_is_stmt; 148b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer BasicBlock = false; 149b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer EndSequence = false; 150b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer PrologueEnd = false; 151b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer EpilogueBegin = false; 152b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 153b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 154b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::dump(raw_ostream &OS) const { 15541a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format(" %6u %3u %13u ", File, Isa, Discriminator) 157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") 158b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer << (PrologueEnd ? " prologue_end" : "") 159b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer << (EpilogueBegin ? " epilogue_begin" : "") 160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << (EndSequence ? " end_sequence" : "") << '\n'; 161b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 162b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Sequence::Sequence() { reset(); } 164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::Sequence::reset() { 166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LowPC = 0; 167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines HighPC = 0; 168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FirstRowIndex = 0; 169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LastRowIndex = 0; 170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Empty = true; 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::LineTable::LineTable() { clear(); } 174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 175b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { 176b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer Prologue.dump(OS); 177b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer OS << '\n'; 178b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 179b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer if (!Rows.empty()) { 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "Address Line Column File ISA Discriminator Flags\n" 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << "------------------ ------ ------ ------ --- ------------- " 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "-------------\n"; 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const Row &R : Rows) { 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines R.dump(OS); 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 186b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 187b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 188b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::LineTable::clear() { 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Prologue.clear(); 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Rows.clear(); 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequences.clear(); 193b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 194b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT) 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : LineTable(LT), RowNumber(0) { 197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resetRowAndSequence(); 198351f83be64057380877615153fe5dc50308ab017Alexey Samsonov} 199351f83be64057380877615153fe5dc50308ab017Alexey Samsonov 200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::ParsingState::resetRowAndSequence() { 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Row.reset(LineTable->Prologue.DefaultIsStmt); 202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.reset(); 203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 2046bc4e712dc35db68a621f54c176f6e0b14f40f97Nick Lewycky 205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) { 206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Sequence.Empty) { 207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Record the beginning of instruction sequence. 208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.Empty = false; 209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.LowPC = Row.Address; 210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.FirstRowIndex = RowNumber; 211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++RowNumber; 213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LineTable->appendRow(Row); 214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Row.EndSequence) { 215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Record the end of instruction sequence. 216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.HighPC = Row.Address; 217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.LastRowIndex = RowNumber; 218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Sequence.isValid()) 219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LineTable->appendSequence(Sequence); 220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Sequence.reset(); 221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Row.postAppend(); 223b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 224b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 225b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerconst DWARFDebugLine::LineTable * 226b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin KramerDWARFDebugLine::getLineTable(uint32_t offset) const { 227b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer LineTableConstIter pos = LineTableMap.find(offset); 228b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer if (pos != LineTableMap.end()) 229b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer return &pos->second; 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 231b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 232b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 233c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramerconst DWARFDebugLine::LineTable * 234c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin KramerDWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, 235c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer uint32_t offset) { 2361d13d9ed969259d3be267cf0e2c6fe92c1baed49Benjamin Kramer std::pair<LineTableIter, bool> pos = 237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); 238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LineTable *LT = &pos.first->second; 2391d13d9ed969259d3be267cf0e2c6fe92c1baed49Benjamin Kramer if (pos.second) { 240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!LT->parse(debug_line_data, RelocMap, &offset)) 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 242c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer } 243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return LT; 244c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer} 245c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const RelocAddrMap *RMap, 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t *offset_ptr) { 249b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer const uint32_t debug_line_offset = *offset_ptr; 250b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines clear(); 252b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Prologue.parse(debug_line_data, offset_ptr)) { 254b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Restore our offset and return false to indicate failure! 255b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer *offset_ptr = debug_line_offset; 256b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer return false; 257b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 258b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const uint32_t end_offset = 260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength(); 261b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ParsingState State(this); 2639013db3399d2847899ba32daf58844bba1aef6ddBenjamin Kramer 264b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer while (*offset_ptr < end_offset) { 265b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer uint8_t opcode = debug_line_data.getU8(offset_ptr); 266b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 267b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer if (opcode == 0) { 268b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Extended Opcodes always start with a zero opcode followed by 269b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // a uleb128 length so you can skip ones you don't know about 270b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer uint32_t ext_offset = *offset_ptr; 271b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer uint64_t len = debug_line_data.getULEB128(offset_ptr); 272b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer uint32_t arg_size = len - (*offset_ptr - ext_offset); 273b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 274b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer uint8_t sub_opcode = debug_line_data.getU8(offset_ptr); 275b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer switch (sub_opcode) { 276b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNE_end_sequence: 277b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Set the end_sequence register of the state machine to true and 278b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // append a row to the matrix using the current values of the 279b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // state-machine registers. Then reset the registers to the initial 280b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // values specified above. Every statement program sequence must end 281b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // with a DW_LNE_end_sequence instruction which creates a row whose 282b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // address is that of the byte after the last target machine instruction 283b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // of the sequence. 284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.EndSequence = true; 285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.appendRowToMatrix(*offset_ptr); 286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.resetRowAndSequence(); 287b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 288b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 289b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNE_set_address: 290b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single relocatable address as an operand. The size of the 291b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // operand is the size appropriate to hold an address on the target 292b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // machine. Set the address register to the value given by the 293b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // relocatable address. All of the other statement program opcodes 294b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // that affect the address register add a delta to it. This instruction 295b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // stores a relocatable value into it instead. 296ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor { 297ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor // If this address is in our relocation map, apply the relocation. 298ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr); 299ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor if (AI != RMap->end()) { 300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const std::pair<uint8_t, int64_t> &R = AI->second; 301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar State.Row.Address = 302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar debug_line_data.getAddress(offset_ptr) + R.second; 303ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor } else 304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Address = debug_line_data.getAddress(offset_ptr); 305ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor } 306b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 307b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 308b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNE_define_file: 309b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes 4 arguments. The first is a null terminated string containing 310b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // a source file name. The second is an unsigned LEB128 number 311b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // representing the directory index of the directory in which the file 312b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // was found. The third is an unsigned LEB128 number representing the 313b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // time of last modification of the file. The fourth is an unsigned 314b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // LEB128 number representing the length in bytes of the file. The time 315b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // and length fields may contain LEB128(0) if the information is not 316b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // available. 317b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 318b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // The directory index represents an entry in the include_directories 319b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // section of the statement program prologue. The index is LEB128(0) 320b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // if the file was found in the current directory of the compilation, 321b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // LEB128(1) if it was found in the first directory in the 322b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // include_directories section, and so on. The directory index is 323b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // ignored for file names that represent full path names. 324b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 325b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // The files are numbered, starting at 1, in the order in which they 326b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // appear; the names in the prologue come before names defined by 327b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the DW_LNE_define_file instruction. These numbers are used in the 328b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the file register of the state machine. 329b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer { 330b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer FileNameEntry fileEntry; 331b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer fileEntry.Name = debug_line_data.getCStr(offset_ptr); 332b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 333b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 334b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Prologue.FileNames.push_back(fileEntry); 336b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 337b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 338b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DW_LNE_set_discriminator: 340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr); 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 343b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer default: 344b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Length doesn't include the zero opcode byte or the length itself, but 345b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // it does include the sub_opcode, so we have to adjust for that below 346b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer (*offset_ptr) += arg_size; 347b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 348b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (opcode < Prologue.OpcodeBase) { 350b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer switch (opcode) { 351b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Standard Opcodes 352b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_copy: 353b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Append a row to the matrix using the 354b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // current values of the state-machine registers. Then set 355b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the basic_block register to false. 356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.appendRowToMatrix(*offset_ptr); 357b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 358b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 359b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_advance_pc: 360b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single unsigned LEB128 operand, multiplies it by the 361b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // min_inst_length field of the prologue, and adds the 362b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // result to the address register of the state machine. 363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Address += 364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength; 365b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 366b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 367b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_advance_line: 368b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single signed LEB128 operand and adds that value to 369b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the line register of the state machine. 370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Line += debug_line_data.getSLEB128(offset_ptr); 371b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 372b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 373b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_file: 374b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single unsigned LEB128 operand and stores it in the file 375b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // register of the state machine. 376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.File = debug_line_data.getULEB128(offset_ptr); 377b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 378b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 379b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_column: 380b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single unsigned LEB128 operand and stores it in the 381b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // column register of the state machine. 382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Column = debug_line_data.getULEB128(offset_ptr); 383b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 384b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 385b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_negate_stmt: 386b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Set the is_stmt register of the state 387b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // machine to the logical negation of its current value. 388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.IsStmt = !State.Row.IsStmt; 389b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 390b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 391b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_basic_block: 392b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Set the basic_block register of the 393b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // state machine to true 394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.BasicBlock = true; 395b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 396b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 397b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_const_add_pc: 398b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Add to the address register of the state 399b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // machine the address increment value corresponding to special 400b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // opcode 255. The motivation for DW_LNS_const_add_pc is this: 401b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // when the statement program needs to advance the address by a 402b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // small amount, it can use a single special opcode, which occupies 403b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // a single byte. When it needs to advance the address by up to 404b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // twice the range of the last special opcode, it can use 405b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // DW_LNS_const_add_pc followed by a special opcode, for a total 406b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // of two bytes. Only if it needs to advance the address by more 407b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // than twice that range will it need to use both DW_LNS_advance_pc 408b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // and a special opcode, requiring three or more bytes. 409b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer { 410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t adjust_opcode = 255 - Prologue.OpcodeBase; 411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t addr_offset = 412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Address += addr_offset; 414b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 415b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 416b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 417b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_fixed_advance_pc: 418b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single uhalf operand. Add to the address register of 419b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the state machine the value of the (unencoded) operand. This 420b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // is the only extended opcode that takes an argument that is not 421b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // a variable length number. The motivation for DW_LNS_fixed_advance_pc 422b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // is this: existing assemblers cannot emit DW_LNS_advance_pc or 423b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // special opcodes because they cannot encode LEB128 numbers or 424b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // judge when the computation of a special opcode overflows and 425b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // requires the use of DW_LNS_advance_pc. Such assemblers, however, 426b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. 427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Address += debug_line_data.getU16(offset_ptr); 428b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 429b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 430b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_prologue_end: 431b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Set the prologue_end register of the 432b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // state machine to true 433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.PrologueEnd = true; 434b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 435b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 436b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_epilogue_begin: 437b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes no arguments. Set the basic_block register of the 438b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // state machine to true 439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.EpilogueBegin = true; 440b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 441b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 442b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer case DW_LNS_set_isa: 443b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Takes a single unsigned LEB128 operand and stores it in the 444b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // column register of the state machine. 445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Isa = debug_line_data.getULEB128(offset_ptr); 446b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 447b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 448b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer default: 449b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Handle any unknown standard opcodes here. We know the lengths 450b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // of such opcodes because they are specified in the prologue 451b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // as a multiple of LEB128 operands for each opcode. 452b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer { 453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(opcode - 1U < Prologue.StandardOpcodeLengths.size()); 454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1]; 455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (uint8_t i = 0; i < opcode_length; ++i) 456b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer debug_line_data.getULEB128(offset_ptr); 457b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 458b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer break; 459b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 460b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } else { 461b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // Special Opcodes 462b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 463b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // A special opcode value is chosen based on the amount that needs 464b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // to be added to the line and address registers. The maximum line 465b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // increment for a special opcode is the value of the line_base 466b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // field in the header, plus the value of the line_range field, 467b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // minus 1 (line base + line range - 1). If the desired line 468b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // increment is greater than the maximum line increment, a standard 469017449d64b8920eb926e9e752e22d2f5921a6237NAKAMURA Takumi // opcode must be used instead of a special opcode. The "address 470017449d64b8920eb926e9e752e22d2f5921a6237NAKAMURA Takumi // advance" is calculated by dividing the desired address increment 471b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // by the minimum_instruction_length field from the header. The 472b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // special opcode is then calculated using the following formula: 473b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 474b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // opcode = (desired line increment - line_base) + 475b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // (line_range * address advance) + opcode_base 476b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 477b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // If the resulting opcode is greater than 255, a standard opcode 478b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // must be used instead. 479b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 480b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // To decode a special opcode, subtract the opcode_base from the 481b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // opcode itself to give the adjusted opcode. The amount to 482b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // increment the address register is the result of the adjusted 483b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // opcode divided by the line_range multiplied by the 484b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // minimum_instruction_length field from the header. That is: 485b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 486b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // address increment = (adjusted opcode / line_range) * 487b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // minimum_instruction_length 488b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 489b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // The amount to increment the line register is the line_base plus 490b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // the result of the adjusted opcode modulo the line_range. That is: 491b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // 492b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer // line increment = line_base + (adjusted opcode % line_range) 493b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t adjust_opcode = opcode - Prologue.OpcodeBase; 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t addr_offset = 496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int32_t line_offset = 498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Prologue.LineBase + (adjust_opcode % Prologue.LineRange); 499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Line += line_offset; 500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.Row.Address += addr_offset; 501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines State.appendRowToMatrix(*offset_ptr); 502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Reset discriminator to 0. 503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar State.Row.Discriminator = 0; 504b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 505b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer } 506b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!State.Sequence.Empty) { 508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fprintf(stderr, "warning: last sequence in debug line table is not" 509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "terminated!\n"); 510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Sort all sequences so that address lookup will work faster. 513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Sequences.empty()) { 514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC); 515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Note: actually, instruction address ranges of sequences should not 516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // overlap (in shared objects and executables). If they do, the address 517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // lookup would still work, though, but result would be ambiguous. 518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // We don't report warning in this case. For example, 519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // sometimes .so compiled from multiple object files contains a few 520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // rudimentary sequences for address ranges [0x0, 0xsomething). 521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 522b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 523b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer return end_offset; 524b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 525b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer 5266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainaruint32_t 5276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq, 5286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t address) const { 5296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!seq.containsPC(address)) 5306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return UnknownRowIndex; 5316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Search for instruction address in the rows describing the sequence. 5326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rows are stored in a vector, so we may use arithmetical operations with 5336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // iterators. 5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DWARFDebugLine::Row row; 5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar row.Address = address; 5366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RowIter first_row = Rows.begin() + seq.FirstRowIndex; 5376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RowIter last_row = Rows.begin() + seq.LastRowIndex; 5386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar LineTable::RowIter row_pos = std::lower_bound( 5396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar first_row, last_row, row, DWARFDebugLine::Row::orderByAddress); 5406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (row_pos == last_row) { 5416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return seq.LastRowIndex - 1; 5426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 5436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t index = seq.FirstRowIndex + (row_pos - first_row); 5446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (row_pos->Address > address) { 5456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (row_pos == first_row) 5466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return UnknownRowIndex; 5476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else 5486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar index--; 5496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 5506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return index; 5516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 5526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesuint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { 554351f83be64057380877615153fe5dc50308ab017Alexey Samsonov if (Sequences.empty()) 5556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return UnknownRowIndex; 556351f83be64057380877615153fe5dc50308ab017Alexey Samsonov // First, find an instruction sequence containing the given address. 557351f83be64057380877615153fe5dc50308ab017Alexey Samsonov DWARFDebugLine::Sequence sequence; 558351f83be64057380877615153fe5dc50308ab017Alexey Samsonov sequence.LowPC = address; 559351f83be64057380877615153fe5dc50308ab017Alexey Samsonov SequenceIter first_seq = Sequences.begin(); 560351f83be64057380877615153fe5dc50308ab017Alexey Samsonov SequenceIter last_seq = Sequences.end(); 561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SequenceIter seq_pos = std::lower_bound( 562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); 563351f83be64057380877615153fe5dc50308ab017Alexey Samsonov DWARFDebugLine::Sequence found_seq; 564351f83be64057380877615153fe5dc50308ab017Alexey Samsonov if (seq_pos == last_seq) { 565351f83be64057380877615153fe5dc50308ab017Alexey Samsonov found_seq = Sequences.back(); 566351f83be64057380877615153fe5dc50308ab017Alexey Samsonov } else if (seq_pos->LowPC == address) { 567351f83be64057380877615153fe5dc50308ab017Alexey Samsonov found_seq = *seq_pos; 568351f83be64057380877615153fe5dc50308ab017Alexey Samsonov } else { 569351f83be64057380877615153fe5dc50308ab017Alexey Samsonov if (seq_pos == first_seq) 5706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return UnknownRowIndex; 571351f83be64057380877615153fe5dc50308ab017Alexey Samsonov found_seq = *(seq_pos - 1); 572351f83be64057380877615153fe5dc50308ab017Alexey Samsonov } 5736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return findRowInSeq(found_seq, address); 574b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer} 57538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov 576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::LineTable::lookupAddressRange( 577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t address, uint64_t size, std::vector<uint32_t> &result) const { 578e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor if (Sequences.empty()) 579e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor return false; 580e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor uint64_t end_addr = address + size; 581e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor // First, find an instruction sequence containing the given address. 582e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor DWARFDebugLine::Sequence sequence; 583e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor sequence.LowPC = address; 584e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor SequenceIter first_seq = Sequences.begin(); 585e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor SequenceIter last_seq = Sequences.end(); 586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SequenceIter seq_pos = std::lower_bound( 587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); 588e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor if (seq_pos == last_seq || seq_pos->LowPC != address) { 589e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor if (seq_pos == first_seq) 590e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor return false; 591e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor seq_pos--; 592e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor } 593e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor if (!seq_pos->containsPC(address)) 594e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor return false; 595e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 596e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor SequenceIter start_pos = seq_pos; 597e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 598e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor // Add the rows from the first sequence to the vector, starting with the 599e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor // index we just calculated 600e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 601e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor while (seq_pos != last_seq && seq_pos->LowPC < end_addr) { 6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const DWARFDebugLine::Sequence &cur_seq = *seq_pos; 6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // For the first sequence, we need to find which row in the sequence is the 6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // first in our range. 6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t first_row_index = cur_seq.FirstRowIndex; 6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (seq_pos == start_pos) 6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar first_row_index = findRowInSeq(cur_seq, address); 6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Figure out the last row in the range. 6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1); 6116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (last_row_index == UnknownRowIndex) 612e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor last_row_index = cur_seq.LastRowIndex - 1; 613e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 6146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(first_row_index != UnknownRowIndex); 6156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(last_row_index != UnknownRowIndex); 6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 617e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor for (uint32_t i = first_row_index; i <= last_row_index; ++i) { 618e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor result.push_back(i); 619e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor } 620e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 621e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor ++seq_pos; 622e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor } 6238090a24bd6369662dfcd9d9df21b9c122238ed10NAKAMURA Takumi 6248090a24bd6369662dfcd9d9df21b9c122238ed10NAKAMURA Takumi return true; 625e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor} 626e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor 627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, 628de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const char *CompDir, 629de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FileLineInfoKind Kind, 630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::string &Result) const { 631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || 632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Kind == FileLineInfoKind::None) 63338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov return false; 63438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; 63538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov const char *FileName = Entry.Name; 636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Kind != FileLineInfoKind::AbsoluteFilePath || 63738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov sys::path::is_absolute(FileName)) { 63838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov Result = FileName; 63938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov return true; 64038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov } 64137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 64238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov SmallString<16> FilePath; 64338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov uint64_t IncludeDirIndex = Entry.DirIdx; 64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const char *IncludeDir = ""; 64538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov // Be defensive about the contents of Entry. 64638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov if (IncludeDirIndex > 0 && 64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IncludeDirIndex <= Prologue.IncludeDirectories.size()) 64837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; 64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 65037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We may still need to append compilation directory of compile unit. 65137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We know that FileName is not absolute, the only way to have an 65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // absolute path at this point would be if IncludeDir is absolute. 65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath && 65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::path::is_relative(IncludeDir)) 65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::path::append(FilePath, CompDir); 65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // sys::path::append skips empty strings. 65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::path::append(FilePath, IncludeDir, FileName); 65938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov Result = FilePath.str(); 66038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov return true; 66138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov} 66237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool DWARFDebugLine::LineTable::getFileLineInfoForAddress( 664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t Address, const char *CompDir, FileLineInfoKind Kind, 665de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DILineInfo &Result) const { 66637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Get the index of row we're looking for in the line table. 66737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RowIndex = lookupAddress(Address); 66837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RowIndex == -1U) 66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 67037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Take file number and line/column from the row. 67137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const auto &Row = Rows[RowIndex]; 67237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName)) 67337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result.Line = Row.Line; 67537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result.Column = Row.Column; 67637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 67737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 678