diff options
Diffstat (limited to 'include/llvm/DebugInfo/DWARF/DWARFUnit.h')
| -rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFUnit.h | 100 |
1 files changed, 92 insertions, 8 deletions
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index e9178e03fa8a..3cec58383f87 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -165,6 +165,29 @@ struct BaseAddress { uint64_t SectionIndex; }; +/// Represents a unit's contribution to the string offsets table. +struct StrOffsetsContributionDescriptor { + uint64_t Base = 0; + uint64_t Size = 0; + /// Format and version. + DWARFFormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32}; + + StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size, + uint8_t Version, dwarf::DwarfFormat Format) + : Base(Base), Size(Size), FormParams({Version, 0, Format}) {} + + uint8_t getVersion() const { return FormParams.Version; } + dwarf::DwarfFormat getFormat() const { return FormParams.Format; } + uint8_t getDwarfOffsetByteSize() const { + return FormParams.getDwarfOffsetByteSize(); + } + /// Determine whether a contribution to the string offsets table is + /// consistent with the relevant section size and that its length is + /// a multiple of the size of one of its entries. + Optional<StrOffsetsContributionDescriptor> + validateContributionSize(DWARFDataExtractor &DA); +}; + class DWARFUnit { DWARFContext &Context; /// Section containing this DWARFUnit. @@ -176,7 +199,6 @@ class DWARFUnit { const DWARFSection &LineSection; StringRef StringSection; const DWARFSection &StringOffsetSection; - uint64_t StringOffsetSectionBase = 0; const DWARFSection *AddrOffsetSection; uint32_t AddrOffsetSectionBase = 0; bool isLittleEndian; @@ -185,6 +207,9 @@ class DWARFUnit { // Version, address size, and DWARF format. DWARFFormParams FormParams; + /// Start, length, and DWARF format of the unit's contribution to the string + /// offsets table (DWARF v5). + Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution; uint32_t Offset; uint32_t Length; @@ -195,10 +220,40 @@ class DWARFUnit { /// The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; - /// Map from range's start address to end address and corresponding DIE. - /// IntervalMap does not support range removal, as a result, we use the - /// std::map::upper_bound for address range lookup. - std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap; + /// The vector of inlined subroutine DIEs that we can map directly to from + /// their subprogram below. + std::vector<DWARFDie> InlinedSubroutineDIEs; + + /// A type representing a subprogram DIE and a map (built using a sorted + /// vector) into that subprogram's inlined subroutine DIEs. + struct SubprogramDIEAddrInfo { + DWARFDie SubprogramDIE; + + uint64_t SubprogramBasePC; + + /// A vector sorted to allow mapping from a relative PC to the inlined + /// subroutine DIE with the most specific address range covering that PC. + /// + /// The PCs are relative to the `SubprogramBasePC`. + /// + /// The vector is sorted in ascending order of the first int which + /// represents the relative PC for an interval in the map. The second int + /// represents the index into the `InlinedSubroutineDIEs` vector of the DIE + /// that interval maps to. An index of '-1` indicates an empty mapping. The + /// interval covered is from the `.first` relative PC to the next entry's + /// `.first` relative PC. + std::vector<std::pair<uint32_t, int32_t>> InlinedSubroutineDIEAddrMap; + }; + + /// Vector of the subprogram DIEs and their subroutine address maps. + std::vector<SubprogramDIEAddrInfo> SubprogramDIEAddrInfos; + + /// A vector sorted to allow mapping from a PC to the subprogram DIE (and + /// associated addr map) index. Subprograms with overlapping PC ranges aren't + /// supported here. Nothing will crash, but the mapping may be inaccurate. + /// This vector may also contain "empty" ranges marked by an address with + /// a DIE index of '-1'. + std::vector<std::pair<uint64_t, int64_t>> SubprogramDIEAddrMap; using die_iterator_range = iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>; @@ -219,6 +274,21 @@ protected: /// Size in bytes of the unit header. virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; } + /// Find the unit's contribution to the string offsets table and determine its + /// length and form. The given offset is expected to be derived from the unit + /// DIE's DW_AT_str_offsets_base attribute. + Optional<StrOffsetsContributionDescriptor> + determineStringOffsetsTableContribution(DWARFDataExtractor &DA, + uint64_t Offset); + + /// Find the unit's contribution to the string offsets table and determine its + /// length and form. The given offset is expected to be 0 in a dwo file or, + /// in a dwp file, the start of the unit's contribution to the string offsets + /// table section (as determined by the index table). + Optional<StrOffsetsContributionDescriptor> + determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA, + uint64_t Offset); + public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, @@ -242,9 +312,6 @@ public: AddrOffsetSectionBase = Base; } - /// Recursively update address to Die map. - void updateAddressDieMap(DWARFDie Die); - void setRangesSection(const DWARFSection *RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; @@ -272,6 +339,10 @@ public: uint32_t getNextUnitOffset() const { return Offset + Length + 4; } uint32_t getLength() const { return Length; } + const Optional<StrOffsetsContributionDescriptor> & + getStringOffsetsTableContribution() const { + return StringOffsetsTableContribution; + } const DWARFFormParams &getFormParams() const { return FormParams; } uint16_t getVersion() const { return FormParams.Version; } dwarf::DwarfFormat getFormat() const { return FormParams.Format; } @@ -281,6 +352,16 @@ public: return FormParams.getDwarfOffsetByteSize(); } + uint8_t getDwarfStringOffsetsByteSize() const { + assert(StringOffsetsTableContribution); + return StringOffsetsTableContribution->getDwarfOffsetByteSize(); + } + + uint64_t getStringOffsetsBase() const { + assert(StringOffsetsTableContribution); + return StringOffsetsTableContribution->Base; + } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const; uint8_t getUnitType() const { return UnitType; } @@ -426,6 +507,9 @@ private: /// parseDWO - Parses .dwo file for current compile unit. Returns true if /// it was actually constructed. bool parseDWO(); + + void buildSubprogramDIEAddrMap(); + void buildInlinedSubroutineDIEAddrMap(SubprogramDIEAddrInfo &SPInfo); }; } // end namespace llvm |
