File: DWARFLinkerUnit.h

package info (click to toggle)
llvm-toolchain-18 1%3A18.1.8-18
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,908,340 kB
  • sloc: cpp: 6,667,937; ansic: 1,440,452; asm: 883,619; python: 230,549; objc: 76,880; f90: 74,238; lisp: 35,989; pascal: 16,571; sh: 10,229; perl: 7,459; ml: 5,047; awk: 3,523; makefile: 2,987; javascript: 2,149; xml: 892; fortran: 649; cs: 573
file content (223 lines) | stat: -rw-r--r-- 6,755 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
//===- DWARFLinkerUnit.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 LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H
#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H

#include "DWARFLinkerGlobalData.h"
#include "OutputSections.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DWARFLinker/IndexedValuesMap.h"
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
#include "llvm/DWARFLinker/StringPool.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/LEB128.h"

namespace llvm {
namespace dwarf_linker {
namespace parallel {

class DwarfUnit;
using MacroOffset2UnitMapTy = DenseMap<uint64_t, DwarfUnit *>;

/// Base class for all Dwarf units(Compile unit/Type table unit).
class DwarfUnit : public OutputSections {
public:
  virtual ~DwarfUnit() {}
  DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID,
            StringRef ClangModuleName)
      : OutputSections(GlobalData), ID(ID), ClangModuleName(ClangModuleName),
        OutUnitDIE(nullptr) {}

  /// Unique id of the unit.
  unsigned getUniqueID() const { return ID; }

  /// Returns size of this(newly generated) compile unit.
  uint64_t getUnitSize() const { return UnitSize; }

  /// Returns this unit name.
  StringRef getUnitName() const { return UnitName; }

  /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
  StringRef getSysRoot() { return SysRoot; }

  /// Return true if this compile unit is from Clang module.
  bool isClangModule() const { return !ClangModuleName.empty(); }

  /// Return Clang module name;
  const std::string &getClangModuleName() const { return ClangModuleName; }

  /// Return global data.
  LinkingGlobalData &getGlobalData() { return GlobalData; }

  /// Returns true if unit is inter-connected(it references/referenced by other
  /// unit).
  bool isInterconnectedCU() const { return IsInterconnectedCU; }

  /// Mark this unit as inter-connected(it references/referenced by other unit).
  void setInterconnectedCU() { IsInterconnectedCU = true; }

  /// Adds \p Abbrev into unit`s abbreviation table.
  void assignAbbrev(DIEAbbrev &Abbrev);

  /// Returns abbreviations for this compile unit.
  const std::vector<std::unique_ptr<DIEAbbrev>> &getAbbreviations() const {
    return Abbreviations;
  }

  /// Returns output unit DIE.
  DIE *getOutUnitDIE() { return OutUnitDIE; }

  /// Set output unit DIE.
  void setOutUnitDIE(DIE *UnitDie) {
    OutUnitDIE = UnitDie;

    if (OutUnitDIE != nullptr)
      UnitSize = getDebugInfoHeaderSize() + OutUnitDIE->getSize();
  }

  /// \defgroup Methods used to emit unit's debug info:
  ///
  /// @{
  /// Emit unit's abbreviations.
  Error emitAbbreviations();

  /// Emit .debug_info section for unit DIEs.
  Error emitDebugInfo(const Triple &TargetTriple);

  /// Emit .debug_line section.
  Error emitDebugLine(const Triple &TargetTriple,
                      const DWARFDebugLine::LineTable &OutLineTable);

  /// Emit the .debug_str_offsets section for current unit.
  Error emitDebugStringOffsetSection();
  /// @}

  /// \defgroup Methods used for reporting warnings and errors:
  ///
  /// @{
  void warn(const Twine &Warning) { GlobalData.warn(Warning, getUnitName()); }

  void error(const Twine &Err) { GlobalData.warn(Err, getUnitName()); }
  /// @}

  /// \defgroup Methods and data members used for building accelerator tables:
  ///
  /// @{

  enum class AccelType : uint8_t { None, Name, Namespace, ObjC, Type };

  /// This structure keeps fields which would be used for creating accelerator
  /// table.
  struct AccelInfo {
    AccelInfo() {
      AvoidForPubSections = false;
      ObjcClassImplementation = false;
    }

    /// Name of the entry.
    StringEntry *String = nullptr;

    /// Output offset of the DIE this entry describes.
    uint64_t OutOffset;

    /// Hash of the fully qualified name.
    uint32_t QualifiedNameHash = 0;

    /// Tag of the DIE this entry describes.
    dwarf::Tag Tag = dwarf::DW_TAG_null;

    /// Type of this accelerator record.
    AccelType Type = AccelType::None;

    /// Avoid emitting this entry for pub sections.
    bool AvoidForPubSections : 1;

    /// Is this an ObjC class implementation?
    bool ObjcClassImplementation : 1;
  };

  /// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
  void emitPubAccelerators();

  /// Enumerates accelerator data.
  virtual void
  forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) = 0;

  /// @}

  /// Returns index(inside .debug_str_offsets) of specified string.
  virtual uint64_t getDebugStrIndex(const StringEntry *String) {
    return DebugStringIndexMap.getValueIndex(String);
  }

protected:
  /// Emit single abbreviation entry.
  void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev,
                            SectionDescriptor &AbbrevSection);

  /// Emit single pubnames/pubtypes accelerator entry.
  std::optional<uint64_t>
  emitPubAcceleratorEntry(SectionDescriptor &OutSection, const AccelInfo &Info,
                          std::optional<uint64_t> LengthOffset);

  /// Unique ID for the unit.
  unsigned ID = 0;

  /// The name of this unit.
  std::string UnitName;

  /// The DW_AT_LLVM_sysroot of this unit.
  std::string SysRoot;

  /// If this is a Clang module, this holds the module's name.
  std::string ClangModuleName;

  uint64_t UnitSize = 0;

  /// true if current unit references_to/is_referenced by other unit.
  std::atomic<bool> IsInterconnectedCU = {false};

  /// FoldingSet that uniques the abbreviations.
  FoldingSet<DIEAbbrev> AbbreviationsSet;

  /// Storage for the unique Abbreviations.
  std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;

  /// Output unit DIE.
  DIE *OutUnitDIE = nullptr;

  /// Cache for file names for this unit.
  using FileNamesCache =
      DenseMap<uint64_t, std::pair<std::string, std::string>>;
  FileNamesCache FileNames;

  /// Maps a string into the index inside .debug_str_offsets section.
  IndexedValuesMap<const StringEntry *> DebugStringIndexMap;
};

inline bool isODRLanguage(uint16_t Language) {
  switch (Language) {
  case dwarf::DW_LANG_C_plus_plus:
  case dwarf::DW_LANG_C_plus_plus_03:
  case dwarf::DW_LANG_C_plus_plus_11:
  case dwarf::DW_LANG_C_plus_plus_14:
  case dwarf::DW_LANG_ObjC_plus_plus:
    return true;
  default:
    return false;
  };

  return false;
}

} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm

#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H