1 //===- DWARFLinkerUnit.h ----------------------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERUNIT_H
10 #define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERUNIT_H
12 #include "DWARFLinkerGlobalData.h"
13 #include "OutputSections.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/CodeGen/DIE.h"
16 #include "llvm/DWARFLinkerParallel/DWARFLinker.h"
17 #include "llvm/DWARFLinkerParallel/StringPool.h"
18 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
19 #include "llvm/Support/LEB128.h"
22 namespace dwarflinker_parallel
{
25 using MacroOffset2UnitMapTy
= DenseMap
<uint64_t, DwarfUnit
*>;
27 /// Base class for all Dwarf units(Compile unit/Type table unit).
28 class DwarfUnit
: public OutputSections
{
30 virtual ~DwarfUnit() {}
31 DwarfUnit(LinkingGlobalData
&GlobalData
, unsigned ID
,
32 StringRef ClangModuleName
)
33 : OutputSections(GlobalData
), ID(ID
), ClangModuleName(ClangModuleName
),
35 AcceleratorRecords
.setAllocator(&GlobalData
.getAllocator());
38 /// Unique id of the unit.
39 unsigned getUniqueID() const { return ID
; }
41 /// Return language of this unit.
42 uint16_t getLanguage() const { return Language
; }
44 /// Returns size of this(newly generated) compile unit.
45 uint64_t getUnitSize() const { return UnitSize
; }
47 /// Returns this unit name.
48 StringRef
getUnitName() const { return UnitName
; }
50 /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
51 StringRef
getSysRoot() { return SysRoot
; }
53 /// Return true if this compile unit is from Clang module.
54 bool isClangModule() const { return !ClangModuleName
.empty(); }
56 /// Return Clang module name;
57 const std::string
&getClangModuleName() const { return ClangModuleName
; }
59 /// Return global data.
60 LinkingGlobalData
&getGlobalData() { return GlobalData
; }
62 /// Returns true if unit is inter-connected(it references/referenced by other
64 bool isInterconnectedCU() const { return IsInterconnectedCU
; }
66 /// Mark this unit as inter-connected(it references/referenced by other unit).
67 void setInterconnectedCU() { IsInterconnectedCU
= true; }
69 /// Adds \p Abbrev into unit`s abbreviation table.
70 void assignAbbrev(DIEAbbrev
&Abbrev
);
72 /// Returns abbreviations for this compile unit.
73 const std::vector
<std::unique_ptr
<DIEAbbrev
>> &getAbbreviations() const {
77 /// Returns output unit DIE.
78 DIE
*getOutUnitDIE() { return OutUnitDIE
; }
80 /// Set output unit DIE.
81 void setOutUnitDIE(DIE
*UnitDie
) {
84 if (OutUnitDIE
!= nullptr)
85 UnitSize
= getDebugInfoHeaderSize() + OutUnitDIE
->getSize();
88 /// \defgroup Methods used to emit unit's debug info:
91 /// Emit unit's abbreviations.
92 Error
emitAbbreviations();
94 /// Emit .debug_info section for unit DIEs.
95 Error
emitDebugInfo(Triple
&TargetTriple
);
97 /// Emit .debug_line section.
98 Error
emitDebugLine(Triple
&TargetTriple
,
99 const DWARFDebugLine::LineTable
&OutLineTable
);
102 /// \defgroup Methods used for reporting warnings and errors:
105 void warn(const Twine
&Warning
) { GlobalData
.warn(Warning
, getUnitName()); }
107 void error(const Twine
&Err
) { GlobalData
.warn(Err
, getUnitName()); }
110 /// \defgroup Methods and data members used for building accelerator tables:
114 enum class AccelType
: uint8_t { None
, Name
, Namespace
, ObjC
, Type
};
116 /// This structure keeps fields which would be used for creating accelerator
120 AvoidForPubSections
= false;
121 ObjcClassImplementation
= false;
124 /// Name of the entry.
125 StringEntry
*String
= nullptr;
127 /// Output offset of the DIE this entry describes.
128 uint64_t OutOffset
= 0;
130 /// Hash of the fully qualified name.
131 uint32_t QualifiedNameHash
= 0;
133 /// Tag of the DIE this entry describes.
134 dwarf::Tag Tag
= dwarf::DW_TAG_null
;
136 /// Type of this accelerator record.
137 AccelType Type
= AccelType::None
;
139 /// Avoid using this entry for pub sections.
140 bool AvoidForPubSections
: 1;
142 /// Is this an ObjC class implementation?
143 bool ObjcClassImplementation
: 1;
146 void rememberNameForAccelerators(StringEntry
*Name
, uint64_t OutOffset
,
147 dwarf::Tag Tag
, bool AvoidForPubSections
) {
150 Info
.Type
= AccelType::Name
;
152 Info
.OutOffset
= OutOffset
;
154 Info
.AvoidForPubSections
= AvoidForPubSections
;
156 AcceleratorRecords
.add(Info
);
158 void rememberNamespaceForAccelerators(StringEntry
*Name
, uint64_t OutOffset
,
162 Info
.Type
= AccelType::Namespace
;
164 Info
.OutOffset
= OutOffset
;
167 AcceleratorRecords
.add(Info
);
169 void rememberObjCNameForAccelerators(StringEntry
*Name
, uint64_t OutOffset
,
173 Info
.Type
= AccelType::ObjC
;
175 Info
.OutOffset
= OutOffset
;
177 Info
.AvoidForPubSections
= true;
179 AcceleratorRecords
.add(Info
);
181 void rememberTypeForAccelerators(StringEntry
*Name
, uint64_t OutOffset
,
182 dwarf::Tag Tag
, uint32_t QualifiedNameHash
,
183 bool ObjcClassImplementation
) {
186 Info
.Type
= AccelType::Type
;
188 Info
.OutOffset
= OutOffset
;
190 Info
.QualifiedNameHash
= QualifiedNameHash
;
191 Info
.ObjcClassImplementation
= ObjcClassImplementation
;
193 AcceleratorRecords
.add(Info
);
196 /// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
197 void emitPubAccelerators();
199 /// Accelerator tables data.
200 ArrayList
<AccelInfo
> AcceleratorRecords
;
205 /// Emit single abbreviation entry.
206 void emitDwarfAbbrevEntry(const DIEAbbrev
&Abbrev
,
207 SectionDescriptor
&AbbrevSection
);
209 /// Emit single pubnames/pubtypes accelerator entry.
210 std::optional
<uint64_t>
211 emitPubAcceleratorEntry(SectionDescriptor
&OutSection
,
212 DwarfUnit::AccelInfo
&Info
,
213 std::optional
<uint64_t> LengthOffset
);
215 /// Unique ID for the unit.
218 /// The DW_AT_language of this unit.
219 uint16_t Language
= 0;
221 /// The name of this unit.
222 std::string UnitName
;
224 /// The DW_AT_LLVM_sysroot of this unit.
227 /// If this is a Clang module, this holds the module's name.
228 std::string ClangModuleName
;
230 uint64_t UnitSize
= 0;
232 /// true if current unit references_to/is_referenced by other unit.
233 std::atomic
<bool> IsInterconnectedCU
= {false};
235 /// FoldingSet that uniques the abbreviations.
236 FoldingSet
<DIEAbbrev
> AbbreviationsSet
;
238 /// Storage for the unique Abbreviations.
239 std::vector
<std::unique_ptr
<DIEAbbrev
>> Abbreviations
;
242 DIE
*OutUnitDIE
= nullptr;
245 } // end of namespace dwarflinker_parallel
246 } // end namespace llvm
248 #endif // LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERUNIT_H