172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFCompileUnit.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 "DWARFCompileUnit.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFContext.h"
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFFormValue.h"
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h"
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf;
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDataExtractor DWARFCompileUnit::getDebugInfoExtractor() const {
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return DataExtractor(Context.getInfoSection(),
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                       Context.isLittleEndian(), getAddressByteSize());
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  clear();
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = *offset_ptr;
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info.isValidOffset(*offset_ptr)) {
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint64_t abbrOffset;
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFDebugAbbrev *abbr = Context.getDebugAbbrev();
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Length = debug_info.getU32(offset_ptr);
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Version = debug_info.getU16(offset_ptr);
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    abbrOffset = debug_info.getU32(offset_ptr);
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    AddrSize = debug_info.getU8(offset_ptr);
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool lengthOK = debug_info.isValidOffset(getNextCompileUnitOffset()-1);
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool versionOK = DWARFContext::isSupportedVersion(Version);
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool abbrOffsetOK = Context.getAbbrevSection().size() > abbrOffset;
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
4172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && abbr != NULL) {
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      Abbrevs = abbr->getAbbreviationDeclarationSet(abbrOffset);
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // reset the offset to where we tried to parse from if anything went wrong
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    *offset_ptr = Offset;
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return false;
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint32_t
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFCompileUnit::extract(uint32_t offset, DataExtractor debug_info_data,
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                          const DWARFAbbreviationDeclarationSet *abbrevs) {
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  clear();
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = offset;
6072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info_data.isValidOffset(offset)) {
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Length = debug_info_data.getU32(&offset);
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Version = debug_info_data.getU16(&offset);
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool abbrevsOK = debug_info_data.getU32(&offset) == abbrevs->getOffset();
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Abbrevs = abbrevs;
665d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    AddrSize = debug_info_data.getU8(&offset);
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool versionOK = DWARFContext::isSupportedVersion(Version);
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (versionOK && addrSizeOK && abbrevsOK &&
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        debug_info_data.isValidOffset(offset))
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return offset;
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return 0;
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
7772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
785eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFCompileUnit::extractRangeList(uint32_t RangeListOffset,
795eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                        DWARFDebugRangeList &RangeList) const {
805eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Require that compile unit is extracted.
815eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  assert(DieArray.size() > 0);
825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DataExtractor RangesData(Context.getRangeSection(),
835eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                           Context.isLittleEndian(), AddrSize);
845eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return RangeList.extract(RangesData, &RangeListOffset);
855eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
865eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::clear() {
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = 0;
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Length = 0;
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Version = 0;
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Abbrevs = 0;
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  AddrSize = 0;
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  BaseAddr = 0;
943e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  clearDIEs(false);
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::dump(raw_ostream &OS) {
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << format("0x%08x", Offset) << ": Compile Unit:"
9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " length = " << format("0x%08x", Length)
10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " version = " << format("0x%04x", Version)
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " abbr_offset = " << format("0x%04x", Abbrevs->getOffset())
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " addr_size = " << format("0x%02x", AddrSize)
10372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " (next CU at " << format("0x%08x", getNextCompileUnitOffset())
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << ")\n";
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
106fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
107fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  assert(CU && "Null Compile Unit?");
108fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  CU->dump(OS, this, -1U);
10972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
11072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11171d94f805514f28730bf39143ee227648d521d09Alexey Samsonovconst char *DWARFCompileUnit::getCompilationDir() {
11271d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  extractDIEsIfNeeded(true);
11371d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  if (DieArray.empty())
11471d94f805514f28730bf39143ee227648d521d09Alexey Samsonov    return 0;
11571d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
11671d94f805514f28730bf39143ee227648d521d09Alexey Samsonov}
11771d94f805514f28730bf39143ee227648d521d09Alexey Samsonov
11872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::setDIERelations() {
11972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (DieArray.empty())
12072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
12172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front();
12272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back();
12372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *curr_die;
12472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We purposely are skipping the last element in the array in the loop below
12572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // so that we can always have a valid next item
12672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
12772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Since our loop doesn't include the last element, we can always
12872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // safely access the next die in the array.
12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFDebugInfoEntryMinimal *next_die = curr_die + 1;
13072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFAbbreviationDeclaration *curr_die_abbrev =
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      curr_die->getAbbreviationDeclarationPtr();
13372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (curr_die_abbrev) {
13572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Normal DIE
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (curr_die_abbrev->hasChildren())
13772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        next_die->setParent(curr_die);
13872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      else
13972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        curr_die->setSibling(next_die);
14072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
14172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // NULL DIE that terminates a sibling chain
14272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      DWARFDebugInfoEntryMinimal *parent = curr_die->getParent();
14372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (parent)
14472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        parent->setSibling(next_die);
14572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
14672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Since we skipped the last element, we need to fix it up!
14972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (die_array_begin < die_array_end)
15072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    curr_die->setParent(die_array_begin);
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
15272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramersize_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) {
15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const size_t initial_die_array_size = DieArray.size();
15572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if ((cu_die_only && initial_die_array_size > 0) ||
15672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      initial_die_array_size > 1)
15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return 0; // Already parsed
15872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Set the offset to that of the first DIE and calculate the start of the
16072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // next compilation unit header.
16172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = getFirstDIEOffset();
16272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t next_cu_offset = getNextCompileUnitOffset();
16372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal die;
16572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Keep a flat array of the DIE for binary lookup by DIE offset
16672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t depth = 0;
16772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We are in our compile unit, parse starting at the offset
16872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // we were told to parse
16972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const uint8_t *fixed_form_sizes =
17172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFFormValue::getFixedFormSizesForAddressSize(getAddressByteSize());
17272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  while (offset < next_cu_offset &&
17472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer         die.extractFast(this, fixed_form_sizes, &offset)) {
17572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (depth == 0) {
17772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint64_t base_addr =
17872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        die.getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
17972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (base_addr == -1U)
18072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
18172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      setBaseAddress(base_addr);
18272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
18372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (cu_die_only) {
18572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      addDIE(die);
18672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return 1;
18772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
1885d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    else if (depth == 0 && initial_die_array_size == 1)
18972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Don't append the CU die as we already did that
1905d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher      ;
1915d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    else
1925d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher      addDIE(die);
19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFAbbreviationDeclaration *abbrDecl =
19572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      die.getAbbreviationDeclarationPtr();
19672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrDecl) {
19772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Normal DIE
19872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (abbrDecl->hasChildren())
19972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        ++depth;
20072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
20172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // NULL DIE.
20272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (depth > 0)
20372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        --depth;
20472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (depth == 0)
20572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        break;  // We are done with this compile unit!
20672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
20772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
20872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
20972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Give a little bit of info if we encounter corrupt DWARF (our offset
21172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // should always terminate at or before the start of the next compilation
21272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // unit header).
2131a145c409af461a12a385540e7a0781eec13e9daEric Christopher  if (offset > next_cu_offset)
2145d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    fprintf(stderr, "warning: DWARF compile unit extends beyond its"
2155d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher                    "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), offset);
21672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  setDIERelations();
21872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return DieArray.size();
21972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
22010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
22110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramervoid DWARFCompileUnit::clearDIEs(bool keep_compile_unit_die) {
2223e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  if (DieArray.size() > (unsigned)keep_compile_unit_die) {
22310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // std::vectors never get any smaller when resized to a smaller size,
22410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // or when clear() or erase() are called, the size will report that it
22510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // is smaller, but the memory allocated remains intact (call capacity()
22610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // to see this). So we need to create a temporary vector and swap the
22710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents which will cause just the internal pointers to be swapped
22810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // so that when "tmp_array" goes out of scope, it will destroy the
22910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents.
23010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
23110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // Save at least the compile unit DIE
23210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    std::vector<DWARFDebugInfoEntryMinimal> tmpArray;
23310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    DieArray.swap(tmpArray);
23410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    if (keep_compile_unit_die)
23510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer      DieArray.push_back(tmpArray.front());
23610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  }
23710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
23810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
23910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramervoid
24010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin KramerDWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
24110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer                                         bool clear_dies_if_already_not_parsed){
24210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // This function is usually called if there in no .debug_aranges section
24310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // in order to produce a compile unit level set of address ranges that
24410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // is accurate. If the DIEs weren't parsed, then we don't want all dies for
24510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // all compile units to stay loaded when they weren't needed. So we can end
24610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // up parsing the DWARF and then throwing them all away to keep memory usage
24710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // down.
2483e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
2493e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov                          clear_dies_if_already_not_parsed;
25010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  DieArray[0].buildAddressRangeTable(this, debug_aranges);
25110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
25210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // Keep memory down by clearing DIEs if this generate function
25310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // caused them to be parsed.
25410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  if (clear_dies)
25510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    clearDIEs(true);
25610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
2573e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
2585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFDebugInfoEntryMinimal::InlinedChain
2595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
2605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // First, find a subprogram that contains the given address (the root
2615eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // of inlined chain).
262a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  extractDIEsIfNeeded(false);
2635eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  const DWARFDebugInfoEntryMinimal *SubprogramDIE = 0;
264a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  for (size_t i = 0, n = DieArray.size(); i != n; i++) {
2655eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (DieArray[i].isSubprogramDIE() &&
2665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        DieArray[i].addressRangeContainsAddress(this, Address)) {
2675eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      SubprogramDIE = &DieArray[i];
2685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      break;
2695eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
2703e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
2715eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Get inlined chain rooted at this subprogram DIE.
2725eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (!SubprogramDIE)
2735eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return DWARFDebugInfoEntryMinimal::InlinedChain();
2745eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return SubprogramDIE->getInlinedChainForAddress(this, Address);
2753e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov}
276