1 //===- DWARFDebugLine.cpp -------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/SmallString.h" 11 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 12 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 13 #include "llvm/Support/Dwarf.h" 14 #include "llvm/Support/Format.h" 15 #include "llvm/Support/Path.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include <algorithm> 18 #include <cassert> 19 #include <cinttypes> 20 #include <cstdint> 21 #include <cstdio> 22 #include <utility> 23 24 using namespace llvm; 25 using namespace dwarf; 26 27 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; 28 29 DWARFDebugLine::Prologue::Prologue() { clear(); } 30 31 void DWARFDebugLine::Prologue::clear() { 32 TotalLength = Version = PrologueLength = 0; 33 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; 34 OpcodeBase = 0; 35 IsDWARF64 = false; 36 StandardOpcodeLengths.clear(); 37 IncludeDirectories.clear(); 38 FileNames.clear(); 39 } 40 41 void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { 42 OS << "Line table prologue:\n" 43 << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength) 44 << format(" version: %u\n", Version) 45 << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) 46 << format(" min_inst_length: %u\n", MinInstLength) 47 << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) 48 << format(" default_is_stmt: %u\n", DefaultIsStmt) 49 << format(" line_base: %i\n", LineBase) 50 << format(" line_range: %u\n", LineRange) 51 << format(" opcode_base: %u\n", OpcodeBase); 52 53 for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) 54 OS << format("standard_opcode_lengths[%s] = %u\n", 55 LNStandardString(i + 1).data(), StandardOpcodeLengths[i]); 56 57 if (!IncludeDirectories.empty()) 58 for (uint32_t i = 0; i < IncludeDirectories.size(); ++i) 59 OS << format("include_directories[%3u] = '", i + 1) 60 << IncludeDirectories[i] << "'\n"; 61 62 if (!FileNames.empty()) { 63 OS << " Dir Mod Time File Len File Name\n" 64 << " ---- ---------- ---------- -----------" 65 "----------------\n"; 66 for (uint32_t i = 0; i < FileNames.size(); ++i) { 67 const FileNameEntry &fileEntry = FileNames[i]; 68 OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx) 69 << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime, 70 fileEntry.Length) 71 << fileEntry.Name << '\n'; 72 } 73 } 74 } 75 76 bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, 77 uint32_t *offset_ptr) { 78 const uint64_t prologue_offset = *offset_ptr; 79 80 clear(); 81 TotalLength = debug_line_data.getU32(offset_ptr); 82 if (TotalLength == UINT32_MAX) { 83 IsDWARF64 = true; 84 TotalLength = debug_line_data.getU64(offset_ptr); 85 } else if (TotalLength > 0xffffff00) { 86 return false; 87 } 88 Version = debug_line_data.getU16(offset_ptr); 89 if (Version < 2) 90 return false; 91 92 PrologueLength = 93 debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength()); 94 const uint64_t end_prologue_offset = PrologueLength + *offset_ptr; 95 MinInstLength = debug_line_data.getU8(offset_ptr); 96 if (Version >= 4) 97 MaxOpsPerInst = debug_line_data.getU8(offset_ptr); 98 DefaultIsStmt = debug_line_data.getU8(offset_ptr); 99 LineBase = debug_line_data.getU8(offset_ptr); 100 LineRange = debug_line_data.getU8(offset_ptr); 101 OpcodeBase = debug_line_data.getU8(offset_ptr); 102 103 StandardOpcodeLengths.reserve(OpcodeBase - 1); 104 for (uint32_t i = 1; i < OpcodeBase; ++i) { 105 uint8_t op_len = debug_line_data.getU8(offset_ptr); 106 StandardOpcodeLengths.push_back(op_len); 107 } 108 109 while (*offset_ptr < end_prologue_offset) { 110 const char *s = debug_line_data.getCStr(offset_ptr); 111 if (s && s[0]) 112 IncludeDirectories.push_back(s); 113 else 114 break; 115 } 116 117 while (*offset_ptr < end_prologue_offset) { 118 const char *name = debug_line_data.getCStr(offset_ptr); 119 if (name && name[0]) { 120 FileNameEntry fileEntry; 121 fileEntry.Name = name; 122 fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 123 fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 124 fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 125 FileNames.push_back(fileEntry); 126 } else { 127 break; 128 } 129 } 130 131 if (*offset_ptr != end_prologue_offset) { 132 fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 133 " should have ended at 0x%8.8" PRIx64 134 " but it ended at 0x%8.8" PRIx64 "\n", 135 prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr); 136 return false; 137 } 138 return true; 139 } 140 141 DWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); } 142 143 void DWARFDebugLine::Row::postAppend() { 144 BasicBlock = false; 145 PrologueEnd = false; 146 EpilogueBegin = false; 147 } 148 149 void DWARFDebugLine::Row::reset(bool default_is_stmt) { 150 Address = 0; 151 Line = 1; 152 Column = 0; 153 File = 1; 154 Isa = 0; 155 Discriminator = 0; 156 IsStmt = default_is_stmt; 157 BasicBlock = false; 158 EndSequence = false; 159 PrologueEnd = false; 160 EpilogueBegin = false; 161 } 162 163 void DWARFDebugLine::Row::dump(raw_ostream &OS) const { 164 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) 165 << format(" %6u %3u %13u ", File, Isa, Discriminator) 166 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") 167 << (PrologueEnd ? " prologue_end" : "") 168 << (EpilogueBegin ? " epilogue_begin" : "") 169 << (EndSequence ? " end_sequence" : "") << '\n'; 170 } 171 172 DWARFDebugLine::Sequence::Sequence() { reset(); } 173 174 void DWARFDebugLine::Sequence::reset() { 175 LowPC = 0; 176 HighPC = 0; 177 FirstRowIndex = 0; 178 LastRowIndex = 0; 179 Empty = true; 180 } 181 182 DWARFDebugLine::LineTable::LineTable() { clear(); } 183 184 void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { 185 Prologue.dump(OS); 186 OS << '\n'; 187 188 if (!Rows.empty()) { 189 OS << "Address Line Column File ISA Discriminator Flags\n" 190 << "------------------ ------ ------ ------ --- ------------- " 191 "-------------\n"; 192 for (const Row &R : Rows) { 193 R.dump(OS); 194 } 195 } 196 } 197 198 void DWARFDebugLine::LineTable::clear() { 199 Prologue.clear(); 200 Rows.clear(); 201 Sequences.clear(); 202 } 203 204 DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT) 205 : LineTable(LT), RowNumber(0) { 206 resetRowAndSequence(); 207 } 208 209 void DWARFDebugLine::ParsingState::resetRowAndSequence() { 210 Row.reset(LineTable->Prologue.DefaultIsStmt); 211 Sequence.reset(); 212 } 213 214 void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) { 215 if (Sequence.Empty) { 216 // Record the beginning of instruction sequence. 217 Sequence.Empty = false; 218 Sequence.LowPC = Row.Address; 219 Sequence.FirstRowIndex = RowNumber; 220 } 221 ++RowNumber; 222 LineTable->appendRow(Row); 223 if (Row.EndSequence) { 224 // Record the end of instruction sequence. 225 Sequence.HighPC = Row.Address; 226 Sequence.LastRowIndex = RowNumber; 227 if (Sequence.isValid()) 228 LineTable->appendSequence(Sequence); 229 Sequence.reset(); 230 } 231 Row.postAppend(); 232 } 233 234 const DWARFDebugLine::LineTable * 235 DWARFDebugLine::getLineTable(uint32_t offset) const { 236 LineTableConstIter pos = LineTableMap.find(offset); 237 if (pos != LineTableMap.end()) 238 return &pos->second; 239 return nullptr; 240 } 241 242 const DWARFDebugLine::LineTable * 243 DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, 244 uint32_t offset) { 245 std::pair<LineTableIter, bool> pos = 246 LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); 247 LineTable *LT = &pos.first->second; 248 if (pos.second) { 249 if (!LT->parse(debug_line_data, RelocMap, &offset)) 250 return nullptr; 251 } 252 return LT; 253 } 254 255 bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, 256 const RelocAddrMap *RMap, 257 uint32_t *offset_ptr) { 258 const uint32_t debug_line_offset = *offset_ptr; 259 260 clear(); 261 262 if (!Prologue.parse(debug_line_data, offset_ptr)) { 263 // Restore our offset and return false to indicate failure! 264 *offset_ptr = debug_line_offset; 265 return false; 266 } 267 268 const uint32_t end_offset = 269 debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength(); 270 271 ParsingState State(this); 272 273 while (*offset_ptr < end_offset) { 274 uint8_t opcode = debug_line_data.getU8(offset_ptr); 275 276 if (opcode == 0) { 277 // Extended Opcodes always start with a zero opcode followed by 278 // a uleb128 length so you can skip ones you don't know about 279 uint32_t ext_offset = *offset_ptr; 280 uint64_t len = debug_line_data.getULEB128(offset_ptr); 281 uint32_t arg_size = len - (*offset_ptr - ext_offset); 282 283 uint8_t sub_opcode = debug_line_data.getU8(offset_ptr); 284 switch (sub_opcode) { 285 case DW_LNE_end_sequence: 286 // Set the end_sequence register of the state machine to true and 287 // append a row to the matrix using the current values of the 288 // state-machine registers. Then reset the registers to the initial 289 // values specified above. Every statement program sequence must end 290 // with a DW_LNE_end_sequence instruction which creates a row whose 291 // address is that of the byte after the last target machine instruction 292 // of the sequence. 293 State.Row.EndSequence = true; 294 State.appendRowToMatrix(*offset_ptr); 295 State.resetRowAndSequence(); 296 break; 297 298 case DW_LNE_set_address: 299 // Takes a single relocatable address as an operand. The size of the 300 // operand is the size appropriate to hold an address on the target 301 // machine. Set the address register to the value given by the 302 // relocatable address. All of the other statement program opcodes 303 // that affect the address register add a delta to it. This instruction 304 // stores a relocatable value into it instead. 305 { 306 // If this address is in our relocation map, apply the relocation. 307 RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr); 308 if (AI != RMap->end()) { 309 const std::pair<uint8_t, int64_t> &R = AI->second; 310 State.Row.Address = 311 debug_line_data.getAddress(offset_ptr) + R.second; 312 } else 313 State.Row.Address = debug_line_data.getAddress(offset_ptr); 314 } 315 break; 316 317 case DW_LNE_define_file: 318 // Takes 4 arguments. The first is a null terminated string containing 319 // a source file name. The second is an unsigned LEB128 number 320 // representing the directory index of the directory in which the file 321 // was found. The third is an unsigned LEB128 number representing the 322 // time of last modification of the file. The fourth is an unsigned 323 // LEB128 number representing the length in bytes of the file. The time 324 // and length fields may contain LEB128(0) if the information is not 325 // available. 326 // 327 // The directory index represents an entry in the include_directories 328 // section of the statement program prologue. The index is LEB128(0) 329 // if the file was found in the current directory of the compilation, 330 // LEB128(1) if it was found in the first directory in the 331 // include_directories section, and so on. The directory index is 332 // ignored for file names that represent full path names. 333 // 334 // The files are numbered, starting at 1, in the order in which they 335 // appear; the names in the prologue come before names defined by 336 // the DW_LNE_define_file instruction. These numbers are used in the 337 // the file register of the state machine. 338 { 339 FileNameEntry fileEntry; 340 fileEntry.Name = debug_line_data.getCStr(offset_ptr); 341 fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 342 fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 343 fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 344 Prologue.FileNames.push_back(fileEntry); 345 } 346 break; 347 348 case DW_LNE_set_discriminator: 349 State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr); 350 break; 351 352 default: 353 // Length doesn't include the zero opcode byte or the length itself, but 354 // it does include the sub_opcode, so we have to adjust for that below 355 (*offset_ptr) += arg_size; 356 break; 357 } 358 } else if (opcode < Prologue.OpcodeBase) { 359 switch (opcode) { 360 // Standard Opcodes 361 case DW_LNS_copy: 362 // Takes no arguments. Append a row to the matrix using the 363 // current values of the state-machine registers. Then set 364 // the basic_block register to false. 365 State.appendRowToMatrix(*offset_ptr); 366 break; 367 368 case DW_LNS_advance_pc: 369 // Takes a single unsigned LEB128 operand, multiplies it by the 370 // min_inst_length field of the prologue, and adds the 371 // result to the address register of the state machine. 372 State.Row.Address += 373 debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength; 374 break; 375 376 case DW_LNS_advance_line: 377 // Takes a single signed LEB128 operand and adds that value to 378 // the line register of the state machine. 379 State.Row.Line += debug_line_data.getSLEB128(offset_ptr); 380 break; 381 382 case DW_LNS_set_file: 383 // Takes a single unsigned LEB128 operand and stores it in the file 384 // register of the state machine. 385 State.Row.File = debug_line_data.getULEB128(offset_ptr); 386 break; 387 388 case DW_LNS_set_column: 389 // Takes a single unsigned LEB128 operand and stores it in the 390 // column register of the state machine. 391 State.Row.Column = debug_line_data.getULEB128(offset_ptr); 392 break; 393 394 case DW_LNS_negate_stmt: 395 // Takes no arguments. Set the is_stmt register of the state 396 // machine to the logical negation of its current value. 397 State.Row.IsStmt = !State.Row.IsStmt; 398 break; 399 400 case DW_LNS_set_basic_block: 401 // Takes no arguments. Set the basic_block register of the 402 // state machine to true 403 State.Row.BasicBlock = true; 404 break; 405 406 case DW_LNS_const_add_pc: 407 // Takes no arguments. Add to the address register of the state 408 // machine the address increment value corresponding to special 409 // opcode 255. The motivation for DW_LNS_const_add_pc is this: 410 // when the statement program needs to advance the address by a 411 // small amount, it can use a single special opcode, which occupies 412 // a single byte. When it needs to advance the address by up to 413 // twice the range of the last special opcode, it can use 414 // DW_LNS_const_add_pc followed by a special opcode, for a total 415 // of two bytes. Only if it needs to advance the address by more 416 // than twice that range will it need to use both DW_LNS_advance_pc 417 // and a special opcode, requiring three or more bytes. 418 { 419 uint8_t adjust_opcode = 255 - Prologue.OpcodeBase; 420 uint64_t addr_offset = 421 (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 422 State.Row.Address += addr_offset; 423 } 424 break; 425 426 case DW_LNS_fixed_advance_pc: 427 // Takes a single uhalf operand. Add to the address register of 428 // the state machine the value of the (unencoded) operand. This 429 // is the only extended opcode that takes an argument that is not 430 // a variable length number. The motivation for DW_LNS_fixed_advance_pc 431 // is this: existing assemblers cannot emit DW_LNS_advance_pc or 432 // special opcodes because they cannot encode LEB128 numbers or 433 // judge when the computation of a special opcode overflows and 434 // requires the use of DW_LNS_advance_pc. Such assemblers, however, 435 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. 436 State.Row.Address += debug_line_data.getU16(offset_ptr); 437 break; 438 439 case DW_LNS_set_prologue_end: 440 // Takes no arguments. Set the prologue_end register of the 441 // state machine to true 442 State.Row.PrologueEnd = true; 443 break; 444 445 case DW_LNS_set_epilogue_begin: 446 // Takes no arguments. Set the basic_block register of the 447 // state machine to true 448 State.Row.EpilogueBegin = true; 449 break; 450 451 case DW_LNS_set_isa: 452 // Takes a single unsigned LEB128 operand and stores it in the 453 // column register of the state machine. 454 State.Row.Isa = debug_line_data.getULEB128(offset_ptr); 455 break; 456 457 default: 458 // Handle any unknown standard opcodes here. We know the lengths 459 // of such opcodes because they are specified in the prologue 460 // as a multiple of LEB128 operands for each opcode. 461 { 462 assert(opcode - 1U < Prologue.StandardOpcodeLengths.size()); 463 uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1]; 464 for (uint8_t i = 0; i < opcode_length; ++i) 465 debug_line_data.getULEB128(offset_ptr); 466 } 467 break; 468 } 469 } else { 470 // Special Opcodes 471 472 // A special opcode value is chosen based on the amount that needs 473 // to be added to the line and address registers. The maximum line 474 // increment for a special opcode is the value of the line_base 475 // field in the header, plus the value of the line_range field, 476 // minus 1 (line base + line range - 1). If the desired line 477 // increment is greater than the maximum line increment, a standard 478 // opcode must be used instead of a special opcode. The "address 479 // advance" is calculated by dividing the desired address increment 480 // by the minimum_instruction_length field from the header. The 481 // special opcode is then calculated using the following formula: 482 // 483 // opcode = (desired line increment - line_base) + 484 // (line_range * address advance) + opcode_base 485 // 486 // If the resulting opcode is greater than 255, a standard opcode 487 // must be used instead. 488 // 489 // To decode a special opcode, subtract the opcode_base from the 490 // opcode itself to give the adjusted opcode. The amount to 491 // increment the address register is the result of the adjusted 492 // opcode divided by the line_range multiplied by the 493 // minimum_instruction_length field from the header. That is: 494 // 495 // address increment = (adjusted opcode / line_range) * 496 // minimum_instruction_length 497 // 498 // The amount to increment the line register is the line_base plus 499 // the result of the adjusted opcode modulo the line_range. That is: 500 // 501 // line increment = line_base + (adjusted opcode % line_range) 502 503 uint8_t adjust_opcode = opcode - Prologue.OpcodeBase; 504 uint64_t addr_offset = 505 (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 506 int32_t line_offset = 507 Prologue.LineBase + (adjust_opcode % Prologue.LineRange); 508 State.Row.Line += line_offset; 509 State.Row.Address += addr_offset; 510 State.appendRowToMatrix(*offset_ptr); 511 // Reset discriminator to 0. 512 State.Row.Discriminator = 0; 513 } 514 } 515 516 if (!State.Sequence.Empty) { 517 fprintf(stderr, "warning: last sequence in debug line table is not" 518 "terminated!\n"); 519 } 520 521 // Sort all sequences so that address lookup will work faster. 522 if (!Sequences.empty()) { 523 std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC); 524 // Note: actually, instruction address ranges of sequences should not 525 // overlap (in shared objects and executables). If they do, the address 526 // lookup would still work, though, but result would be ambiguous. 527 // We don't report warning in this case. For example, 528 // sometimes .so compiled from multiple object files contains a few 529 // rudimentary sequences for address ranges [0x0, 0xsomething). 530 } 531 532 return end_offset; 533 } 534 535 uint32_t 536 DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq, 537 uint64_t address) const { 538 if (!seq.containsPC(address)) 539 return UnknownRowIndex; 540 // Search for instruction address in the rows describing the sequence. 541 // Rows are stored in a vector, so we may use arithmetical operations with 542 // iterators. 543 DWARFDebugLine::Row row; 544 row.Address = address; 545 RowIter first_row = Rows.begin() + seq.FirstRowIndex; 546 RowIter last_row = Rows.begin() + seq.LastRowIndex; 547 LineTable::RowIter row_pos = std::lower_bound( 548 first_row, last_row, row, DWARFDebugLine::Row::orderByAddress); 549 if (row_pos == last_row) { 550 return seq.LastRowIndex - 1; 551 } 552 uint32_t index = seq.FirstRowIndex + (row_pos - first_row); 553 if (row_pos->Address > address) { 554 if (row_pos == first_row) 555 return UnknownRowIndex; 556 else 557 index--; 558 } 559 return index; 560 } 561 562 uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { 563 if (Sequences.empty()) 564 return UnknownRowIndex; 565 // First, find an instruction sequence containing the given address. 566 DWARFDebugLine::Sequence sequence; 567 sequence.LowPC = address; 568 SequenceIter first_seq = Sequences.begin(); 569 SequenceIter last_seq = Sequences.end(); 570 SequenceIter seq_pos = std::lower_bound( 571 first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); 572 DWARFDebugLine::Sequence found_seq; 573 if (seq_pos == last_seq) { 574 found_seq = Sequences.back(); 575 } else if (seq_pos->LowPC == address) { 576 found_seq = *seq_pos; 577 } else { 578 if (seq_pos == first_seq) 579 return UnknownRowIndex; 580 found_seq = *(seq_pos - 1); 581 } 582 return findRowInSeq(found_seq, address); 583 } 584 585 bool DWARFDebugLine::LineTable::lookupAddressRange( 586 uint64_t address, uint64_t size, std::vector<uint32_t> &result) const { 587 if (Sequences.empty()) 588 return false; 589 uint64_t end_addr = address + size; 590 // First, find an instruction sequence containing the given address. 591 DWARFDebugLine::Sequence sequence; 592 sequence.LowPC = address; 593 SequenceIter first_seq = Sequences.begin(); 594 SequenceIter last_seq = Sequences.end(); 595 SequenceIter seq_pos = std::lower_bound( 596 first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); 597 if (seq_pos == last_seq || seq_pos->LowPC != address) { 598 if (seq_pos == first_seq) 599 return false; 600 seq_pos--; 601 } 602 if (!seq_pos->containsPC(address)) 603 return false; 604 605 SequenceIter start_pos = seq_pos; 606 607 // Add the rows from the first sequence to the vector, starting with the 608 // index we just calculated 609 610 while (seq_pos != last_seq && seq_pos->LowPC < end_addr) { 611 const DWARFDebugLine::Sequence &cur_seq = *seq_pos; 612 // For the first sequence, we need to find which row in the sequence is the 613 // first in our range. 614 uint32_t first_row_index = cur_seq.FirstRowIndex; 615 if (seq_pos == start_pos) 616 first_row_index = findRowInSeq(cur_seq, address); 617 618 // Figure out the last row in the range. 619 uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1); 620 if (last_row_index == UnknownRowIndex) 621 last_row_index = cur_seq.LastRowIndex - 1; 622 623 assert(first_row_index != UnknownRowIndex); 624 assert(last_row_index != UnknownRowIndex); 625 626 for (uint32_t i = first_row_index; i <= last_row_index; ++i) { 627 result.push_back(i); 628 } 629 630 ++seq_pos; 631 } 632 633 return true; 634 } 635 636 bool 637 DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { 638 return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); 639 } 640 641 bool 642 DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, 643 const char *CompDir, 644 FileLineInfoKind Kind, 645 std::string &Result) const { 646 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) 647 return false; 648 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; 649 const char *FileName = Entry.Name; 650 if (Kind != FileLineInfoKind::AbsoluteFilePath || 651 sys::path::is_absolute(FileName)) { 652 Result = FileName; 653 return true; 654 } 655 656 SmallString<16> FilePath; 657 uint64_t IncludeDirIndex = Entry.DirIdx; 658 const char *IncludeDir = ""; 659 // Be defensive about the contents of Entry. 660 if (IncludeDirIndex > 0 && 661 IncludeDirIndex <= Prologue.IncludeDirectories.size()) 662 IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; 663 664 // We may still need to append compilation directory of compile unit. 665 // We know that FileName is not absolute, the only way to have an 666 // absolute path at this point would be if IncludeDir is absolute. 667 if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath && 668 sys::path::is_relative(IncludeDir)) 669 sys::path::append(FilePath, CompDir); 670 671 // sys::path::append skips empty strings. 672 sys::path::append(FilePath, IncludeDir, FileName); 673 Result = FilePath.str(); 674 return true; 675 } 676 677 bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( 678 uint64_t Address, const char *CompDir, FileLineInfoKind Kind, 679 DILineInfo &Result) const { 680 // Get the index of row we're looking for in the line table. 681 uint32_t RowIndex = lookupAddress(Address); 682 if (RowIndex == -1U) 683 return false; 684 // Take file number and line/column from the row. 685 const auto &Row = Rows[RowIndex]; 686 if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName)) 687 return false; 688 Result.Line = Row.Line; 689 Result.Column = Row.Column; 690 Result.Discriminator = Row.Discriminator; 691 return true; 692 } 693