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