1 //===-- LVLocation.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This implements the LVOperation and LVLocation classes. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h" 14 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" 15 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h" 16 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" 17 18 using namespace llvm; 19 using namespace llvm::logicalview; 20 21 #define DEBUG_TYPE "Location" 22 23 void LVOperation::print(raw_ostream &OS, bool Full) const {} 24 25 // Identify the most common type of operations and print them using a high 26 // level format, trying to isolate the DWARF complexity. 27 std::string LVOperation::getOperandsDWARFInfo() { 28 std::string String; 29 raw_string_ostream Stream(String); 30 31 auto PrintRegisterInfo = [&](LVSmall Code) { 32 //----------------------------------------------------------------------- 33 // 2.5.1.1 Literal encodings. 34 //----------------------------------------------------------------------- 35 if (dwarf::DW_OP_lit0 <= Code && Code <= dwarf::DW_OP_lit31) { 36 Stream << format("lit%d", Code - dwarf::DW_OP_lit0); 37 return; 38 } 39 40 //----------------------------------------------------------------------- 41 // 2.5.1.2 Register values. 42 //----------------------------------------------------------------------- 43 if (dwarf::DW_OP_breg0 <= Code && Code <= dwarf::DW_OP_breg31) { 44 std::string RegisterName(getReader().getRegisterName(Code, Operands)); 45 Stream << format("breg%d+%d%s", Code - dwarf::DW_OP_breg0, Operands[0], 46 RegisterName.c_str()); 47 return; 48 } 49 50 //----------------------------------------------------------------------- 51 // 2.6.1.1.3 Register location descriptions. 52 //----------------------------------------------------------------------- 53 if (dwarf::DW_OP_reg0 <= Code && Code <= dwarf::DW_OP_reg31) { 54 std::string RegisterName(getReader().getRegisterName(Code, Operands)); 55 Stream << format("reg%d%s", Code - dwarf::DW_OP_reg0, 56 RegisterName.c_str()); 57 return; 58 } 59 60 Stream << format("#0x%02x ", Code) << hexString(Operands[0]) << " " 61 << hexString(Operands[1]) << "#"; 62 }; 63 64 switch (Opcode) { 65 //------------------------------------------------------------------------- 66 // 2.5.1.1 Literal encodings. 67 //------------------------------------------------------------------------- 68 case dwarf::DW_OP_addr: 69 Stream << "addr " << hexString(Operands[0]); 70 break; 71 case dwarf::DW_OP_constu: 72 case dwarf::DW_OP_const1u: 73 case dwarf::DW_OP_const2u: 74 case dwarf::DW_OP_const4u: 75 case dwarf::DW_OP_const8u: 76 Stream << "const_u " << unsigned(Operands[0]); 77 break; 78 case dwarf::DW_OP_consts: 79 case dwarf::DW_OP_const1s: 80 case dwarf::DW_OP_const2s: 81 case dwarf::DW_OP_const4s: 82 case dwarf::DW_OP_const8s: 83 Stream << "const_s " << int(Operands[0]); 84 break; 85 case dwarf::DW_OP_addrx: 86 Stream << "addrx " << unsigned(Operands[0]); 87 break; 88 case dwarf::DW_OP_constx: 89 Stream << "constx " << unsigned(Operands[0]); 90 break; 91 case dwarf::DW_OP_const_type: 92 Stream << "TODO: DW_OP_const_type"; 93 break; 94 95 //------------------------------------------------------------------------- 96 // 2.5.1.2 Register values. 97 //------------------------------------------------------------------------- 98 case dwarf::DW_OP_fbreg: 99 Stream << "fbreg " << int(Operands[0]); 100 break; 101 case dwarf::DW_OP_bregx: { 102 std::string RegisterName(getReader().getRegisterName(Opcode, Operands)); 103 Stream << format("bregx %d%s+%d", Operands[0], RegisterName.c_str(), 104 unsigned(Operands[1])); 105 break; 106 } 107 case dwarf::DW_OP_regval_type: { 108 std::string RegisterName(getReader().getRegisterName(Opcode, Operands)); 109 Stream << format("regval_type %d%s+%d", Operands[0], RegisterName.c_str(), 110 unsigned(Operands[1])); 111 break; 112 } 113 114 //------------------------------------------------------------------------- 115 // 2.5.1.3 Stack operations. 116 //------------------------------------------------------------------------- 117 case dwarf::DW_OP_dup: 118 Stream << "dup"; 119 break; 120 case dwarf::DW_OP_drop: 121 Stream << "drop"; 122 break; 123 case dwarf::DW_OP_pick: 124 Stream << "pick " << unsigned(Operands[0]); 125 break; 126 case dwarf::DW_OP_over: 127 Stream << "over"; 128 break; 129 case dwarf::DW_OP_swap: 130 Stream << "swap"; 131 break; 132 case dwarf::DW_OP_rot: 133 Stream << "rot"; 134 break; 135 case dwarf::DW_OP_deref: 136 Stream << "deref"; 137 break; 138 case dwarf::DW_OP_deref_size: 139 Stream << "deref_size " << unsigned(Operands[0]); 140 break; 141 case dwarf::DW_OP_deref_type: 142 Stream << "deref_type " << unsigned(Operands[0]) << " DIE offset " 143 << hexString(Operands[1]); 144 break; 145 case dwarf::DW_OP_xderef: 146 Stream << "xderef"; 147 break; 148 case dwarf::DW_OP_xderef_size: 149 Stream << "xderef_size " << unsigned(Operands[0]); 150 break; 151 case dwarf::DW_OP_xderef_type: 152 Stream << "xderef_type " << unsigned(Operands[0]) << " DIE offset " 153 << hexString(Operands[1]); 154 break; 155 case dwarf::DW_OP_push_object_address: 156 Stream << "push_object_address"; 157 break; 158 case dwarf::DW_OP_form_tls_address: 159 Stream << "form_tls_address " << hexString(Operands[0]); 160 break; 161 case dwarf::DW_OP_call_frame_cfa: 162 Stream << "call_frame_cfa"; 163 break; 164 165 //------------------------------------------------------------------------- 166 // 2.5.1.4 Arithmetic and Logical Operations. 167 //------------------------------------------------------------------------- 168 case dwarf::DW_OP_abs: 169 Stream << "abs"; 170 break; 171 case dwarf::DW_OP_and: 172 Stream << "and"; 173 break; 174 case dwarf::DW_OP_div: 175 Stream << "div"; 176 break; 177 case dwarf::DW_OP_minus: 178 Stream << "minus"; 179 break; 180 case dwarf::DW_OP_mod: 181 Stream << "mod"; 182 break; 183 case dwarf::DW_OP_mul: 184 Stream << "mul"; 185 break; 186 case dwarf::DW_OP_neg: 187 Stream << "neg"; 188 break; 189 case dwarf::DW_OP_not: 190 Stream << "not"; 191 break; 192 case dwarf::DW_OP_or: 193 Stream << "or"; 194 break; 195 case dwarf::DW_OP_plus: 196 Stream << "plus"; 197 break; 198 case dwarf::DW_OP_plus_uconst: 199 Stream << "plus_uconst " << unsigned(Operands[0]); 200 break; 201 case dwarf::DW_OP_shl: 202 Stream << "shl"; 203 break; 204 case dwarf::DW_OP_shr: 205 Stream << "shr"; 206 break; 207 case dwarf::DW_OP_shra: 208 Stream << "shra"; 209 break; 210 case dwarf::DW_OP_xor: 211 Stream << "xor"; 212 break; 213 214 //------------------------------------------------------------------------- 215 // 2.5.1.5 Control Flow Operations. 216 //------------------------------------------------------------------------- 217 case dwarf::DW_OP_le: 218 Stream << "le"; 219 break; 220 case dwarf::DW_OP_ge: 221 Stream << "ge"; 222 break; 223 case dwarf::DW_OP_eq: 224 Stream << "eq"; 225 break; 226 case dwarf::DW_OP_lt: 227 Stream << "lt"; 228 break; 229 case dwarf::DW_OP_gt: 230 Stream << "gt"; 231 break; 232 case dwarf::DW_OP_ne: 233 Stream << "ne"; 234 break; 235 case dwarf::DW_OP_skip: 236 Stream << "skip " << signed(Operands[0]); 237 break; 238 case dwarf::DW_OP_bra: 239 Stream << "bra " << signed(Operands[0]); 240 break; 241 case dwarf::DW_OP_call2: 242 Stream << "call2 DIE offset " << hexString(Operands[0]); 243 break; 244 case dwarf::DW_OP_call4: 245 Stream << "call4 DIE offset " << hexString(Operands[0]); 246 break; 247 case dwarf::DW_OP_call_ref: 248 Stream << "call_ref DIE offset " << hexString(Operands[0]); 249 break; 250 251 //------------------------------------------------------------------------- 252 // 2.5.1.6 Type Conversions. 253 //------------------------------------------------------------------------- 254 case dwarf::DW_OP_convert: 255 Stream << "convert DIE offset " << hexString(Operands[0]); 256 break; 257 case dwarf::DW_OP_reinterpret: 258 Stream << "reinterpret DIE offset " << hexString(Operands[0]); 259 break; 260 261 //------------------------------------------------------------------------- 262 // 2.5.1.7 Special Operations. 263 //------------------------------------------------------------------------- 264 case dwarf::DW_OP_nop: 265 Stream << "nop"; 266 break; 267 case dwarf::DW_OP_entry_value: 268 Stream << "TODO: DW_OP_entry_value"; 269 break; 270 271 //------------------------------------------------------------------------- 272 // 2.6.1.1.3 Register location descriptions. 273 //------------------------------------------------------------------------- 274 case dwarf::DW_OP_regx: 275 Stream << "regx" << getReader().getRegisterName(Opcode, Operands); 276 break; 277 278 //------------------------------------------------------------------------- 279 // 2.6.1.1.4 Implicit location descriptions. 280 //------------------------------------------------------------------------- 281 case dwarf::DW_OP_stack_value: 282 Stream << "stack_value"; 283 break; 284 case dwarf::DW_OP_implicit_value: 285 Stream << "TODO: DW_OP_implicit_value"; 286 break; 287 case dwarf::DW_OP_implicit_pointer: 288 Stream << "implicit_pointer DIE offset " << hexString(Operands[0]) << " " 289 << int(Operands[1]); 290 break; 291 292 //------------------------------------------------------------------------- 293 // 2.6.1.2 Composite location descriptions. 294 //------------------------------------------------------------------------- 295 case dwarf::DW_OP_piece: 296 Stream << "piece " << int(Operands[0]); 297 break; 298 case dwarf::DW_OP_bit_piece: 299 Stream << "bit_piece " << int(Operands[0]) << " offset " 300 << int(Operands[1]); 301 break; 302 303 //------------------------------------------------------------------------- 304 // GNU extensions. 305 //------------------------------------------------------------------------- 306 case dwarf::DW_OP_GNU_entry_value: 307 Stream << "gnu_entry_value "; 308 PrintRegisterInfo(dwarf::DW_OP_reg0); 309 break; 310 case dwarf::DW_OP_GNU_push_tls_address: 311 Stream << "gnu_push_tls_address " << hexString(Operands[0]); 312 break; 313 case dwarf::DW_OP_GNU_addr_index: 314 Stream << "gnu_addr_index " << unsigned(Operands[0]); 315 break; 316 case dwarf::DW_OP_GNU_const_index: 317 Stream << "gnu_const_index " << unsigned(Operands[0]); 318 break; 319 320 //------------------------------------------------------------------------- 321 // Member location. 322 //------------------------------------------------------------------------- 323 case LVLocationMemberOffset: 324 Stream << "offset " << int(Operands[0]); 325 break; 326 327 //------------------------------------------------------------------------- 328 // Missing location. 329 //------------------------------------------------------------------------- 330 case dwarf::DW_OP_hi_user: 331 Stream << "missing"; 332 break; 333 334 //------------------------------------------------------------------------- 335 // Register values. 336 //------------------------------------------------------------------------- 337 default: 338 PrintRegisterInfo(Opcode); 339 break; 340 } 341 342 return String; 343 } 344 345 // Identify the most common type of operations and print them using a high 346 // level format, trying to isolate the CodeView complexity. 347 std::string LVOperation::getOperandsCodeViewInfo() { 348 std::string String; 349 raw_string_ostream Stream(String); 350 351 // Get original CodeView operation code. 352 uint16_t OperationCode = getCodeViewOperationCode(Opcode); 353 354 switch (OperationCode) { 355 // Operands: [Offset]. 356 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL: 357 Stream << "frame_pointer_rel " << int(Operands[0]); 358 break; 359 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: 360 Stream << "frame_pointer_rel_full_scope " << int(Operands[0]); 361 break; 362 363 // Operands: [Register]. 364 case codeview::SymbolKind::S_DEFRANGE_REGISTER: 365 Stream << "register " << getReader().getRegisterName(Opcode, Operands); 366 break; 367 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER: 368 Stream << "subfield_register " 369 << getReader().getRegisterName(Opcode, Operands); 370 break; 371 372 // Operands: [Register, Offset]. 373 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL: 374 Stream << "register_rel " << getReader().getRegisterName(Opcode, Operands) 375 << " offset " << int(Operands[1]); 376 break; 377 378 // Operands: [Program]. 379 case codeview::SymbolKind::S_DEFRANGE: 380 Stream << "frame " << int(Operands[0]); 381 break; 382 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD: 383 Stream << "subfield " << int(Operands[0]); 384 break; 385 386 default: 387 Stream << format("#0x%02x: ", Opcode) << hexString(Operands[0]) << " " 388 << hexString(Operands[1]) << "#"; 389 break; 390 } 391 392 return String; 393 } 394 395 namespace { 396 const char *const KindBaseClassOffset = "BaseClassOffset"; 397 const char *const KindBaseClassStep = "BaseClassStep"; 398 const char *const KindClassOffset = "ClassOffset"; 399 const char *const KindFixedAddress = "FixedAddress"; 400 const char *const KindMissingInfo = "Missing"; 401 const char *const KindOperation = "Operation"; 402 const char *const KindOperationList = "OperationList"; 403 const char *const KindRegister = "Register"; 404 const char *const KindUndefined = "Undefined"; 405 } // end anonymous namespace 406 407 //===----------------------------------------------------------------------===// 408 // DWARF location information. 409 //===----------------------------------------------------------------------===// 410 const char *LVLocation::kind() const { 411 const char *Kind = KindUndefined; 412 if (getIsBaseClassOffset()) 413 Kind = KindBaseClassOffset; 414 else if (getIsBaseClassStep()) 415 Kind = KindBaseClassStep; 416 else if (getIsClassOffset()) 417 Kind = KindClassOffset; 418 else if (getIsFixedAddress()) 419 Kind = KindFixedAddress; 420 else if (getIsGapEntry()) 421 Kind = KindMissingInfo; 422 else if (getIsOperation()) 423 Kind = KindOperation; 424 else if (getIsOperationList()) 425 Kind = KindOperationList; 426 else if (getIsRegister()) 427 Kind = KindRegister; 428 return Kind; 429 } 430 431 std::string LVLocation::getIntervalInfo() const { 432 static const char *const Question = "?"; 433 std::string String; 434 raw_string_ostream Stream(String); 435 if (getIsAddressRange()) 436 Stream << "{Range}"; 437 438 auto PrintLine = [&](const LVLine *Line) { 439 if (Line) { 440 std::string TheLine; 441 TheLine = Line->lineNumberAsStringStripped(); 442 Stream << TheLine.c_str(); 443 } else { 444 Stream << Question; 445 } 446 }; 447 448 Stream << " Lines "; 449 PrintLine(getLowerLine()); 450 Stream << ":"; 451 PrintLine(getUpperLine()); 452 453 if (options().getAttributeOffset()) 454 // Print the active range (low pc and high pc). 455 Stream << " [" << hexString(getLowerAddress()) << ":" 456 << hexString(getUpperAddress()) << "]"; 457 458 return String; 459 } 460 461 // Validate the ranges associated with the location. 462 bool LVLocation::validateRanges() { 463 // Traverse the locations and validate them against the address to line 464 // mapping in the current compile unit. Record those invalid ranges. 465 // A valid range must meet the following conditions: 466 // a) line(lopc) <= line(hipc) 467 // b) line(lopc) and line(hipc) are valid. 468 469 if (!hasAssociatedRange()) 470 return true; 471 472 LVLineRange Range = getReaderCompileUnit()->lineRange(this); 473 LVLine *LowLine = Range.first; 474 LVLine *HighLine = Range.second; 475 if (LowLine) 476 setLowerLine(LowLine); 477 else { 478 setIsInvalidLower(); 479 return false; 480 } 481 if (HighLine) 482 setUpperLine(HighLine); 483 else { 484 setIsInvalidUpper(); 485 return false; 486 } 487 // Check for a valid interval. 488 if (LowLine->getLineNumber() > HighLine->getLineNumber()) { 489 setIsInvalidRange(); 490 return false; 491 } 492 493 return true; 494 } 495 496 bool LVLocation::calculateCoverage(LVLocations *Locations, unsigned &Factor, 497 float &Percentage) { 498 if (!options().getAttributeCoverage() && !Locations) 499 return false; 500 501 // Calculate the coverage depending on the kind of location. We have 502 // the simple and composed locations. 503 if (Locations->size() == 1) { 504 // Simple: fixed address, class offset, stack offset. 505 LVLocation *Location = Locations->front(); 506 // Some types of locations do not have specific kind. Now is the time 507 // to set those types, depending on the operation type. 508 Location->updateKind(); 509 if (Location->getIsLocationSimple()) { 510 Factor = 100; 511 Percentage = 100; 512 return true; 513 } 514 } 515 516 // Composed locations. 517 LVAddress LowerAddress = 0; 518 LVAddress UpperAddress = 0; 519 for (const LVLocation *Location : *Locations) 520 // Do not include locations representing a gap. 521 if (!Location->getIsGapEntry()) { 522 LowerAddress = Location->getLowerAddress(); 523 UpperAddress = Location->getUpperAddress(); 524 Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress 525 : LowerAddress - UpperAddress; 526 } 527 528 Percentage = 0; 529 return false; 530 } 531 532 void LVLocation::printRaw(raw_ostream &OS, bool Full) const { 533 // Print the active range (low pc and high pc). 534 OS << " [" << hexString(getLowerAddress()) << ":" 535 << hexString(getUpperAddress()) << "]\n"; 536 // Print any DWARF operations. 537 printRawExtra(OS, Full); 538 } 539 540 void LVLocation::printInterval(raw_ostream &OS, bool Full) const { 541 if (hasAssociatedRange()) 542 OS << getIntervalInfo(); 543 } 544 545 void LVLocation::print(raw_ostream &OS, bool Full) const { 546 if (getReader().doPrintLocation(this)) { 547 LVObject::print(OS, Full); 548 printExtra(OS, Full); 549 } 550 } 551 552 void LVLocation::printExtra(raw_ostream &OS, bool Full) const { 553 printInterval(OS, Full); 554 OS << "\n"; 555 } 556 557 //===----------------------------------------------------------------------===// 558 // DWARF location for a symbol. 559 //===----------------------------------------------------------------------===// 560 // Add a Location Entry. 561 void LVLocationSymbol::addObject(LVAddress LowPC, LVAddress HighPC, 562 LVUnsigned SectionOffset, 563 uint64_t LocDescOffset) { 564 setLowerAddress(LowPC); 565 setUpperAddress(HighPC); 566 567 // Record the offset where the location information begins. 568 setOffset(LocDescOffset ? LocDescOffset : SectionOffset); 569 570 // A -1 HighPC value, indicates no range. 571 if (HighPC == LVAddress(UINT64_MAX)) 572 setIsDiscardedRange(); 573 574 // Update the location kind, using the DWARF attribute. 575 setKind(); 576 } 577 578 // Add a Location Record. 579 void LVLocationSymbol::addObject(LVSmall Opcode, 580 ArrayRef<LVUnsigned> Operands) { 581 if (!Entries) 582 Entries = std::make_unique<LVOperations>(); 583 Entries->push_back(getReader().createOperation(Opcode, Operands)); 584 } 585 586 // Based on the DWARF attribute, define the location kind. 587 void LVLocation::setKind() { 588 switch (getAttr()) { 589 case dwarf::DW_AT_data_member_location: 590 setIsClassOffset(); 591 break; 592 case dwarf::DW_AT_location: 593 // Depending on the operand, we have a fixed address. 594 setIsFixedAddress(); 595 break; 596 default: 597 break; 598 } 599 // For those symbols with absolute location information, ignore any 600 // gaps in their location description; that is the case with absolute 601 // memory addresses and members located at specific offsets. 602 if (hasAssociatedRange()) 603 getParentSymbol()->setFillGaps(); 604 } 605 606 void LVLocationSymbol::updateKind() { 607 // Update the location type for simple ones. 608 if (Entries && Entries->size() == 1) { 609 if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode()) 610 setIsStackOffset(); 611 } 612 } 613 614 void LVLocationSymbol::printRawExtra(raw_ostream &OS, bool Full) const { 615 if (Entries) 616 for (const LVOperation *Operation : *Entries) 617 Operation->print(OS, Full); 618 } 619 620 // Print location (formatted version). 621 void LVLocation::print(LVLocations *Locations, raw_ostream &OS, bool Full) { 622 if (!Locations || Locations->empty()) 623 return; 624 625 // Print the symbol coverage. 626 if (options().getAttributeCoverage()) { 627 // The location entries are contained within a symbol. Get a location, 628 // to access basic information about indentation, parent, etc. 629 LVLocation *Location = Locations->front(); 630 LVSymbol *Symbol = Location->getParentSymbol(); 631 float Percentage = Symbol->getCoveragePercentage(); 632 633 // The coverage is dependent on the kind of location. 634 std::string String; 635 raw_string_ostream Stream(String); 636 Stream << format("%.2f%%", Percentage); 637 if (!Location->getIsLocationSimple()) 638 Stream << format(" (%d/%d)", Symbol->getCoverageFactor(), 639 Symbol->getParentScope()->getCoverageFactor()); 640 Symbol->printAttributes(OS, Full, "{Coverage} ", Symbol, StringRef(String), 641 /*UseQuotes=*/false, 642 /*PrintRef=*/false); 643 } 644 645 // Print the symbol location, including the missing entries. 646 if (getReader().doPrintLocation(/*Location=*/nullptr)) 647 for (const LVLocation *Location : *Locations) 648 Location->print(OS, Full); 649 } 650 651 void LVLocationSymbol::printExtra(raw_ostream &OS, bool Full) const { 652 OS << "{Location}"; 653 if (getIsCallSite()) 654 OS << " -> CallSite"; 655 printInterval(OS, Full); 656 OS << "\n"; 657 658 // Print location entries. 659 if (Full && Entries) { 660 bool CodeViewLocation = getParentSymbol()->getHasCodeViewLocation(); 661 std::stringstream Stream; 662 std::string Leading; 663 for (LVOperation *Operation : *Entries) { 664 Stream << Leading 665 << (CodeViewLocation ? Operation->getOperandsCodeViewInfo() 666 : Operation->getOperandsDWARFInfo()); 667 Leading = ", "; 668 } 669 printAttributes(OS, Full, "{Entry} ", const_cast<LVLocationSymbol *>(this), 670 StringRef(Stream.str()), 671 /*UseQuotes=*/false, 672 /*PrintRef=*/false); 673 } 674 } 675