21 AcceleratorRecords(&
GlobalData.getAllocator()) {
29 LineTable.Prologue.MinInstLength = 1;
30 LineTable.Prologue.MaxOpsPerInst = 1;
31 LineTable.Prologue.DefaultIsStmt = 1;
32 LineTable.Prologue.LineBase = -5;
33 LineTable.Prologue.LineRange = 14;
34 LineTable.Prologue.OpcodeBase = 13;
35 LineTable.Prologue.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0,
42 prepareDataForTreeCreation();
57 DIE *UnitDIE = DIETreeGenerator.
createDIE(dwarf::DW_TAG_compile_unit, 0);
61 const char *ProducerString =
62 "llvm DWARFLinkerParallel library version " LLVM_VERSION_STRING;
65 GlobalData.getStringPool().insert(ProducerString).first},
67 OutOffset += DIETreeGenerator
73 OutOffset += DIETreeGenerator
75 dwarf::DW_FORM_data2, *Language)
83 OutOffset += DIETreeGenerator
88 if (!LineTable.Prologue.FileNames.empty()) {
92 OutOffset += DIETreeGenerator
94 dwarf::DW_FORM_sec_offset, 0xbaddef)
101 OutOffset += DIETreeGenerator
110 OutOffset += DIETreeGenerator
112 dwarf::DW_FORM_sec_offset,
119 finalizeTypeEntryRec(UnitDIE->
getOffset(), UnitDIE, Types.getRoot());
122 for (
uint64_t *OffsetPtr : PatchesOffsets)
129void TypeUnit::prepareDataForTreeCreation() {
149 return LHS.Directory->first() < RHS.Directory->first() ||
150 (!(RHS.Directory->first() < LHS.Directory->first()) &&
151 LHS.FilePath->first() < RHS.FilePath->first());
153 DebugInfoSection.ListDebugTypeDeclFilePatch.sort(PatchesComparator);
157 getScalarFormForValue(
158 DebugInfoSection.ListDebugTypeDeclFilePatch.size())
161 DebugInfoSection.ListDebugTypeDeclFilePatch.forEach(
179 .addScalarAttribute(dwarf::DW_AT_decl_file,
180 DeclFileForm, FileIdx)
188 forEach([&](SectionDescriptor &OutSection) {
189 std::function<bool(
const DebugStrPatch &
LHS,
const DebugStrPatch &
RHS)>
190 StrPatchesComparator =
191 [&](
const DebugStrPatch &
LHS,
const DebugStrPatch &
RHS) {
192 return LHS.String->getKey() <
RHS.String->getKey();
194 OutSection.ListDebugStrPatch.sort(StrPatchesComparator);
196 std::function<bool(
const DebugTypeStrPatch &
LHS,
197 const DebugTypeStrPatch &
RHS)>
198 TypeStrPatchesComparator =
199 [&](
const DebugTypeStrPatch &
LHS,
const DebugTypeStrPatch &
RHS) {
200 return LHS.String->getKey() <
RHS.String->getKey();
202 OutSection.ListDebugTypeStrPatch.sort(TypeStrPatchesComparator);
208 forEach([&](SectionDescriptor &OutSection) {
209 std::function<bool(
const DebugLineStrPatch &
LHS,
210 const DebugLineStrPatch &
RHS)>
211 LineStrPatchesComparator =
212 [&](
const DebugLineStrPatch &
LHS,
const DebugLineStrPatch &
RHS) {
213 return LHS.String->getKey() <
RHS.String->getKey();
215 OutSection.ListDebugLineStrPatch.sort(LineStrPatchesComparator);
217 std::function<bool(
const DebugTypeLineStrPatch &
LHS,
218 const DebugTypeLineStrPatch &
RHS)>
219 TypeLineStrPatchesComparator = [&](
const DebugTypeLineStrPatch &
LHS,
220 const DebugTypeLineStrPatch &
RHS) {
221 return LHS.String->getKey() <
RHS.String->getKey();
223 OutSection.ListDebugTypeLineStrPatch.sort(TypeLineStrPatchesComparator);
228uint64_t TypeUnit::finalizeTypeEntryRec(uint64_t OutOffset, DIE *OutDIE,
230 bool HasChildren = !
Entry->getValue().load()->Children.empty();
231 DIEGenerator DIEGen(OutDIE, Types.getThreadLocalAllocator(), *
this);
232 OutOffset += DIEGen.finalizeAbbreviations(HasChildren,
nullptr);
233 OutOffset += OutDIE->
getSize() - 1;
236 Entry->getValue().load()->Children.forEach([&](
TypeEntry *ChildEntry) {
237 DIE *ChildDIE = &ChildEntry->
getValue().load()->getFinalDie();
238 DIEGen.addChild(ChildDIE);
242 OutOffset = finalizeTypeEntryRec(OutOffset, ChildDIE, ChildEntry);
246 OutOffset +=
sizeof(int8_t);
253uint32_t TypeUnit::addFileNameIntoLinetable(
StringEntry *Dir,
257 if (Dir->
first() ==
"") {
260 DirectoriesMapTy::iterator DirEntry = DirectoriesMap.find(Dir);
261 if (DirEntry == DirectoriesMap.end()) {
263 assert(LineTable.Prologue.IncludeDirectories.size() < UINT32_MAX);
264 DirIdx = LineTable.Prologue.IncludeDirectories.size();
265 DirectoriesMap.insert({Dir, DirIdx});
266 LineTable.Prologue.IncludeDirectories.push_back(
270 DirIdx = DirEntry->second;
277 auto [FileEntry,
Inserted] = FileNamesMap.try_emplace(
278 {FileName, DirIdx}, LineTable.Prologue.FileNames.size());
281 assert(LineTable.Prologue.FileNames.size() < UINT32_MAX);
282 LineTable.Prologue.FileNames.push_back(DWARFDebugLine::FileNameEntry());
284 dwarf::DW_FORM_string, FileName->
getKeyData());
285 LineTable.Prologue.FileNames.back().DirIdx = DirIdx;
288 uint32_t FileIdx = FileEntry->second;
289 return getVersion() < 5 ? FileIdx + 1 : FileIdx;
292std::pair<dwarf::Form, uint8_t>
293TypeUnit::getScalarFormForValue(uint64_t
Value)
const {
294 if (
Value > 0xFFFFFFFF)
295 return std::make_pair(dwarf::DW_FORM_data8, 8);
298 return std::make_pair(dwarf::DW_FORM_data4, 4);
301 return std::make_pair(dwarf::DW_FORM_data2, 2);
303 return std::make_pair(dwarf::DW_FORM_data1, 1);
306uint8_t TypeUnit::getSizeByAttrForm(
dwarf::Form Form)
const {
307 if (Form == dwarf::DW_FORM_data1)
310 if (Form == dwarf::DW_FORM_data2)
313 if (Form == dwarf::DW_FORM_data4)
316 if (Form == dwarf::DW_FORM_data8)
319 if (Form == dwarf::DW_FORM_data16)
347 if (!LineTable.Prologue.FileNames.empty()) {
358 Tasks.push_back([&]() ->
Error {
371 Tasks, [&](std::function<
Error(
void)>
F) {
return F(); }))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
A structured debug information entry.
unsigned getAbbrevNumber() const
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
void setOffset(unsigned O)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const ValueTy & getValue() const
const char * getKeyData() const
getKeyData - Return the start of the string data that is the key for this value.
Triple - Helper class for working with autoconf configuration names.
@ Pub
.debug_pubnames, .debug_pubtypes
This class is a helper to create output DIE tree.
std::pair< DIEValue &, size_t > addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm)
Adds string attribute with dummy offset to the current DIE.
DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)
Creates a DIE of specified tag DieTag and OutOffset.
std::pair< DIEValue &, size_t > addScalarAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Value)
Adds specified scalar attribute to the current DIE.
std::string UnitName
The name of this unit.
IndexedValuesMap< const StringEntry * > DebugStringIndexMap
Maps a string into the index inside .debug_str_offsets section.
unsigned ID
Unique ID for the unit.
StringRef getUnitName() const
Returns this unit name.
void setOutUnitDIE(DIE *UnitDie)
Set output unit DIE.
DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName)
DIE * getOutUnitDIE()
Returns output unit DIE.
This class keeps data and services common for the whole linking process.
uint16_t getDebugStrOffsetsHeaderSize() const
Return size of header of debug_str_offsets table.
LinkingGlobalData & GlobalData
dwarf::FormParams Format
Format for sections.
const dwarf::FormParams & getFormParams() const
Return size of address.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
uint16_t getVersion() const
Return DWARF version.
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
void forEach(function_ref< void(SectionDescriptor &)> Handler)
Enumerate all sections and call Handler for each.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
Keeps cloned data for the type DIE.
Error finishCloningAndEmit(const Triple &TargetTriple)
Emits resulting dwarf based on information from DIE tree.
void createDIETree(BumpPtrAllocator &Allocator)
Generates DIE tree based on information from TypesMap.
TypeUnit(LinkingGlobalData &GlobalData, unsigned ID, std::optional< uint16_t > Language, dwarf::FormParams Format, llvm::endianness Endianess)
LLVM_ABI void spawn(std::function< void()> f)
Error emitDebugInfo(const Triple &TargetTriple)
Emit .debug_info section for unit DIEs.
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable, ArrayRef< uint64_t > OrigRowIndices={}, DenseMap< uint64_t, uint64_t > *RowIndexToSeqStartOffset=nullptr)
Emit .debug_line section.
Error emitDebugStringOffsetSection()
Emit the .debug_str_offsets section for current unit.
void emitPubAccelerators()
Emit .debug_pubnames and .debug_pubtypes for Unit.
Error emitAbbreviations()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SmallVector< uint64_t * > OffsetsPtrVector
Type for list of pointers to patches offsets.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
This is an optimization pass for GlobalISel generic memory operations.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Error parallelForEachError(RangeTy &&R, FuncTy Fn)
This structure is used to update strings offsets into .debug_str.
This structure is used to keep data of the concrete section.
void notePatchWithOffsetUpdate(const T &Patch, OffsetsPtrVector &PatchesOffsetsList)
While creating patches, offsets to attributes may be partially unknown(because size of abbreviation n...