1 //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===// 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 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 10 #include "llvm/ADT/DenseMap.h" 11 #include "llvm/ADT/Optional.h" 12 #include "llvm/ADT/StringExtras.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/BinaryFormat/Dwarf.h" 15 #include "llvm/MC/MCRegisterInfo.h" 16 #include "llvm/Support/Casting.h" 17 #include "llvm/Support/Compiler.h" 18 #include "llvm/Support/DataExtractor.h" 19 #include "llvm/Support/Errc.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/Format.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include <algorithm> 24 #include <cassert> 25 #include <cinttypes> 26 #include <cstdint> 27 #include <string> 28 29 using namespace llvm; 30 using namespace dwarf; 31 32 static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, 33 unsigned RegNum) { 34 if (MRI) { 35 if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) { 36 if (const char *RegName = MRI->getName(*LLVMRegNum)) { 37 OS << RegName; 38 return; 39 } 40 } 41 } 42 OS << "reg" << RegNum; 43 } 44 45 UnwindLocation UnwindLocation::createUnspecified() { return {Unspecified}; } 46 47 UnwindLocation UnwindLocation::createUndefined() { return {Undefined}; } 48 49 UnwindLocation UnwindLocation::createSame() { return {Same}; } 50 51 UnwindLocation UnwindLocation::createIsConstant(int32_t Value) { 52 return {Constant, InvalidRegisterNumber, Value, false}; 53 } 54 55 UnwindLocation UnwindLocation::createIsCFAPlusOffset(int32_t Offset) { 56 return {CFAPlusOffset, InvalidRegisterNumber, Offset, false}; 57 } 58 59 UnwindLocation UnwindLocation::createAtCFAPlusOffset(int32_t Offset) { 60 return {CFAPlusOffset, InvalidRegisterNumber, Offset, true}; 61 } 62 63 UnwindLocation UnwindLocation::createIsRegisterPlusOffset(uint32_t RegNum, 64 int32_t Offset) { 65 return {RegPlusOffset, RegNum, Offset, false}; 66 } 67 UnwindLocation UnwindLocation::createAtRegisterPlusOffset(uint32_t RegNum, 68 int32_t Offset) { 69 return {RegPlusOffset, RegNum, Offset, true}; 70 } 71 72 UnwindLocation UnwindLocation::createIsDWARFExpression(DWARFExpression Expr) { 73 return {Expr, false}; 74 } 75 76 UnwindLocation UnwindLocation::createAtDWARFExpression(DWARFExpression Expr) { 77 return {Expr, true}; 78 } 79 80 void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, 81 bool IsEH) const { 82 if (Dereference) 83 OS << '['; 84 switch (Kind) { 85 case Unspecified: 86 OS << "unspecified"; 87 break; 88 case Undefined: 89 OS << "undefined"; 90 break; 91 case Same: 92 OS << "same"; 93 break; 94 case CFAPlusOffset: 95 OS << "CFA"; 96 if (Offset == 0) 97 break; 98 if (Offset > 0) 99 OS << "+"; 100 OS << Offset; 101 break; 102 case RegPlusOffset: 103 printRegister(OS, MRI, IsEH, RegNum); 104 if (Offset == 0) 105 break; 106 if (Offset > 0) 107 OS << "+"; 108 OS << Offset; 109 break; 110 case DWARFExpr: 111 Expr->print(OS, DIDumpOptions(), MRI, nullptr, IsEH); 112 break; 113 case Constant: 114 OS << Offset; 115 break; 116 } 117 if (Dereference) 118 OS << ']'; 119 } 120 121 raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, 122 const UnwindLocation &UL) { 123 UL.dump(OS, nullptr, false); 124 return OS; 125 } 126 127 bool UnwindLocation::operator==(const UnwindLocation &RHS) const { 128 if (Kind != RHS.Kind) 129 return false; 130 switch (Kind) { 131 case Unspecified: 132 case Undefined: 133 case Same: 134 return true; 135 case CFAPlusOffset: 136 return Offset == RHS.Offset && Dereference == RHS.Dereference; 137 case RegPlusOffset: 138 return RegNum == RHS.RegNum && Offset == RHS.Offset && 139 Dereference == RHS.Dereference; 140 case DWARFExpr: 141 return *Expr == *RHS.Expr && Dereference == RHS.Dereference; 142 case Constant: 143 return Offset == RHS.Offset; 144 } 145 return false; 146 } 147 148 void RegisterLocations::dump(raw_ostream &OS, const MCRegisterInfo *MRI, 149 bool IsEH) const { 150 bool First = true; 151 for (const auto &RegLocPair : Locations) { 152 if (First) 153 First = false; 154 else 155 OS << ", "; 156 printRegister(OS, MRI, IsEH, RegLocPair.first); 157 OS << '='; 158 RegLocPair.second.dump(OS, MRI, IsEH); 159 } 160 } 161 162 raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, 163 const RegisterLocations &RL) { 164 RL.dump(OS, nullptr, false); 165 return OS; 166 } 167 168 void UnwindRow::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, 169 unsigned IndentLevel) const { 170 OS.indent(2 * IndentLevel); 171 if (hasAddress()) 172 OS << format("0x%" PRIx64 ": ", *Address); 173 OS << "CFA="; 174 CFAValue.dump(OS, MRI, IsEH); 175 if (RegLocs.hasLocations()) { 176 OS << ": "; 177 RegLocs.dump(OS, MRI, IsEH); 178 } 179 OS << "\n"; 180 } 181 182 raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindRow &Row) { 183 Row.dump(OS, nullptr, false, 0); 184 return OS; 185 } 186 187 void UnwindTable::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, 188 unsigned IndentLevel) const { 189 for (const UnwindRow &Row : Rows) 190 Row.dump(OS, MRI, IsEH, IndentLevel); 191 } 192 193 raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindTable &Rows) { 194 Rows.dump(OS, nullptr, false, 0); 195 return OS; 196 } 197 198 Expected<UnwindTable> UnwindTable::create(const FDE *Fde) { 199 UnwindTable UT; 200 UnwindRow Row; 201 Row.setAddress(Fde->getInitialLocation()); 202 UT.EndAddress = Fde->getInitialLocation() + Fde->getAddressRange(); 203 204 const CIE *Cie = Fde->getLinkedCIE(); 205 if (Cie == nullptr) 206 return createStringError(errc::invalid_argument, 207 "unable to get CIE for FDE at offset 0x%" PRIx64, 208 Fde->getOffset()); 209 210 if (Error CieError = UT.parseRows(Cie->cfis(), Row, nullptr)) 211 return std::move(CieError); 212 // We need to save the initial locations of registers from the CIE parsing 213 // in case we run into DW_CFA_restore or DW_CFA_restore_extended opcodes. 214 const RegisterLocations InitialLocs = Row.getRegisterLocations(); 215 if (Error FdeError = UT.parseRows(Fde->cfis(), Row, &InitialLocs)) 216 return std::move(FdeError); 217 UT.Rows.push_back(Row); 218 return UT; 219 } 220 221 Expected<UnwindTable> UnwindTable::create(const CIE *Cie) { 222 UnwindTable UT; 223 UnwindRow Row; 224 if (Error CieError = UT.parseRows(Cie->cfis(), Row, nullptr)) 225 return std::move(CieError); 226 UT.Rows.push_back(Row); 227 return UT; 228 } 229 230 // See DWARF standard v3, section 7.23 231 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 232 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 233 234 Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset, 235 uint64_t EndOffset) { 236 DataExtractor::Cursor C(*Offset); 237 while (C && C.tell() < EndOffset) { 238 uint8_t Opcode = Data.getRelocatedValue(C, 1); 239 if (!C) 240 break; 241 242 // Some instructions have a primary opcode encoded in the top bits. 243 if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) { 244 // If it's a primary opcode, the first operand is encoded in the bottom 245 // bits of the opcode itself. 246 uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 247 switch (Primary) { 248 case DW_CFA_advance_loc: 249 case DW_CFA_restore: 250 addInstruction(Primary, Op1); 251 break; 252 case DW_CFA_offset: 253 addInstruction(Primary, Op1, Data.getULEB128(C)); 254 break; 255 default: 256 llvm_unreachable("invalid primary CFI opcode"); 257 } 258 continue; 259 } 260 261 // Extended opcode - its value is Opcode itself. 262 switch (Opcode) { 263 default: 264 return createStringError(errc::illegal_byte_sequence, 265 "invalid extended CFI opcode 0x%" PRIx8, Opcode); 266 case DW_CFA_nop: 267 case DW_CFA_remember_state: 268 case DW_CFA_restore_state: 269 case DW_CFA_GNU_window_save: 270 // No operands 271 addInstruction(Opcode); 272 break; 273 case DW_CFA_set_loc: 274 // Operands: Address 275 addInstruction(Opcode, Data.getRelocatedAddress(C)); 276 break; 277 case DW_CFA_advance_loc1: 278 // Operands: 1-byte delta 279 addInstruction(Opcode, Data.getRelocatedValue(C, 1)); 280 break; 281 case DW_CFA_advance_loc2: 282 // Operands: 2-byte delta 283 addInstruction(Opcode, Data.getRelocatedValue(C, 2)); 284 break; 285 case DW_CFA_advance_loc4: 286 // Operands: 4-byte delta 287 addInstruction(Opcode, Data.getRelocatedValue(C, 4)); 288 break; 289 case DW_CFA_restore_extended: 290 case DW_CFA_undefined: 291 case DW_CFA_same_value: 292 case DW_CFA_def_cfa_register: 293 case DW_CFA_def_cfa_offset: 294 case DW_CFA_GNU_args_size: 295 // Operands: ULEB128 296 addInstruction(Opcode, Data.getULEB128(C)); 297 break; 298 case DW_CFA_def_cfa_offset_sf: 299 // Operands: SLEB128 300 addInstruction(Opcode, Data.getSLEB128(C)); 301 break; 302 case DW_CFA_offset_extended: 303 case DW_CFA_register: 304 case DW_CFA_def_cfa: 305 case DW_CFA_val_offset: { 306 // Operands: ULEB128, ULEB128 307 // Note: We can not embed getULEB128 directly into function 308 // argument list. getULEB128 changes Offset and order of evaluation 309 // for arguments is unspecified. 310 uint64_t op1 = Data.getULEB128(C); 311 uint64_t op2 = Data.getULEB128(C); 312 addInstruction(Opcode, op1, op2); 313 break; 314 } 315 case DW_CFA_offset_extended_sf: 316 case DW_CFA_def_cfa_sf: 317 case DW_CFA_val_offset_sf: { 318 // Operands: ULEB128, SLEB128 319 // Note: see comment for the previous case 320 uint64_t op1 = Data.getULEB128(C); 321 uint64_t op2 = (uint64_t)Data.getSLEB128(C); 322 addInstruction(Opcode, op1, op2); 323 break; 324 } 325 case DW_CFA_def_cfa_expression: { 326 uint64_t ExprLength = Data.getULEB128(C); 327 addInstruction(Opcode, 0); 328 StringRef Expression = Data.getBytes(C, ExprLength); 329 330 DataExtractor Extractor(Expression, Data.isLittleEndian(), 331 Data.getAddressSize()); 332 // Note. We do not pass the DWARF format to DWARFExpression, because 333 // DW_OP_call_ref, the only operation which depends on the format, is 334 // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5. 335 Instructions.back().Expression = 336 DWARFExpression(Extractor, Data.getAddressSize()); 337 break; 338 } 339 case DW_CFA_expression: 340 case DW_CFA_val_expression: { 341 uint64_t RegNum = Data.getULEB128(C); 342 addInstruction(Opcode, RegNum, 0); 343 344 uint64_t BlockLength = Data.getULEB128(C); 345 StringRef Expression = Data.getBytes(C, BlockLength); 346 DataExtractor Extractor(Expression, Data.isLittleEndian(), 347 Data.getAddressSize()); 348 // Note. We do not pass the DWARF format to DWARFExpression, because 349 // DW_OP_call_ref, the only operation which depends on the format, is 350 // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5. 351 Instructions.back().Expression = 352 DWARFExpression(Extractor, Data.getAddressSize()); 353 break; 354 } 355 } 356 } 357 358 *Offset = C.tell(); 359 return C.takeError(); 360 } 361 362 StringRef CFIProgram::callFrameString(unsigned Opcode) const { 363 return dwarf::CallFrameString(Opcode, Arch); 364 } 365 366 const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) { 367 #define ENUM_TO_CSTR(e) \ 368 case e: \ 369 return #e; 370 switch (OT) { 371 ENUM_TO_CSTR(OT_Unset); 372 ENUM_TO_CSTR(OT_None); 373 ENUM_TO_CSTR(OT_Address); 374 ENUM_TO_CSTR(OT_Offset); 375 ENUM_TO_CSTR(OT_FactoredCodeOffset); 376 ENUM_TO_CSTR(OT_SignedFactDataOffset); 377 ENUM_TO_CSTR(OT_UnsignedFactDataOffset); 378 ENUM_TO_CSTR(OT_Register); 379 ENUM_TO_CSTR(OT_Expression); 380 } 381 return "<unknown CFIProgram::OperandType>"; 382 } 383 384 llvm::Expected<uint64_t> 385 CFIProgram::Instruction::getOperandAsUnsigned(const CFIProgram &CFIP, 386 uint32_t OperandIdx) const { 387 if (OperandIdx >= 2) 388 return createStringError(errc::invalid_argument, 389 "operand index %" PRIu32 " is not valid", 390 OperandIdx); 391 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx]; 392 uint64_t Operand = Ops[OperandIdx]; 393 switch (Type) { 394 case OT_Unset: 395 case OT_None: 396 case OT_Expression: 397 return createStringError(errc::invalid_argument, 398 "op[%" PRIu32 "] has type %s which has no value", 399 OperandIdx, CFIProgram::operandTypeString(Type)); 400 401 case OT_Offset: 402 case OT_SignedFactDataOffset: 403 case OT_UnsignedFactDataOffset: 404 return createStringError( 405 errc::invalid_argument, 406 "op[%" PRIu32 "] has OperandType OT_Offset which produces a signed " 407 "result, call getOperandAsSigned instead", 408 OperandIdx); 409 410 case OT_Address: 411 case OT_Register: 412 return Operand; 413 414 case OT_FactoredCodeOffset: { 415 const uint64_t CodeAlignmentFactor = CFIP.codeAlign(); 416 if (CodeAlignmentFactor == 0) 417 return createStringError( 418 errc::invalid_argument, 419 "op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment " 420 "is zero", 421 OperandIdx); 422 return Operand * CodeAlignmentFactor; 423 } 424 } 425 } 426 427 llvm::Expected<int64_t> 428 CFIProgram::Instruction::getOperandAsSigned(const CFIProgram &CFIP, 429 uint32_t OperandIdx) const { 430 if (OperandIdx >= 2) 431 return createStringError(errc::invalid_argument, 432 "operand index %" PRIu32 " is not valid", 433 OperandIdx); 434 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx]; 435 uint64_t Operand = Ops[OperandIdx]; 436 switch (Type) { 437 case OT_Unset: 438 case OT_None: 439 case OT_Expression: 440 return createStringError(errc::invalid_argument, 441 "op[%" PRIu32 "] has type %s which has no value", 442 OperandIdx, CFIProgram::operandTypeString(Type)); 443 444 case OT_Address: 445 case OT_Register: 446 return createStringError( 447 errc::invalid_argument, 448 "op[%" PRIu32 "] has OperandType %s which produces an unsigned result, " 449 "call getOperandAsUnsigned instead", 450 OperandIdx, CFIProgram::operandTypeString(Type)); 451 452 case OT_Offset: 453 return (int64_t)Operand; 454 455 case OT_FactoredCodeOffset: 456 case OT_SignedFactDataOffset: { 457 const int64_t DataAlignmentFactor = CFIP.dataAlign(); 458 if (DataAlignmentFactor == 0) 459 return createStringError(errc::invalid_argument, 460 "op[%" PRIu32 "] has type %s but data " 461 "alignment is zero", 462 OperandIdx, CFIProgram::operandTypeString(Type)); 463 return int64_t(Operand) * DataAlignmentFactor; 464 } 465 466 case OT_UnsignedFactDataOffset: { 467 const int64_t DataAlignmentFactor = CFIP.dataAlign(); 468 if (DataAlignmentFactor == 0) 469 return createStringError(errc::invalid_argument, 470 "op[%" PRIu32 471 "] has type OT_UnsignedFactDataOffset but data " 472 "alignment is zero", 473 OperandIdx); 474 return Operand * DataAlignmentFactor; 475 } 476 } 477 } 478 479 Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row, 480 const RegisterLocations *InitialLocs) { 481 std::vector<RegisterLocations> RegisterStates; 482 for (const CFIProgram::Instruction &Inst : CFIP) { 483 switch (Inst.Opcode) { 484 case dwarf::DW_CFA_set_loc: { 485 // The DW_CFA_set_loc instruction takes a single operand that 486 // represents a target address. The required action is to create a new 487 // table row using the specified address as the location. All other 488 // values in the new row are initially identical to the current row. 489 // The new location value is always greater than the current one. If 490 // the segment_size field of this FDE's CIE is non- zero, the initial 491 // location is preceded by a segment selector of the given length 492 llvm::Expected<uint64_t> NewAddress = Inst.getOperandAsUnsigned(CFIP, 0); 493 if (!NewAddress) 494 return NewAddress.takeError(); 495 if (*NewAddress <= Row.getAddress()) 496 return createStringError( 497 errc::invalid_argument, 498 "%s with adrress 0x%" PRIx64 " which must be greater than the " 499 "current row address 0x%" PRIx64, 500 CFIP.callFrameString(Inst.Opcode).str().c_str(), *NewAddress, 501 Row.getAddress()); 502 Rows.push_back(Row); 503 Row.setAddress(*NewAddress); 504 break; 505 } 506 507 case dwarf::DW_CFA_advance_loc: 508 case dwarf::DW_CFA_advance_loc1: 509 case dwarf::DW_CFA_advance_loc2: 510 case dwarf::DW_CFA_advance_loc4: { 511 // The DW_CFA_advance instruction takes a single operand that 512 // represents a constant delta. The required action is to create a new 513 // table row with a location value that is computed by taking the 514 // current entry’s location value and adding the value of delta * 515 // code_alignment_factor. All other values in the new row are initially 516 // identical to the current row. 517 Rows.push_back(Row); 518 llvm::Expected<uint64_t> Offset = Inst.getOperandAsUnsigned(CFIP, 0); 519 if (!Offset) 520 return Offset.takeError(); 521 Row.slideAddress(*Offset); 522 break; 523 } 524 525 case dwarf::DW_CFA_restore: 526 case dwarf::DW_CFA_restore_extended: { 527 // The DW_CFA_restore instruction takes a single operand (encoded with 528 // the opcode) that represents a register number. The required action 529 // is to change the rule for the indicated register to the rule 530 // assigned it by the initial_instructions in the CIE. 531 if (InitialLocs == nullptr) 532 return createStringError( 533 errc::invalid_argument, "%s encountered while parsing a CIE", 534 CFIP.callFrameString(Inst.Opcode).str().c_str()); 535 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 536 if (!RegNum) 537 return RegNum.takeError(); 538 if (Optional<UnwindLocation> O = 539 InitialLocs->getRegisterLocation(*RegNum)) 540 Row.getRegisterLocations().setRegisterLocation(*RegNum, *O); 541 else 542 Row.getRegisterLocations().removeRegisterLocation(*RegNum); 543 break; 544 } 545 546 case dwarf::DW_CFA_offset: 547 case dwarf::DW_CFA_offset_extended: 548 case dwarf::DW_CFA_offset_extended_sf: { 549 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 550 if (!RegNum) 551 return RegNum.takeError(); 552 llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1); 553 if (!Offset) 554 return Offset.takeError(); 555 Row.getRegisterLocations().setRegisterLocation( 556 *RegNum, UnwindLocation::createAtCFAPlusOffset(*Offset)); 557 break; 558 } 559 560 case dwarf::DW_CFA_nop: 561 break; 562 563 case dwarf::DW_CFA_remember_state: 564 RegisterStates.push_back(Row.getRegisterLocations()); 565 break; 566 567 case dwarf::DW_CFA_restore_state: 568 if (RegisterStates.empty()) 569 return createStringError(errc::invalid_argument, 570 "DW_CFA_restore_state without a matching " 571 "previous DW_CFA_remember_state"); 572 Row.getRegisterLocations() = RegisterStates.back(); 573 RegisterStates.pop_back(); 574 break; 575 576 case dwarf::DW_CFA_GNU_window_save: 577 switch (CFIP.triple()) { 578 case Triple::aarch64: 579 case Triple::aarch64_be: 580 case Triple::aarch64_32: { 581 // DW_CFA_GNU_window_save is used for different things on different 582 // architectures. For aarch64 it is known as 583 // DW_CFA_AARCH64_negate_ra_state. The action is to toggle the 584 // value of the return address state between 1 and 0. If there is 585 // no rule for the AARCH64_DWARF_PAUTH_RA_STATE register, then it 586 // should be initially set to 1. 587 constexpr uint32_t AArch64DWARFPAuthRaState = 34; 588 auto LRLoc = Row.getRegisterLocations().getRegisterLocation( 589 AArch64DWARFPAuthRaState); 590 if (LRLoc) { 591 if (LRLoc->getLocation() == UnwindLocation::Constant) { 592 // Toggle the constant value from 0 to 1 or 1 to 0. 593 LRLoc->setConstant(LRLoc->getConstant() ^ 1); 594 } else { 595 return createStringError( 596 errc::invalid_argument, 597 "%s encountered when existing rule for this register is not " 598 "a constant", 599 CFIP.callFrameString(Inst.Opcode).str().c_str()); 600 } 601 } else { 602 Row.getRegisterLocations().setRegisterLocation( 603 AArch64DWARFPAuthRaState, UnwindLocation::createIsConstant(1)); 604 } 605 break; 606 } 607 608 case Triple::sparc: 609 case Triple::sparcv9: 610 case Triple::sparcel: 611 for (uint32_t RegNum = 16; RegNum < 32; ++RegNum) { 612 Row.getRegisterLocations().setRegisterLocation( 613 RegNum, UnwindLocation::createAtCFAPlusOffset((RegNum - 16) * 8)); 614 } 615 break; 616 617 default: { 618 return createStringError( 619 errc::not_supported, 620 "DW_CFA opcode %#x is not supported for architecture %s", 621 Inst.Opcode, Triple::getArchTypeName(CFIP.triple()).str().c_str()); 622 623 break; 624 } 625 } 626 break; 627 628 case dwarf::DW_CFA_undefined: { 629 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 630 if (!RegNum) 631 return RegNum.takeError(); 632 Row.getRegisterLocations().setRegisterLocation( 633 *RegNum, UnwindLocation::createUndefined()); 634 break; 635 } 636 637 case dwarf::DW_CFA_same_value: { 638 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 639 if (!RegNum) 640 return RegNum.takeError(); 641 Row.getRegisterLocations().setRegisterLocation( 642 *RegNum, UnwindLocation::createSame()); 643 break; 644 } 645 646 case dwarf::DW_CFA_GNU_args_size: 647 break; 648 649 case dwarf::DW_CFA_register: { 650 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 651 if (!RegNum) 652 return RegNum.takeError(); 653 llvm::Expected<uint64_t> NewRegNum = Inst.getOperandAsUnsigned(CFIP, 1); 654 if (!NewRegNum) 655 return NewRegNum.takeError(); 656 Row.getRegisterLocations().setRegisterLocation( 657 *RegNum, UnwindLocation::createIsRegisterPlusOffset(*NewRegNum, 0)); 658 break; 659 } 660 661 case dwarf::DW_CFA_val_offset: 662 case dwarf::DW_CFA_val_offset_sf: { 663 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 664 if (!RegNum) 665 return RegNum.takeError(); 666 llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1); 667 if (!Offset) 668 return Offset.takeError(); 669 Row.getRegisterLocations().setRegisterLocation( 670 *RegNum, UnwindLocation::createIsCFAPlusOffset(*Offset)); 671 break; 672 } 673 674 case dwarf::DW_CFA_expression: { 675 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 676 if (!RegNum) 677 return RegNum.takeError(); 678 Row.getRegisterLocations().setRegisterLocation( 679 *RegNum, UnwindLocation::createAtDWARFExpression(*Inst.Expression)); 680 break; 681 } 682 683 case dwarf::DW_CFA_val_expression: { 684 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 685 if (!RegNum) 686 return RegNum.takeError(); 687 Row.getRegisterLocations().setRegisterLocation( 688 *RegNum, UnwindLocation::createIsDWARFExpression(*Inst.Expression)); 689 break; 690 } 691 692 case dwarf::DW_CFA_def_cfa_register: { 693 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 694 if (!RegNum) 695 return RegNum.takeError(); 696 if (Row.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset) 697 Row.getCFAValue() = 698 UnwindLocation::createIsRegisterPlusOffset(*RegNum, 0); 699 else 700 Row.getCFAValue().setRegister(*RegNum); 701 break; 702 } 703 704 case dwarf::DW_CFA_def_cfa_offset: 705 case dwarf::DW_CFA_def_cfa_offset_sf: { 706 llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 0); 707 if (!Offset) 708 return Offset.takeError(); 709 if (Row.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset) { 710 return createStringError( 711 errc::invalid_argument, 712 "%s found when CFA rule was not RegPlusOffset", 713 CFIP.callFrameString(Inst.Opcode).str().c_str()); 714 } 715 Row.getCFAValue().setOffset(*Offset); 716 break; 717 } 718 719 case dwarf::DW_CFA_def_cfa: 720 case dwarf::DW_CFA_def_cfa_sf: { 721 llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); 722 if (!RegNum) 723 return RegNum.takeError(); 724 llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1); 725 if (!Offset) 726 return Offset.takeError(); 727 Row.getCFAValue() = 728 UnwindLocation::createIsRegisterPlusOffset(*RegNum, *Offset); 729 break; 730 } 731 732 case dwarf::DW_CFA_def_cfa_expression: 733 Row.getCFAValue() = 734 UnwindLocation::createIsDWARFExpression(*Inst.Expression); 735 break; 736 } 737 } 738 return Error::success(); 739 } 740 741 ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() { 742 static OperandType OpTypes[DW_CFA_restore+1][2]; 743 static bool Initialized = false; 744 if (Initialized) { 745 return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1); 746 } 747 Initialized = true; 748 749 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \ 750 do { \ 751 OpTypes[OP][0] = OPTYPE0; \ 752 OpTypes[OP][1] = OPTYPE1; \ 753 } while (false) 754 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None) 755 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None) 756 757 DECLARE_OP1(DW_CFA_set_loc, OT_Address); 758 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset); 759 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset); 760 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset); 761 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset); 762 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset); 763 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset); 764 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset); 765 DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register); 766 DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset); 767 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset); 768 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression); 769 DECLARE_OP1(DW_CFA_undefined, OT_Register); 770 DECLARE_OP1(DW_CFA_same_value, OT_Register); 771 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset); 772 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset); 773 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset); 774 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset); 775 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset); 776 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register); 777 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression); 778 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression); 779 DECLARE_OP1(DW_CFA_restore, OT_Register); 780 DECLARE_OP1(DW_CFA_restore_extended, OT_Register); 781 DECLARE_OP0(DW_CFA_remember_state); 782 DECLARE_OP0(DW_CFA_restore_state); 783 DECLARE_OP0(DW_CFA_GNU_window_save); 784 DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset); 785 DECLARE_OP0(DW_CFA_nop); 786 787 #undef DECLARE_OP0 788 #undef DECLARE_OP1 789 #undef DECLARE_OP2 790 791 return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1); 792 } 793 794 /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. 795 void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, 796 const MCRegisterInfo *MRI, bool IsEH, 797 const Instruction &Instr, unsigned OperandIdx, 798 uint64_t Operand) const { 799 assert(OperandIdx < 2); 800 uint8_t Opcode = Instr.Opcode; 801 OperandType Type = getOperandTypes()[Opcode][OperandIdx]; 802 803 switch (Type) { 804 case OT_Unset: { 805 OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to"; 806 auto OpcodeName = callFrameString(Opcode); 807 if (!OpcodeName.empty()) 808 OS << " " << OpcodeName; 809 else 810 OS << format(" Opcode %x", Opcode); 811 break; 812 } 813 case OT_None: 814 break; 815 case OT_Address: 816 OS << format(" %" PRIx64, Operand); 817 break; 818 case OT_Offset: 819 // The offsets are all encoded in a unsigned form, but in practice 820 // consumers use them signed. It's most certainly legacy due to 821 // the lack of signed variants in the first Dwarf standards. 822 OS << format(" %+" PRId64, int64_t(Operand)); 823 break; 824 case OT_FactoredCodeOffset: // Always Unsigned 825 if (CodeAlignmentFactor) 826 OS << format(" %" PRId64, Operand * CodeAlignmentFactor); 827 else 828 OS << format(" %" PRId64 "*code_alignment_factor" , Operand); 829 break; 830 case OT_SignedFactDataOffset: 831 if (DataAlignmentFactor) 832 OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor); 833 else 834 OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand)); 835 break; 836 case OT_UnsignedFactDataOffset: 837 if (DataAlignmentFactor) 838 OS << format(" %" PRId64, Operand * DataAlignmentFactor); 839 else 840 OS << format(" %" PRId64 "*data_alignment_factor" , Operand); 841 break; 842 case OT_Register: 843 OS << ' '; 844 printRegister(OS, MRI, IsEH, Operand); 845 break; 846 case OT_Expression: 847 assert(Instr.Expression && "missing DWARFExpression object"); 848 OS << " "; 849 Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH); 850 break; 851 } 852 } 853 854 void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts, 855 const MCRegisterInfo *MRI, bool IsEH, 856 unsigned IndentLevel) const { 857 for (const auto &Instr : Instructions) { 858 uint8_t Opcode = Instr.Opcode; 859 OS.indent(2 * IndentLevel); 860 OS << callFrameString(Opcode) << ":"; 861 for (unsigned i = 0; i < Instr.Ops.size(); ++i) 862 printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]); 863 OS << '\n'; 864 } 865 } 866 867 // Returns the CIE identifier to be used by the requested format. 868 // CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5. 869 // For CIE ID in .eh_frame sections see 870 // https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html 871 constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) { 872 if (IsEH) 873 return 0; 874 if (IsDWARF64) 875 return DW64_CIE_ID; 876 return DW_CIE_ID; 877 } 878 879 void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, 880 const MCRegisterInfo *MRI, bool IsEH) const { 881 // A CIE with a zero length is a terminator entry in the .eh_frame section. 882 if (IsEH && Length == 0) { 883 OS << format("%08" PRIx64, Offset) << " ZERO terminator\n"; 884 return; 885 } 886 887 OS << format("%08" PRIx64, Offset) 888 << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) 889 << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, 890 getCIEId(IsDWARF64, IsEH)) 891 << " CIE\n" 892 << " Format: " << FormatString(IsDWARF64) << "\n" 893 << format(" Version: %d\n", Version) 894 << " Augmentation: \"" << Augmentation << "\"\n"; 895 if (Version >= 4) { 896 OS << format(" Address size: %u\n", (uint32_t)AddressSize); 897 OS << format(" Segment desc size: %u\n", 898 (uint32_t)SegmentDescriptorSize); 899 } 900 OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor); 901 OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor); 902 OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister); 903 if (Personality) 904 OS << format(" Personality Address: %016" PRIx64 "\n", *Personality); 905 if (!AugmentationData.empty()) { 906 OS << " Augmentation data: "; 907 for (uint8_t Byte : AugmentationData) 908 OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf); 909 OS << "\n"; 910 } 911 OS << "\n"; 912 CFIs.dump(OS, DumpOpts, MRI, IsEH); 913 OS << "\n"; 914 915 if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this)) 916 RowsOrErr->dump(OS, MRI, IsEH, 1); 917 else { 918 DumpOpts.RecoverableErrorHandler(joinErrors( 919 createStringError(errc::invalid_argument, 920 "decoding the CIE opcodes into rows failed"), 921 RowsOrErr.takeError())); 922 } 923 OS << "\n"; 924 } 925 926 void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, 927 const MCRegisterInfo *MRI, bool IsEH) const { 928 OS << format("%08" PRIx64, Offset) 929 << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) 930 << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer) 931 << " FDE cie="; 932 if (LinkedCIE) 933 OS << format("%08" PRIx64, LinkedCIE->getOffset()); 934 else 935 OS << "<invalid offset>"; 936 OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation, 937 InitialLocation + AddressRange); 938 OS << " Format: " << FormatString(IsDWARF64) << "\n"; 939 if (LSDAAddress) 940 OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); 941 CFIs.dump(OS, DumpOpts, MRI, IsEH); 942 OS << "\n"; 943 944 if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this)) 945 RowsOrErr->dump(OS, MRI, IsEH, 1); 946 else { 947 DumpOpts.RecoverableErrorHandler(joinErrors( 948 createStringError(errc::invalid_argument, 949 "decoding the FDE opcodes into rows failed"), 950 RowsOrErr.takeError())); 951 } 952 OS << "\n"; 953 } 954 955 DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch, 956 bool IsEH, uint64_t EHFrameAddress) 957 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {} 958 959 DWARFDebugFrame::~DWARFDebugFrame() = default; 960 961 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 962 uint64_t Offset, int Length) { 963 errs() << "DUMP: "; 964 for (int i = 0; i < Length; ++i) { 965 uint8_t c = Data.getU8(&Offset); 966 errs().write_hex(c); errs() << " "; 967 } 968 errs() << "\n"; 969 } 970 971 Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { 972 uint64_t Offset = 0; 973 DenseMap<uint64_t, CIE *> CIEs; 974 975 while (Data.isValidOffset(Offset)) { 976 uint64_t StartOffset = Offset; 977 978 uint64_t Length; 979 DwarfFormat Format; 980 std::tie(Length, Format) = Data.getInitialLength(&Offset); 981 bool IsDWARF64 = Format == DWARF64; 982 983 // If the Length is 0, then this CIE is a terminator. We add it because some 984 // dumper tools might need it to print something special for such entries 985 // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator"). 986 if (Length == 0) { 987 auto Cie = std::make_unique<CIE>( 988 IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0, 989 SmallString<8>(), 0, 0, None, None, Arch); 990 CIEs[StartOffset] = Cie.get(); 991 Entries.push_back(std::move(Cie)); 992 break; 993 } 994 995 // At this point, Offset points to the next field after Length. 996 // Length is the structure size excluding itself. Compute an offset one 997 // past the end of the structure (needed to know how many instructions to 998 // read). 999 uint64_t StartStructureOffset = Offset; 1000 uint64_t EndStructureOffset = Offset + Length; 1001 1002 // The Id field's size depends on the DWARF format 1003 Error Err = Error::success(); 1004 uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset, 1005 /*SectionIndex=*/nullptr, &Err); 1006 if (Err) 1007 return Err; 1008 1009 if (Id == getCIEId(IsDWARF64, IsEH)) { 1010 uint8_t Version = Data.getU8(&Offset); 1011 const char *Augmentation = Data.getCStr(&Offset); 1012 StringRef AugmentationString(Augmentation ? Augmentation : ""); 1013 // TODO: we should provide a way to report a warning and continue dumping. 1014 if (IsEH && Version != 1) 1015 return createStringError(errc::not_supported, 1016 "unsupported CIE version: %" PRIu8, Version); 1017 1018 uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : 1019 Data.getU8(&Offset); 1020 Data.setAddressSize(AddressSize); 1021 uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset); 1022 uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 1023 int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 1024 uint64_t ReturnAddressRegister = 1025 Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset); 1026 1027 // Parse the augmentation data for EH CIEs 1028 StringRef AugmentationData(""); 1029 uint32_t FDEPointerEncoding = DW_EH_PE_absptr; 1030 uint32_t LSDAPointerEncoding = DW_EH_PE_omit; 1031 Optional<uint64_t> Personality; 1032 Optional<uint32_t> PersonalityEncoding; 1033 if (IsEH) { 1034 Optional<uint64_t> AugmentationLength; 1035 uint64_t StartAugmentationOffset; 1036 uint64_t EndAugmentationOffset; 1037 1038 // Walk the augmentation string to get all the augmentation data. 1039 for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { 1040 switch (AugmentationString[i]) { 1041 default: 1042 return createStringError( 1043 errc::invalid_argument, 1044 "unknown augmentation character in entry at 0x%" PRIx64, 1045 StartOffset); 1046 case 'L': 1047 LSDAPointerEncoding = Data.getU8(&Offset); 1048 break; 1049 case 'P': { 1050 if (Personality) 1051 return createStringError( 1052 errc::invalid_argument, 1053 "duplicate personality in entry at 0x%" PRIx64, StartOffset); 1054 PersonalityEncoding = Data.getU8(&Offset); 1055 Personality = Data.getEncodedPointer( 1056 &Offset, *PersonalityEncoding, 1057 EHFrameAddress ? EHFrameAddress + Offset : 0); 1058 break; 1059 } 1060 case 'R': 1061 FDEPointerEncoding = Data.getU8(&Offset); 1062 break; 1063 case 'S': 1064 // Current frame is a signal trampoline. 1065 break; 1066 case 'z': 1067 if (i) 1068 return createStringError( 1069 errc::invalid_argument, 1070 "'z' must be the first character at 0x%" PRIx64, StartOffset); 1071 // Parse the augmentation length first. We only parse it if 1072 // the string contains a 'z'. 1073 AugmentationLength = Data.getULEB128(&Offset); 1074 StartAugmentationOffset = Offset; 1075 EndAugmentationOffset = Offset + *AugmentationLength; 1076 break; 1077 case 'B': 1078 // B-Key is used for signing functions associated with this 1079 // augmentation string 1080 break; 1081 } 1082 } 1083 1084 if (AugmentationLength.hasValue()) { 1085 if (Offset != EndAugmentationOffset) 1086 return createStringError(errc::invalid_argument, 1087 "parsing augmentation data at 0x%" PRIx64 1088 " failed", 1089 StartOffset); 1090 AugmentationData = Data.getData().slice(StartAugmentationOffset, 1091 EndAugmentationOffset); 1092 } 1093 } 1094 1095 auto Cie = std::make_unique<CIE>( 1096 IsDWARF64, StartOffset, Length, Version, AugmentationString, 1097 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor, 1098 DataAlignmentFactor, ReturnAddressRegister, AugmentationData, 1099 FDEPointerEncoding, LSDAPointerEncoding, Personality, 1100 PersonalityEncoding, Arch); 1101 CIEs[StartOffset] = Cie.get(); 1102 Entries.emplace_back(std::move(Cie)); 1103 } else { 1104 // FDE 1105 uint64_t CIEPointer = Id; 1106 uint64_t InitialLocation = 0; 1107 uint64_t AddressRange = 0; 1108 Optional<uint64_t> LSDAAddress; 1109 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer]; 1110 1111 if (IsEH) { 1112 // The address size is encoded in the CIE we reference. 1113 if (!Cie) 1114 return createStringError(errc::invalid_argument, 1115 "parsing FDE data at 0x%" PRIx64 1116 " failed due to missing CIE", 1117 StartOffset); 1118 if (auto Val = 1119 Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(), 1120 EHFrameAddress + Offset)) { 1121 InitialLocation = *Val; 1122 } 1123 if (auto Val = Data.getEncodedPointer( 1124 &Offset, Cie->getFDEPointerEncoding(), 0)) { 1125 AddressRange = *Val; 1126 } 1127 1128 StringRef AugmentationString = Cie->getAugmentationString(); 1129 if (!AugmentationString.empty()) { 1130 // Parse the augmentation length and data for this FDE. 1131 uint64_t AugmentationLength = Data.getULEB128(&Offset); 1132 1133 uint64_t EndAugmentationOffset = Offset + AugmentationLength; 1134 1135 // Decode the LSDA if the CIE augmentation string said we should. 1136 if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) { 1137 LSDAAddress = Data.getEncodedPointer( 1138 &Offset, Cie->getLSDAPointerEncoding(), 1139 EHFrameAddress ? Offset + EHFrameAddress : 0); 1140 } 1141 1142 if (Offset != EndAugmentationOffset) 1143 return createStringError(errc::invalid_argument, 1144 "parsing augmentation data at 0x%" PRIx64 1145 " failed", 1146 StartOffset); 1147 } 1148 } else { 1149 InitialLocation = Data.getRelocatedAddress(&Offset); 1150 AddressRange = Data.getRelocatedAddress(&Offset); 1151 } 1152 1153 Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer, 1154 InitialLocation, AddressRange, Cie, 1155 LSDAAddress, Arch)); 1156 } 1157 1158 if (Error E = 1159 Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset)) 1160 return E; 1161 1162 if (Offset != EndStructureOffset) 1163 return createStringError( 1164 errc::invalid_argument, 1165 "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset); 1166 } 1167 1168 return Error::success(); 1169 } 1170 1171 FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const { 1172 auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) { 1173 return E->getOffset() < Offset; 1174 }); 1175 if (It != Entries.end() && (*It)->getOffset() == Offset) 1176 return It->get(); 1177 return nullptr; 1178 } 1179 1180 void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts, 1181 const MCRegisterInfo *MRI, 1182 Optional<uint64_t> Offset) const { 1183 if (Offset) { 1184 if (auto *Entry = getEntryAtOffset(*Offset)) 1185 Entry->dump(OS, DumpOpts, MRI, IsEH); 1186 return; 1187 } 1188 1189 OS << "\n"; 1190 for (const auto &Entry : Entries) 1191 Entry->dump(OS, DumpOpts, MRI, IsEH); 1192 } 1193