File: DIERef.h

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (141 lines) | stat: -rw-r--r-- 5,560 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//===-- DIERef.h ------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H

#include "lldb/Core/dwarf.h"
#include "lldb/Utility/LLDBAssert.h"
#include <cassert>
#include <optional>

/// Identifies a DWARF debug info entry within a given Module. It contains three
/// "coordinates":
/// - file_index: identifies the separate stand alone debug info file
///   that is referred to by the main debug info file. This will be the
///   index of a DWO file for fission, or the .o file on mac when not
///   using a dSYM file. If this field is not set, then this references
///   a DIE inside the original object file.
/// - section: identifies the section of the debug info entry in the given file:
///   debug_info or debug_types.
/// - die_offset: The offset of the debug info entry as an absolute offset from
///   the beginning of the section specified in the section field.
class DIERef {
public:
  enum Section : uint8_t { DebugInfo, DebugTypes };
  DIERef(std::optional<uint32_t> file_index, Section section,
         dw_offset_t die_offset)
      : m_die_offset(die_offset), m_file_index(file_index.value_or(0)),
        m_file_index_valid(file_index ? true : false), m_section(section) {
    assert(this->file_index() == file_index && "File Index is out of range?");
  }

  explicit DIERef(lldb::user_id_t uid) {
    m_die_offset = uid & k_die_offset_mask;
    m_file_index_valid = (uid & k_file_index_valid_bit) != 0;
    m_file_index = m_file_index_valid
                       ? (uid >> k_die_offset_bit_size) & k_file_index_mask
                       : 0;
    m_section =
        (uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo;
  }

  lldb::user_id_t get_id() const {
    if (m_die_offset == k_die_offset_mask)
      return LLDB_INVALID_UID;

    return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size |
           die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) |
           (section() == Section::DebugTypes ? k_section_bit : 0);
  }

  std::optional<uint32_t> file_index() const {
    if (m_file_index_valid)
      return m_file_index;
    return std::nullopt;
  }

  Section section() const { return static_cast<Section>(m_section); }

  dw_offset_t die_offset() const { return m_die_offset; }

  bool operator<(DIERef other) const {
    if (m_file_index_valid != other.m_file_index_valid)
      return m_file_index_valid < other.m_file_index_valid;
    if (m_file_index_valid && (m_file_index != other.m_file_index))
      return m_file_index < other.m_file_index;
    if (m_section != other.m_section)
      return m_section < other.m_section;
    return m_die_offset < other.m_die_offset;
  }

  bool operator==(const DIERef &rhs) const {
    return file_index() == rhs.file_index() && m_section == rhs.m_section &&
           m_die_offset == rhs.m_die_offset;
  }

  bool operator!=(const DIERef &rhs) const { return !(*this == rhs); }

  /// Decode a serialized version of this object from data.
  ///
  /// \param data
  ///   The decoder object that references the serialized data.
  ///
  /// \param offset_ptr
  ///   A pointer that contains the offset from which the data will be decoded
  ///   from that gets updated as data gets decoded.
  ///
  /// \return
  ///   Returns a valid DIERef if decoding succeeded, std::nullopt if there was
  ///   unsufficient or invalid values that were decoded.
  static std::optional<DIERef> Decode(const lldb_private::DataExtractor &data,
                                      lldb::offset_t *offset_ptr);

  /// Encode this object into a data encoder object.
  ///
  /// This allows this object to be serialized to disk.
  ///
  /// \param encoder
  ///   A data encoder object that serialized bytes will be encoded into.
  ///
  void Encode(lldb_private::DataEncoder &encoder) const;

  static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;
  static constexpr uint64_t k_file_index_bit_size =
      64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;

  static constexpr uint64_t k_file_index_valid_bit =
      (1ull << (k_file_index_bit_size + k_die_offset_bit_size));
  static constexpr uint64_t k_section_bit =
      (1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1));
  static constexpr uint64_t
      k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff;
  static constexpr uint64_t k_die_offset_mask = (~0ull) >>
                                                (64 - k_die_offset_bit_size);

private:
  // Allow 2TB of .debug_info/.debug_types offset
  dw_offset_t m_die_offset : k_die_offset_bit_size;
  // Used for DWO index or for .o file index on mac
  dw_offset_t m_file_index : k_file_index_bit_size;
  // Set to 1 if m_file_index is a DWO number
  dw_offset_t m_file_index_valid : 1;
  // Set to 0 for .debug_info 1 for .debug_types,
  dw_offset_t m_section : 1;
};
static_assert(sizeof(DIERef) == 8);

typedef std::vector<DIERef> DIEArray;

namespace llvm {
template<> struct format_provider<DIERef> {
  static void format(const DIERef &ref, raw_ostream &OS, StringRef Style);
};
} // namespace llvm

#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H