]> git.proxmox.com Git - rustc.git/blame - src/llvm/include/llvm/MC/MCDwarf.h
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / llvm / include / llvm / MC / MCDwarf.h
CommitLineData
223e47cc
LB
1//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
2//
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// This file contains the declaration of the MCDwarfFile to support the dwarf
11// .file directive and the .loc directive.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_MC_MCDWARF_H
16#define LLVM_MC_MCDWARF_H
17
1a4d82fc 18#include "llvm/ADT/ArrayRef.h"
1a4d82fc 19#include "llvm/ADT/MapVector.h"
85aaf69f
SL
20#include "llvm/ADT/StringMap.h"
21#include "llvm/ADT/StringRef.h"
223e47cc 22#include "llvm/Support/Compiler.h"
970d7e83
LB
23#include "llvm/Support/Dwarf.h"
24#include "llvm/Support/raw_ostream.h"
25#include <map>
1a4d82fc
JJ
26#include <string>
27#include <utility>
85aaf69f 28#include <vector>
223e47cc
LB
29
30namespace llvm {
1a4d82fc
JJ
31class MCAsmBackend;
32class MCContext;
33class MCObjectStreamer;
34class MCSection;
35class MCStreamer;
36class MCSymbol;
37class SourceMgr;
38class SMLoc;
39
40/// MCDwarfFile - Instances of this class represent the name of the dwarf
41/// .file directive and its associated dwarf file number in the MC file,
42/// and MCDwarfFile's are created and unique'd by the MCContext class where
43/// the file number for each is its index into the vector of DwarfFiles (note
44/// index 0 is not used and not a valid dwarf file number).
45struct MCDwarfFile {
46 // Name - the base name of the file without its directory path.
47 // The StringRef references memory allocated in the MCContext.
48 std::string Name;
49
50 // DirIndex - the index into the list of directory names for this file name.
51 unsigned DirIndex;
52};
53
54/// MCDwarfLoc - Instances of this class represent the information from a
55/// dwarf .loc directive.
56class MCDwarfLoc {
57 // FileNum - the file number.
58 unsigned FileNum;
59 // Line - the line number.
60 unsigned Line;
61 // Column - the column position.
62 unsigned Column;
63 // Flags (see #define's below)
64 unsigned Flags;
65 // Isa
66 unsigned Isa;
67 // Discriminator
68 unsigned Discriminator;
223e47cc
LB
69
70// Flag that indicates the initial value of the is_stmt_start flag.
1a4d82fc 71#define DWARF2_LINE_DEFAULT_IS_STMT 1
223e47cc 72
1a4d82fc
JJ
73#define DWARF2_FLAG_IS_STMT (1 << 0)
74#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
75#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
223e47cc
LB
76#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
77
1a4d82fc
JJ
78private: // MCContext manages these
79 friend class MCContext;
80 friend class MCLineEntry;
81 MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
82 unsigned isa, unsigned discriminator)
223e47cc
LB
83 : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
84 Discriminator(discriminator) {}
85
1a4d82fc
JJ
86 // Allow the default copy constructor and assignment operator to be used
87 // for an MCDwarfLoc object.
223e47cc 88
1a4d82fc
JJ
89public:
90 /// getFileNum - Get the FileNum of this MCDwarfLoc.
91 unsigned getFileNum() const { return FileNum; }
223e47cc 92
1a4d82fc
JJ
93 /// getLine - Get the Line of this MCDwarfLoc.
94 unsigned getLine() const { return Line; }
223e47cc 95
1a4d82fc
JJ
96 /// getColumn - Get the Column of this MCDwarfLoc.
97 unsigned getColumn() const { return Column; }
223e47cc 98
1a4d82fc
JJ
99 /// getFlags - Get the Flags of this MCDwarfLoc.
100 unsigned getFlags() const { return Flags; }
223e47cc 101
1a4d82fc
JJ
102 /// getIsa - Get the Isa of this MCDwarfLoc.
103 unsigned getIsa() const { return Isa; }
223e47cc 104
1a4d82fc
JJ
105 /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
106 unsigned getDiscriminator() const { return Discriminator; }
223e47cc 107
1a4d82fc
JJ
108 /// setFileNum - Set the FileNum of this MCDwarfLoc.
109 void setFileNum(unsigned fileNum) { FileNum = fileNum; }
223e47cc 110
1a4d82fc
JJ
111 /// setLine - Set the Line of this MCDwarfLoc.
112 void setLine(unsigned line) { Line = line; }
223e47cc 113
1a4d82fc
JJ
114 /// setColumn - Set the Column of this MCDwarfLoc.
115 void setColumn(unsigned column) { Column = column; }
223e47cc 116
1a4d82fc
JJ
117 /// setFlags - Set the Flags of this MCDwarfLoc.
118 void setFlags(unsigned flags) { Flags = flags; }
223e47cc 119
1a4d82fc
JJ
120 /// setIsa - Set the Isa of this MCDwarfLoc.
121 void setIsa(unsigned isa) { Isa = isa; }
223e47cc 122
1a4d82fc
JJ
123 /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
124 void setDiscriminator(unsigned discriminator) {
125 Discriminator = discriminator;
126 }
127};
128
129/// MCLineEntry - Instances of this class represent the line information for
130/// the dwarf line table entries. Which is created after a machine
131/// instruction is assembled and uses an address from a temporary label
132/// created at the current address in the current section and the info from
133/// the last .loc directive seen as stored in the context.
134class MCLineEntry : public MCDwarfLoc {
135 MCSymbol *Label;
136
137private:
138 // Allow the default copy constructor and assignment operator to be used
139 // for an MCLineEntry object.
140
141public:
142 // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
143 MCLineEntry(MCSymbol *label, const MCDwarfLoc loc)
144 : MCDwarfLoc(loc), Label(label) {}
145
146 MCSymbol *getLabel() const { return Label; }
147
148 // This is called when an instruction is assembled into the specified
149 // section and if there is information from the last .loc directive that
150 // has yet to have a line entry made for it is made.
151 static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
152};
153
154/// MCLineSection - Instances of this class represent the line information
155/// for a compile unit where machine instructions have been assembled after seeing
156/// .loc directives. This is the information used to build the dwarf line
157/// table for a section.
158class MCLineSection {
159public:
160 // addLineEntry - adds an entry to this MCLineSection's line entries
161 void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
162 MCLineDivisions[Sec].push_back(LineEntry);
163 }
223e47cc 164
1a4d82fc
JJ
165 typedef std::vector<MCLineEntry> MCLineEntryCollection;
166 typedef MCLineEntryCollection::iterator iterator;
167 typedef MCLineEntryCollection::const_iterator const_iterator;
168 typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
223e47cc 169
1a4d82fc
JJ
170private:
171 // A collection of MCLineEntry for each section.
172 MCLineDivisionMap MCLineDivisions;
223e47cc 173
1a4d82fc
JJ
174public:
175 // Returns the collection of MCLineEntry for a given Compile Unit ID.
176 const MCLineDivisionMap &getMCLineEntries() const {
177 return MCLineDivisions;
178 }
179};
180
181struct MCDwarfLineTableHeader {
182 MCSymbol *Label;
183 SmallVector<std::string, 3> MCDwarfDirs;
184 SmallVector<MCDwarfFile, 3> MCDwarfFiles;
185 StringMap<unsigned> SourceIdMap;
186 StringRef CompilationDir;
187
188 MCDwarfLineTableHeader() : Label(nullptr) {}
189 unsigned getFile(StringRef &Directory, StringRef &FileName,
190 unsigned FileNumber = 0);
191 std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
192 std::pair<MCSymbol *, MCSymbol *>
193 Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
194};
195
196class MCDwarfDwoLineTable {
197 MCDwarfLineTableHeader Header;
198public:
199 void setCompilationDir(StringRef CompilationDir) {
200 Header.CompilationDir = CompilationDir;
201 }
202 unsigned getFile(StringRef Directory, StringRef FileName) {
203 return Header.getFile(Directory, FileName);
204 }
205 void Emit(MCStreamer &MCOS) const;
206};
223e47cc 207
1a4d82fc
JJ
208class MCDwarfLineTable {
209 MCDwarfLineTableHeader Header;
210 MCLineSection MCLineSections;
223e47cc 211
1a4d82fc
JJ
212public:
213 // This emits the Dwarf file and the line tables for all Compile Units.
214 static void Emit(MCObjectStreamer *MCOS);
223e47cc 215
1a4d82fc
JJ
216 // This emits the Dwarf file and the line tables for a given Compile Unit.
217 void EmitCU(MCObjectStreamer *MCOS) const;
223e47cc 218
1a4d82fc
JJ
219 unsigned getFile(StringRef &Directory, StringRef &FileName,
220 unsigned FileNumber = 0);
223e47cc 221
1a4d82fc
JJ
222 MCSymbol *getLabel() const {
223 return Header.Label;
224 }
223e47cc 225
1a4d82fc
JJ
226 void setLabel(MCSymbol *Label) {
227 Header.Label = Label;
228 }
223e47cc 229
1a4d82fc
JJ
230 void setCompilationDir(StringRef CompilationDir) {
231 Header.CompilationDir = CompilationDir;
232 }
233
234 const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
235 return Header.MCDwarfDirs;
236 }
237
238 SmallVectorImpl<std::string> &getMCDwarfDirs() {
239 return Header.MCDwarfDirs;
240 }
241
242 const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
243 return Header.MCDwarfFiles;
244 }
245
246 SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
247 return Header.MCDwarfFiles;
248 }
249
250 const MCLineSection &getMCLineSections() const {
251 return MCLineSections;
252 }
253 MCLineSection &getMCLineSections() {
254 return MCLineSections;
255 }
256};
257
258class MCDwarfLineAddr {
259public:
260 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
261 static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta,
262 raw_ostream &OS);
263
264 /// Utility function to emit the encoding to a streamer.
265 static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta);
266};
267
268class MCGenDwarfInfo {
269public:
270 //
271 // When generating dwarf for assembly source files this emits the Dwarf
272 // sections.
273 //
274 static void Emit(MCStreamer *MCOS);
275};
276
277// When generating dwarf for assembly source files this is the info that is
278// needed to be gathered for each symbol that will have a dwarf label.
279class MCGenDwarfLabelEntry {
280private:
281 // Name of the symbol without a leading underbar, if any.
282 StringRef Name;
283 // The dwarf file number this symbol is in.
284 unsigned FileNumber;
285 // The line number this symbol is at.
286 unsigned LineNumber;
287 // The low_pc for the dwarf label is taken from this symbol.
288 MCSymbol *Label;
289
290public:
291 MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
292 MCSymbol *label)
293 : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
294 Label(label) {}
295
296 StringRef getName() const { return Name; }
297 unsigned getFileNumber() const { return FileNumber; }
298 unsigned getLineNumber() const { return LineNumber; }
299 MCSymbol *getLabel() const { return Label; }
300
301 // This is called when label is created when we are generating dwarf for
302 // assembly source files.
303 static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
304 SMLoc &Loc);
305};
306
307class MCCFIInstruction {
308public:
309 enum OpType {
310 OpSameValue,
311 OpRememberState,
312 OpRestoreState,
313 OpOffset,
314 OpDefCfaRegister,
315 OpDefCfaOffset,
316 OpDefCfa,
317 OpRelOffset,
318 OpAdjustCfaOffset,
319 OpEscape,
320 OpRestore,
321 OpUndefined,
322 OpRegister,
323 OpWindowSave
223e47cc
LB
324 };
325
1a4d82fc
JJ
326private:
327 OpType Operation;
328 MCSymbol *Label;
329 unsigned Register;
330 union {
331 int Offset;
332 unsigned Register2;
223e47cc 333 };
1a4d82fc
JJ
334 std::vector<char> Values;
335
336 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
337 : Operation(Op), Label(L), Register(R), Offset(O),
338 Values(V.begin(), V.end()) {
339 assert(Op != OpRegister);
340 }
341
342 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
343 : Operation(Op), Label(L), Register(R1), Register2(R2) {
344 assert(Op == OpRegister);
345 }
346
347public:
348 /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from
349 /// Register and add Offset to it.
350 static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
351 int Offset) {
352 return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
353 }
354
355 /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now
356 /// on Register will be used instead of the old one. Offset remains the same.
357 static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
358 return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
359 }
360
361 /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register
362 /// remains the same, but offset is new. Note that it is the absolute offset
363 /// that will be added to a defined register to the compute CFA address.
364 static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
365 return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
366 }
367
368 /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
369 /// Offset is a relative value that is added/subtracted from the previous
370 /// offset.
371 static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
372 return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
373 }
374
375 /// \brief .cfi_offset Previous value of Register is saved at offset Offset
376 /// from CFA.
377 static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
378 int Offset) {
379 return MCCFIInstruction(OpOffset, L, Register, Offset, "");
380 }
381
382 /// \brief .cfi_rel_offset Previous value of Register is saved at offset
383 /// Offset from the current CFA register. This is transformed to .cfi_offset
384 /// using the known displacement of the CFA register from the CFA.
385 static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
386 int Offset) {
387 return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
388 }
389
390 /// \brief .cfi_register Previous value of Register1 is saved in
391 /// register Register2.
392 static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
393 unsigned Register2) {
394 return MCCFIInstruction(OpRegister, L, Register1, Register2);
395 }
396
397 /// \brief .cfi_window_save SPARC register window is saved.
398 static MCCFIInstruction createWindowSave(MCSymbol *L) {
399 return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
400 }
401
402 /// \brief .cfi_restore says that the rule for Register is now the same as it
403 /// was at the beginning of the function, after all initial instructions added
404 /// by .cfi_startproc were executed.
405 static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
406 return MCCFIInstruction(OpRestore, L, Register, 0, "");
407 }
408
409 /// \brief .cfi_undefined From now on the previous value of Register can't be
410 /// restored anymore.
411 static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
412 return MCCFIInstruction(OpUndefined, L, Register, 0, "");
413 }
414
415 /// \brief .cfi_same_value Current value of Register is the same as in the
416 /// previous frame. I.e., no restoration is needed.
417 static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
418 return MCCFIInstruction(OpSameValue, L, Register, 0, "");
419 }
420
421 /// \brief .cfi_remember_state Save all current rules for all registers.
422 static MCCFIInstruction createRememberState(MCSymbol *L) {
423 return MCCFIInstruction(OpRememberState, L, 0, 0, "");
424 }
425
426 /// \brief .cfi_restore_state Restore the previously saved state.
427 static MCCFIInstruction createRestoreState(MCSymbol *L) {
428 return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
429 }
430
431 /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind
432 /// info.
433 static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
434 return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
435 }
436
437 OpType getOperation() const { return Operation; }
438 MCSymbol *getLabel() const { return Label; }
439
440 unsigned getRegister() const {
441 assert(Operation == OpDefCfa || Operation == OpOffset ||
442 Operation == OpRestore || Operation == OpUndefined ||
443 Operation == OpSameValue || Operation == OpDefCfaRegister ||
444 Operation == OpRelOffset || Operation == OpRegister);
445 return Register;
446 }
447
448 unsigned getRegister2() const {
449 assert(Operation == OpRegister);
450 return Register2;
451 }
452
453 int getOffset() const {
454 assert(Operation == OpDefCfa || Operation == OpOffset ||
455 Operation == OpRelOffset || Operation == OpDefCfaOffset ||
456 Operation == OpAdjustCfaOffset);
457 return Offset;
458 }
459
460 StringRef getValues() const {
461 assert(Operation == OpEscape);
462 return StringRef(&Values[0], Values.size());
463 }
464};
465
466struct MCDwarfFrameInfo {
467 MCDwarfFrameInfo()
468 : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
85aaf69f
SL
469 Instructions(), CurrentCfaRegister(0), PersonalityEncoding(),
470 LsdaEncoding(0), CompactUnwindEncoding(0), IsSignalFrame(false),
471 IsSimple(false) {}
1a4d82fc
JJ
472 MCSymbol *Begin;
473 MCSymbol *End;
474 const MCSymbol *Personality;
475 const MCSymbol *Lsda;
476 std::vector<MCCFIInstruction> Instructions;
85aaf69f 477 unsigned CurrentCfaRegister;
1a4d82fc
JJ
478 unsigned PersonalityEncoding;
479 unsigned LsdaEncoding;
480 uint32_t CompactUnwindEncoding;
481 bool IsSignalFrame;
482 bool IsSimple;
483};
484
485class MCDwarfFrameEmitter {
486public:
487 //
488 // This emits the frame info section.
489 //
490 static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
491 static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
492 static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
493 raw_ostream &OS);
494};
223e47cc
LB
495} // end namespace llvm
496
497#endif