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"
12cd61455798777446f35723fdb77f54a17e602009Alexey Samsonov#include "llvm/DebugInfo/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
15040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonovvoid DWARFCompileUnit::extractDIEsToVector(
15140d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    bool AppendCUDie, bool AppendNonCUDies,
15240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    std::vector<DWARFDebugInfoEntryMinimal> &Dies) const {
15340d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  if (!AppendCUDie && !AppendNonCUDies)
15440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    return;
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.
15840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  uint32_t Offset = getFirstDIEOffset();
15940d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  uint32_t NextCUOffset = getNextCompileUnitOffset();
16040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  DWARFDebugInfoEntryMinimal DIE;
16140d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  uint32_t Depth = 0;
16240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  const uint8_t *FixedFormSizes =
16332a3e78304a94ea214aee5fe82b10dd110e8863aAlexey Samsonov    DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion());
16440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  bool IsCUDie = true;
16540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov
16640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  while (Offset < NextCUOffset &&
16740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov         DIE.extractFast(this, FixedFormSizes, &Offset)) {
16840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    if (IsCUDie) {
16940d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      if (AppendCUDie)
17040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov        Dies.push_back(DIE);
17140d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      if (!AppendNonCUDies)
17240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov        break;
17340d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      // The average bytes per DIE entry has been seen to be
17440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      // around 14-20 so let's pre-reserve the needed memory for
17540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      // our DIE entries accordingly.
17640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
17740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      IsCUDie = false;
17840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    } else {
17940d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      Dies.push_back(DIE);
18072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
18172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    const DWARFAbbreviationDeclaration *AbbrDecl =
18340d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      DIE.getAbbreviationDeclarationPtr();
18440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    if (AbbrDecl) {
18572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // Normal DIE
18640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      if (AbbrDecl->hasChildren())
18740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov        ++Depth;
18872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
18972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // NULL DIE.
19040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      if (Depth > 0)
19140d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov        --Depth;
19240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      if (Depth == 0)
19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        break;  // We are done with this compile unit!
19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
19572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
19672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
19772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Give a little bit of info if we encounter corrupt DWARF (our offset
19872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // should always terminate at or before the start of the next compilation
19972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // unit header).
20040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  if (Offset > NextCUOffset)
201642469f5826a29beb7d8abf675fc669c42f804c9Eric Christopher    fprintf(stderr, "warning: DWARF compile unit extends beyond its "
20240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov                    "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset);
20340d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov}
20440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov
20540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonovsize_t DWARFCompileUnit::extractDIEsIfNeeded(bool CUDieOnly) {
20640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  if ((CUDieOnly && DieArray.size() > 0) ||
20740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      DieArray.size() > 1)
20840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    return 0; // Already parsed.
20940d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov
21040d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  extractDIEsToVector(DieArray.empty(), !CUDieOnly, DieArray);
21140d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov
21240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  // Set the base address of current compile unit.
21340d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  if (!DieArray.empty()) {
21440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    uint64_t BaseAddr =
21540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
21640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    if (BaseAddr == -1U)
21740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      BaseAddr = DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
21840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    setBaseAddress(BaseAddr);
21940d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  }
22072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  setDIERelations();
22272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return DieArray.size();
22372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
22410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
22540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonovvoid DWARFCompileUnit::clearDIEs(bool KeepCUDie) {
22640d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov  if (DieArray.size() > (unsigned)KeepCUDie) {
22710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // std::vectors never get any smaller when resized to a smaller size,
22810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // or when clear() or erase() are called, the size will report that it
22910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // is smaller, but the memory allocated remains intact (call capacity()
23010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // to see this). So we need to create a temporary vector and swap the
23110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents which will cause just the internal pointers to be swapped
23240d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    // so that when temporary vector goes out of scope, it will destroy the
23310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // contents.
23440d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    std::vector<DWARFDebugInfoEntryMinimal> TmpArray;
23540d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    DieArray.swap(TmpArray);
23610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    // Save at least the compile unit DIE
23740d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov    if (KeepCUDie)
23840d8c69c596e3aa5c2679014f07bb065ced2cb3bAlexey Samsonov      DieArray.push_back(TmpArray.front());
23910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  }
24010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
24110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
24210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramervoid
24310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin KramerDWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
24410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer                                         bool clear_dies_if_already_not_parsed){
24510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // This function is usually called if there in no .debug_aranges section
24610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // in order to produce a compile unit level set of address ranges that
24710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // is accurate. If the DIEs weren't parsed, then we don't want all dies for
24810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // all compile units to stay loaded when they weren't needed. So we can end
24910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // up parsing the DWARF and then throwing them all away to keep memory usage
25010df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // down.
2513e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
2523e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov                          clear_dies_if_already_not_parsed;
25310df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  DieArray[0].buildAddressRangeTable(this, debug_aranges);
25410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
25510df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // Keep memory down by clearing DIEs if this generate function
25610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  // caused them to be parsed.
25710df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer  if (clear_dies)
25810df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer    clearDIEs(true);
25910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer}
2603e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
261e664290ad6d988e0ae40f2461084f6adbababa47Alexey SamsonovDWARFDebugInfoEntryInlinedChain
2625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
2635eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // First, find a subprogram that contains the given address (the root
2645eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // of inlined chain).
265a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  extractDIEsIfNeeded(false);
2665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  const DWARFDebugInfoEntryMinimal *SubprogramDIE = 0;
267a9543aadffcee08d1e49ec9b6904db55671f71f3Alexey Samsonov  for (size_t i = 0, n = DieArray.size(); i != n; i++) {
2685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (DieArray[i].isSubprogramDIE() &&
2695eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        DieArray[i].addressRangeContainsAddress(this, Address)) {
2705eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      SubprogramDIE = &DieArray[i];
2715eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      break;
2725eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
2733e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
2745eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Get inlined chain rooted at this subprogram DIE.
2755eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (!SubprogramDIE)
276e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    return DWARFDebugInfoEntryInlinedChain();
2775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return SubprogramDIE->getInlinedChainForAddress(this, Address);
2783e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov}
279