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