1283625Sdim//===-- DWARFFormValue.cpp ------------------------------------------------===// 2283625Sdim// 3283625Sdim// The LLVM Compiler Infrastructure 4283625Sdim// 5283625Sdim// This file is distributed under the University of Illinois Open Source 6283625Sdim// License. See LICENSE.TXT for details. 7283625Sdim// 8283625Sdim//===----------------------------------------------------------------------===// 9283625Sdim 10283625Sdim#include "SyntaxHighlighting.h" 11283625Sdim#include "llvm/ADT/ArrayRef.h" 12283625Sdim#include "llvm/ADT/StringRef.h" 13283625Sdim#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 14283625Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h" 15283625Sdim#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 16283625Sdim#include "llvm/Support/Debug.h" 17283625Sdim#include "llvm/Support/Dwarf.h" 18283625Sdim#include "llvm/Support/Format.h" 19283625Sdim#include "llvm/Support/raw_ostream.h" 20283625Sdim#include <cassert> 21296417Sdim#include <limits> 22283625Sdimusing namespace llvm; 23283625Sdimusing namespace dwarf; 24283625Sdimusing namespace syntax; 25283625Sdim 26283625Sdimnamespace { 27283625Sdimuint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { 28283625Sdim // FIXME: Support DWARF64. 29283625Sdim return (Version == 2) ? AddrSize : 4; 30283625Sdim} 31283625Sdim 32283625Sdimtemplate <uint8_t AddrSize, uint8_t RefAddrSize> 33283625SdimArrayRef<uint8_t> makeFixedFormSizesArrayRef() { 34283625Sdim static const uint8_t sizes[] = { 35283625Sdim 0, // 0x00 unused 36283625Sdim AddrSize, // 0x01 DW_FORM_addr 37283625Sdim 0, // 0x02 unused 38283625Sdim 0, // 0x03 DW_FORM_block2 39283625Sdim 0, // 0x04 DW_FORM_block4 40283625Sdim 2, // 0x05 DW_FORM_data2 41283625Sdim 4, // 0x06 DW_FORM_data4 42283625Sdim 8, // 0x07 DW_FORM_data8 43283625Sdim 0, // 0x08 DW_FORM_string 44283625Sdim 0, // 0x09 DW_FORM_block 45283625Sdim 0, // 0x0a DW_FORM_block1 46283625Sdim 1, // 0x0b DW_FORM_data1 47283625Sdim 1, // 0x0c DW_FORM_flag 48283625Sdim 0, // 0x0d DW_FORM_sdata 49283625Sdim 4, // 0x0e DW_FORM_strp 50283625Sdim 0, // 0x0f DW_FORM_udata 51283625Sdim RefAddrSize, // 0x10 DW_FORM_ref_addr 52283625Sdim 1, // 0x11 DW_FORM_ref1 53283625Sdim 2, // 0x12 DW_FORM_ref2 54283625Sdim 4, // 0x13 DW_FORM_ref4 55283625Sdim 8, // 0x14 DW_FORM_ref8 56283625Sdim 0, // 0x15 DW_FORM_ref_udata 57283625Sdim 0, // 0x16 DW_FORM_indirect 58283625Sdim 4, // 0x17 DW_FORM_sec_offset 59283625Sdim 0, // 0x18 DW_FORM_exprloc 60283625Sdim 0, // 0x19 DW_FORM_flag_present 61283625Sdim }; 62283625Sdim return makeArrayRef(sizes); 63283625Sdim} 64285181Sdim} 65283625Sdim 66283625SdimArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize, 67283625Sdim uint16_t Version) { 68283625Sdim uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version); 69283625Sdim if (AddrSize == 4 && RefAddrSize == 4) 70283625Sdim return makeFixedFormSizesArrayRef<4, 4>(); 71283625Sdim if (AddrSize == 4 && RefAddrSize == 8) 72283625Sdim return makeFixedFormSizesArrayRef<4, 8>(); 73283625Sdim if (AddrSize == 8 && RefAddrSize == 4) 74283625Sdim return makeFixedFormSizesArrayRef<8, 4>(); 75283625Sdim if (AddrSize == 8 && RefAddrSize == 8) 76283625Sdim return makeFixedFormSizesArrayRef<8, 8>(); 77283625Sdim return None; 78283625Sdim} 79283625Sdim 80283625Sdimstatic const DWARFFormValue::FormClass DWARF4FormClasses[] = { 81283625Sdim DWARFFormValue::FC_Unknown, // 0x0 82283625Sdim DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr 83283625Sdim DWARFFormValue::FC_Unknown, // 0x02 unused 84283625Sdim DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2 85283625Sdim DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4 86283625Sdim DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2 87283625Sdim // --- These can be FC_SectionOffset in DWARF3 and below: 88283625Sdim DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4 89283625Sdim DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8 90283625Sdim // --- 91283625Sdim DWARFFormValue::FC_String, // 0x08 DW_FORM_string 92283625Sdim DWARFFormValue::FC_Block, // 0x09 DW_FORM_block 93283625Sdim DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1 94283625Sdim DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1 95283625Sdim DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag 96283625Sdim DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata 97283625Sdim DWARFFormValue::FC_String, // 0x0e DW_FORM_strp 98283625Sdim DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata 99283625Sdim DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr 100283625Sdim DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1 101283625Sdim DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2 102283625Sdim DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4 103283625Sdim DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8 104283625Sdim DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata 105283625Sdim DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect 106283625Sdim DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset 107283625Sdim DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc 108283625Sdim DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present 109283625Sdim}; 110283625Sdim 111283625Sdimbool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { 112283625Sdim // First, check DWARF4 form classes. 113296417Sdim if (Form < makeArrayRef(DWARF4FormClasses).size() && 114283625Sdim DWARF4FormClasses[Form] == FC) 115283625Sdim return true; 116283625Sdim // Check more forms from DWARF4 and DWARF5 proposals. 117283625Sdim switch (Form) { 118283625Sdim case DW_FORM_ref_sig8: 119283625Sdim case DW_FORM_GNU_ref_alt: 120283625Sdim return (FC == FC_Reference); 121283625Sdim case DW_FORM_GNU_addr_index: 122283625Sdim return (FC == FC_Address); 123283625Sdim case DW_FORM_GNU_str_index: 124283625Sdim case DW_FORM_GNU_strp_alt: 125283625Sdim return (FC == FC_String); 126283625Sdim } 127283625Sdim // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset. 128283625Sdim // Don't check for DWARF version here, as some producers may still do this 129283625Sdim // by mistake. 130283625Sdim return (Form == DW_FORM_data4 || Form == DW_FORM_data8) && 131283625Sdim FC == FC_SectionOffset; 132283625Sdim} 133283625Sdim 134283625Sdimbool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, 135283625Sdim const DWARFUnit *cu) { 136283625Sdim bool indirect = false; 137283625Sdim bool is_block = false; 138283625Sdim Value.data = nullptr; 139283625Sdim // Read the value for the form into value and follow and DW_FORM_indirect 140283625Sdim // instances we run into 141283625Sdim do { 142283625Sdim indirect = false; 143283625Sdim switch (Form) { 144283625Sdim case DW_FORM_addr: 145283625Sdim case DW_FORM_ref_addr: { 146283625Sdim if (!cu) 147283625Sdim return false; 148283625Sdim uint16_t AddrSize = 149283625Sdim (Form == DW_FORM_addr) 150283625Sdim ? cu->getAddressByteSize() 151283625Sdim : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion()); 152283625Sdim RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr); 153283625Sdim if (AI != cu->getRelocMap()->end()) { 154283625Sdim const std::pair<uint8_t, int64_t> &R = AI->second; 155283625Sdim Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second; 156283625Sdim } else 157283625Sdim Value.uval = data.getUnsigned(offset_ptr, AddrSize); 158283625Sdim break; 159283625Sdim } 160283625Sdim case DW_FORM_exprloc: 161283625Sdim case DW_FORM_block: 162283625Sdim Value.uval = data.getULEB128(offset_ptr); 163283625Sdim is_block = true; 164283625Sdim break; 165283625Sdim case DW_FORM_block1: 166283625Sdim Value.uval = data.getU8(offset_ptr); 167283625Sdim is_block = true; 168283625Sdim break; 169283625Sdim case DW_FORM_block2: 170283625Sdim Value.uval = data.getU16(offset_ptr); 171283625Sdim is_block = true; 172283625Sdim break; 173283625Sdim case DW_FORM_block4: 174283625Sdim Value.uval = data.getU32(offset_ptr); 175283625Sdim is_block = true; 176283625Sdim break; 177283625Sdim case DW_FORM_data1: 178283625Sdim case DW_FORM_ref1: 179283625Sdim case DW_FORM_flag: 180283625Sdim Value.uval = data.getU8(offset_ptr); 181283625Sdim break; 182283625Sdim case DW_FORM_data2: 183283625Sdim case DW_FORM_ref2: 184283625Sdim Value.uval = data.getU16(offset_ptr); 185283625Sdim break; 186283625Sdim case DW_FORM_data4: 187283625Sdim case DW_FORM_ref4: { 188283625Sdim Value.uval = data.getU32(offset_ptr); 189283625Sdim if (!cu) 190283625Sdim break; 191283625Sdim RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4); 192283625Sdim if (AI != cu->getRelocMap()->end()) 193283625Sdim Value.uval += AI->second.second; 194283625Sdim break; 195283625Sdim } 196283625Sdim case DW_FORM_data8: 197283625Sdim case DW_FORM_ref8: 198283625Sdim Value.uval = data.getU64(offset_ptr); 199283625Sdim break; 200283625Sdim case DW_FORM_sdata: 201283625Sdim Value.sval = data.getSLEB128(offset_ptr); 202283625Sdim break; 203283625Sdim case DW_FORM_udata: 204283625Sdim case DW_FORM_ref_udata: 205283625Sdim Value.uval = data.getULEB128(offset_ptr); 206283625Sdim break; 207283625Sdim case DW_FORM_string: 208283625Sdim Value.cstr = data.getCStr(offset_ptr); 209283625Sdim break; 210283625Sdim case DW_FORM_indirect: 211283625Sdim Form = data.getULEB128(offset_ptr); 212283625Sdim indirect = true; 213283625Sdim break; 214283625Sdim case DW_FORM_sec_offset: 215283625Sdim case DW_FORM_strp: 216283625Sdim case DW_FORM_GNU_ref_alt: 217283625Sdim case DW_FORM_GNU_strp_alt: { 218283625Sdim // FIXME: This is 64-bit for DWARF64. 219283625Sdim Value.uval = data.getU32(offset_ptr); 220283625Sdim if (!cu) 221283625Sdim break; 222283625Sdim RelocAddrMap::const_iterator AI = 223283625Sdim cu->getRelocMap()->find(*offset_ptr - 4); 224283625Sdim if (AI != cu->getRelocMap()->end()) 225283625Sdim Value.uval += AI->second.second; 226283625Sdim break; 227283625Sdim } 228283625Sdim case DW_FORM_flag_present: 229283625Sdim Value.uval = 1; 230283625Sdim break; 231283625Sdim case DW_FORM_ref_sig8: 232283625Sdim Value.uval = data.getU64(offset_ptr); 233283625Sdim break; 234283625Sdim case DW_FORM_GNU_addr_index: 235283625Sdim case DW_FORM_GNU_str_index: 236283625Sdim Value.uval = data.getULEB128(offset_ptr); 237283625Sdim break; 238283625Sdim default: 239283625Sdim return false; 240283625Sdim } 241283625Sdim } while (indirect); 242283625Sdim 243283625Sdim if (is_block) { 244283625Sdim StringRef str = data.getData().substr(*offset_ptr, Value.uval); 245283625Sdim Value.data = nullptr; 246283625Sdim if (!str.empty()) { 247283625Sdim Value.data = reinterpret_cast<const uint8_t *>(str.data()); 248283625Sdim *offset_ptr += Value.uval; 249283625Sdim } 250283625Sdim } 251283625Sdim 252283625Sdim return true; 253283625Sdim} 254283625Sdim 255283625Sdimbool 256283625SdimDWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr, 257283625Sdim const DWARFUnit *cu) const { 258283625Sdim return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu); 259283625Sdim} 260283625Sdim 261283625Sdimbool 262283625SdimDWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, 263283625Sdim uint32_t *offset_ptr, const DWARFUnit *cu) { 264296417Sdim return skipValue(form, debug_info_data, offset_ptr, cu->getVersion(), 265296417Sdim cu->getAddressByteSize()); 266296417Sdim} 267296417Sdimbool DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, 268296417Sdim uint32_t *offset_ptr, uint16_t Version, 269296417Sdim uint8_t AddrSize) { 270283625Sdim bool indirect = false; 271283625Sdim do { 272283625Sdim switch (form) { 273283625Sdim // Blocks if inlined data that have a length field and the data bytes 274283625Sdim // inlined in the .debug_info 275283625Sdim case DW_FORM_exprloc: 276283625Sdim case DW_FORM_block: { 277283625Sdim uint64_t size = debug_info_data.getULEB128(offset_ptr); 278283625Sdim *offset_ptr += size; 279283625Sdim return true; 280283625Sdim } 281283625Sdim case DW_FORM_block1: { 282283625Sdim uint8_t size = debug_info_data.getU8(offset_ptr); 283283625Sdim *offset_ptr += size; 284283625Sdim return true; 285283625Sdim } 286283625Sdim case DW_FORM_block2: { 287283625Sdim uint16_t size = debug_info_data.getU16(offset_ptr); 288283625Sdim *offset_ptr += size; 289283625Sdim return true; 290283625Sdim } 291283625Sdim case DW_FORM_block4: { 292283625Sdim uint32_t size = debug_info_data.getU32(offset_ptr); 293283625Sdim *offset_ptr += size; 294283625Sdim return true; 295283625Sdim } 296283625Sdim 297283625Sdim // Inlined NULL terminated C-strings 298283625Sdim case DW_FORM_string: 299283625Sdim debug_info_data.getCStr(offset_ptr); 300283625Sdim return true; 301283625Sdim 302283625Sdim // Compile unit address sized values 303283625Sdim case DW_FORM_addr: 304296417Sdim *offset_ptr += AddrSize; 305283625Sdim return true; 306283625Sdim case DW_FORM_ref_addr: 307296417Sdim *offset_ptr += getRefAddrSize(AddrSize, Version); 308283625Sdim return true; 309283625Sdim 310283625Sdim // 0 byte values - implied from the form. 311283625Sdim case DW_FORM_flag_present: 312283625Sdim return true; 313283625Sdim 314283625Sdim // 1 byte values 315283625Sdim case DW_FORM_data1: 316283625Sdim case DW_FORM_flag: 317283625Sdim case DW_FORM_ref1: 318283625Sdim *offset_ptr += 1; 319283625Sdim return true; 320283625Sdim 321283625Sdim // 2 byte values 322283625Sdim case DW_FORM_data2: 323283625Sdim case DW_FORM_ref2: 324283625Sdim *offset_ptr += 2; 325283625Sdim return true; 326283625Sdim 327283625Sdim // 4 byte values 328283625Sdim case DW_FORM_data4: 329283625Sdim case DW_FORM_ref4: 330283625Sdim *offset_ptr += 4; 331283625Sdim return true; 332283625Sdim 333283625Sdim // 8 byte values 334283625Sdim case DW_FORM_data8: 335283625Sdim case DW_FORM_ref8: 336283625Sdim case DW_FORM_ref_sig8: 337283625Sdim *offset_ptr += 8; 338283625Sdim return true; 339283625Sdim 340283625Sdim // signed or unsigned LEB 128 values 341283625Sdim // case DW_FORM_APPLE_db_str: 342283625Sdim case DW_FORM_sdata: 343283625Sdim case DW_FORM_udata: 344283625Sdim case DW_FORM_ref_udata: 345283625Sdim case DW_FORM_GNU_str_index: 346283625Sdim case DW_FORM_GNU_addr_index: 347283625Sdim debug_info_data.getULEB128(offset_ptr); 348283625Sdim return true; 349283625Sdim 350283625Sdim case DW_FORM_indirect: 351283625Sdim indirect = true; 352283625Sdim form = debug_info_data.getULEB128(offset_ptr); 353283625Sdim break; 354283625Sdim 355283625Sdim // FIXME: 4 for DWARF32, 8 for DWARF64. 356283625Sdim case DW_FORM_sec_offset: 357283625Sdim case DW_FORM_strp: 358283625Sdim case DW_FORM_GNU_ref_alt: 359283625Sdim case DW_FORM_GNU_strp_alt: 360283625Sdim *offset_ptr += 4; 361283625Sdim return true; 362283625Sdim 363283625Sdim default: 364283625Sdim return false; 365283625Sdim } 366283625Sdim } while (indirect); 367283625Sdim return true; 368283625Sdim} 369283625Sdim 370283625Sdimvoid 371283625SdimDWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { 372283625Sdim uint64_t uvalue = Value.uval; 373283625Sdim bool cu_relative_offset = false; 374283625Sdim 375283625Sdim switch (Form) { 376283625Sdim case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break; 377283625Sdim case DW_FORM_GNU_addr_index: { 378283625Sdim OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue); 379283625Sdim uint64_t Address; 380283625Sdim if (cu->getAddrOffsetSectionItem(uvalue, Address)) 381283625Sdim OS << format("0x%016" PRIx64, Address); 382283625Sdim else 383283625Sdim OS << "<no .debug_addr section>"; 384283625Sdim break; 385283625Sdim } 386283625Sdim case DW_FORM_flag_present: OS << "true"; break; 387283625Sdim case DW_FORM_flag: 388283625Sdim case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break; 389283625Sdim case DW_FORM_data2: OS << format("0x%04x", (uint16_t)uvalue); break; 390283625Sdim case DW_FORM_data4: OS << format("0x%08x", (uint32_t)uvalue); break; 391283625Sdim case DW_FORM_ref_sig8: 392283625Sdim case DW_FORM_data8: OS << format("0x%016" PRIx64, uvalue); break; 393283625Sdim case DW_FORM_string: 394283625Sdim OS << '"'; 395283625Sdim OS.write_escaped(Value.cstr); 396283625Sdim OS << '"'; 397283625Sdim break; 398283625Sdim case DW_FORM_exprloc: 399283625Sdim case DW_FORM_block: 400283625Sdim case DW_FORM_block1: 401283625Sdim case DW_FORM_block2: 402283625Sdim case DW_FORM_block4: 403283625Sdim if (uvalue > 0) { 404283625Sdim switch (Form) { 405283625Sdim case DW_FORM_exprloc: 406283625Sdim case DW_FORM_block: OS << format("<0x%" PRIx64 "> ", uvalue); break; 407283625Sdim case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue); break; 408283625Sdim case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break; 409283625Sdim case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break; 410283625Sdim default: break; 411283625Sdim } 412283625Sdim 413283625Sdim const uint8_t* data_ptr = Value.data; 414283625Sdim if (data_ptr) { 415283625Sdim // uvalue contains size of block 416283625Sdim const uint8_t* end_data_ptr = data_ptr + uvalue; 417283625Sdim while (data_ptr < end_data_ptr) { 418283625Sdim OS << format("%2.2x ", *data_ptr); 419283625Sdim ++data_ptr; 420283625Sdim } 421283625Sdim } 422283625Sdim else 423283625Sdim OS << "NULL"; 424283625Sdim } 425283625Sdim break; 426283625Sdim 427283625Sdim case DW_FORM_sdata: OS << Value.sval; break; 428283625Sdim case DW_FORM_udata: OS << Value.uval; break; 429283625Sdim case DW_FORM_strp: { 430283625Sdim OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); 431283625Sdim dumpString(OS, cu); 432283625Sdim break; 433283625Sdim } 434283625Sdim case DW_FORM_GNU_str_index: { 435283625Sdim OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); 436283625Sdim dumpString(OS, cu); 437283625Sdim break; 438283625Sdim } 439283625Sdim case DW_FORM_GNU_strp_alt: { 440283625Sdim OS << format("alt indirect string, offset: 0x%" PRIx64 "", uvalue); 441283625Sdim dumpString(OS, cu); 442283625Sdim break; 443283625Sdim } 444283625Sdim case DW_FORM_ref_addr: 445283625Sdim OS << format("0x%016" PRIx64, uvalue); 446283625Sdim break; 447283625Sdim case DW_FORM_ref1: 448283625Sdim cu_relative_offset = true; 449283625Sdim OS << format("cu + 0x%2.2x", (uint8_t)uvalue); 450283625Sdim break; 451283625Sdim case DW_FORM_ref2: 452283625Sdim cu_relative_offset = true; 453283625Sdim OS << format("cu + 0x%4.4x", (uint16_t)uvalue); 454283625Sdim break; 455283625Sdim case DW_FORM_ref4: 456283625Sdim cu_relative_offset = true; 457283625Sdim OS << format("cu + 0x%4.4x", (uint32_t)uvalue); 458283625Sdim break; 459283625Sdim case DW_FORM_ref8: 460283625Sdim cu_relative_offset = true; 461283625Sdim OS << format("cu + 0x%8.8" PRIx64, uvalue); 462283625Sdim break; 463283625Sdim case DW_FORM_ref_udata: 464283625Sdim cu_relative_offset = true; 465283625Sdim OS << format("cu + 0x%" PRIx64, uvalue); 466283625Sdim break; 467283625Sdim case DW_FORM_GNU_ref_alt: 468283625Sdim OS << format("<alt 0x%" PRIx64 ">", uvalue); 469283625Sdim break; 470283625Sdim 471283625Sdim // All DW_FORM_indirect attributes should be resolved prior to calling 472283625Sdim // this function 473283625Sdim case DW_FORM_indirect: 474283625Sdim OS << "DW_FORM_indirect"; 475283625Sdim break; 476283625Sdim 477283625Sdim // Should be formatted to 64-bit for DWARF64. 478283625Sdim case DW_FORM_sec_offset: 479283625Sdim OS << format("0x%08x", (uint32_t)uvalue); 480283625Sdim break; 481283625Sdim 482283625Sdim default: 483283625Sdim OS << format("DW_FORM(0x%4.4x)", Form); 484283625Sdim break; 485283625Sdim } 486283625Sdim 487283625Sdim if (cu_relative_offset) { 488283625Sdim OS << " => {"; 489283625Sdim WithColor(OS, syntax::Address).get() 490283625Sdim << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0)); 491283625Sdim OS << "}"; 492283625Sdim } 493283625Sdim} 494283625Sdim 495283625Sdimvoid DWARFFormValue::dumpString(raw_ostream &OS, const DWARFUnit *U) const { 496283625Sdim Optional<const char *> DbgStr = getAsCString(U); 497283625Sdim if (DbgStr.hasValue()) { 498283625Sdim raw_ostream &COS = WithColor(OS, syntax::String); 499283625Sdim COS << '"'; 500283625Sdim COS.write_escaped(DbgStr.getValue()); 501283625Sdim COS << '"'; 502283625Sdim } 503283625Sdim} 504283625Sdim 505283625SdimOptional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const { 506283625Sdim if (!isFormClass(FC_String)) 507283625Sdim return None; 508283625Sdim if (Form == DW_FORM_string) 509283625Sdim return Value.cstr; 510283625Sdim // FIXME: Add support for DW_FORM_GNU_strp_alt 511283625Sdim if (Form == DW_FORM_GNU_strp_alt || U == nullptr) 512283625Sdim return None; 513283625Sdim uint32_t Offset = Value.uval; 514283625Sdim if (Form == DW_FORM_GNU_str_index) { 515283625Sdim uint32_t StrOffset; 516283625Sdim if (!U->getStringOffsetSectionItem(Offset, StrOffset)) 517283625Sdim return None; 518283625Sdim Offset = StrOffset; 519283625Sdim } 520283625Sdim if (const char *Str = U->getStringExtractor().getCStr(&Offset)) { 521283625Sdim return Str; 522283625Sdim } 523283625Sdim return None; 524283625Sdim} 525283625Sdim 526283625SdimOptional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const { 527283625Sdim if (!isFormClass(FC_Address)) 528283625Sdim return None; 529283625Sdim if (Form == DW_FORM_GNU_addr_index) { 530283625Sdim uint32_t Index = Value.uval; 531283625Sdim uint64_t Result; 532283625Sdim if (!U || !U->getAddrOffsetSectionItem(Index, Result)) 533283625Sdim return None; 534283625Sdim return Result; 535283625Sdim } 536283625Sdim return Value.uval; 537283625Sdim} 538283625Sdim 539283625SdimOptional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const { 540283625Sdim if (!isFormClass(FC_Reference)) 541283625Sdim return None; 542283625Sdim switch (Form) { 543283625Sdim case DW_FORM_ref1: 544283625Sdim case DW_FORM_ref2: 545283625Sdim case DW_FORM_ref4: 546283625Sdim case DW_FORM_ref8: 547283625Sdim case DW_FORM_ref_udata: 548283625Sdim if (!U) 549283625Sdim return None; 550283625Sdim return Value.uval + U->getOffset(); 551283625Sdim case DW_FORM_ref_addr: 552283625Sdim return Value.uval; 553283625Sdim // FIXME: Add proper support for DW_FORM_ref_sig8 and DW_FORM_GNU_ref_alt. 554283625Sdim default: 555283625Sdim return None; 556283625Sdim } 557283625Sdim} 558283625Sdim 559283625SdimOptional<uint64_t> DWARFFormValue::getAsSectionOffset() const { 560283625Sdim if (!isFormClass(FC_SectionOffset)) 561283625Sdim return None; 562283625Sdim return Value.uval; 563283625Sdim} 564283625Sdim 565283625SdimOptional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { 566283625Sdim if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) 567283625Sdim || Form == DW_FORM_sdata) 568283625Sdim return None; 569283625Sdim return Value.uval; 570283625Sdim} 571283625Sdim 572283625SdimOptional<int64_t> DWARFFormValue::getAsSignedConstant() const { 573283625Sdim if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || 574296417Sdim (Form == DW_FORM_udata && uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval)) 575283625Sdim return None; 576283625Sdim switch (Form) { 577283625Sdim case DW_FORM_data4: 578283625Sdim return int32_t(Value.uval); 579283625Sdim case DW_FORM_data2: 580283625Sdim return int16_t(Value.uval); 581283625Sdim case DW_FORM_data1: 582283625Sdim return int8_t(Value.uval); 583283625Sdim case DW_FORM_sdata: 584283625Sdim case DW_FORM_data8: 585283625Sdim default: 586283625Sdim return Value.sval; 587283625Sdim } 588283625Sdim} 589283625Sdim 590283625SdimOptional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { 591283625Sdim if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc)) 592283625Sdim return None; 593296417Sdim return makeArrayRef(Value.data, Value.uval); 594283625Sdim} 595283625Sdim 596