DWARFCompileUnit.cpp revision 82de10a34c9432029040ced17129079a7d80904e
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 {
2082de10a34c9432029040ced17129079a7d80904eEric Christopher  return DataExtractor(InfoSection, isLittleEndian, AddrSize);
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  clear();
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = *offset_ptr;
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info.isValidOffset(*offset_ptr)) {
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint64_t abbrOffset;
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Length = debug_info.getU32(offset_ptr);
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Version = debug_info.getU16(offset_ptr);
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    abbrOffset = debug_info.getU32(offset_ptr);
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    AddrSize = debug_info.getU8(offset_ptr);
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool lengthOK = debug_info.isValidOffset(getNextCompileUnitOffset()-1);
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool versionOK = DWARFContext::isSupportedVersion(Version);
3782de10a34c9432029040ced17129079a7d80904eEric Christopher    bool abbrOffsetOK = AbbrevSection.size() > abbrOffset;
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4082de10a34c9432029040ced17129079a7d80904eEric Christopher    if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && Abbrev != NULL) {
4182de10a34c9432029040ced17129079a7d80904eEric Christopher      Abbrevs = Abbrev->getAbbreviationDeclarationSet(abbrOffset);
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return true;
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // reset the offset to where we tried to parse from if anything went wrong
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    *offset_ptr = Offset;
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return false;
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint32_t
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFCompileUnit::extract(uint32_t offset, DataExtractor debug_info_data,
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                          const DWARFAbbreviationDeclarationSet *abbrevs) {
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  clear();
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = offset;
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info_data.isValidOffset(offset)) {
6072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Length = debug_info_data.getU32(&offset);
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Version = debug_info_data.getU16(&offset);
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool abbrevsOK = debug_info_data.getU32(&offset) == abbrevs->getOffset();
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Abbrevs = abbrevs;
645d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    AddrSize = debug_info_data.getU8(&offset);
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool versionOK = DWARFContext::isSupportedVersion(Version);
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (versionOK && addrSizeOK && abbrevsOK &&
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        debug_info_data.isValidOffset(offset))
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return offset;
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return 0;
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
765eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFCompileUnit::extractRangeList(uint32_t RangeListOffset,
775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                        DWARFDebugRangeList &RangeList) const {
785eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Require that compile unit is extracted.
795eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  assert(DieArray.size() > 0);
8082de10a34c9432029040ced17129079a7d80904eEric Christopher  DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
815eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return RangeList.extract(RangesData, &RangeListOffset);
825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
835eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::clear() {
8572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = 0;
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Length = 0;
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Version = 0;
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Abbrevs = 0;
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  AddrSize = 0;
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  BaseAddr = 0;
913e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  clearDIEs(false);
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::dump(raw_ostream &OS) {
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << format("0x%08x", Offset) << ": Compile Unit:"
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " length = " << format("0x%08x", Length)
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " version = " << format("0x%04x", Version)
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " abbr_offset = " << format("0x%04x", Abbrevs->getOffset())
9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " addr_size = " << format("0x%02x", AddrSize)
10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << " (next CU at " << format("0x%08x", getNextCompileUnitOffset())
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer     << ")\n";
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
103fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
104fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  assert(CU && "Null Compile Unit?");
105fa76f22865a8ee2adf29fdd4087b0982b7aedaf2Eric Christopher  CU->dump(OS, this, -1U);
10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10871d94f805514f28730bf39143ee227648d521d09Alexey Samsonovconst char *DWARFCompileUnit::getCompilationDir() {
10971d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  extractDIEsIfNeeded(true);
11071d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  if (DieArray.empty())
11171d94f805514f28730bf39143ee227648d521d09Alexey Samsonov    return 0;
11271d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
11371d94f805514f28730bf39143ee227648d521d09Alexey Samsonov}
11471d94f805514f28730bf39143ee227648d521d09Alexey Samsonov
11572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFCompileUnit::setDIERelations() {
11672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (DieArray.empty())
11772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
11872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front();
11972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back();
12072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *curr_die;
12172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We purposely are skipping the last element in the array in the loop below
12272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // so that we can always have a valid next item
12372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
12472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // Since our loop doesn't include the last element, we can always
12572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    // safely access the next die in the array.
12672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFDebugInfoEntryMinimal *next_die = curr_die + 1;
12772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
12872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFAbbreviationDeclaration *curr_die_abbrev =
12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      curr_die->getAbbreviationDeclarationPtr();
13072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (curr_die_abbrev) {
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Normal DIE
13372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (curr_die_abbrev->hasChildren())
13472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        next_die->setParent(curr_die);
13572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      else
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        curr_die->setSibling(next_die);
13772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
13872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // NULL DIE that terminates a sibling chain
13972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      DWARFDebugInfoEntryMinimal *parent = curr_die->getParent();
14072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (parent)
14172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        parent->setSibling(next_die);
14272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
14372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
14472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Since we skipped the last element, we need to fix it up!
14672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (die_array_begin < die_array_end)
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    curr_die->setParent(die_array_begin);
14872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
14972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramersize_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) {
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const size_t initial_die_array_size = DieArray.size();
15272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if ((cu_die_only && initial_die_array_size > 0) ||
15372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      initial_die_array_size > 1)
15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return 0; // Already parsed
15572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Set the offset to that of the first DIE and calculate the start of the
15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // next compilation unit header.
15872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = getFirstDIEOffset();
15972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t next_cu_offset = getNextCompileUnitOffset();
16072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal die;
16272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Keep a flat array of the DIE for binary lookup by DIE offset
16372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t depth = 0;
16472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We are in our compile unit, parse starting at the offset
16572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // we were told to parse
16672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const uint8_t *fixed_form_sizes =
16872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFFormValue::getFixedFormSizesForAddressSize(getAddressByteSize());
16972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  while (offset < next_cu_offset &&
17172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer         die.extractFast(this, fixed_form_sizes, &offset)) {
17272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (depth == 0) {
17472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      uint64_t base_addr =
17572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        die.getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
17672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (base_addr == -1U)
17772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
17872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      setBaseAddress(base_addr);
17972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
18072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (cu_die_only) {
18272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      addDIE(die);
18372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return 1;
18472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
1855d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    else if (depth == 0 && initial_die_array_size == 1)
18672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Don't append the CU die as we already did that
1875d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher      ;
1885d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    else
1895d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher      addDIE(die);
19072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
19172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    const DWARFAbbreviationDeclaration *abbrDecl =
19272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      die.getAbbreviationDeclarationPtr();
19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrDecl) {
19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Normal DIE
19572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (abbrDecl->hasChildren())
19672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        ++depth;
19772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
19872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // NULL DIE.
19972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (depth > 0)
20072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        --depth;
20172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (depth == 0)
20272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        break;  // We are done with this compile unit!
20372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
20472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
20572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
20672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
20772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Give a little bit of info if we encounter corrupt DWARF (our offset
20872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // should always terminate at or before the start of the next compilation
20972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // unit header).
2101a145c409af461a12a385540e7a0781eec13e9daEric Christopher  if (offset > next_cu_offset)
2115d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher    fprintf(stderr, "warning: DWARF compile unit extends beyond its"
2125d04a3ad0e202a50122d6739c9af533575254a80Eric Christopher                    "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), offset);
21372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  setDIERelations();
21572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return DieArray.size();
21672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
21710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
21810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramervoid DWARFCompileUnit::clearDIEs(bool keep_compile_unit_die) {
2193e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  if (DieArray.size() > (unsigned)keep_compile_unit_die) {
22010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // std::vectors never get any smaller when resized to a smaller size,
22110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // or when clear() or erase() are called, the size will report that it
22210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // is smaller, but the memory allocated remains intact (call capacity()
22310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // to see this). So we need to create a temporary vector and swap the
22410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents which will cause just the internal pointers to be swapped
22510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // so that when "tmp_array" goes out of scope, it will destroy the
22610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents.
22710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
22810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // Save at least the compile unit DIE
22910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    std::vector<DWARFDebugInfoEntryMinimal> tmpArray;
23010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    DieArray.swap(tmpArray);
23110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    if (keep_compile_unit_die)
23210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer      DieArray.push_back(tmpArray.front());
23310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  }
23410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
23510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
23610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramervoid
23710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin KramerDWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
23810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer                                         bool clear_dies_if_already_not_parsed){
23910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // This function is usually called if there in no .debug_aranges section
24010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // in order to produce a compile unit level set of address ranges that
24110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // is accurate. If the DIEs weren't parsed, then we don't want all dies for
24210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // all compile units to stay loaded when they weren't needed. So we can end
24310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // up parsing the DWARF and then throwing them all away to keep memory usage
24410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // down.
2453e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
2463e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov                          clear_dies_if_already_not_parsed;
24710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  DieArray[0].buildAddressRangeTable(this, debug_aranges);
24810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
24910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // Keep memory down by clearing DIEs if this generate function
25010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // caused them to be parsed.
25110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  if (clear_dies)
25210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    clearDIEs(true);
25310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
2543e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
2555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFDebugInfoEntryMinimal::InlinedChain
2565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
2575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // First, find a subprogram that contains the given address (the root
2585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // of inlined chain).
259a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  extractDIEsIfNeeded(false);
2605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  const DWARFDebugInfoEntryMinimal *SubprogramDIE = 0;
261a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  for (size_t i = 0, n = DieArray.size(); i != n; i++) {
2625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (DieArray[i].isSubprogramDIE() &&
2635eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        DieArray[i].addressRangeContainsAddress(this, Address)) {
2645eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      SubprogramDIE = &DieArray[i];
2655eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      break;
2665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
2673e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
2685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Get inlined chain rooted at this subprogram DIE.
2695eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (!SubprogramDIE)
2705eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return DWARFDebugInfoEntryMinimal::InlinedChain();
2715eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return SubprogramDIE->getInlinedChainForAddress(this, Address);
2723e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov}
273