Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
39645 views
//===-- DIERef.h ------------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H9#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H1011#include "lldb/Core/dwarf.h"12#include "lldb/Utility/LLDBAssert.h"13#include <cassert>14#include <optional>1516namespace lldb_private::plugin {17namespace dwarf {18/// Identifies a DWARF debug info entry within a given Module. It contains three19/// "coordinates":20/// - file_index: identifies the separate stand alone debug info file21/// that is referred to by the main debug info file. This will be the22/// index of a DWO file for fission, or the .o file on mac when not23/// using a dSYM file. If this field is not set, then this references24/// a DIE inside the original object file.25/// - section: identifies the section of the debug info entry in the given file:26/// debug_info or debug_types.27/// - die_offset: The offset of the debug info entry as an absolute offset from28/// the beginning of the section specified in the section field.29class DIERef {30public:31enum Section : uint8_t { DebugInfo, DebugTypes };32DIERef(std::optional<uint32_t> file_index, Section section,33dw_offset_t die_offset)34: m_die_offset(die_offset), m_file_index(file_index.value_or(0)),35m_file_index_valid(file_index ? true : false), m_section(section) {36assert(this->file_index() == file_index && "File Index is out of range?");37}3839explicit DIERef(lldb::user_id_t uid) {40m_die_offset = uid & k_die_offset_mask;41m_file_index_valid = (uid & k_file_index_valid_bit) != 0;42m_file_index = m_file_index_valid43? (uid >> k_die_offset_bit_size) & k_file_index_mask44: 0;45m_section =46(uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo;47}4849lldb::user_id_t get_id() const {50if (m_die_offset == k_die_offset_mask)51return LLDB_INVALID_UID;5253return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size |54die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) |55(section() == Section::DebugTypes ? k_section_bit : 0);56}5758std::optional<uint32_t> file_index() const {59if (m_file_index_valid)60return m_file_index;61return std::nullopt;62}6364Section section() const { return static_cast<Section>(m_section); }6566dw_offset_t die_offset() const { return m_die_offset; }6768bool operator<(DIERef other) const {69if (m_file_index_valid != other.m_file_index_valid)70return m_file_index_valid < other.m_file_index_valid;71if (m_file_index_valid && (m_file_index != other.m_file_index))72return m_file_index < other.m_file_index;73if (m_section != other.m_section)74return m_section < other.m_section;75return m_die_offset < other.m_die_offset;76}7778bool operator==(const DIERef &rhs) const {79return file_index() == rhs.file_index() && m_section == rhs.m_section &&80m_die_offset == rhs.m_die_offset;81}8283bool operator!=(const DIERef &rhs) const { return !(*this == rhs); }8485/// Decode a serialized version of this object from data.86///87/// \param data88/// The decoder object that references the serialized data.89///90/// \param offset_ptr91/// A pointer that contains the offset from which the data will be decoded92/// from that gets updated as data gets decoded.93///94/// \return95/// Returns a valid DIERef if decoding succeeded, std::nullopt if there was96/// unsufficient or invalid values that were decoded.97static std::optional<DIERef> Decode(const DataExtractor &data,98lldb::offset_t *offset_ptr);99100/// Encode this object into a data encoder object.101///102/// This allows this object to be serialized to disk.103///104/// \param encoder105/// A data encoder object that serialized bytes will be encoded into.106///107void Encode(DataEncoder &encoder) const;108109static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;110static constexpr uint64_t k_file_index_bit_size =11164 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;112113static constexpr uint64_t k_file_index_valid_bit =114(1ull << (k_file_index_bit_size + k_die_offset_bit_size));115static constexpr uint64_t k_section_bit =116(1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1));117static constexpr uint64_t118k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff;119static constexpr uint64_t k_die_offset_mask = (~0ull) >>120(64 - k_die_offset_bit_size);121122private:123// Allow 2TB of .debug_info/.debug_types offset124dw_offset_t m_die_offset : k_die_offset_bit_size;125// Used for DWO index or for .o file index on mac126dw_offset_t m_file_index : k_file_index_bit_size;127// Set to 1 if m_file_index is a DWO number128dw_offset_t m_file_index_valid : 1;129// Set to 0 for .debug_info 1 for .debug_types,130dw_offset_t m_section : 1;131};132static_assert(sizeof(DIERef) == 8);133134typedef std::vector<DIERef> DIEArray;135} // namespace dwarf136} // namespace lldb_private::plugin137138namespace llvm {139template <> struct format_provider<lldb_private::plugin::dwarf::DIERef> {140static void format(const lldb_private::plugin::dwarf::DIERef &ref,141raw_ostream &OS, StringRef Style);142};143} // namespace llvm144145#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H146147148