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