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