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