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/DebugInfo/DWARF/DWARFDebugLine.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/BinaryFormat/Dwarf.h" 15 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 16 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 17 #include "llvm/Support/Format.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/raw_ostream.h" 20 #include <algorithm> 21 #include <cassert> 22 #include <cinttypes> 23 #include <cstdint> 24 #include <cstdio> 25 #include <utility> 26 27 using namespace llvm; 28 using namespace dwarf; 29 30 using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; 31 32 namespace { 33 34 struct ContentDescriptor { 35 dwarf::LineNumberEntryFormat Type; 36 dwarf::Form Form; 37 }; 38 39 using ContentDescriptors = SmallVector<ContentDescriptor, 4>; 40 41 } // end anonmyous namespace 42 43 DWARFDebugLine::Prologue::Prologue() { clear(); } 44 45 void DWARFDebugLine::Prologue::clear() { 46 TotalLength = PrologueLength = 0; 47 SegSelectorSize = 0; 48 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; 49 OpcodeBase = 0; 50 FormParams = DWARFFormParams({0, 0, DWARF32}); 51 HasMD5 = false; 52 StandardOpcodeLengths.clear(); 53 IncludeDirectories.clear(); 54 FileNames.clear(); 55 } 56 57 void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { 58 OS << "Line table prologue:\n" 59 << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength) 60 << format(" version: %u\n", getVersion()); 61 if (getVersion() >= 5) 62 OS << format(" address_size: %u\n", getAddressSize()) 63 << format(" seg_select_size: %u\n", SegSelectorSize); 64 OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) 65 << format(" min_inst_length: %u\n", MinInstLength) 66 << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) 67 << format(" default_is_stmt: %u\n", DefaultIsStmt) 68 << format(" line_base: %i\n", LineBase) 69 << format(" line_range: %u\n", LineRange) 70 << format(" opcode_base: %u\n", OpcodeBase); 71 72 for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I) 73 OS << format("standard_opcode_lengths[%s] = %u\n", 74 LNStandardString(I + 1).data(), StandardOpcodeLengths[I]); 75 76 if (!IncludeDirectories.empty()) { 77 // DWARF v5 starts directory indexes at 0. 78 uint32_t DirBase = getVersion() >= 5 ? 0 : 1; 79 for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) 80 OS << format("include_directories[%3u] = '", I + DirBase) 81 << IncludeDirectories[I] << "'\n"; 82 } 83 84 if (!FileNames.empty()) { 85 if (HasMD5) 86 OS << " Dir MD5 Checksum File Name\n" 87 << " ---- -------------------------------- -----------" 88 "---------------\n"; 89 else 90 OS << " Dir Mod Time File Len File Name\n" 91 << " ---- ---------- ---------- -----------" 92 "----------------\n"; 93 for (uint32_t I = 0; I != FileNames.size(); ++I) { 94 const FileNameEntry &FileEntry = FileNames[I]; 95 OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx); 96 if (HasMD5) 97 OS << FileEntry.Checksum.digest(); 98 else 99 OS << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64, FileEntry.ModTime, 100 FileEntry.Length); 101 OS << ' ' << FileEntry.Name << '\n'; 102 } 103 } 104 } 105 106 // Parse v2-v4 directory and file tables. 107 static void 108 parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, 109 uint32_t *OffsetPtr, uint64_t EndPrologueOffset, 110 std::vector<StringRef> &IncludeDirectories, 111 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) { 112 while (*OffsetPtr < EndPrologueOffset) { 113 StringRef S = DebugLineData.getCStrRef(OffsetPtr); 114 if (S.empty()) 115 break; 116 IncludeDirectories.push_back(S); 117 } 118 119 while (*OffsetPtr < EndPrologueOffset) { 120 StringRef Name = DebugLineData.getCStrRef(OffsetPtr); 121 if (Name.empty()) 122 break; 123 DWARFDebugLine::FileNameEntry FileEntry; 124 FileEntry.Name = Name; 125 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); 126 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); 127 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); 128 FileNames.push_back(FileEntry); 129 } 130 } 131 132 // Parse v5 directory/file entry content descriptions. 133 // Returns the descriptors, or an empty vector if we did not find a path or 134 // ran off the end of the prologue. 135 static ContentDescriptors 136 parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, 137 uint64_t EndPrologueOffset, bool *HasMD5) { 138 ContentDescriptors Descriptors; 139 int FormatCount = DebugLineData.getU8(OffsetPtr); 140 bool HasPath = false; 141 for (int I = 0; I != FormatCount; ++I) { 142 if (*OffsetPtr >= EndPrologueOffset) 143 return ContentDescriptors(); 144 ContentDescriptor Descriptor; 145 Descriptor.Type = 146 dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr)); 147 Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr)); 148 if (Descriptor.Type == dwarf::DW_LNCT_path) 149 HasPath = true; 150 else if (Descriptor.Type == dwarf::DW_LNCT_MD5 && HasMD5) 151 *HasMD5 = true; 152 Descriptors.push_back(Descriptor); 153 } 154 return HasPath ? Descriptors : ContentDescriptors(); 155 } 156 157 static bool 158 parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, 159 uint32_t *OffsetPtr, uint64_t EndPrologueOffset, 160 const DWARFFormParams &FormParams, const DWARFContext &Ctx, 161 const DWARFUnit *U, bool &HasMD5, 162 std::vector<StringRef> &IncludeDirectories, 163 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) { 164 // Get the directory entry description. 165 ContentDescriptors DirDescriptors = 166 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr); 167 if (DirDescriptors.empty()) 168 return false; 169 170 // Get the directory entries, according to the format described above. 171 int DirEntryCount = DebugLineData.getU8(OffsetPtr); 172 for (int I = 0; I != DirEntryCount; ++I) { 173 if (*OffsetPtr >= EndPrologueOffset) 174 return false; 175 for (auto Descriptor : DirDescriptors) { 176 DWARFFormValue Value(Descriptor.Form); 177 switch (Descriptor.Type) { 178 case DW_LNCT_path: 179 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U)) 180 return false; 181 IncludeDirectories.push_back(Value.getAsCString().getValue()); 182 break; 183 default: 184 if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams)) 185 return false; 186 } 187 } 188 } 189 190 // Get the file entry description. 191 ContentDescriptors FileDescriptors = 192 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, &HasMD5); 193 if (FileDescriptors.empty()) 194 return false; 195 196 // Get the file entries, according to the format described above. 197 int FileEntryCount = DebugLineData.getU8(OffsetPtr); 198 for (int I = 0; I != FileEntryCount; ++I) { 199 if (*OffsetPtr >= EndPrologueOffset) 200 return false; 201 DWARFDebugLine::FileNameEntry FileEntry; 202 for (auto Descriptor : FileDescriptors) { 203 DWARFFormValue Value(Descriptor.Form); 204 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U)) 205 return false; 206 switch (Descriptor.Type) { 207 case DW_LNCT_path: 208 FileEntry.Name = Value.getAsCString().getValue(); 209 break; 210 case DW_LNCT_directory_index: 211 FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue(); 212 break; 213 case DW_LNCT_timestamp: 214 FileEntry.ModTime = Value.getAsUnsignedConstant().getValue(); 215 break; 216 case DW_LNCT_size: 217 FileEntry.Length = Value.getAsUnsignedConstant().getValue(); 218 break; 219 case DW_LNCT_MD5: 220 assert(Value.getAsBlock().getValue().size() == 16); 221 std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16, 222 FileEntry.Checksum.Bytes.begin()); 223 break; 224 default: 225 break; 226 } 227 } 228 FileNames.push_back(FileEntry); 229 } 230 return true; 231 } 232 233 bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, 234 uint32_t *OffsetPtr, 235 const DWARFContext &Ctx, 236 const DWARFUnit *U) { 237 const uint64_t PrologueOffset = *OffsetPtr; 238 239 clear(); 240 TotalLength = DebugLineData.getU32(OffsetPtr); 241 if (TotalLength == UINT32_MAX) { 242 FormParams.Format = dwarf::DWARF64; 243 TotalLength = DebugLineData.getU64(OffsetPtr); 244 } else if (TotalLength >= 0xffffff00) { 245 return false; 246 } 247 FormParams.Version = DebugLineData.getU16(OffsetPtr); 248 if (getVersion() < 2) 249 return false; 250 251 if (getVersion() >= 5) { 252 FormParams.AddrSize = DebugLineData.getU8(OffsetPtr); 253 assert((DebugLineData.getAddressSize() == 0 || 254 DebugLineData.getAddressSize() == getAddressSize()) && 255 "Line table header and data extractor disagree"); 256 SegSelectorSize = DebugLineData.getU8(OffsetPtr); 257 } 258 259 PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength()); 260 const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr; 261 MinInstLength = DebugLineData.getU8(OffsetPtr); 262 if (getVersion() >= 4) 263 MaxOpsPerInst = DebugLineData.getU8(OffsetPtr); 264 DefaultIsStmt = DebugLineData.getU8(OffsetPtr); 265 LineBase = DebugLineData.getU8(OffsetPtr); 266 LineRange = DebugLineData.getU8(OffsetPtr); 267 OpcodeBase = DebugLineData.getU8(OffsetPtr); 268 269 StandardOpcodeLengths.reserve(OpcodeBase - 1); 270 for (uint32_t I = 1; I < OpcodeBase; ++I) { 271 uint8_t OpLen = DebugLineData.getU8(OffsetPtr); 272 StandardOpcodeLengths.push_back(OpLen); 273 } 274 275 if (getVersion() >= 5) { 276 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, 277 FormParams, Ctx, U, HasMD5, IncludeDirectories, 278 FileNames)) { 279 fprintf(stderr, 280 "warning: parsing line table prologue at 0x%8.8" PRIx64 281 " found an invalid directory or file table description at" 282 " 0x%8.8" PRIx64 "\n", PrologueOffset, (uint64_t)*OffsetPtr); 283 return false; 284 } 285 } else 286 parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, 287 IncludeDirectories, FileNames); 288 289 if (*OffsetPtr != EndPrologueOffset) { 290 fprintf(stderr, 291 "warning: parsing line table prologue at 0x%8.8" PRIx64 292 " should have ended at 0x%8.8" PRIx64 293 " but it ended at 0x%8.8" PRIx64 "\n", 294 PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr); 295 return false; 296 } 297 return true; 298 } 299 300 DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); } 301 302 void DWARFDebugLine::Row::postAppend() { 303 BasicBlock = false; 304 PrologueEnd = false; 305 EpilogueBegin = false; 306 } 307 308 void DWARFDebugLine::Row::reset(bool DefaultIsStmt) { 309 Address = 0; 310 Line = 1; 311 Column = 0; 312 File = 1; 313 Isa = 0; 314 Discriminator = 0; 315 IsStmt = DefaultIsStmt; 316 BasicBlock = false; 317 EndSequence = false; 318 PrologueEnd = false; 319 EpilogueBegin = false; 320 } 321 322 void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS) { 323 OS << "Address Line Column File ISA Discriminator Flags\n" 324 << "------------------ ------ ------ ------ --- ------------- " 325 "-------------\n"; 326 } 327 328 void DWARFDebugLine::Row::dump(raw_ostream &OS) const { 329 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) 330 << format(" %6u %3u %13u ", File, Isa, Discriminator) 331 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") 332 << (PrologueEnd ? " prologue_end" : "") 333 << (EpilogueBegin ? " epilogue_begin" : "") 334 << (EndSequence ? " end_sequence" : "") << '\n'; 335 } 336 337 DWARFDebugLine::Sequence::Sequence() { reset(); } 338 339 void DWARFDebugLine::Sequence::reset() { 340 LowPC = 0; 341 HighPC = 0; 342 FirstRowIndex = 0; 343 LastRowIndex = 0; 344 Empty = true; 345 } 346 347 DWARFDebugLine::LineTable::LineTable() { clear(); } 348 349 void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { 350 Prologue.dump(OS); 351 OS << '\n'; 352 353 if (!Rows.empty()) { 354 Row::dumpTableHeader(OS); 355 for (const Row &R : Rows) { 356 R.dump(OS); 357 } 358 } 359 } 360 361 void DWARFDebugLine::LineTable::clear() { 362 Prologue.clear(); 363 Rows.clear(); 364 Sequences.clear(); 365 } 366 367 DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT) 368 : LineTable(LT) { 369 resetRowAndSequence(); 370 } 371 372 void DWARFDebugLine::ParsingState::resetRowAndSequence() { 373 Row.reset(LineTable->Prologue.DefaultIsStmt); 374 Sequence.reset(); 375 } 376 377 void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) { 378 if (Sequence.Empty) { 379 // Record the beginning of instruction sequence. 380 Sequence.Empty = false; 381 Sequence.LowPC = Row.Address; 382 Sequence.FirstRowIndex = RowNumber; 383 } 384 ++RowNumber; 385 LineTable->appendRow(Row); 386 if (Row.EndSequence) { 387 // Record the end of instruction sequence. 388 Sequence.HighPC = Row.Address; 389 Sequence.LastRowIndex = RowNumber; 390 if (Sequence.isValid()) 391 LineTable->appendSequence(Sequence); 392 Sequence.reset(); 393 } 394 Row.postAppend(); 395 } 396 397 const DWARFDebugLine::LineTable * 398 DWARFDebugLine::getLineTable(uint32_t Offset) const { 399 LineTableConstIter Pos = LineTableMap.find(Offset); 400 if (Pos != LineTableMap.end()) 401 return &Pos->second; 402 return nullptr; 403 } 404 405 const DWARFDebugLine::LineTable * 406 DWARFDebugLine::getOrParseLineTable(DWARFDataExtractor &DebugLineData, 407 uint32_t Offset, const DWARFContext &Ctx, 408 const DWARFUnit *U) { 409 std::pair<LineTableIter, bool> Pos = 410 LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable())); 411 LineTable *LT = &Pos.first->second; 412 if (Pos.second) { 413 if (!LT->parse(DebugLineData, &Offset, Ctx, U)) 414 return nullptr; 415 } 416 return LT; 417 } 418 419 bool DWARFDebugLine::LineTable::parse(DWARFDataExtractor &DebugLineData, 420 uint32_t *OffsetPtr, 421 const DWARFContext &Ctx, 422 const DWARFUnit *U, raw_ostream *OS) { 423 const uint32_t DebugLineOffset = *OffsetPtr; 424 425 clear(); 426 427 if (!Prologue.parse(DebugLineData, OffsetPtr, Ctx, U)) { 428 // Restore our offset and return false to indicate failure! 429 *OffsetPtr = DebugLineOffset; 430 return false; 431 } 432 433 if (OS) 434 Prologue.dump(*OS); 435 436 const uint32_t EndOffset = 437 DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength(); 438 439 // See if we should tell the data extractor the address size. 440 if (DebugLineData.getAddressSize() == 0) 441 DebugLineData.setAddressSize(Prologue.getAddressSize()); 442 else 443 assert(Prologue.getAddressSize() == 0 || 444 Prologue.getAddressSize() == DebugLineData.getAddressSize()); 445 446 ParsingState State(this); 447 448 while (*OffsetPtr < EndOffset) { 449 if (OS) 450 *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr); 451 452 uint8_t Opcode = DebugLineData.getU8(OffsetPtr); 453 454 if (OS) 455 *OS << format("%02.02" PRIx8 " ", Opcode); 456 457 if (Opcode == 0) { 458 // Extended Opcodes always start with a zero opcode followed by 459 // a uleb128 length so you can skip ones you don't know about 460 uint64_t Len = DebugLineData.getULEB128(OffsetPtr); 461 uint32_t ExtOffset = *OffsetPtr; 462 463 // Tolerate zero-length; assume length is correct and soldier on. 464 if (Len == 0) { 465 if (OS) 466 *OS << "Badly formed extended line op (length 0)\n"; 467 continue; 468 } 469 470 uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr); 471 if (OS) 472 *OS << LNExtendedString(SubOpcode); 473 switch (SubOpcode) { 474 case DW_LNE_end_sequence: 475 // Set the end_sequence register of the state machine to true and 476 // append a row to the matrix using the current values of the 477 // state-machine registers. Then reset the registers to the initial 478 // values specified above. Every statement program sequence must end 479 // with a DW_LNE_end_sequence instruction which creates a row whose 480 // address is that of the byte after the last target machine instruction 481 // of the sequence. 482 State.Row.EndSequence = true; 483 State.appendRowToMatrix(*OffsetPtr); 484 if (OS) { 485 *OS << "\n"; 486 OS->indent(12); 487 State.Row.dump(*OS); 488 } 489 State.resetRowAndSequence(); 490 break; 491 492 case DW_LNE_set_address: 493 // Takes a single relocatable address as an operand. The size of the 494 // operand is the size appropriate to hold an address on the target 495 // machine. Set the address register to the value given by the 496 // relocatable address. All of the other statement program opcodes 497 // that affect the address register add a delta to it. This instruction 498 // stores a relocatable value into it instead. 499 // 500 // Make sure the extractor knows the address size. If not, infer it 501 // from the size of the operand. 502 if (DebugLineData.getAddressSize() == 0) 503 DebugLineData.setAddressSize(Len - 1); 504 else 505 assert(DebugLineData.getAddressSize() == Len - 1); 506 State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr); 507 if (OS) 508 *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address); 509 break; 510 511 case DW_LNE_define_file: 512 // Takes 4 arguments. The first is a null terminated string containing 513 // a source file name. The second is an unsigned LEB128 number 514 // representing the directory index of the directory in which the file 515 // was found. The third is an unsigned LEB128 number representing the 516 // time of last modification of the file. The fourth is an unsigned 517 // LEB128 number representing the length in bytes of the file. The time 518 // and length fields may contain LEB128(0) if the information is not 519 // available. 520 // 521 // The directory index represents an entry in the include_directories 522 // section of the statement program prologue. The index is LEB128(0) 523 // if the file was found in the current directory of the compilation, 524 // LEB128(1) if it was found in the first directory in the 525 // include_directories section, and so on. The directory index is 526 // ignored for file names that represent full path names. 527 // 528 // The files are numbered, starting at 1, in the order in which they 529 // appear; the names in the prologue come before names defined by 530 // the DW_LNE_define_file instruction. These numbers are used in the 531 // the file register of the state machine. 532 { 533 FileNameEntry FileEntry; 534 FileEntry.Name = DebugLineData.getCStr(OffsetPtr); 535 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); 536 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); 537 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); 538 Prologue.FileNames.push_back(FileEntry); 539 if (OS) 540 *OS << " (" << FileEntry.Name.str() 541 << ", dir=" << FileEntry.DirIdx << ", mod_time=" 542 << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime) 543 << ", length=" << FileEntry.Length << ")"; 544 } 545 break; 546 547 case DW_LNE_set_discriminator: 548 State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr); 549 if (OS) 550 *OS << " (" << State.Row.Discriminator << ")"; 551 break; 552 553 default: 554 if (OS) 555 *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode) 556 << format(" length %" PRIx64, Len); 557 // Len doesn't include the zero opcode byte or the length itself, but 558 // it does include the sub_opcode, so we have to adjust for that. 559 (*OffsetPtr) += Len - 1; 560 break; 561 } 562 // Make sure the stated and parsed lengths are the same. 563 // Otherwise we have an unparseable line-number program. 564 if (*OffsetPtr - ExtOffset != Len) { 565 fprintf(stderr, "Unexpected line op length at offset 0x%8.8" PRIx32 566 " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32 "\n", 567 ExtOffset, Len, *OffsetPtr - ExtOffset); 568 // Skip the rest of the line-number program. 569 *OffsetPtr = EndOffset; 570 return false; 571 } 572 } else if (Opcode < Prologue.OpcodeBase) { 573 if (OS) 574 *OS << LNStandardString(Opcode); 575 switch (Opcode) { 576 // Standard Opcodes 577 case DW_LNS_copy: 578 // Takes no arguments. Append a row to the matrix using the 579 // current values of the state-machine registers. Then set 580 // the basic_block register to false. 581 State.appendRowToMatrix(*OffsetPtr); 582 if (OS) { 583 *OS << "\n"; 584 OS->indent(12); 585 State.Row.dump(*OS); 586 *OS << "\n"; 587 } 588 break; 589 590 case DW_LNS_advance_pc: 591 // Takes a single unsigned LEB128 operand, multiplies it by the 592 // min_inst_length field of the prologue, and adds the 593 // result to the address register of the state machine. 594 { 595 uint64_t AddrOffset = 596 DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength; 597 State.Row.Address += AddrOffset; 598 if (OS) 599 *OS << " (" << AddrOffset << ")"; 600 } 601 break; 602 603 case DW_LNS_advance_line: 604 // Takes a single signed LEB128 operand and adds that value to 605 // the line register of the state machine. 606 State.Row.Line += DebugLineData.getSLEB128(OffsetPtr); 607 if (OS) 608 *OS << " (" << State.Row.Line << ")"; 609 break; 610 611 case DW_LNS_set_file: 612 // Takes a single unsigned LEB128 operand and stores it in the file 613 // register of the state machine. 614 State.Row.File = DebugLineData.getULEB128(OffsetPtr); 615 if (OS) 616 *OS << " (" << State.Row.File << ")"; 617 break; 618 619 case DW_LNS_set_column: 620 // Takes a single unsigned LEB128 operand and stores it in the 621 // column register of the state machine. 622 State.Row.Column = DebugLineData.getULEB128(OffsetPtr); 623 if (OS) 624 *OS << " (" << State.Row.Column << ")"; 625 break; 626 627 case DW_LNS_negate_stmt: 628 // Takes no arguments. Set the is_stmt register of the state 629 // machine to the logical negation of its current value. 630 State.Row.IsStmt = !State.Row.IsStmt; 631 break; 632 633 case DW_LNS_set_basic_block: 634 // Takes no arguments. Set the basic_block register of the 635 // state machine to true 636 State.Row.BasicBlock = true; 637 break; 638 639 case DW_LNS_const_add_pc: 640 // Takes no arguments. Add to the address register of the state 641 // machine the address increment value corresponding to special 642 // opcode 255. The motivation for DW_LNS_const_add_pc is this: 643 // when the statement program needs to advance the address by a 644 // small amount, it can use a single special opcode, which occupies 645 // a single byte. When it needs to advance the address by up to 646 // twice the range of the last special opcode, it can use 647 // DW_LNS_const_add_pc followed by a special opcode, for a total 648 // of two bytes. Only if it needs to advance the address by more 649 // than twice that range will it need to use both DW_LNS_advance_pc 650 // and a special opcode, requiring three or more bytes. 651 { 652 uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase; 653 uint64_t AddrOffset = 654 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; 655 State.Row.Address += AddrOffset; 656 if (OS) 657 *OS 658 << format(" (0x%16.16" PRIx64 ")", AddrOffset); 659 } 660 break; 661 662 case DW_LNS_fixed_advance_pc: 663 // Takes a single uhalf operand. Add to the address register of 664 // the state machine the value of the (unencoded) operand. This 665 // is the only extended opcode that takes an argument that is not 666 // a variable length number. The motivation for DW_LNS_fixed_advance_pc 667 // is this: existing assemblers cannot emit DW_LNS_advance_pc or 668 // special opcodes because they cannot encode LEB128 numbers or 669 // judge when the computation of a special opcode overflows and 670 // requires the use of DW_LNS_advance_pc. Such assemblers, however, 671 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. 672 { 673 uint16_t PCOffset = DebugLineData.getU16(OffsetPtr); 674 State.Row.Address += PCOffset; 675 if (OS) 676 *OS 677 << format(" (0x%16.16" PRIx64 ")", PCOffset); 678 } 679 break; 680 681 case DW_LNS_set_prologue_end: 682 // Takes no arguments. Set the prologue_end register of the 683 // state machine to true 684 State.Row.PrologueEnd = true; 685 break; 686 687 case DW_LNS_set_epilogue_begin: 688 // Takes no arguments. Set the basic_block register of the 689 // state machine to true 690 State.Row.EpilogueBegin = true; 691 break; 692 693 case DW_LNS_set_isa: 694 // Takes a single unsigned LEB128 operand and stores it in the 695 // column register of the state machine. 696 State.Row.Isa = DebugLineData.getULEB128(OffsetPtr); 697 if (OS) 698 *OS << " (" << State.Row.Isa << ")"; 699 break; 700 701 default: 702 // Handle any unknown standard opcodes here. We know the lengths 703 // of such opcodes because they are specified in the prologue 704 // as a multiple of LEB128 operands for each opcode. 705 { 706 assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size()); 707 uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1]; 708 for (uint8_t I = 0; I < OpcodeLength; ++I) { 709 uint64_t Value = DebugLineData.getULEB128(OffsetPtr); 710 if (OS) 711 *OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n", 712 Value); 713 } 714 } 715 break; 716 } 717 } else { 718 // Special Opcodes 719 720 // A special opcode value is chosen based on the amount that needs 721 // to be added to the line and address registers. The maximum line 722 // increment for a special opcode is the value of the line_base 723 // field in the header, plus the value of the line_range field, 724 // minus 1 (line base + line range - 1). If the desired line 725 // increment is greater than the maximum line increment, a standard 726 // opcode must be used instead of a special opcode. The "address 727 // advance" is calculated by dividing the desired address increment 728 // by the minimum_instruction_length field from the header. The 729 // special opcode is then calculated using the following formula: 730 // 731 // opcode = (desired line increment - line_base) + 732 // (line_range * address advance) + opcode_base 733 // 734 // If the resulting opcode is greater than 255, a standard opcode 735 // must be used instead. 736 // 737 // To decode a special opcode, subtract the opcode_base from the 738 // opcode itself to give the adjusted opcode. The amount to 739 // increment the address register is the result of the adjusted 740 // opcode divided by the line_range multiplied by the 741 // minimum_instruction_length field from the header. That is: 742 // 743 // address increment = (adjusted opcode / line_range) * 744 // minimum_instruction_length 745 // 746 // The amount to increment the line register is the line_base plus 747 // the result of the adjusted opcode modulo the line_range. That is: 748 // 749 // line increment = line_base + (adjusted opcode % line_range) 750 751 uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase; 752 uint64_t AddrOffset = 753 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; 754 int32_t LineOffset = 755 Prologue.LineBase + (AdjustOpcode % Prologue.LineRange); 756 State.Row.Line += LineOffset; 757 State.Row.Address += AddrOffset; 758 759 if (OS) { 760 *OS << "address += " << ((uint32_t)AdjustOpcode) 761 << ", line += " << LineOffset << "\n"; 762 OS->indent(12); 763 State.Row.dump(*OS); 764 } 765 766 State.appendRowToMatrix(*OffsetPtr); 767 // Reset discriminator to 0. 768 State.Row.Discriminator = 0; 769 } 770 if(OS) 771 *OS << "\n"; 772 } 773 774 if (!State.Sequence.Empty) { 775 fprintf(stderr, "warning: last sequence in debug line table is not" 776 "terminated!\n"); 777 } 778 779 // Sort all sequences so that address lookup will work faster. 780 if (!Sequences.empty()) { 781 std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC); 782 // Note: actually, instruction address ranges of sequences should not 783 // overlap (in shared objects and executables). If they do, the address 784 // lookup would still work, though, but result would be ambiguous. 785 // We don't report warning in this case. For example, 786 // sometimes .so compiled from multiple object files contains a few 787 // rudimentary sequences for address ranges [0x0, 0xsomething). 788 } 789 790 return EndOffset; 791 } 792 793 uint32_t 794 DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq, 795 uint64_t Address) const { 796 if (!Seq.containsPC(Address)) 797 return UnknownRowIndex; 798 // Search for instruction address in the rows describing the sequence. 799 // Rows are stored in a vector, so we may use arithmetical operations with 800 // iterators. 801 DWARFDebugLine::Row Row; 802 Row.Address = Address; 803 RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex; 804 RowIter LastRow = Rows.begin() + Seq.LastRowIndex; 805 LineTable::RowIter RowPos = std::lower_bound( 806 FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress); 807 if (RowPos == LastRow) { 808 return Seq.LastRowIndex - 1; 809 } 810 uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow); 811 if (RowPos->Address > Address) { 812 if (RowPos == FirstRow) 813 return UnknownRowIndex; 814 else 815 Index--; 816 } 817 return Index; 818 } 819 820 uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const { 821 if (Sequences.empty()) 822 return UnknownRowIndex; 823 // First, find an instruction sequence containing the given address. 824 DWARFDebugLine::Sequence Sequence; 825 Sequence.LowPC = Address; 826 SequenceIter FirstSeq = Sequences.begin(); 827 SequenceIter LastSeq = Sequences.end(); 828 SequenceIter SeqPos = std::lower_bound( 829 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); 830 DWARFDebugLine::Sequence FoundSeq; 831 if (SeqPos == LastSeq) { 832 FoundSeq = Sequences.back(); 833 } else if (SeqPos->LowPC == Address) { 834 FoundSeq = *SeqPos; 835 } else { 836 if (SeqPos == FirstSeq) 837 return UnknownRowIndex; 838 FoundSeq = *(SeqPos - 1); 839 } 840 return findRowInSeq(FoundSeq, Address); 841 } 842 843 bool DWARFDebugLine::LineTable::lookupAddressRange( 844 uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const { 845 if (Sequences.empty()) 846 return false; 847 uint64_t EndAddr = Address + Size; 848 // First, find an instruction sequence containing the given address. 849 DWARFDebugLine::Sequence Sequence; 850 Sequence.LowPC = Address; 851 SequenceIter FirstSeq = Sequences.begin(); 852 SequenceIter LastSeq = Sequences.end(); 853 SequenceIter SeqPos = std::lower_bound( 854 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); 855 if (SeqPos == LastSeq || SeqPos->LowPC != Address) { 856 if (SeqPos == FirstSeq) 857 return false; 858 SeqPos--; 859 } 860 if (!SeqPos->containsPC(Address)) 861 return false; 862 863 SequenceIter StartPos = SeqPos; 864 865 // Add the rows from the first sequence to the vector, starting with the 866 // index we just calculated 867 868 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) { 869 const DWARFDebugLine::Sequence &CurSeq = *SeqPos; 870 // For the first sequence, we need to find which row in the sequence is the 871 // first in our range. 872 uint32_t FirstRowIndex = CurSeq.FirstRowIndex; 873 if (SeqPos == StartPos) 874 FirstRowIndex = findRowInSeq(CurSeq, Address); 875 876 // Figure out the last row in the range. 877 uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1); 878 if (LastRowIndex == UnknownRowIndex) 879 LastRowIndex = CurSeq.LastRowIndex - 1; 880 881 assert(FirstRowIndex != UnknownRowIndex); 882 assert(LastRowIndex != UnknownRowIndex); 883 884 for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) { 885 Result.push_back(I); 886 } 887 888 ++SeqPos; 889 } 890 891 return true; 892 } 893 894 bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { 895 return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); 896 } 897 898 bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, 899 const char *CompDir, 900 FileLineInfoKind Kind, 901 std::string &Result) const { 902 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) 903 return false; 904 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; 905 StringRef FileName = Entry.Name; 906 if (Kind != FileLineInfoKind::AbsoluteFilePath || 907 sys::path::is_absolute(FileName)) { 908 Result = FileName; 909 return true; 910 } 911 912 SmallString<16> FilePath; 913 uint64_t IncludeDirIndex = Entry.DirIdx; 914 StringRef IncludeDir; 915 // Be defensive about the contents of Entry. 916 if (IncludeDirIndex > 0 && 917 IncludeDirIndex <= Prologue.IncludeDirectories.size()) 918 IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; 919 920 // We may still need to append compilation directory of compile unit. 921 // We know that FileName is not absolute, the only way to have an 922 // absolute path at this point would be if IncludeDir is absolute. 923 if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath && 924 sys::path::is_relative(IncludeDir)) 925 sys::path::append(FilePath, CompDir); 926 927 // sys::path::append skips empty strings. 928 sys::path::append(FilePath, IncludeDir, FileName); 929 Result = FilePath.str(); 930 return true; 931 } 932 933 bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( 934 uint64_t Address, const char *CompDir, FileLineInfoKind Kind, 935 DILineInfo &Result) const { 936 // Get the index of row we're looking for in the line table. 937 uint32_t RowIndex = lookupAddress(Address); 938 if (RowIndex == -1U) 939 return false; 940 // Take file number and line/column from the row. 941 const auto &Row = Rows[RowIndex]; 942 if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName)) 943 return false; 944 Result.Line = Row.Line; 945 Result.Column = Row.Column; 946 Result.Discriminator = Row.Discriminator; 947 return true; 948 } 949