diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFUnit.h')
| -rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFUnit.h | 209 |
1 files changed, 130 insertions, 79 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 178c894686ee..8aa1e449f3ed 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -1,9 +1,8 @@ //===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -32,11 +31,52 @@ enum DWARFProducer { eProcucerOther }; -class DWARFUnit { +/// Base class describing the header of any kind of "unit." Some information +/// is specific to certain unit types. We separate this class out so we can +/// parse the header before deciding what specific kind of unit to construct. +class DWARFUnitHeader { + dw_offset_t m_offset = 0; + dw_offset_t m_length = 0; + uint16_t m_version = 0; + dw_offset_t m_abbr_offset = 0; + uint8_t m_unit_type = 0; + uint8_t m_addr_size = 0; + + uint64_t m_type_hash = 0; + uint32_t m_type_offset = 0; + + uint64_t m_dwo_id = 0; + + DWARFUnitHeader() = default; + +public: + dw_offset_t GetOffset() const { return m_offset; } + uint16_t GetVersion() const { return m_version; } + uint16_t GetAddressByteSize() const { return m_addr_size; } + dw_offset_t GetLength() const { return m_length; } + dw_offset_t GetAbbrOffset() const { return m_abbr_offset; } + uint8_t GetUnitType() const { return m_unit_type; } + uint64_t GetTypeHash() const { return m_type_hash; } + dw_offset_t GetTypeOffset() const { return m_type_offset; } + bool IsTypeUnit() const { + return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type; + } + uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; } + + static llvm::Expected<DWARFUnitHeader> + extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, + lldb::offset_t *offset_ptr); +}; + +class DWARFUnit : public lldb_private::UserID { using die_iterator_range = llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>; public: + static llvm::Expected<DWARFUnitSP> + extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid, + const lldb_private::DWARFDataExtractor &debug_info, + DIERef::Section section, lldb::offset_t *offset_ptr); virtual ~DWARFUnit(); void ExtractUnitDIEIfNeeded(); @@ -46,7 +86,7 @@ public: DWARFUnit *m_cu; public: bool m_clear_dies = false; - ScopedExtractDIEs(DWARFUnit *cu); + ScopedExtractDIEs(DWARFUnit &cu); ~ScopedExtractDIEs(); DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs); ScopedExtractDIEs(ScopedExtractDIEs &&rhs); @@ -55,69 +95,61 @@ public: ScopedExtractDIEs ExtractDIEsScoped(); DWARFDIE LookupAddress(const dw_addr_t address); - size_t AppendDIEsWithTag(const dw_tag_t tag, - DWARFDIECollection &matching_dies, + size_t AppendDIEsWithTag(const dw_tag_t tag, std::vector<DWARFDIE> &dies, uint32_t depth = UINT32_MAX) const; bool Verify(lldb_private::Stream *s) const; virtual void Dump(lldb_private::Stream *s) const = 0; - //------------------------------------------------------------------ /// Get the data that contains the DIE information for this unit. /// /// This will return the correct bytes that contain the data for /// this DWARFUnit. It could be .debug_info or .debug_types /// depending on where the data for this unit originates. /// - /// @return + /// \return /// The correct data for the DIE information in this unit. - //------------------------------------------------------------------ - virtual const lldb_private::DWARFDataExtractor &GetData() const = 0; - //------------------------------------------------------------------ - /// Get the size in bytes of the compile unit header. + const lldb_private::DWARFDataExtractor &GetData() const; + + /// Get the size in bytes of the unit header. /// - /// @return - /// Byte size of the compile unit header - //------------------------------------------------------------------ - virtual uint32_t GetHeaderByteSize() const = 0; + /// \return + /// Byte size of the unit header + uint32_t GetHeaderByteSize() const; + // Offset of the initial length field. - dw_offset_t GetOffset() const { return m_offset; } - lldb::user_id_t GetID() const; - //------------------------------------------------------------------ + dw_offset_t GetOffset() const { return m_header.GetOffset(); } /// Get the size in bytes of the length field in the header. /// - /// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4 - /// are 0xFFFFFFFF followed by the actual 64 bit length. + /// In DWARF32 this is just 4 bytes /// - /// @return + /// \return /// Byte size of the compile unit header length field - //------------------------------------------------------------------ - size_t GetLengthByteSize() const { return IsDWARF64() ? 12 : 4; } - + size_t GetLengthByteSize() const { return 4; } + bool ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && - die_offset < GetNextCompileUnitOffset(); + die_offset < GetNextUnitOffset(); } dw_offset_t GetFirstDIEOffset() const { - return m_offset + GetHeaderByteSize(); + return GetOffset() + GetHeaderByteSize(); } - dw_offset_t GetNextCompileUnitOffset() const; + dw_offset_t GetNextUnitOffset() const { return m_header.GetNextUnitOffset(); } // Size of the CU data (without initial length and without header). size_t GetDebugInfoSize() const; // Size of the CU data incl. header but without initial length. - uint32_t GetLength() const { return m_length; } - uint16_t GetVersion() const { return m_version; } + uint32_t GetLength() const { return m_header.GetLength(); } + uint16_t GetVersion() const { return m_header.GetVersion(); } const DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; - uint8_t GetAddressByteSize() const { return m_addr_size; } - dw_addr_t GetBaseAddress() const { return m_base_addr; } + uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); } dw_addr_t GetAddrBase() const { return m_addr_base; } + dw_addr_t GetBaseAddress() const { return m_base_addr; } + dw_offset_t GetLineTableOffset(); dw_addr_t GetRangesBase() const { return m_ranges_base; } dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; } void SetAddrBase(dw_addr_t addr_base); void SetRangesBase(dw_addr_t ranges_base); - void SetBaseObjOffset(dw_offset_t base_obj_offset); void SetStrOffsetsBase(dw_offset_t str_offsets_base); - void BuildAddressRangeTable(SymbolFileDWARF *dwarf, - DWARFDebugAranges *debug_aranges); + virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0; lldb::ByteOrder GetByteOrder() const; @@ -125,8 +157,6 @@ public: const DWARFDebugAranges &GetFunctionAranges(); - DWARFFormValue::FixedFormSizes GetFixedFormSizes(); - void SetBaseAddress(dw_addr_t base_addr); DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); } @@ -135,9 +165,9 @@ public: DWARFDIE GetDIE(dw_offset_t die_offset); - static uint8_t GetAddressByteSize(const DWARFUnit *cu); + DWARFUnit &GetNonSkeletonUnit(); - static bool IsDWARF64(const DWARFUnit *cu); + static uint8_t GetAddressByteSize(const DWARFUnit *cu); static uint8_t GetDefaultAddressSize(); @@ -151,7 +181,7 @@ public: bool Supports_unnamed_objc_bitfields(); - SymbolFileDWARF *GetSymbolFileDWARF() const; + SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; } DWARFProducer GetProducer(); @@ -165,24 +195,65 @@ public: lldb::LanguageType GetLanguageType(); - bool IsDWARF64() const { return m_is_dwarf64; } - bool GetIsOptimized(); - SymbolFileDWARFDwo *GetDwoSymbolFile() const; + const lldb_private::FileSpec &GetCompilationDirectory(); + const lldb_private::FileSpec &GetAbsolutePath(); + lldb_private::FileSpec GetFile(size_t file_idx); + lldb_private::FileSpec::Style GetPathStyle(); - dw_offset_t GetBaseObjOffset() const; + SymbolFileDWARFDwo *GetDwoSymbolFile() const; die_iterator_range dies() { ExtractDIEsIfNeeded(); return die_iterator_range(m_die_array.begin(), m_die_array.end()); } + DIERef::Section GetDebugSection() const { return m_section; } + + uint8_t GetUnitType() const { return m_header.GetUnitType(); } + bool IsTypeUnit() const { return m_header.IsTypeUnit(); } + + /// Return a list of address ranges resulting from a (possibly encoded) + /// range list starting at a given offset in the appropriate ranges section. + llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset) const; + + /// Return a list of address ranges retrieved from an encoded range + /// list whose offset is found via a table lookup given an index (DWARF v5 + /// and later). + llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index) const; + protected: - DWARFUnit(SymbolFileDWARF *dwarf); + DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, + const DWARFUnitHeader &header, + const DWARFAbbreviationDeclarationSet &abbrevs, + DIERef::Section section); + + llvm::Error ExtractHeader(SymbolFileDWARF &dwarf, + const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); + + // Get the DWARF unit DWARF debug information entry. Parse the single DIE + // if needed. + const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() { + ExtractUnitDIEIfNeeded(); + // m_first_die_mutex is not required as m_first_die is never cleared. + if (!m_first_die) + return NULL; + return &m_first_die; + } + + // Get all DWARF debug informration entries. Parse all DIEs if needed. + const DWARFDebugInfoEntry *DIEPtr() { + ExtractDIEsIfNeeded(); + if (m_die_array.empty()) + return NULL; + return &m_die_array[0]; + } - SymbolFileDWARF *m_dwarf = nullptr; + SymbolFileDWARF &m_dwarf; std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file; + DWARFUnitHeader m_header; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; // The compile unit debug information entry item @@ -200,54 +271,34 @@ protected: llvm::sys::RWMutex m_first_die_mutex; // A table similar to the .debug_aranges table, but this one points to the // exact DW_TAG_subprogram DIEs - std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; + std::unique_ptr<DWARFDebugAranges> m_func_aranges_up; dw_addr_t m_base_addr = 0; - dw_offset_t m_length = 0; - uint16_t m_version = 0; - uint8_t m_addr_size = 0; - uint8_t m_unit_type = 0; - uint64_t m_dwo_id = 0; DWARFProducer m_producer = eProducerInvalid; uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; uint32_t m_producer_version_update = 0; lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; - bool m_is_dwarf64 = false; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; + llvm::Optional<lldb_private::FileSpec> m_comp_dir; + llvm::Optional<lldb_private::FileSpec> m_file_spec; dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base - // If this is a dwo compile unit this is the offset of the base compile unit - // in the main object file - dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; + + /// Value of DW_AT_stmt_list. + dw_offset_t m_line_table_offset = DW_INVALID_OFFSET; + dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. - // Offset of the initial length field. - dw_offset_t m_offset; + const DIERef::Section m_section; private: void ParseProducerInfo(); void ExtractDIEsRWLocked(); void ClearDIEsRWLocked(); - // Get the DWARF unit DWARF debug informration entry. Parse the single DIE - // if needed. - const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() { - ExtractUnitDIEIfNeeded(); - // m_first_die_mutex is not required as m_first_die is never cleared. - if (!m_first_die) - return NULL; - return &m_first_die; - } - - // Get all DWARF debug informration entries. Parse all DIEs if needed. - const DWARFDebugInfoEntry *DIEPtr() { - ExtractDIEsIfNeeded(); - if (m_die_array.empty()) - return NULL; - return &m_die_array[0]; - } - void AddUnitDIE(const DWARFDebugInfoEntry &cu_die); - void ExtractDIEsEndCheck(lldb::offset_t offset) const; + + void ComputeCompDirAndGuessPathStyle(); + void ComputeAbsolutePath(); DISALLOW_COPY_AND_ASSIGN(DWARFUnit); }; |
