1 //===- DWARFLinkerUnit.cpp ------------------------------------------------===//
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 #include "DWARFLinkerUnit.h"
10 #include "DWARFEmitterImpl.h"
11 #include "DebugLineSectionEmitter.h"
14 namespace dwarflinker_parallel
{
16 void DwarfUnit::assignAbbrev(DIEAbbrev
&Abbrev
) {
17 // Check the set for priors.
22 DIEAbbrev
*InSet
= AbbreviationsSet
.FindNodeOrInsertPos(ID
, InsertToken
);
23 // If it's newly added.
25 // Assign existing abbreviation number.
26 Abbrev
.setNumber(InSet
->getNumber());
28 // Add to abbreviation list.
29 Abbreviations
.push_back(
30 std::make_unique
<DIEAbbrev
>(Abbrev
.getTag(), Abbrev
.hasChildren()));
31 for (const auto &Attr
: Abbrev
.getData())
32 Abbreviations
.back()->AddAttribute(Attr
);
33 AbbreviationsSet
.InsertNode(Abbreviations
.back().get(), InsertToken
);
34 // Assign the unique abbreviation number.
35 Abbrev
.setNumber(Abbreviations
.size());
36 Abbreviations
.back()->setNumber(Abbreviations
.size());
40 Error
DwarfUnit::emitAbbreviations() {
41 const std::vector
<std::unique_ptr
<DIEAbbrev
>> &Abbrevs
= getAbbreviations();
43 return Error::success();
45 SectionDescriptor
&AbbrevSection
=
46 getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev
);
48 // For each abbreviation.
49 for (const auto &Abbrev
: Abbrevs
)
50 emitDwarfAbbrevEntry(*Abbrev
, AbbrevSection
);
52 // Mark end of abbreviations.
53 encodeULEB128(0, AbbrevSection
.OS
);
55 return Error::success();
58 void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev
&Abbrev
,
59 SectionDescriptor
&AbbrevSection
) {
60 // Emit the abbreviations code (base 1 index.)
61 encodeULEB128(Abbrev
.getNumber(), AbbrevSection
.OS
);
63 // Emit the abbreviations data.
64 // Emit its Dwarf tag type.
65 encodeULEB128(Abbrev
.getTag(), AbbrevSection
.OS
);
67 // Emit whether it has children DIEs.
68 encodeULEB128((unsigned)Abbrev
.hasChildren(), AbbrevSection
.OS
);
70 // For each attribute description.
71 const SmallVectorImpl
<DIEAbbrevData
> &Data
= Abbrev
.getData();
72 for (unsigned i
= 0, N
= Data
.size(); i
< N
; ++i
) {
73 const DIEAbbrevData
&AttrData
= Data
[i
];
75 // Emit attribute type.
76 encodeULEB128(AttrData
.getAttribute(), AbbrevSection
.OS
);
79 encodeULEB128(AttrData
.getForm(), AbbrevSection
.OS
);
81 // Emit value for DW_FORM_implicit_const.
82 if (AttrData
.getForm() == dwarf::DW_FORM_implicit_const
)
83 encodeSLEB128(AttrData
.getValue(), AbbrevSection
.OS
);
86 // Mark end of abbreviation.
87 encodeULEB128(0, AbbrevSection
.OS
);
88 encodeULEB128(0, AbbrevSection
.OS
);
91 Error
DwarfUnit::emitDebugInfo(Triple
&TargetTriple
) {
92 DIE
*OutUnitDIE
= getOutUnitDIE();
93 if (OutUnitDIE
== nullptr)
94 return Error::success();
96 // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs
99 SectionDescriptor
&OutSection
=
100 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
101 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
, OutSection
.OS
);
102 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF"))
105 // Emit compile unit header.
106 Emitter
.emitCompileUnitHeader(*this);
107 size_t OffsetToAbbreviationTableOffset
=
108 (getFormParams().Version
>= 5) ? 8 : 6;
109 OutSection
.notePatch(DebugOffsetPatch
{
110 OffsetToAbbreviationTableOffset
,
111 &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev
)});
114 Emitter
.emitDIE(*OutUnitDIE
);
117 // Set start offset ans size for .debug_info section.
118 OutSection
.setSizesForSectionCreatedByAsmPrinter();
119 return Error::success();
122 Error
DwarfUnit::emitDebugLine(Triple
&TargetTriple
,
123 const DWARFDebugLine::LineTable
&OutLineTable
) {
124 DebugLineSectionEmitter
DebugLineEmitter(TargetTriple
, *this);
126 return DebugLineEmitter
.emit(OutLineTable
);
129 } // end of namespace dwarflinker_parallel
130 } // end of namespace llvm