1 //===- DWARFFormValue.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/DWARFFormValue.h" 11 #include "SyntaxHighlighting.h" 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/None.h" 14 #include "llvm/ADT/Optional.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/BinaryFormat/Dwarf.h" 17 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 18 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 19 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/Format.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include <cinttypes> 24 #include <cstdint> 25 #include <limits> 26 27 using namespace llvm; 28 using namespace dwarf; 29 using namespace syntax; 30 31 static const DWARFFormValue::FormClass DWARF5FormClasses[] = { 32 DWARFFormValue::FC_Unknown, // 0x0 33 DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr 34 DWARFFormValue::FC_Unknown, // 0x02 unused 35 DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2 36 DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4 37 DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2 38 // --- These can be FC_SectionOffset in DWARF3 and below: 39 DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4 40 DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8 41 // --- 42 DWARFFormValue::FC_String, // 0x08 DW_FORM_string 43 DWARFFormValue::FC_Block, // 0x09 DW_FORM_block 44 DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1 45 DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1 46 DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag 47 DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata 48 DWARFFormValue::FC_String, // 0x0e DW_FORM_strp 49 DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata 50 DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr 51 DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1 52 DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2 53 DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4 54 DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8 55 DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata 56 DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect 57 DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset 58 DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc 59 DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present 60 DWARFFormValue::FC_String, // 0x1a DW_FORM_strx 61 DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx 62 DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4 63 DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup 64 DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16 65 DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp 66 DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8 67 DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const 68 DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx 69 DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx 70 DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8 71 DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1 72 DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2 73 DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3 74 DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4 75 DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1 76 DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2 77 DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3 78 DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4 79 80 }; 81 82 Optional<uint8_t> 83 DWARFFormValue::getFixedByteSize(dwarf::Form Form, 84 const DWARFFormParams Params) { 85 switch (Form) { 86 case DW_FORM_addr: 87 if (Params) 88 return Params.AddrSize; 89 return None; 90 91 case DW_FORM_block: // ULEB128 length L followed by L bytes. 92 case DW_FORM_block1: // 1 byte length L followed by L bytes. 93 case DW_FORM_block2: // 2 byte length L followed by L bytes. 94 case DW_FORM_block4: // 4 byte length L followed by L bytes. 95 case DW_FORM_string: // C-string with null terminator. 96 case DW_FORM_sdata: // SLEB128. 97 case DW_FORM_udata: // ULEB128. 98 case DW_FORM_ref_udata: // ULEB128. 99 case DW_FORM_indirect: // ULEB128. 100 case DW_FORM_exprloc: // ULEB128 length L followed by L bytes. 101 case DW_FORM_strx: // ULEB128. 102 case DW_FORM_addrx: // ULEB128. 103 case DW_FORM_loclistx: // ULEB128. 104 case DW_FORM_rnglistx: // ULEB128. 105 case DW_FORM_GNU_addr_index: // ULEB128. 106 case DW_FORM_GNU_str_index: // ULEB128. 107 return None; 108 109 case DW_FORM_ref_addr: 110 if (Params) 111 return Params.getRefAddrByteSize(); 112 return None; 113 114 case DW_FORM_flag: 115 case DW_FORM_data1: 116 case DW_FORM_ref1: 117 case DW_FORM_strx1: 118 case DW_FORM_addrx1: 119 return 1; 120 121 case DW_FORM_data2: 122 case DW_FORM_ref2: 123 case DW_FORM_strx2: 124 case DW_FORM_addrx2: 125 return 2; 126 127 case DW_FORM_strx3: 128 return 3; 129 130 case DW_FORM_data4: 131 case DW_FORM_ref4: 132 case DW_FORM_ref_sup4: 133 case DW_FORM_strx4: 134 case DW_FORM_addrx4: 135 return 4; 136 137 case DW_FORM_strp: 138 case DW_FORM_GNU_ref_alt: 139 case DW_FORM_GNU_strp_alt: 140 case DW_FORM_line_strp: 141 case DW_FORM_sec_offset: 142 case DW_FORM_strp_sup: 143 if (Params) 144 return Params.getDwarfOffsetByteSize(); 145 return None; 146 147 case DW_FORM_data8: 148 case DW_FORM_ref8: 149 case DW_FORM_ref_sig8: 150 case DW_FORM_ref_sup8: 151 return 8; 152 153 case DW_FORM_flag_present: 154 return 0; 155 156 case DW_FORM_data16: 157 return 16; 158 159 case DW_FORM_implicit_const: 160 // The implicit value is stored in the abbreviation as a SLEB128, and 161 // there no data in debug info. 162 return 0; 163 164 default: 165 llvm_unreachable("Handle this form in this switch statement"); 166 } 167 return None; 168 } 169 170 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 171 uint32_t *OffsetPtr, 172 const DWARFFormParams Params) { 173 bool Indirect = false; 174 do { 175 switch (Form) { 176 // Blocks of inlined data that have a length field and the data bytes 177 // inlined in the .debug_info. 178 case DW_FORM_exprloc: 179 case DW_FORM_block: { 180 uint64_t size = DebugInfoData.getULEB128(OffsetPtr); 181 *OffsetPtr += size; 182 return true; 183 } 184 case DW_FORM_block1: { 185 uint8_t size = DebugInfoData.getU8(OffsetPtr); 186 *OffsetPtr += size; 187 return true; 188 } 189 case DW_FORM_block2: { 190 uint16_t size = DebugInfoData.getU16(OffsetPtr); 191 *OffsetPtr += size; 192 return true; 193 } 194 case DW_FORM_block4: { 195 uint32_t size = DebugInfoData.getU32(OffsetPtr); 196 *OffsetPtr += size; 197 return true; 198 } 199 200 // Inlined NULL terminated C-strings. 201 case DW_FORM_string: 202 DebugInfoData.getCStr(OffsetPtr); 203 return true; 204 205 case DW_FORM_addr: 206 case DW_FORM_ref_addr: 207 case DW_FORM_flag_present: 208 case DW_FORM_data1: 209 case DW_FORM_data2: 210 case DW_FORM_data4: 211 case DW_FORM_data8: 212 case DW_FORM_data16: 213 case DW_FORM_flag: 214 case DW_FORM_ref1: 215 case DW_FORM_ref2: 216 case DW_FORM_ref4: 217 case DW_FORM_ref8: 218 case DW_FORM_ref_sig8: 219 case DW_FORM_ref_sup4: 220 case DW_FORM_ref_sup8: 221 case DW_FORM_strx1: 222 case DW_FORM_strx2: 223 case DW_FORM_strx4: 224 case DW_FORM_addrx1: 225 case DW_FORM_addrx2: 226 case DW_FORM_addrx4: 227 case DW_FORM_sec_offset: 228 case DW_FORM_strp: 229 case DW_FORM_strp_sup: 230 case DW_FORM_line_strp: 231 case DW_FORM_GNU_ref_alt: 232 case DW_FORM_GNU_strp_alt: 233 if (Optional<uint8_t> FixedSize = 234 DWARFFormValue::getFixedByteSize(Form, Params)) { 235 *OffsetPtr += *FixedSize; 236 return true; 237 } 238 return false; 239 240 // signed or unsigned LEB 128 values. 241 case DW_FORM_sdata: 242 DebugInfoData.getSLEB128(OffsetPtr); 243 return true; 244 245 case DW_FORM_udata: 246 case DW_FORM_ref_udata: 247 case DW_FORM_strx: 248 case DW_FORM_addrx: 249 case DW_FORM_loclistx: 250 case DW_FORM_rnglistx: 251 case DW_FORM_GNU_addr_index: 252 case DW_FORM_GNU_str_index: 253 DebugInfoData.getULEB128(OffsetPtr); 254 return true; 255 256 case DW_FORM_indirect: 257 Indirect = true; 258 Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr)); 259 break; 260 261 default: 262 return false; 263 } 264 } while (Indirect); 265 return true; 266 } 267 268 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { 269 // First, check DWARF5 form classes. 270 if (Form < makeArrayRef(DWARF5FormClasses).size() && 271 DWARF5FormClasses[Form] == FC) 272 return true; 273 // Check more forms from extensions and proposals. 274 switch (Form) { 275 case DW_FORM_GNU_ref_alt: 276 return (FC == FC_Reference); 277 case DW_FORM_GNU_addr_index: 278 return (FC == FC_Address); 279 case DW_FORM_GNU_str_index: 280 case DW_FORM_GNU_strp_alt: 281 return (FC == FC_String); 282 default: 283 break; 284 } 285 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset. 286 // Don't check for DWARF version here, as some producers may still do this 287 // by mistake. Also accept DW_FORM_[line_]strp since these are 288 // .debug_[line_]str section offsets. 289 return (Form == DW_FORM_data4 || Form == DW_FORM_data8 || 290 Form == DW_FORM_strp || Form == DW_FORM_line_strp) && 291 FC == FC_SectionOffset; 292 } 293 294 bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, 295 uint32_t *OffsetPtr, DWARFFormParams FP, 296 const DWARFContext *Ctx, 297 const DWARFUnit *CU) { 298 if (!Ctx && CU) 299 Ctx = &CU->getContext(); 300 C = Ctx; 301 U = CU; 302 bool Indirect = false; 303 bool IsBlock = false; 304 Value.data = nullptr; 305 // Read the value for the form into value and follow and DW_FORM_indirect 306 // instances we run into 307 do { 308 Indirect = false; 309 switch (Form) { 310 case DW_FORM_addr: 311 case DW_FORM_ref_addr: { 312 uint16_t Size = 313 (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize(); 314 Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex); 315 break; 316 } 317 case DW_FORM_exprloc: 318 case DW_FORM_block: 319 Value.uval = Data.getULEB128(OffsetPtr); 320 IsBlock = true; 321 break; 322 case DW_FORM_block1: 323 Value.uval = Data.getU8(OffsetPtr); 324 IsBlock = true; 325 break; 326 case DW_FORM_block2: 327 Value.uval = Data.getU16(OffsetPtr); 328 IsBlock = true; 329 break; 330 case DW_FORM_block4: 331 Value.uval = Data.getU32(OffsetPtr); 332 IsBlock = true; 333 break; 334 case DW_FORM_data1: 335 case DW_FORM_ref1: 336 case DW_FORM_flag: 337 case DW_FORM_strx1: 338 case DW_FORM_addrx1: 339 Value.uval = Data.getU8(OffsetPtr); 340 break; 341 case DW_FORM_data2: 342 case DW_FORM_ref2: 343 case DW_FORM_strx2: 344 case DW_FORM_addrx2: 345 Value.uval = Data.getU16(OffsetPtr); 346 break; 347 case DW_FORM_strx3: 348 Value.uval = Data.getU24(OffsetPtr); 349 break; 350 case DW_FORM_data4: 351 case DW_FORM_ref4: 352 case DW_FORM_ref_sup4: 353 case DW_FORM_strx4: 354 case DW_FORM_addrx4: 355 Value.uval = Data.getRelocatedValue(4, OffsetPtr); 356 break; 357 case DW_FORM_data8: 358 case DW_FORM_ref8: 359 case DW_FORM_ref_sup8: 360 Value.uval = Data.getU64(OffsetPtr); 361 break; 362 case DW_FORM_data16: 363 // Treat this like a 16-byte block. 364 Value.uval = 16; 365 IsBlock = true; 366 break; 367 case DW_FORM_sdata: 368 Value.sval = Data.getSLEB128(OffsetPtr); 369 break; 370 case DW_FORM_udata: 371 case DW_FORM_ref_udata: 372 Value.uval = Data.getULEB128(OffsetPtr); 373 break; 374 case DW_FORM_string: 375 Value.cstr = Data.getCStr(OffsetPtr); 376 break; 377 case DW_FORM_indirect: 378 Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr)); 379 Indirect = true; 380 break; 381 case DW_FORM_strp: 382 case DW_FORM_sec_offset: 383 case DW_FORM_GNU_ref_alt: 384 case DW_FORM_GNU_strp_alt: 385 case DW_FORM_line_strp: 386 case DW_FORM_strp_sup: { 387 Value.uval = 388 Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr); 389 break; 390 } 391 case DW_FORM_flag_present: 392 Value.uval = 1; 393 break; 394 case DW_FORM_ref_sig8: 395 Value.uval = Data.getU64(OffsetPtr); 396 break; 397 case DW_FORM_GNU_addr_index: 398 case DW_FORM_GNU_str_index: 399 case DW_FORM_strx: 400 Value.uval = Data.getULEB128(OffsetPtr); 401 break; 402 default: 403 // DWARFFormValue::skipValue() will have caught this and caused all 404 // DWARF DIEs to fail to be parsed, so this code is not be reachable. 405 llvm_unreachable("unsupported form"); 406 } 407 } while (Indirect); 408 409 if (IsBlock) { 410 StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval); 411 Value.data = nullptr; 412 if (!Str.empty()) { 413 Value.data = reinterpret_cast<const uint8_t *>(Str.data()); 414 *OffsetPtr += Value.uval; 415 } 416 } 417 418 return true; 419 } 420 421 void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { 422 uint64_t UValue = Value.uval; 423 bool CURelativeOffset = false; 424 raw_ostream &AddrOS = 425 DumpOpts.ShowAddresses ? WithColor(OS, syntax::Address).get() : nulls(); 426 switch (Form) { 427 case DW_FORM_addr: 428 AddrOS << format("0x%016" PRIx64, UValue); 429 break; 430 case DW_FORM_GNU_addr_index: { 431 AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue); 432 uint64_t Address; 433 if (U == nullptr) 434 OS << "<invalid dwarf unit>"; 435 else if (U->getAddrOffsetSectionItem(UValue, Address)) 436 AddrOS << format("0x%016" PRIx64, Address); 437 else 438 OS << "<no .debug_addr section>"; 439 break; 440 } 441 case DW_FORM_flag_present: 442 OS << "true"; 443 break; 444 case DW_FORM_flag: 445 case DW_FORM_data1: 446 OS << format("0x%02x", (uint8_t)UValue); 447 break; 448 case DW_FORM_data2: 449 OS << format("0x%04x", (uint16_t)UValue); 450 break; 451 case DW_FORM_data4: 452 OS << format("0x%08x", (uint32_t)UValue); 453 break; 454 case DW_FORM_ref_sig8: 455 AddrOS << format("0x%016" PRIx64, UValue); 456 break; 457 case DW_FORM_data8: 458 OS << format("0x%016" PRIx64, UValue); 459 break; 460 case DW_FORM_data16: 461 OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16); 462 break; 463 case DW_FORM_string: 464 OS << '"'; 465 OS.write_escaped(Value.cstr); 466 OS << '"'; 467 break; 468 case DW_FORM_exprloc: 469 case DW_FORM_block: 470 case DW_FORM_block1: 471 case DW_FORM_block2: 472 case DW_FORM_block4: 473 if (UValue > 0) { 474 switch (Form) { 475 case DW_FORM_exprloc: 476 case DW_FORM_block: 477 OS << format("<0x%" PRIx64 "> ", UValue); 478 break; 479 case DW_FORM_block1: 480 OS << format("<0x%2.2x> ", (uint8_t)UValue); 481 break; 482 case DW_FORM_block2: 483 OS << format("<0x%4.4x> ", (uint16_t)UValue); 484 break; 485 case DW_FORM_block4: 486 OS << format("<0x%8.8x> ", (uint32_t)UValue); 487 break; 488 default: 489 break; 490 } 491 492 const uint8_t *DataPtr = Value.data; 493 if (DataPtr) { 494 // UValue contains size of block 495 const uint8_t *EndDataPtr = DataPtr + UValue; 496 while (DataPtr < EndDataPtr) { 497 OS << format("%2.2x ", *DataPtr); 498 ++DataPtr; 499 } 500 } else 501 OS << "NULL"; 502 } 503 break; 504 505 case DW_FORM_sdata: 506 OS << Value.sval; 507 break; 508 case DW_FORM_udata: 509 OS << Value.uval; 510 break; 511 case DW_FORM_strp: 512 if (DumpOpts.Verbose) 513 OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue); 514 dumpString(OS); 515 break; 516 case DW_FORM_line_strp: 517 if (DumpOpts.Verbose) 518 OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue); 519 dumpString(OS); 520 break; 521 case DW_FORM_strx: 522 case DW_FORM_strx1: 523 case DW_FORM_strx2: 524 case DW_FORM_strx3: 525 case DW_FORM_strx4: 526 case DW_FORM_GNU_str_index: 527 if (DumpOpts.Verbose) 528 OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue); 529 dumpString(OS); 530 break; 531 case DW_FORM_GNU_strp_alt: 532 if (DumpOpts.Verbose) 533 OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue); 534 dumpString(OS); 535 break; 536 case DW_FORM_ref_addr: 537 AddrOS << format("0x%016" PRIx64, UValue); 538 break; 539 case DW_FORM_ref1: 540 CURelativeOffset = true; 541 AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue); 542 break; 543 case DW_FORM_ref2: 544 CURelativeOffset = true; 545 AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue); 546 break; 547 case DW_FORM_ref4: 548 CURelativeOffset = true; 549 AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue); 550 break; 551 case DW_FORM_ref8: 552 CURelativeOffset = true; 553 AddrOS << format("cu + 0x%8.8" PRIx64, UValue); 554 break; 555 case DW_FORM_ref_udata: 556 CURelativeOffset = true; 557 AddrOS << format("cu + 0x%" PRIx64, UValue); 558 break; 559 case DW_FORM_GNU_ref_alt: 560 AddrOS << format("<alt 0x%" PRIx64 ">", UValue); 561 break; 562 563 // All DW_FORM_indirect attributes should be resolved prior to calling 564 // this function 565 case DW_FORM_indirect: 566 OS << "DW_FORM_indirect"; 567 break; 568 569 // Should be formatted to 64-bit for DWARF64. 570 case DW_FORM_sec_offset: 571 AddrOS << format("0x%08x", (uint32_t)UValue); 572 break; 573 574 default: 575 OS << format("DW_FORM(0x%4.4x)", Form); 576 break; 577 } 578 579 if (CURelativeOffset && DumpOpts.Verbose) { 580 OS << " => {"; 581 WithColor(OS, syntax::Address).get() 582 << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0)); 583 OS << "}"; 584 } 585 } 586 587 void DWARFFormValue::dumpString(raw_ostream &OS) const { 588 Optional<const char *> DbgStr = getAsCString(); 589 if (DbgStr.hasValue()) { 590 auto COS = WithColor(OS, syntax::String); 591 COS.get() << '"'; 592 COS.get().write_escaped(DbgStr.getValue()); 593 COS.get() << '"'; 594 } 595 } 596 597 Optional<const char *> DWARFFormValue::getAsCString() const { 598 if (!isFormClass(FC_String)) 599 return None; 600 if (Form == DW_FORM_string) 601 return Value.cstr; 602 // FIXME: Add support for DW_FORM_GNU_strp_alt 603 if (Form == DW_FORM_GNU_strp_alt || C == nullptr) 604 return None; 605 uint32_t Offset = Value.uval; 606 if (Form == DW_FORM_line_strp) { 607 // .debug_line_str is tracked in the Context. 608 if (const char *Str = C->getLineStringExtractor().getCStr(&Offset)) 609 return Str; 610 return None; 611 } 612 if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx || 613 Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 || 614 Form == DW_FORM_strx4) { 615 uint64_t StrOffset; 616 if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset)) 617 return None; 618 Offset = StrOffset; 619 } 620 // Prefer the Unit's string extractor, because for .dwo it will point to 621 // .debug_str.dwo, while the Context's extractor always uses .debug_str. 622 if (U) { 623 if (const char *Str = U->getStringExtractor().getCStr(&Offset)) 624 return Str; 625 return None; 626 } 627 if (const char *Str = C->getStringExtractor().getCStr(&Offset)) 628 return Str; 629 return None; 630 } 631 632 Optional<uint64_t> DWARFFormValue::getAsAddress() const { 633 if (!isFormClass(FC_Address)) 634 return None; 635 if (Form == DW_FORM_GNU_addr_index) { 636 uint32_t Index = Value.uval; 637 uint64_t Result; 638 if (!U || !U->getAddrOffsetSectionItem(Index, Result)) 639 return None; 640 return Result; 641 } 642 return Value.uval; 643 } 644 645 Optional<uint64_t> DWARFFormValue::getAsReference() const { 646 if (!isFormClass(FC_Reference)) 647 return None; 648 switch (Form) { 649 case DW_FORM_ref1: 650 case DW_FORM_ref2: 651 case DW_FORM_ref4: 652 case DW_FORM_ref8: 653 case DW_FORM_ref_udata: 654 if (!U) 655 return None; 656 return Value.uval + U->getOffset(); 657 case DW_FORM_ref_addr: 658 case DW_FORM_ref_sig8: 659 case DW_FORM_GNU_ref_alt: 660 return Value.uval; 661 default: 662 return None; 663 } 664 } 665 666 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { 667 if (!isFormClass(FC_SectionOffset)) 668 return None; 669 return Value.uval; 670 } 671 672 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { 673 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || 674 Form == DW_FORM_sdata) 675 return None; 676 return Value.uval; 677 } 678 679 Optional<int64_t> DWARFFormValue::getAsSignedConstant() const { 680 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || 681 (Form == DW_FORM_udata && 682 uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval)) 683 return None; 684 switch (Form) { 685 case DW_FORM_data4: 686 return int32_t(Value.uval); 687 case DW_FORM_data2: 688 return int16_t(Value.uval); 689 case DW_FORM_data1: 690 return int8_t(Value.uval); 691 case DW_FORM_sdata: 692 case DW_FORM_data8: 693 default: 694 return Value.sval; 695 } 696 } 697 698 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { 699 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) && 700 Form != DW_FORM_data16) 701 return None; 702 return makeArrayRef(Value.data, Value.uval); 703 } 704 705 Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const { 706 if (!isFormClass(FC_String) && Form == DW_FORM_string) 707 return None; 708 return Value.uval; 709 } 710 711 Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const { 712 if (!isFormClass(FC_Reference)) 713 return None; 714 return Value.uval; 715 } 716