148 lines · c
1//===-- DIERef.h ------------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H10#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H11 12#include "lldb/Core/dwarf.h"13#include "lldb/lldb-defines.h"14#include "lldb/lldb-types.h"15#include <cassert>16#include <optional>17 18namespace lldb_private::plugin {19namespace dwarf {20/// Identifies a DWARF debug info entry within a given Module. It contains three21/// "coordinates":22/// - file_index: identifies the separate stand alone debug info file23/// that is referred to by the main debug info file. This will be the24/// index of a DWO file for fission, or the .o file on mac when not25/// using a dSYM file. If this field is not set, then this references26/// a DIE inside the original object file.27/// - section: identifies the section of the debug info entry in the given file:28/// debug_info or debug_types.29/// - die_offset: The offset of the debug info entry as an absolute offset from30/// the beginning of the section specified in the section field.31class DIERef {32public:33 enum Section : uint8_t { DebugInfo, DebugTypes };34 DIERef(std::optional<uint32_t> file_index, Section section,35 dw_offset_t die_offset)36 : m_die_offset(die_offset), m_file_index(file_index.value_or(0)),37 m_file_index_valid(file_index ? true : false), m_section(section) {38 assert(this->file_index() == file_index && "File Index is out of range?");39 }40 41 explicit DIERef(lldb::user_id_t uid) {42 m_die_offset = uid & k_die_offset_mask;43 m_file_index_valid = (uid & k_file_index_valid_bit) != 0;44 m_file_index = m_file_index_valid45 ? (uid >> k_die_offset_bit_size) & k_file_index_mask46 : 0;47 m_section =48 (uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo;49 }50 51 lldb::user_id_t get_id() const {52 if (m_die_offset == k_die_offset_mask)53 return LLDB_INVALID_UID;54 55 return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size |56 die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) |57 (section() == Section::DebugTypes ? k_section_bit : 0);58 }59 60 std::optional<uint32_t> file_index() const {61 if (m_file_index_valid)62 return m_file_index;63 return std::nullopt;64 }65 66 Section section() const { return static_cast<Section>(m_section); }67 68 dw_offset_t die_offset() const { return m_die_offset; }69 70 bool operator<(DIERef other) const {71 if (m_file_index_valid != other.m_file_index_valid)72 return m_file_index_valid < other.m_file_index_valid;73 if (m_file_index_valid && (m_file_index != other.m_file_index))74 return m_file_index < other.m_file_index;75 if (m_section != other.m_section)76 return m_section < other.m_section;77 return m_die_offset < other.m_die_offset;78 }79 80 bool operator==(const DIERef &rhs) const {81 return file_index() == rhs.file_index() && m_section == rhs.m_section &&82 m_die_offset == rhs.m_die_offset;83 }84 85 bool operator!=(const DIERef &rhs) const { return !(*this == rhs); }86 87 /// Decode a serialized version of this object from data.88 ///89 /// \param data90 /// The decoder object that references the serialized data.91 ///92 /// \param offset_ptr93 /// A pointer that contains the offset from which the data will be decoded94 /// from that gets updated as data gets decoded.95 ///96 /// \return97 /// Returns a valid DIERef if decoding succeeded, std::nullopt if there was98 /// unsufficient or invalid values that were decoded.99 static std::optional<DIERef> Decode(const DataExtractor &data,100 lldb::offset_t *offset_ptr);101 102 /// Encode this object into a data encoder object.103 ///104 /// This allows this object to be serialized to disk.105 ///106 /// \param encoder107 /// A data encoder object that serialized bytes will be encoded into.108 ///109 void Encode(DataEncoder &encoder) const;110 111 static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;112 static constexpr uint64_t k_file_index_bit_size =113 64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;114 115 static constexpr uint64_t k_file_index_valid_bit =116 (1ull << (k_file_index_bit_size + k_die_offset_bit_size));117 static constexpr uint64_t k_section_bit =118 (1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1));119 static constexpr uint64_t120 k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff;121 static constexpr uint64_t k_die_offset_mask = (~0ull) >>122 (64 - k_die_offset_bit_size);123 124private:125 // Allow 2TB of .debug_info/.debug_types offset126 dw_offset_t m_die_offset : k_die_offset_bit_size;127 // Used for DWO index or for .o file index on mac128 dw_offset_t m_file_index : k_file_index_bit_size;129 // Set to 1 if m_file_index is a DWO number130 dw_offset_t m_file_index_valid : 1;131 // Set to 0 for .debug_info 1 for .debug_types,132 dw_offset_t m_section : 1;133};134static_assert(sizeof(DIERef) == 8);135 136typedef std::vector<DIERef> DIEArray;137} // namespace dwarf138} // namespace lldb_private::plugin139 140namespace llvm {141template <> struct format_provider<lldb_private::plugin::dwarf::DIERef> {142 static void format(const lldb_private::plugin::dwarf::DIERef &ref,143 raw_ostream &OS, StringRef Style);144};145} // namespace llvm146 147#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H148