172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFFormValue.cpp ------------------------------------------------===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10cd61455798777446f35723fdb77f54a17e602009Alexey Samsonov#include "llvm/DebugInfo/DWARFFormValue.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFCompileUnit.h"
1234f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer#include "DWARFContext.h"
13c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov#include "llvm/ADT/ArrayRef.h"
14c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov#include "llvm/ADT/StringRef.h"
15806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include "llvm/Support/Debug.h"
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h"
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include <cassert>
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
23acc897a5e1bd7320da5aab728b9e0c39552f3816Benjamin Kramernamespace {
24636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonovuint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
25636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  // FIXME: Support DWARF64.
26636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  return (Version == 2) ? AddrSize : 4;
27acc897a5e1bd7320da5aab728b9e0c39552f3816Benjamin Kramer}
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2932a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonovtemplate <uint8_t AddrSize, uint8_t RefAddrSize>
30636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey SamsonovArrayRef<uint8_t> makeFixedFormSizesArrayRef() {
31636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  static const uint8_t sizes[] = {
32636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x00 unused
33636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    AddrSize,    // 0x01 DW_FORM_addr
34636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x02 unused
35636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x03 DW_FORM_block2
36636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x04 DW_FORM_block4
37636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    2,           // 0x05 DW_FORM_data2
38636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    4,           // 0x06 DW_FORM_data4
39636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    8,           // 0x07 DW_FORM_data8
40636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x08 DW_FORM_string
41636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x09 DW_FORM_block
42636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x0a DW_FORM_block1
43636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    1,           // 0x0b DW_FORM_data1
44636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    1,           // 0x0c DW_FORM_flag
45636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x0d DW_FORM_sdata
46636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    4,           // 0x0e DW_FORM_strp
47636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x0f DW_FORM_udata
48636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    RefAddrSize, // 0x10 DW_FORM_ref_addr
49636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    1,           // 0x11 DW_FORM_ref1
50636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    2,           // 0x12 DW_FORM_ref2
51636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    4,           // 0x13 DW_FORM_ref4
52636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    8,           // 0x14 DW_FORM_ref8
53636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x15 DW_FORM_ref_udata
54636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x16 DW_FORM_indirect
55636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    4,           // 0x17 DW_FORM_sec_offset
56636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x18 DW_FORM_exprloc
57636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    0,           // 0x19 DW_FORM_flag_present
58636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  };
59636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  return makeArrayRef(sizes);
60636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov}
6132a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov}
6232a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov
636faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey SamsonovArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize,
646faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov                                                    uint16_t Version) {
6532a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov  uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version);
6632a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov  if (AddrSize == 4 && RefAddrSize == 4)
67636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    return makeFixedFormSizesArrayRef<4, 4>();
6832a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov  if (AddrSize == 4 && RefAddrSize == 8)
69636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    return makeFixedFormSizesArrayRef<4, 8>();
7032a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov  if (AddrSize == 8 && RefAddrSize == 4)
71636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    return makeFixedFormSizesArrayRef<8, 4>();
7232a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov  if (AddrSize == 8 && RefAddrSize == 8)
73636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    return makeFixedFormSizesArrayRef<8, 8>();
746faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov  return None;
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
77c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovstatic const DWARFFormValue::FormClass DWARF4FormClasses[] = {
78c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Unknown,       // 0x0
79c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Address,       // 0x01 DW_FORM_addr
80c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Unknown,       // 0x02 unused
81c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Block,         // 0x03 DW_FORM_block2
82c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Block,         // 0x04 DW_FORM_block4
83c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x05 DW_FORM_data2
84c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // --- These can be FC_SectionOffset in DWARF3 and below:
85c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x06 DW_FORM_data4
86c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x07 DW_FORM_data8
87c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // ---
88c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
89c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
90c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
91c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
92c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
93c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
94c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
95c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
96c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
97c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
98c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
99c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
100c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
101c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
102c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
103c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
104c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
105c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
106c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov};
107c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov
108c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovbool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
109c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // First, check DWARF4 form classes.
110c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (Form < ArrayRef<FormClass>(DWARF4FormClasses).size() &&
111c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      DWARF4FormClasses[Form] == FC)
112c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return true;
113636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  // Check DW_FORM_ref_sig8 from DWARF4.
114636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov  if (Form == DW_FORM_ref_sig8)
115636a5cb8ded0d6ab7051cbde98953039ef80a6bbAlexey Samsonov    return (FC == FC_Reference);
116c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // Check for some DWARF5 forms.
117c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (Form == DW_FORM_GNU_addr_index)
118c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return (FC == FC_Address);
119c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (Form == DW_FORM_GNU_str_index)
120c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return (FC == FC_String);
121c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
122c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // Don't check for DWARF version here, as some producers may still do this
123c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // by mistake.
124c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if ((Form == DW_FORM_data4 || Form == DW_FORM_data8) &&
125c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      FC == FC_SectionOffset)
126c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return true;
127c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return false;
128c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov}
129c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov
130cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
131cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                                  const DWARFUnit *cu) {
1324aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  bool indirect = false;
1334aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  bool is_block = false;
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Value.data = nullptr;
1354aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  // Read the value for the form into value and follow and DW_FORM_indirect
1364aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  // instances we run into
1374aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  do {
13889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    indirect = false;
13989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    switch (Form) {
14089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_addr:
141806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher    case DW_FORM_ref_addr: {
14232a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov      uint16_t AddrSize =
14332a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov          (Form == DW_FORM_addr)
14432a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov              ? cu->getAddressByteSize()
14532a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov              : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
14632a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
14782de10a34c9432029040ced17129079a7d80904eEric Christopher      if (AI != cu->getRelocMap()->end()) {
148d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        const std::pair<uint8_t, int64_t> &R = AI->second;
14932a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov        Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
150d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      } else
15132a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov        Value.uval = data.getUnsigned(offset_ptr, AddrSize);
15289aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
1534c0ae9066fecbbd507162a880450641aa5c33098Alexey Samsonov    }
1543887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_exprloc:
15589aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_block:
15689aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getULEB128(offset_ptr);
15789aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      is_block = true;
15889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
15989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_block1:
16089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU8(offset_ptr);
16189aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      is_block = true;
16289aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
16389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_block2:
16489aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU16(offset_ptr);
16589aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      is_block = true;
16689aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
16789aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_block4:
16889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU32(offset_ptr);
16989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      is_block = true;
17089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
17189aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_data1:
17289aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_ref1:
17389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_flag:
17489aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU8(offset_ptr);
17589aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
17689aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_data2:
17789aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_ref2:
17889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU16(offset_ptr);
17989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
18089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_data4:
1813df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    case DW_FORM_ref4: {
1823df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
18389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU32(offset_ptr);
1843df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      if (AI != cu->getRelocMap()->end())
1853df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        Value.uval += AI->second.second;
18689aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
1873df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    }
18889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_data8:
18989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_ref8:
19089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getU64(offset_ptr);
19189aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
19289aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_sdata:
19389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.sval = data.getSLEB128(offset_ptr);
19489aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
195806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher    case DW_FORM_strp: {
196d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      RelocAddrMap::const_iterator AI
19782de10a34c9432029040ced17129079a7d80904eEric Christopher        = cu->getRelocMap()->find(*offset_ptr);
19882de10a34c9432029040ced17129079a7d80904eEric Christopher      if (AI != cu->getRelocMap()->end()) {
199d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        const std::pair<uint8_t, int64_t> &R = AI->second;
20032b3768ec1ae95cb05d1f595d31761c510c43251Eric Christopher        Value.uval = data.getU32(offset_ptr) + R.second;
201d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      } else
202806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher        Value.uval = data.getU32(offset_ptr);
20389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
204806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher    }
20589aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_udata:
20689aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_ref_udata:
20789aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.uval = data.getULEB128(offset_ptr);
20889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
20989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_string:
21089aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Value.cstr = data.getCStr(offset_ptr);
21189aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
21289aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    case DW_FORM_indirect:
21389aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      Form = data.getULEB128(offset_ptr);
21489aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      indirect = true;
21589aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      break;
2169a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher    case DW_FORM_sec_offset: {
217d96c72a14cf327af98cbc7d3491f7a2248f5137dEric Christopher      // FIXME: This is 64-bit for DWARF64.
2189a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher      RelocAddrMap::const_iterator AI
2199a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher        = cu->getRelocMap()->find(*offset_ptr);
2209a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher      if (AI != cu->getRelocMap()->end()) {
2219a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher        const std::pair<uint8_t, int64_t> &R = AI->second;
2229a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher        Value.uval = data.getU32(offset_ptr) + R.second;
2239a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher      } else
2249a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher        Value.uval = data.getU32(offset_ptr);
2253887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      break;
2269a9e73b47d139ecb6bfc3c934352ab7c7ee9af44Eric Christopher    }
2273887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_flag_present:
2283887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      Value.uval = 1;
2293887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      break;
2303887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_ref_sig8:
2313887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      Value.uval = data.getU64(offset_ptr);
2323887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      break;
233205e60b223c1f4139d14edd42dfc048adb811ad0Eric Christopher    case DW_FORM_GNU_addr_index:
234205e60b223c1f4139d14edd42dfc048adb811ad0Eric Christopher    case DW_FORM_GNU_str_index:
235205e60b223c1f4139d14edd42dfc048adb811ad0Eric Christopher      Value.uval = data.getULEB128(offset_ptr);
236205e60b223c1f4139d14edd42dfc048adb811ad0Eric Christopher      break;
23789aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    default:
23889aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer      return false;
23989aedba562243c7b60b24b5ffba55394d9c55a12Benjamin Kramer    }
2404aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  } while (indirect);
2414aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer
2424aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  if (is_block) {
2434aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value.data = nullptr;
2454aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    if (!str.empty()) {
2464aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer      Value.data = reinterpret_cast<const uint8_t *>(str.data());
2474aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer      *offset_ptr += Value.uval;
24872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
2494aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  }
25072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2514aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  return true;
25272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
25372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
25472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool
25572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
256cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                          const DWARFUnit *cu) const {
2574aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
25872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
25972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
26072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool
26172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
262cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                          uint32_t *offset_ptr, const DWARFUnit *cu) {
26372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  bool indirect = false;
26472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  do {
26572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    switch (form) {
26672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Blocks if inlined data that have a length field and the data bytes
26772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // inlined in the .debug_info
2683887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_exprloc:
26972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_block: {
27072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint64_t size = debug_info_data.getULEB128(offset_ptr);
27172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += size;
27272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
27372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
27472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_block1: {
27572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint8_t size = debug_info_data.getU8(offset_ptr);
27672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += size;
27772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
27872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
27972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_block2: {
28072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint16_t size = debug_info_data.getU16(offset_ptr);
28172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += size;
28272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
28372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
28472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_block4: {
28572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint32_t size = debug_info_data.getU32(offset_ptr);
28672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += size;
28772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
28872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
28972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
29072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Inlined NULL terminated C-strings
29172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_string:
29272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      debug_info_data.getCStr(offset_ptr);
29372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
29472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
29572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Compile unit address sized values
29672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_addr:
29772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += cu->getAddressByteSize();
29872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
29932a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov    case DW_FORM_ref_addr:
30032a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov      *offset_ptr += getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
30132a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov      return true;
30272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3033887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    // 0 byte values - implied from the form.
3043887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_flag_present:
3053887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      return true;
306e7285c72793b69f005b5656be9f7aed101cdee4aEric Christopher
30772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // 1 byte values
30872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_data1:
30972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_flag:
31072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_ref1:
31172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += 1;
31272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
31372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
31472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // 2 byte values
31572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_data2:
31672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_ref2:
31772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += 2;
31872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
31972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
32072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // 4 byte values
32172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_strp:
32272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_data4:
32372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_ref4:
32472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += 4;
32572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
32672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
32772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // 8 byte values
32872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_data8:
32972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_ref8:
3303887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_ref_sig8:
33172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr += 8;
33272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
33372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
33472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // signed or unsigned LEB 128 values
33572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    //  case DW_FORM_APPLE_db_str:
33672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_sdata:
33772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_udata:
33872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_ref_udata:
339dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher    case DW_FORM_GNU_str_index:
340dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher    case DW_FORM_GNU_addr_index:
34172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      debug_info_data.getULEB128(offset_ptr);
34272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
34372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
34472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    case DW_FORM_indirect:
34572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      indirect = true;
34672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      form = debug_info_data.getULEB128(offset_ptr);
34772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      break;
3483887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher
349446b88fb81e14f5fa6f98ca924c83edc856cade7Eric Christopher    // FIXME: 4 for DWARF32, 8 for DWARF64.
3503887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    case DW_FORM_sec_offset:
351446b88fb81e14f5fa6f98ca924c83edc856cade7Eric Christopher      *offset_ptr += 4;
3523887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      return true;
353e7285c72793b69f005b5656be9f7aed101cdee4aEric Christopher
35472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    default:
35572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return false;
35672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
35772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } while (indirect);
35872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return true;
35972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
36072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
36172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid
362cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
36382de10a34c9432029040ced17129079a7d80904eEric Christopher  DataExtractor debug_str_data(cu->getStringSection(), true, 0);
364dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher  DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
365c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  uint64_t uvalue = Value.uval;
36672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  bool cu_relative_offset = false;
36772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3684aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  switch (Form) {
3695eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer  case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
37072f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher  case DW_FORM_GNU_addr_index: {
37172f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher    OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
37263fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    uint64_t Address;
37363fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    if (cu->getAddrOffsetSectionItem(uvalue, Address))
37463fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov      OS << format("0x%016" PRIx64, Address);
37563fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    else
37672f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher      OS << "<no .debug_addr section>";
37772f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher    break;
37872f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher  }
3793887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher  case DW_FORM_flag_present: OS << "true"; break;
38072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_flag:
3815eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer  case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
3825eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer  case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
3835eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer  case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
3843887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher  case DW_FORM_ref_sig8:
3855eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer  case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
38672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_string:
38772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << '"';
388c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    OS.write_escaped(Value.cstr);
38972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << '"';
39072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
3913887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher  case DW_FORM_exprloc:
39272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_block:
39372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_block1:
39472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_block2:
39572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_block4:
39672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (uvalue > 0) {
39772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      switch (Form) {
3983887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher      case DW_FORM_exprloc:
39941a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer      case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
40072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
40172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
40272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
40372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      default: break;
40472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
40572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
40672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      const uint8_t* data_ptr = Value.data;
40772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (data_ptr) {
40872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        // uvalue contains size of block
40972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        const uint8_t* end_data_ptr = data_ptr + uvalue;
41072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        while (data_ptr < end_data_ptr) {
41172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          OS << format("%2.2x ", *data_ptr);
41272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          ++data_ptr;
41372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
41472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
41572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      else
41672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        OS << "NULL";
41772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
41872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
41972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
420c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  case DW_FORM_sdata:     OS << Value.sval; break;
421c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  case DW_FORM_udata:     OS << Value.uval; break;
42234f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer  case DW_FORM_strp: {
42334f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer    OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
424c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    Optional<const char *> DbgStr = getAsCString(cu);
425c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    if (DbgStr.hasValue()) {
42634f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer      OS << '"';
427c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      OS.write_escaped(DbgStr.getValue());
42834f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer      OS << '"';
42972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
43072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
43134f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer  }
432dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher  case DW_FORM_GNU_str_index: {
433dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher    OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
434c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    Optional<const char *> DbgStr = getAsCString(cu);
435c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    if (DbgStr.hasValue()) {
436dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher      OS << '"';
437c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      OS.write_escaped(DbgStr.getValue());
438dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher      OS << '"';
439dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher    }
440dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher    break;
441dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher  }
44272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref_addr:
4435eccd36f1a8d917201b39697f3f1b6f45ecc139cBenjamin Kramer    OS << format("0x%016" PRIx64, uvalue);
44472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
44572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref1:
44672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    cu_relative_offset = true;
44772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
44872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
44972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref2:
45072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    cu_relative_offset = true;
45172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
45272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
45372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref4:
45472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    cu_relative_offset = true;
45572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
45672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
45772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref8:
45872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    cu_relative_offset = true;
45941a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer    OS << format("cu + 0x%8.8" PRIx64, uvalue);
46072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
46172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_ref_udata:
46272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    cu_relative_offset = true;
46341a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer    OS << format("cu + 0x%" PRIx64, uvalue);
46472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
46572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
46672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // All DW_FORM_indirect attributes should be resolved prior to calling
46772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // this function
46872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  case DW_FORM_indirect:
46972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << "DW_FORM_indirect";
47072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
4713887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher
472446b88fb81e14f5fa6f98ca924c83edc856cade7Eric Christopher    // Should be formatted to 64-bit for DWARF64.
4733887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher  case DW_FORM_sec_offset:
474446b88fb81e14f5fa6f98ca924c83edc856cade7Eric Christopher    OS << format("0x%08x", (uint32_t)uvalue);
4753887a902a1b8e5a6aad4fc822479845ce3ba0dfeEric Christopher    break;
476e7285c72793b69f005b5656be9f7aed101cdee4aEric Christopher
47772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  default:
47872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("DW_FORM(0x%4.4x)", Form);
47972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    break;
48072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
48172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
48272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (cu_relative_offset)
483e25a2bd2e349528e48d3cc8dd287307029acf97bBenjamin Kramer    OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
48472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
48572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
486c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey SamsonovOptional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
487c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!isFormClass(FC_String))
488c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
489c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (Form == DW_FORM_string)
49072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return Value.cstr;
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!U)
492c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
49363fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  uint32_t Offset = Value.uval;
4948d433bd458b37327e2fa979a3234762f206b3467Alexey Samsonov  if (Form == DW_FORM_GNU_str_index) {
49563fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    uint32_t StrOffset;
496c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    if (!U->getStringOffsetSectionItem(Offset, StrOffset))
497c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      return None;
49863fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    Offset = StrOffset;
49972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
500c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
501c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return Str;
502c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  }
503c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return None;
504dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher}
505dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher
506c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey SamsonovOptional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
507c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!isFormClass(FC_Address))
508c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
5098d433bd458b37327e2fa979a3234762f206b3467Alexey Samsonov  if (Form == DW_FORM_GNU_addr_index) {
51063fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov    uint32_t Index = Value.uval;
511c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    uint64_t Result;
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!U || !U->getAddrOffsetSectionItem(Index, Result))
513c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      return None;
514c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return Result;
51563fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  }
51663fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  return Value.uval;
51772f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher}
51872f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher
519c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey SamsonovOptional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
520c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!isFormClass(FC_Reference))
521c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
5224aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  switch (Form) {
5234aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  case DW_FORM_ref1:
5244aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  case DW_FORM_ref2:
5254aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  case DW_FORM_ref4:
5264aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  case DW_FORM_ref8:
5274aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  case DW_FORM_ref_udata:
528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!U)
529c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      return None;
530c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return Value.uval + U->getOffset();
531c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  case DW_FORM_ref_addr:
532c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return Value.uval;
533c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  // FIXME: Add proper support for DW_FORM_ref_sig8
5344aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  default:
535c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return Value.uval;
5364aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  }
537c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov}
53872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
539c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey SamsonovOptional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
540c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!isFormClass(FC_SectionOffset))
541c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
542c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Value.uval;
543c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov}
544c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov
545c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey SamsonovOptional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
546c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!isFormClass(FC_Constant) || Form == DW_FORM_sdata)
547c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return None;
548c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Value.uval;
54972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
550