void DWARFCompileUnit::extractDIEsToVector( bool AppendCUDie, bool AppendNonCUDies, std::vector<DWARFDebugInfoEntryMinimal> &Dies) const { if (!AppendCUDie && !AppendNonCUDies) return; // Set the offset to that of the first DIE and calculate the start of the // next compilation unit header. uint32_t Offset = getFirstDIEOffset(); uint32_t NextCUOffset = getNextCompileUnitOffset(); DWARFDebugInfoEntryMinimal DIE; uint32_t Depth = 0; const uint8_t *FixedFormSizes = DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion()); bool IsCUDie = true; while (Offset < NextCUOffset && DIE.extractFast(this, FixedFormSizes, &Offset)) { if (IsCUDie) { if (AppendCUDie) Dies.push_back(DIE); if (!AppendNonCUDies) break; // The average bytes per DIE entry has been seen to be // around 14-20 so let's pre-reserve the needed memory for // our DIE entries accordingly. Dies.reserve(Dies.size() + getDebugInfoSize() / 14); IsCUDie = false; } else { Dies.push_back(DIE); } const DWARFAbbreviationDeclaration *AbbrDecl = DIE.getAbbreviationDeclarationPtr(); if (AbbrDecl) { // Normal DIE if (AbbrDecl->hasChildren()) ++Depth; } else { // NULL DIE. if (Depth > 0) --Depth; if (Depth == 0) break; // We are done with this compile unit! } } // Give a little bit of info if we encounter corrupt DWARF (our offset // should always terminate at or before the start of the next compilation // unit header). if (Offset > NextCUOffset) fprintf(stderr, "warning: DWARF compile unit extends beyond its " "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset); }
size_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) { const size_t initial_die_array_size = DieArray.size(); if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) return 0; // Already parsed // Set the offset to that of the first DIE and calculate the start of the // next compilation unit header. uint32_t offset = getFirstDIEOffset(); uint32_t next_cu_offset = getNextCompileUnitOffset(); DWARFDebugInfoEntryMinimal die; // Keep a flat array of the DIE for binary lookup by DIE offset uint32_t depth = 0; // We are in our compile unit, parse starting at the offset // we were told to parse const uint8_t *fixed_form_sizes = DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion()); while (offset < next_cu_offset && die.extractFast(this, fixed_form_sizes, &offset)) { if (depth == 0) { uint64_t base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U); if (base_addr == -1U) base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0); setBaseAddress(base_addr); } if (cu_die_only) { addDIE(die); return 1; } else if (depth == 0 && initial_die_array_size == 1) // Don't append the CU die as we already did that ; else addDIE(die); const DWARFAbbreviationDeclaration *abbrDecl = die.getAbbreviationDeclarationPtr(); if (abbrDecl) { // Normal DIE if (abbrDecl->hasChildren()) ++depth; } else { // NULL DIE. if (depth > 0) --depth; if (depth == 0) break; // We are done with this compile unit! } } // Give a little bit of info if we encounter corrupt DWARF (our offset // should always terminate at or before the start of the next compilation // unit header). if (offset > next_cu_offset) fprintf(stderr, "warning: DWARF compile unit extends beyond its " "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), offset); setDIERelations(); return DieArray.size(); }