~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
 
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 implements the Dwarf emissions parts of AsmPrinter.
 
11
//
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
#include "ByteStreamer.h"
 
15
#include "DwarfDebug.h"
 
16
#include "DwarfExpression.h"
 
17
#include "llvm/ADT/Twine.h"
 
18
#include "llvm/CodeGen/AsmPrinter.h"
 
19
#include "llvm/CodeGen/DIE.h"
 
20
#include "llvm/CodeGen/MachineFunction.h"
 
21
#include "llvm/CodeGen/MachineModuleInfo.h"
 
22
#include "llvm/IR/DataLayout.h"
 
23
#include "llvm/MC/MCAsmInfo.h"
 
24
#include "llvm/MC/MCRegisterInfo.h"
 
25
#include "llvm/MC/MCSection.h"
 
26
#include "llvm/MC/MCStreamer.h"
 
27
#include "llvm/MC/MCSymbol.h"
 
28
#include "llvm/MC/MachineLocation.h"
 
29
#include "llvm/Support/Dwarf.h"
 
30
#include "llvm/Support/ErrorHandling.h"
 
31
#include "llvm/Target/TargetLoweringObjectFile.h"
 
32
#include "llvm/Target/TargetMachine.h"
 
33
#include "llvm/Target/TargetSubtargetInfo.h"
 
34
using namespace llvm;
 
35
 
 
36
#define DEBUG_TYPE "asm-printer"
 
37
 
 
38
//===----------------------------------------------------------------------===//
 
39
// Dwarf Emission Helper Routines
 
40
//===----------------------------------------------------------------------===//
 
41
 
 
42
/// EmitSLEB128 - emit the specified signed leb128 value.
 
43
void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
 
44
  if (isVerbose() && Desc)
 
45
    OutStreamer->AddComment(Desc);
 
46
 
 
47
  OutStreamer->EmitSLEB128IntValue(Value);
 
48
}
 
49
 
 
50
/// EmitULEB128 - emit the specified signed leb128 value.
 
51
void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc,
 
52
                             unsigned PadTo) const {
 
53
  if (isVerbose() && Desc)
 
54
    OutStreamer->AddComment(Desc);
 
55
 
 
56
  OutStreamer->EmitULEB128IntValue(Value, PadTo);
 
57
}
 
58
 
 
59
/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
 
60
void AsmPrinter::EmitCFAByte(unsigned Val) const {
 
61
  if (isVerbose()) {
 
62
    if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset + 64)
 
63
      OutStreamer->AddComment("DW_CFA_offset + Reg (" +
 
64
                              Twine(Val - dwarf::DW_CFA_offset) + ")");
 
65
    else
 
66
      OutStreamer->AddComment(dwarf::CallFrameString(Val));
 
67
  }
 
68
  OutStreamer->EmitIntValue(Val, 1);
 
69
}
 
70
 
 
71
static const char *DecodeDWARFEncoding(unsigned Encoding) {
 
72
  switch (Encoding) {
 
73
  case dwarf::DW_EH_PE_absptr:
 
74
    return "absptr";
 
75
  case dwarf::DW_EH_PE_omit:
 
76
    return "omit";
 
77
  case dwarf::DW_EH_PE_pcrel:
 
78
    return "pcrel";
 
79
  case dwarf::DW_EH_PE_udata4:
 
80
    return "udata4";
 
81
  case dwarf::DW_EH_PE_udata8:
 
82
    return "udata8";
 
83
  case dwarf::DW_EH_PE_sdata4:
 
84
    return "sdata4";
 
85
  case dwarf::DW_EH_PE_sdata8:
 
86
    return "sdata8";
 
87
  case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
 
88
    return "pcrel udata4";
 
89
  case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
 
90
    return "pcrel sdata4";
 
91
  case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
 
92
    return "pcrel udata8";
 
93
  case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
 
94
    return "pcrel sdata8";
 
95
  case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
 
96
      :
 
97
    return "indirect pcrel udata4";
 
98
  case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
 
99
      :
 
100
    return "indirect pcrel sdata4";
 
101
  case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
 
102
      :
 
103
    return "indirect pcrel udata8";
 
104
  case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
 
105
      :
 
106
    return "indirect pcrel sdata8";
 
107
  }
 
108
 
 
109
  return "<unknown encoding>";
 
110
}
 
111
 
 
112
/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
 
113
/// encoding.  If verbose assembly output is enabled, we output comments
 
114
/// describing the encoding.  Desc is an optional string saying what the
 
115
/// encoding is specifying (e.g. "LSDA").
 
116
void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
 
117
  if (isVerbose()) {
 
118
    if (Desc)
 
119
      OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
 
120
                              Twine(DecodeDWARFEncoding(Val)));
 
121
    else
 
122
      OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
 
123
  }
 
124
 
 
125
  OutStreamer->EmitIntValue(Val, 1);
 
126
}
 
127
 
 
128
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
 
129
unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
 
130
  if (Encoding == dwarf::DW_EH_PE_omit)
 
131
    return 0;
 
132
 
 
133
  switch (Encoding & 0x07) {
 
134
  default:
 
135
    llvm_unreachable("Invalid encoded value.");
 
136
  case dwarf::DW_EH_PE_absptr:
 
137
    return TM.getDataLayout()->getPointerSize();
 
138
  case dwarf::DW_EH_PE_udata2:
 
139
    return 2;
 
140
  case dwarf::DW_EH_PE_udata4:
 
141
    return 4;
 
142
  case dwarf::DW_EH_PE_udata8:
 
143
    return 8;
 
144
  }
 
145
}
 
146
 
 
147
void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
 
148
                                    unsigned Encoding) const {
 
149
  if (GV) {
 
150
    const TargetLoweringObjectFile &TLOF = getObjFileLowering();
 
151
 
 
152
    const MCExpr *Exp =
 
153
        TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI,
 
154
                                     *OutStreamer);
 
155
    OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
 
156
  } else
 
157
    OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
 
158
}
 
159
 
 
160
void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
 
161
                                          bool ForceOffset) const {
 
162
  if (!ForceOffset) {
 
163
    // On COFF targets, we have to emit the special .secrel32 directive.
 
164
    if (MAI->needsDwarfSectionOffsetDirective()) {
 
165
      OutStreamer->EmitCOFFSecRel32(Label);
 
166
      return;
 
167
    }
 
168
 
 
169
    // If the format uses relocations with dwarf, refer to the symbol directly.
 
170
    if (MAI->doesDwarfUseRelocationsAcrossSections()) {
 
171
      OutStreamer->EmitSymbolValue(Label, 4);
 
172
      return;
 
173
    }
 
174
  }
 
175
 
 
176
  // Otherwise, emit it as a label difference from the start of the section.
 
177
  EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
 
178
}
 
179
 
 
180
void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
 
181
  if (MAI->doesDwarfUseRelocationsAcrossSections()) {
 
182
    emitDwarfSymbolReference(S.getSymbol());
 
183
    return;
 
184
  }
 
185
 
 
186
  // Just emit the offset directly; no need for symbol math.
 
187
  EmitInt32(S.getOffset());
 
188
}
 
189
 
 
190
/// EmitDwarfRegOp - Emit dwarf register operation.
 
191
void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
 
192
                                const MachineLocation &MLoc) const {
 
193
  DebugLocDwarfExpression Expr(*MF->getSubtarget().getRegisterInfo(),
 
194
                               getDwarfDebug()->getDwarfVersion(), Streamer);
 
195
  const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
 
196
  int Reg = MRI->getDwarfRegNum(MLoc.getReg(), false);
 
197
  if (Reg < 0) {
 
198
    // We assume that pointers are always in an addressable register.
 
199
    if (MLoc.isIndirect())
 
200
      // FIXME: We have no reasonable way of handling errors in here. The
 
201
      // caller might be in the middle of a dwarf expression. We should
 
202
      // probably assert that Reg >= 0 once debug info generation is more
 
203
      // mature.
 
204
      return Expr.EmitOp(dwarf::DW_OP_nop,
 
205
                         "nop (could not find a dwarf register number)");
 
206
 
 
207
    // Attempt to find a valid super- or sub-register.
 
208
    if (!Expr.AddMachineRegPiece(MLoc.getReg()))
 
209
      Expr.EmitOp(dwarf::DW_OP_nop,
 
210
                  "nop (could not find a dwarf register number)");
 
211
    return;
 
212
  }
 
213
 
 
214
  if (MLoc.isIndirect())
 
215
    Expr.AddRegIndirect(Reg, MLoc.getOffset());
 
216
  else
 
217
    Expr.AddReg(Reg);
 
218
}
 
219
 
 
220
//===----------------------------------------------------------------------===//
 
221
// Dwarf Lowering Routines
 
222
//===----------------------------------------------------------------------===//
 
223
 
 
224
void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
 
225
  switch (Inst.getOperation()) {
 
226
  default:
 
227
    llvm_unreachable("Unexpected instruction");
 
228
  case MCCFIInstruction::OpDefCfaOffset:
 
229
    OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
 
230
    break;
 
231
  case MCCFIInstruction::OpDefCfa:
 
232
    OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
 
233
    break;
 
234
  case MCCFIInstruction::OpDefCfaRegister:
 
235
    OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
 
236
    break;
 
237
  case MCCFIInstruction::OpOffset:
 
238
    OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
 
239
    break;
 
240
  case MCCFIInstruction::OpRegister:
 
241
    OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
 
242
    break;
 
243
  case MCCFIInstruction::OpWindowSave:
 
244
    OutStreamer->EmitCFIWindowSave();
 
245
    break;
 
246
  case MCCFIInstruction::OpSameValue:
 
247
    OutStreamer->EmitCFISameValue(Inst.getRegister());
 
248
    break;
 
249
  }
 
250
}
 
251
 
 
252
void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
 
253
  // Emit the code (index) for the abbreviation.
 
254
  if (isVerbose())
 
255
    OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
 
256
                            Twine::utohexstr(Die.getOffset()) + ":0x" +
 
257
                            Twine::utohexstr(Die.getSize()) + " " +
 
258
                            dwarf::TagString(Die.getTag()));
 
259
  EmitULEB128(Die.getAbbrevNumber());
 
260
 
 
261
  // Emit the DIE attribute values.
 
262
  for (const auto &V : Die.values()) {
 
263
    dwarf::Attribute Attr = V.getAttribute();
 
264
    assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
 
265
 
 
266
    if (isVerbose()) {
 
267
      OutStreamer->AddComment(dwarf::AttributeString(Attr));
 
268
      if (Attr == dwarf::DW_AT_accessibility)
 
269
        OutStreamer->AddComment(
 
270
            dwarf::AccessibilityString(V.getDIEInteger().getValue()));
 
271
    }
 
272
 
 
273
    // Emit an attribute using the defined form.
 
274
    V.EmitValue(this);
 
275
  }
 
276
 
 
277
  // Emit the DIE children if any.
 
278
  if (Die.hasChildren()) {
 
279
    for (auto &Child : Die.children())
 
280
      emitDwarfDIE(Child);
 
281
 
 
282
    OutStreamer->AddComment("End Of Children Mark");
 
283
    EmitInt8(0);
 
284
  }
 
285
}
 
286
 
 
287
void
 
288
AsmPrinter::emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const {
 
289
  // For each abbrevation.
 
290
  for (const DIEAbbrev *Abbrev : Abbrevs) {
 
291
    // Emit the abbrevations code (base 1 index.)
 
292
    EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
 
293
 
 
294
    // Emit the abbreviations data.
 
295
    Abbrev->Emit(this);
 
296
  }
 
297
 
 
298
  // Mark end of abbreviations.
 
299
  EmitULEB128(0, "EOM(3)");
 
300
}