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