119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- DWARFFormValue.cpp ------------------------------------------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "DWARFFormValue.h"
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "DWARFCompileUnit.h"
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "DWARFContext.h"
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Dwarf.h"
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Format.h"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cassert>
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace dwarf;
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const uint8_t form_sizes_addr4[] = {
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x00 unused
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x01 DW_FORM_addr
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x02 unused
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x03 DW_FORM_block2
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x04 DW_FORM_block4
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  2, // 0x05 DW_FORM_data2
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x06 DW_FORM_data4
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x07 DW_FORM_data8
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x08 DW_FORM_string
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x09 DW_FORM_block
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0a DW_FORM_block1
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x0b DW_FORM_data1
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x0c DW_FORM_flag
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0d DW_FORM_sdata
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x0e DW_FORM_strp
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0f DW_FORM_udata
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x10 DW_FORM_ref_addr
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x11 DW_FORM_ref1
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  2, // 0x12 DW_FORM_ref2
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x13 DW_FORM_ref4
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x14 DW_FORM_ref8
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x15 DW_FORM_ref_udata
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x16 DW_FORM_indirect
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const uint8_t form_sizes_addr8[] = {
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x00 unused
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x01 DW_FORM_addr
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x02 unused
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x03 DW_FORM_block2
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x04 DW_FORM_block4
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  2, // 0x05 DW_FORM_data2
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x06 DW_FORM_data4
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x07 DW_FORM_data8
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x08 DW_FORM_string
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x09 DW_FORM_block
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0a DW_FORM_block1
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x0b DW_FORM_data1
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x0c DW_FORM_flag
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0d DW_FORM_sdata
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x0e DW_FORM_strp
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x0f DW_FORM_udata
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x10 DW_FORM_ref_addr
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  1, // 0x11 DW_FORM_ref1
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  2, // 0x12 DW_FORM_ref2
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  4, // 0x13 DW_FORM_ref4
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  8, // 0x14 DW_FORM_ref8
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x15 DW_FORM_ref_udata
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  0, // 0x16 DW_FORM_indirect
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst uint8_t *
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::getFixedFormSizesForAddressSize(uint8_t addr_size) {
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (addr_size) {
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case 4: return form_sizes_addr4;
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case 8: return form_sizes_addr8;
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NULL;
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             const DWARFCompileUnit *cu) {
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool indirect = false;
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool is_block = false;
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Value.data = NULL;
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Read the value for the form into value and follow and DW_FORM_indirect
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // instances we run into
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    indirect = false;
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Form) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_addr:
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref_addr:
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block:
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getULEB128(offset_ptr);
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      is_block = true;
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block1:
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU8(offset_ptr);
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      is_block = true;
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block2:
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU16(offset_ptr);
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      is_block = true;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block4:
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU32(offset_ptr);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      is_block = true;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data1:
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref1:
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_flag:
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU8(offset_ptr);
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data2:
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref2:
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU16(offset_ptr);
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data4:
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref4:
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU32(offset_ptr);
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data8:
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref8:
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU64(offset_ptr);
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_sdata:
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.sval = data.getSLEB128(offset_ptr);
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_strp:
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getU32(offset_ptr);
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_udata:
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref_udata:
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.uval = data.getULEB128(offset_ptr);
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_string:
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.cstr = data.getCStr(offset_ptr);
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Set the string value to also be the data for inlined cstr form
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // values only so we can tell the differnence between DW_FORM_string
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // and DW_FORM_strp form values
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.data = (uint8_t*)Value.cstr;
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_indirect:
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Form = data.getULEB128(offset_ptr);
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      indirect = true;
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (indirect);
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is_block) {
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value.data = NULL;
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!str.empty()) {
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value.data = reinterpret_cast<const uint8_t *>(str.data());
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += Value.uval;
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          const DWARFCompileUnit *cu) const {
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          uint32_t *offset_ptr, const DWARFCompileUnit *cu) {
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool indirect = false;
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    indirect = false;
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (form) {
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Blocks if inlined data that have a length field and the data bytes
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // inlined in the .debug_info
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block: {
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint64_t size = debug_info_data.getULEB128(offset_ptr);
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += size;
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block1: {
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint8_t size = debug_info_data.getU8(offset_ptr);
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += size;
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block2: {
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint16_t size = debug_info_data.getU16(offset_ptr);
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += size;
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_block4: {
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t size = debug_info_data.getU32(offset_ptr);
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += size;
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Inlined NULL terminated C-strings
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_string:
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      debug_info_data.getCStr(offset_ptr);
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Compile unit address sized values
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_addr:
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref_addr:
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += cu->getAddressByteSize();
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 1 byte values
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data1:
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_flag:
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref1:
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += 1;
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 2 byte values
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data2:
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref2:
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += 2;
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 4 byte values
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_strp:
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data4:
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref4:
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += 4;
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 8 byte values
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_data8:
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref8:
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      *offset_ptr += 8;
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // signed or unsigned LEB 128 values
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //  case DW_FORM_APPLE_db_str:
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_sdata:
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_udata:
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_ref_udata:
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      debug_info_data.getULEB128(offset_ptr);
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case DW_FORM_indirect:
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      indirect = true;
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      form = debug_info_data.getULEB128(offset_ptr);
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (indirect);
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0);
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t uvalue = getUnsigned();
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool cu_relative_offset = false;
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Form) {
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_addr:      OS << format("0x%016x", uvalue); break;
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_flag:
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data1:     OS << format("0x%02x", uvalue);  break;
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data2:     OS << format("0x%04x", uvalue);  break;
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data4:     OS << format("0x%08x", uvalue);  break;
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data8:     OS << format("0x%016x", uvalue); break;
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_string:
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << '"';
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.write_escaped(getAsCString(NULL));
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << '"';
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block:
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block1:
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block2:
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block4:
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (uvalue > 0) {
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Form) {
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case DW_FORM_block:  OS << format("<0x%llx> ", uvalue);            break;
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: break;
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const uint8_t* data_ptr = Value.data;
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (data_ptr) {
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // uvalue contains size of block
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        const uint8_t* end_data_ptr = data_ptr + uvalue;
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        while (data_ptr < end_data_ptr) {
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          OS << format("%2.2x ", *data_ptr);
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ++data_ptr;
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << "NULL";
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_sdata:     OS << getSigned();   break;
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_udata:     OS << getUnsigned(); break;
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_strp: {
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const char* dbg_str = getAsCString(&debug_str_data);
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (dbg_str) {
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OS << '"';
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OS.write_escaped(dbg_str);
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OS << '"';
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref_addr:
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("0x%016x", uvalue);
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref1:
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    cu_relative_offset = true;
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref2:
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    cu_relative_offset = true;
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref4:
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    cu_relative_offset = true;
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref8:
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    cu_relative_offset = true;
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("cu + 0x%8.8llx", uvalue);
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref_udata:
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    cu_relative_offset = true;
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("cu + 0x%llx", uvalue);
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // All DW_FORM_indirect attributes should be resolved prior to calling
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // this function
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_indirect:
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << "DW_FORM_indirect";
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format("DW_FORM(0x%4.4x)", Form);
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (cu_relative_offset)
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << format(" => {0x%8.8x}", (uvalue + (cu ? cu->getOffset() : 0)));
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst char*
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (isInlinedCStr()) {
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Value.cstr;
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (debug_str_data_ptr) {
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint32_t offset = Value.uval;
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return debug_str_data_ptr->getCStr(&offset);
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NULL;
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t die_offset = Value.uval;
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Form) {
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref1:
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref2:
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref4:
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref8:
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref_udata:
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      die_offset += (cu ? cu->getOffset() : 0);
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return die_offset;
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDWARFFormValue::resolveCompileUnitReferences(const DWARFCompileUnit *cu) {
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Form) {
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref1:
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref2:
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref4:
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref8:
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_ref_udata:
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value.uval += cu->getOffset();
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Form = DW_FORM_ref_addr;
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst uint8_t *DWARFFormValue::BlockData() const {
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!isInlinedCStr())
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Value.data;
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NULL;
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool DWARFFormValue::isBlockForm(uint16_t form) {
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (form) {
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block:
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block1:
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block2:
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_block4:
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool DWARFFormValue::isDataForm(uint16_t form) {
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (form) {
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_sdata:
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_udata:
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data1:
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data2:
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data4:
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case DW_FORM_data8:
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
428