blob: dd7e8709638d8440236f39c8ce6704c6c9ec0d6e [file] [log] [blame]
Daniel Jasper0f778692016-12-08 12:45:29 +00001//===--- unittests/DebugInfo/DWARF/DwarfGenerator.h -------------*- C++ -*-===//
Greg Clayton3462a422016-12-08 01:03:48 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// A file that can generate DWARF debug info for unit tests.
11//
12//===----------------------------------------------------------------------===//
13
Daniel Jasper0f778692016-12-08 12:45:29 +000014#ifndef LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H
15#define LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H
Greg Clayton3462a422016-12-08 01:03:48 +000016
17#include "llvm/ADT/StringRef.h"
18#include "llvm/CodeGen/DIE.h"
19#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
20#include "llvm/Support/Error.h"
21
22#include <memory>
23#include <string>
24#include <tuple>
25#include <vector>
26
27namespace llvm {
28
29class AsmPrinter;
30class DIE;
31class DIEAbbrev;
32class DwarfStringPool;
33class MCAsmBackend;
34class MCAsmInfo;
35class MCCodeEmitter;
36class MCContext;
37struct MCDwarfLineTableParams;
38class MCInstrInfo;
39class MCObjectFileInfo;
40class MCRegisterInfo;
41class MCStreamer;
42class MCSubtargetInfo;
43class raw_fd_ostream;
44class TargetMachine;
45class Triple;
46
47namespace dwarfgen {
48
49class Generator;
50class CompileUnit;
51
52/// A DWARF debug information entry class used to generate DWARF DIEs.
53///
54/// This class is used to quickly generate DWARF debug information by creating
55/// child DIEs or adding attributes to the current DIE. Instances of this class
56/// are created from the compile unit (dwarfgen::CompileUnit::getUnitDIE()) or
57/// by calling dwarfgen::DIE::addChild(...) and using the returned DIE object.
58class DIE {
59 dwarfgen::CompileUnit *CU;
60 llvm::DIE *Die;
61
62protected:
63 friend class Generator;
64 friend class CompileUnit;
65
66 DIE(CompileUnit *U = nullptr, llvm::DIE *D = nullptr) : CU(U), Die(D) {}
67
68 /// Called with a compile/type unit relative offset prior to generating the
69 /// DWARF debug info.
70 ///
71 /// \param CUOffset the compile/type unit relative offset where the
72 /// abbreviation code for this DIE will be encoded.
73 unsigned computeSizeAndOffsets(unsigned CUOffset);
74
75public:
76 /// Add an attribute value that has no value.
77 ///
78 /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that
79 /// represents a user defined DWARF attribute.
80 /// \param Form the dwarf::Form to use when encoding the attribute. This is
81 /// only used with the DW_FORM_flag_present form encoding.
82 void addAttribute(uint16_t Attr, dwarf::Form Form);
83
84 /// Add an attribute value to be encoded as a DIEInteger
85 ///
86 /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that
87 /// represents a user defined DWARF attribute.
88 /// \param Form the dwarf::Form to use when encoding the attribute.
89 /// \param U the unsigned integer to encode.
90 void addAttribute(uint16_t Attr, dwarf::Form Form, uint64_t U);
91
92 /// Add an attribute value to be encoded as a DIEString or DIEInlinedString.
93 ///
94 /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that
95 /// represents a user defined DWARF attribute.
96 /// \param Form the dwarf::Form to use when encoding the attribute. The form
97 /// must be one of DW_FORM_strp or DW_FORM_string.
98 /// \param String the string to encode.
99 void addAttribute(uint16_t Attr, dwarf::Form Form, StringRef String);
100
101 /// Add an attribute value to be encoded as a DIEEntry.
102 ///
103 /// DIEEntry attributes refer to other llvm::DIE objects that have been
104 /// created.
105 ///
106 /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that
107 /// represents a user defined DWARF attribute.
108 /// \param Form the dwarf::Form to use when encoding the attribute. The form
109 /// must be one of DW_FORM_strp or DW_FORM_string.
110 /// \param RefDie the DIE that this attriute refers to.
111 void addAttribute(uint16_t Attr, dwarf::Form Form, dwarfgen::DIE &RefDie);
112
113 /// Add an attribute value to be encoded as a DIEBlock.
114 ///
115 /// DIEBlock attributes refers to binary data that is stored as the
116 /// attribute's value.
117 ///
118 /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that
119 /// represents a user defined DWARF attribute.
120 /// \param Form the dwarf::Form to use when encoding the attribute. The form
121 /// must be one of DW_FORM_strp or DW_FORM_string.
122 /// \param P a pointer to the data to store as the attribute value.
NAKAMURA Takumia495f882016-12-08 15:00:07 +0000123 /// \param S the size in bytes of the data pointed to by P .
Greg Clayton3462a422016-12-08 01:03:48 +0000124 void addAttribute(uint16_t Attr, dwarf::Form Form, const void *P, size_t S);
125
126 /// Add a new child to this DIE object.
127 ///
128 /// \param Tag the dwarf::Tag to assing to the llvm::DIE object.
129 /// \returns the newly created DIE object that is now a child owned by this
130 /// object.
131 dwarfgen::DIE addChild(dwarf::Tag Tag);
132};
133
134/// A DWARF compile unit used to generate DWARF compile/type units.
135///
136/// Instances of these classes are created by instances of the Generator
137/// class. All information required to generate a DWARF compile unit is
138/// contained inside this class.
139class CompileUnit {
140 Generator &DG;
David Blaikiec0bb21f2017-04-22 02:18:00 +0000141 BasicDIEUnit DU;
Greg Clayton3462a422016-12-08 01:03:48 +0000142
143public:
144 CompileUnit(Generator &D, uint16_t V, uint8_t A)
145 : DG(D), DU(V, A, dwarf::DW_TAG_compile_unit) {}
146 DIE getUnitDIE();
147 Generator &getGenerator() { return DG; }
148 uint64_t getOffset() const { return DU.getDebugSectionOffset(); }
149 uint64_t getLength() const { return DU.getLength(); }
150 uint16_t getVersion() const { return DU.getDwarfVersion(); }
151 uint16_t getAddressSize() const { return DU.getAddressSize(); }
152 void setOffset(uint64_t Offset) { DU.setDebugSectionOffset(Offset); }
153 void setLength(uint64_t Length) { DU.setLength(Length); }
154};
155
156/// A DWARF generator.
157///
158/// Generate DWARF for unit tests by creating any instance of this class and
159/// calling Generator::addCompileUnit(), and then getting the dwarfgen::DIE from
160/// the returned compile unit and adding attributes and children to each DIE.
161class Generator {
162 std::unique_ptr<MCRegisterInfo> MRI;
163 std::unique_ptr<MCAsmInfo> MAI;
164 std::unique_ptr<MCObjectFileInfo> MOFI;
165 std::unique_ptr<MCContext> MC;
166 MCAsmBackend *MAB; // Owned by MCStreamer
167 std::unique_ptr<MCInstrInfo> MII;
168 std::unique_ptr<MCSubtargetInfo> MSTI;
169 MCCodeEmitter *MCE; // Owned by MCStreamer
170 MCStreamer *MS; // Owned by AsmPrinter
171 std::unique_ptr<TargetMachine> TM;
172 std::unique_ptr<AsmPrinter> Asm;
Greg Clayton3462a422016-12-08 01:03:48 +0000173 BumpPtrAllocator Allocator;
Benjamin Kramer9fcb7fe2016-12-09 13:12:30 +0000174 std::unique_ptr<DwarfStringPool> StringPool; // Entries owned by Allocator.
175 std::vector<std::unique_ptr<CompileUnit>> CompileUnits;
Greg Clayton3462a422016-12-08 01:03:48 +0000176 DIEAbbrevSet Abbreviations;
177
178 SmallString<4096> FileBytes;
179 /// The stream we use to generate the DWARF into as an ELF file.
180 std::unique_ptr<raw_svector_ostream> Stream;
181 /// The DWARF version to generate.
182 uint16_t Version;
183
184 /// Private constructor, call Generator::Create(...) to get a DWARF generator
185 /// expected.
186 Generator();
187
188 /// Create the streamer and setup the output buffer.
189 llvm::Error init(Triple TheTriple, uint16_t DwarfVersion);
190
191public:
192 /// Create a DWARF generator or get an appropriate error.
193 ///
194 /// \param TheTriple the triple to use when creating any required support
195 /// classes needed to emit the DWARF.
196 /// \param DwarfVersion the version of DWARF to emit.
197 ///
198 /// \returns a llvm::Expected that either contains a unique_ptr to a Generator
199 /// or a llvm::Error.
200 static llvm::Expected<std::unique_ptr<Generator>>
201 create(Triple TheTriple, uint16_t DwarfVersion);
202
203 ~Generator();
204
205 /// Generate all DWARF sections and return a memory buffer that
206 /// contains an ELF file that contains the DWARF.
207 StringRef generate();
208
209 /// Add a compile unit to be generated.
210 ///
211 /// \returns a dwarfgen::CompileUnit that can be used to retrieve the compile
212 /// unit dwarfgen::DIE that can be used to add attributes and add child DIE
213 /// objedts to.
214 dwarfgen::CompileUnit &addCompileUnit();
215
216 BumpPtrAllocator &getAllocator() { return Allocator; }
217 AsmPrinter *getAsmPrinter() const { return Asm.get(); }
George Rimar1af3cb22017-06-28 08:21:19 +0000218 MCContext *getMCContext() const { return MC.get(); }
Greg Clayton3462a422016-12-08 01:03:48 +0000219 DIEAbbrevSet &getAbbrevSet() { return Abbreviations; }
220 DwarfStringPool &getStringPool() { return *StringPool; }
221
222 /// Save the generated DWARF file to disk.
223 ///
224 /// \param Path the path to save the ELF file to.
225 bool saveFile(StringRef Path);
226};
227
228} // end namespace dwarfgen
229
230} // end namespace llvm
231
Daniel Jasper0f778692016-12-08 12:45:29 +0000232#endif // LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H