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