blob: b44b1aaa55417b3b539756d4335a2e34059c4510 [file] [log] [blame]
Jim Laskeye5032892005-12-21 19:48:16 +00001//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by James M. Laskey and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for writing dwarf debug info into asm files.
11//
12//===----------------------------------------------------------------------===//
13
Jim Laskeyb2efb852006-01-04 22:28:25 +000014#include "llvm/CodeGen/DwarfWriter.h"
Jim Laskeye5032892005-12-21 19:48:16 +000015
Jim Laskeya7cea6f2006-01-04 13:52:30 +000016#include "llvm/CodeGen/AsmPrinter.h"
Jim Laskeyb2efb852006-01-04 22:28:25 +000017#include "llvm/CodeGen/MachineDebugInfo.h"
Jim Laskeya7cea6f2006-01-04 13:52:30 +000018#include "llvm/Support/CommandLine.h"
19
Jim Laskeyb2efb852006-01-04 22:28:25 +000020#include <iostream>
Jim Laskeya7cea6f2006-01-04 13:52:30 +000021
Jim Laskeyb2efb852006-01-04 22:28:25 +000022using namespace llvm;
Jim Laskeya7cea6f2006-01-04 13:52:30 +000023
24static cl::opt<bool>
25DwarfVerbose("dwarf-verbose", cl::Hidden,
26 cl::desc("Add comments to dwarf directives."));
27
28/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
Jim Laskeyb2efb852006-01-04 22:28:25 +000029/// unsigned leb128 value. Comment is added to the end of the directive if
30/// DwarfVerbose is true (should not contain any newlines.)
Jim Laskeya7cea6f2006-01-04 13:52:30 +000031///
Jim Laskeyb2efb852006-01-04 22:28:25 +000032void DwarfWriter::EmitULEB128Bytes(unsigned Value, const char *Comment) const {
Jim Laskeya7cea6f2006-01-04 13:52:30 +000033 if (hasLEB128) {
34 O << "\t.uleb128\t"
35 << Value;
36 } else {
Jim Laskeyb2efb852006-01-04 22:28:25 +000037 O << Asm->Data8bitsDirective;
Jim Laskeya7cea6f2006-01-04 13:52:30 +000038 EmitULEB128(Value);
39 }
40 if (DwarfVerbose) {
41 O << "\t"
Jim Laskeyb2efb852006-01-04 22:28:25 +000042 << Asm->CommentString
Jim Laskeya7cea6f2006-01-04 13:52:30 +000043 << " "
44 << Comment
45 << " "
46 << Value;
47 }
48 O << "\n";
49}
50
51/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
Jim Laskeyb2efb852006-01-04 22:28:25 +000052/// signed leb128 value. Comment is added to the end of the directive if
53/// DwarfVerbose is true (should not contain any newlines.)
Jim Laskeya7cea6f2006-01-04 13:52:30 +000054///
Jim Laskeyb2efb852006-01-04 22:28:25 +000055void DwarfWriter::EmitSLEB128Bytes(int Value, const char *Comment) const {
Jim Laskeya7cea6f2006-01-04 13:52:30 +000056 if (hasLEB128) {
57 O << "\t.sleb128\t"
58 << Value;
59 } else {
Jim Laskeyb2efb852006-01-04 22:28:25 +000060 O << Asm->Data8bitsDirective;
Jim Laskeya7cea6f2006-01-04 13:52:30 +000061 EmitSLEB128(Value);
62 }
63 if (DwarfVerbose) {
64 O << "\t"
Jim Laskeyb2efb852006-01-04 22:28:25 +000065 << Asm->CommentString
Jim Laskeya7cea6f2006-01-04 13:52:30 +000066 << " "
67 << Comment
68 << " "
69 << Value;
70 }
71 O << "\n";
72}
73
Jim Laskeyb2efb852006-01-04 22:28:25 +000074/// EmitHex - Emit a hexidecimal string to the output stream.
Jim Laskeya7cea6f2006-01-04 13:52:30 +000075///
Jim Laskeyb2efb852006-01-04 22:28:25 +000076void DwarfWriter::EmitHex(unsigned Value) const {
77 O << "0x"
78 << std::hex
79 << Value
80 << std::dec;
81}
82
83/// EmitComment - Emit a simple string comment.
84///
85void DwarfWriter::EmitComment(const char *Comment) const {
86 O << "\t"
87 << Asm->CommentString
88 << " "
89 << Comment
90 << "\n";
91}
92
93/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
94/// representing an unsigned leb128 value.
95///
96void DwarfWriter::EmitULEB128(unsigned Value) const {
97 do {
98 unsigned Byte = Value & 0x7f;
99 Value >>= 7;
100 if (Value) Byte |= 0x80;
101 EmitHex(Byte);
102 if (Value) O << ", ";
103 } while (Value);
104}
105
106/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
107/// representing a signed leb128 value.
108///
109void DwarfWriter::EmitSLEB128(int Value) const {
110 int Sign = Value >> (8 * sizeof(Value) - 1);
111 bool IsMore;
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000112
Jim Laskeyb2efb852006-01-04 22:28:25 +0000113 do {
114 unsigned Byte = Value & 0x7f;
115 Value >>= 7;
116 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
117 if (IsMore) Byte |= 0x80;
118 EmitHex(Byte);
119 if (IsMore) O << ", ";
120 } while (IsMore);
121}
122
123/// EmitLabelName - Emit label name for internal use by dwarf.
124///
125void DwarfWriter::EmitLabelName(const char *Tag, int Num) const {
126 O << Asm->PrivateGlobalPrefix
127 << "debug_"
128 << Tag
129 << Num;
130}
131
132/// EmitLabel - Emit location label for internal use by dwarf.
133///
134void DwarfWriter::EmitLabel(const char *Tag, int Num) const {
135 EmitLabelName(Tag, Num);
136 O << ":\n";
137}
138
139/// EmitInitial -Emit initial dwarf declarations.
140///
141void DwarfWriter::EmitInitial() const {
142 // Dwarf section's base addresses.
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000143 Asm->SwitchSection(DwarfAbbrevSection, 0);
144 EmitLabel("abbrev", 0);
145 Asm->SwitchSection(DwarfInfoSection, 0);
146 EmitLabel("info", 0);
147 Asm->SwitchSection(DwarfLineSection, 0);
148 EmitLabel("line", 0);
149}
150
Jim Laskeyb2efb852006-01-04 22:28:25 +0000151/// ShouldEmitDwarf - Determine if dwarf declarations should be made.
152///
153bool DwarfWriter::ShouldEmitDwarf() {
154 // Check if debug info is present.
155 if (!DebugInfo || !DebugInfo->hasInfo()) return false;
156
157 // Make sure initial declarations are made.
158 if (!didInitial) {
159 EmitInitial();
160 didInitial = true;
161 }
162
163 // Okay to emit.
164 return true;
165}
166
167/// BeginModule - Emit all dwarf sections that should come prior to the content.
168///
169void DwarfWriter::BeginModule() {
170 if (!ShouldEmitDwarf()) return;
171 EmitComment("Dwarf Begin Module");
172}
173
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000174/// EndModule - Emit all dwarf sections that should come after the content.
175///
176void DwarfWriter::EndModule() {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000177 if (!ShouldEmitDwarf()) return;
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000178 EmitComment("Dwarf End Module");
179 // Print out dwarf file info
Jim Laskeyb2efb852006-01-04 22:28:25 +0000180 std::vector<std::string> Sources = DebugInfo->getSourceFiles();
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000181 for (unsigned i = 0, N = Sources.size(); i < N; i++) {
182 O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n";
183 }
184}
185
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000186/// BeginFunction - Emit pre-function debug information.
187///
188void DwarfWriter::BeginFunction() {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000189 if (!ShouldEmitDwarf()) return;
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000190 EmitComment("Dwarf Begin Function");
191}
192
193/// EndFunction - Emit post-function debug information.
194///
195void DwarfWriter::EndFunction() {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000196 if (!ShouldEmitDwarf()) return;
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000197 EmitComment("Dwarf End Function");
198}