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