DWARFDebugInfoEntry.cpp revision 4aa3fea8b13b91800c908f8e7d74fad96adba69a
172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFDebugInfoEntry.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
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugInfoEntry.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFCompileUnit.h"
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFContext.h"
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugAbbrev.h"
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFFormValue.h"
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h"
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf;
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS,
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                      const DWARFCompileUnit *cu,
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                      unsigned recurseDepth,
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                      unsigned indent) const {
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DataExtractor debug_info_data = cu->getDebugInfoExtractor();
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = Offset;
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info_data.isValidOffset(offset)) {
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint64_t abbrCode = debug_info_data.getULEB128(&offset);
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS.indent(indent) << format("\n0x%8.8x: ", Offset);
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrCode) {
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (AbbrevDecl) {
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        OS << TagString(AbbrevDecl->getTag())
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer           << format(" [%u] %c\n", abbrCode,
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                   AbbrevDecl->hasChildren() ? '*': ' ');
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        // Dump all data in the .debug_info for the attributes
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        for (uint32_t i = 0; i != numAttributes; ++i) {
4172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          uint16_t attr = AbbrevDecl->getAttrByIndex(i);
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          uint16_t form = AbbrevDecl->getFormByIndex(i);
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          dumpAttribute(OS, cu, &offset, attr, form, indent);
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        const DWARFDebugInfoEntryMinimal *child = getFirstChild();
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        if (recurseDepth > 0 && child) {
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          indent += 2;
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          while (child) {
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            child->dump(OS, cu, recurseDepth-1, indent);
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            child = child->getSibling();
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          }
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          indent -= 2;
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      } else {
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer           << abbrCode << '\n';
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
6072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      OS << "NULL\n";
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               const DWARFCompileUnit *cu,
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               uint32_t* offset_ptr,
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               uint16_t attr,
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               uint16_t form,
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               unsigned indent) const {
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS.indent(indent) << format("0x%8.8x: ", *offset_ptr)
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                    << AttributeString(attr)
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                    << " [" << FormEncodingString(form) << ']';
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue formValue(form);
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu))
7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
7972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << "\t(";
8172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  formValue.dump(OS, 0, cu);
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << ")\n";
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                             const uint8_t *fixed_form_sizes,
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                             uint32_t *offset_ptr) {
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = *offset_ptr;
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DataExtractor debug_info_data = cu->getDebugInfoExtractor();
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr);
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  assert (fixed_form_sizes); // For best performance this should be specified!
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (abbrCode) {
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t offset = *offset_ptr;
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Skip all data in the .debug_info for the attributes
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t i;
10372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint16_t form;
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    for (i=0; i<numAttributes; ++i) {
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      form = AbbrevDecl->getFormByIndex(i);
10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      const uint8_t fixed_skip_size = fixed_form_sizes[form];
10872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (fixed_skip_size)
10972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        offset += fixed_skip_size;
11072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      else {
11172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        bool form_is_indirect = false;
11272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        do {
11372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          form_is_indirect = false;
11472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          uint32_t form_size = 0;
11572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          switch (form) {
11672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // Blocks if inlined data that have a length field and the data bytes
11772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // inlined in the .debug_info.
11872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_block:
11972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = debug_info_data.getULEB128(&offset);
12072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
12172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_block1:
12272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = debug_info_data.getU8(&offset);
12372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
12472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_block2:
12572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = debug_info_data.getU16(&offset);
12672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
12772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_block4:
12872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = debug_info_data.getU32(&offset);
12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
13072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // Inlined NULL terminated C-strings
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_string:
13372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            debug_info_data.getCStr(&offset);
13472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
13572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // Compile unit address sized values
13772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_addr:
13872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref_addr:
13972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = cu->getAddressByteSize();
14072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
14172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // 1 byte values
14372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_data1:
14472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_flag:
14572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref1:
14672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = 1;
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
14872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // 2 byte values
15072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_data2:
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref2:
15272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = 2;
15372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // 4 byte values
15672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_strp:
15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_data4:
15872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref4:
15972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = 4;
16072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
16172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // 8 byte values
16372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_data8:
16472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref8:
16572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_size = 8;
16672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
16772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          // signed or unsigned LEB 128 values
16972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_sdata:
17072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_udata:
17172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_ref_udata:
17272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            debug_info_data.getULEB128(&offset);
17372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
17472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          case DW_FORM_indirect:
17672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form_is_indirect = true;
17772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            form = debug_info_data.getULEB128(&offset);
17872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            break;
17972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          default:
18172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            *offset_ptr = Offset;
18272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            return false;
18372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          }
18472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          offset += form_size;
18572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        } while (form_is_indirect);
18772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
18872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
18972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    *offset_ptr = offset;
19072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return true;
19172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } else {
19272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    AbbrevDecl = NULL;
19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return true; // NULL debug tag entry
19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
19572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
19672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return false;
19772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
19872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
19972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool
20072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu,
20172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                    uint32_t *offset_ptr) {
20272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DataExtractor debug_info_data = cu->getDebugInfoExtractor();
20372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const uint32_t cu_end_offset = cu->getNextCompileUnitOffset();
20472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const uint8_t cu_addr_size = cu->getAddressByteSize();
20572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = *offset_ptr;
20672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) {
20772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Offset = offset;
20872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
20972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint64_t abbrCode = debug_info_data.getULEB128(&offset);
21072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrCode) {
21272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
21372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (AbbrevDecl) {
21572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        uint16_t tag = AbbrevDecl->getTag();
21672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        bool isCompileUnitTag = tag == DW_TAG_compile_unit;
21872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        if(cu && isCompileUnitTag)
21972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          const_cast<DWARFCompileUnit*>(cu)->setBaseAddress(0);
22072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        // Skip all data in the .debug_info for the attributes
22272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
22372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        for (uint32_t i = 0; i != numAttributes; ++i) {
22472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          uint16_t attr = AbbrevDecl->getAttrByIndex(i);
22572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          uint16_t form = AbbrevDecl->getFormByIndex(i);
22672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          if (isCompileUnitTag &&
22872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
22972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            DWARFFormValue form_value(form);
23072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            if (form_value.extractValue(debug_info_data, &offset, cu)) {
23172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
23272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                const_cast<DWARFCompileUnit*>(cu)
23372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                  ->setBaseAddress(form_value.getUnsigned());
23472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            }
23572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          } else {
23672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            bool form_is_indirect = false;
23772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            do {
23872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              form_is_indirect = false;
23972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              register uint32_t form_size = 0;
24072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              switch (form) {
24172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // Blocks if inlined data that have a length field and the data
24272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // bytes // inlined in the .debug_info
24372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_block:
24472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = debug_info_data.getULEB128(&offset);
24572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
24672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_block1:
24772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = debug_info_data.getU8(&offset);
24872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
24972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_block2:
25072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = debug_info_data.getU16(&offset);
25172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
25272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_block4:
25372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = debug_info_data.getU32(&offset);
25472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
25572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
25672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // Inlined NULL terminated C-strings
25772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_string:
25872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                debug_info_data.getCStr(&offset);
25972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
26072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
26172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // Compile unit address sized values
26272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_addr:
26372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref_addr:
26472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = cu_addr_size;
26572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
26672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
26772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // 1 byte values
26872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_data1:
26972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_flag:
27072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref1:
27172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = 1;
27272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
27372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
27472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // 2 byte values
27572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_data2:
27672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref2:
27772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = 2;
27872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
27972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
28072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                // 4 byte values
28172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_strp:
28272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = 4;
28372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
28472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
28572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_data4:
28672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref4:
28772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = 4;
28872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
28972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
29072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // 8 byte values
29172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_data8:
29272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref8:
29372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_size = 8;
29472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
29572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
29672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              // signed or unsigned LEB 128 values
29772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_sdata:
29872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_udata:
29972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_ref_udata:
30072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                debug_info_data.getULEB128(&offset);
30172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
30272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
30372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              case DW_FORM_indirect:
30472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form = debug_info_data.getULEB128(&offset);
30572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                form_is_indirect = true;
30672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                break;
30772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
30872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              default:
30972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                *offset_ptr = offset;
31072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                return false;
31172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              }
31272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
31372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer              offset += form_size;
31472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            } while (form_is_indirect);
31572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          }
31672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
31772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        *offset_ptr = offset;
31872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        return true;
31972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
32072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
32172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      AbbrevDecl = NULL;
32272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      *offset_ptr = offset;
32372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;    // NULL debug tag entry
32472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
32572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
32672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
32772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return false;
32872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
32972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
33072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint32_t
33172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
33272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                              const uint16_t attr,
33372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                              DWARFFormValue &form_value,
33472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                              uint32_t *end_attr_offset_ptr)
33572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                              const {
33672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (AbbrevDecl) {
33772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr);
33872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
33972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (attr_idx != -1U) {
34072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint32_t offset = getOffset();
34172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
34272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      DataExtractor debug_info_data = cu->getDebugInfoExtractor();
34372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
34472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Skip the abbreviation code so we are at the data for the attributes
34572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      debug_info_data.getULEB128(&offset);
34672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
34772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint32_t idx = 0;
34872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      while (idx < attr_idx)
34972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++),
35072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                  debug_info_data, &offset, cu);
35172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
35272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      const uint32_t attr_offset = offset;
35372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx));
3544aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer      if (form_value.extractValue(debug_info_data, &offset, cu)) {
35572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        if (end_attr_offset_ptr)
35672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          *end_attr_offset_ptr = offset;
35772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        return attr_offset;
35872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
35972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
36072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
36172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
36272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return 0;
36372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
36472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
36572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst char*
36672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::getAttributeValueAsString(
36772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFCompileUnit* cu,
36872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const uint16_t attr,
36972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const char* fail_value) const {
37072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue form_value;
37172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (getAttributeValue(cu, attr, form_value)) {
37272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DataExtractor stringExtractor(cu->getContext().getStringSection(),
37372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        false, 0);
37472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return form_value.getAsCString(&stringExtractor);
37572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
37672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return fail_value;
37772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
37872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
37972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint64_t
38072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
38172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFCompileUnit* cu,
38272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const uint16_t attr,
38372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint64_t fail_value) const {
38472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue form_value;
38572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (getAttributeValue(cu, attr, form_value))
38672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return form_value.getUnsigned();
38772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return fail_value;
38872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
38972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
39072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerint64_t
39172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
39272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFCompileUnit* cu,
39372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const uint16_t attr,
39472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    int64_t fail_value) const {
39572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue form_value;
39672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (getAttributeValue(cu, attr, form_value))
39772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return form_value.getSigned();
39872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return fail_value;
39972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
40072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
40172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint64_t
40272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugInfoEntryMinimal::getAttributeValueAsReference(const DWARFCompileUnit* cu,
40372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                                  const uint16_t attr,
40472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                                  uint64_t fail_value) const {
40572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue form_value;
40672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (getAttributeValue(cu, attr, form_value))
40772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return form_value.getReference(cu);
40872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return fail_value;
40972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
410