1193323Sed//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9193323Sed// Data structures for DWARF info entries.
10249423Sdim//
11193323Sed//===----------------------------------------------------------------------===//
12193323Sed
13280031Sdim#include "llvm/CodeGen/DIE.h"
14280031Sdim#include "DwarfCompileUnit.h"
15261991Sdim#include "DwarfDebug.h"
16276479Sdim#include "DwarfUnit.h"
17202878Srdivacky#include "llvm/ADT/Twine.h"
18193323Sed#include "llvm/CodeGen/AsmPrinter.h"
19341825Sdim#include "llvm/Config/llvm-config.h"
20249423Sdim#include "llvm/IR/DataLayout.h"
21198090Srdivacky#include "llvm/MC/MCAsmInfo.h"
22280031Sdim#include "llvm/MC/MCContext.h"
23202878Srdivacky#include "llvm/MC/MCStreamer.h"
24202878Srdivacky#include "llvm/MC/MCSymbol.h"
25201360Srdivacky#include "llvm/Support/Debug.h"
26198090Srdivacky#include "llvm/Support/ErrorHandling.h"
27198090Srdivacky#include "llvm/Support/Format.h"
28202878Srdivacky#include "llvm/Support/FormattedStream.h"
29276479Sdim#include "llvm/Support/LEB128.h"
30261991Sdim#include "llvm/Support/MD5.h"
31288943Sdim#include "llvm/Support/raw_ostream.h"
32193323Sedusing namespace llvm;
33193323Sed
34321369Sdim#define DEBUG_TYPE "dwarfdebug"
35321369Sdim
36193323Sed//===----------------------------------------------------------------------===//
37193323Sed// DIEAbbrevData Implementation
38193323Sed//===----------------------------------------------------------------------===//
39193323Sed
40193323Sed/// Profile - Used to gather unique data for the abbreviation folding set.
41193323Sed///
42193323Sedvoid DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
43261991Sdim  // Explicitly cast to an integer type for which FoldingSetNodeID has
44261991Sdim  // overloads.  Otherwise MSVC 2010 thinks this call is ambiguous.
45261991Sdim  ID.AddInteger(unsigned(Attribute));
46261991Sdim  ID.AddInteger(unsigned(Form));
47321369Sdim  if (Form == dwarf::DW_FORM_implicit_const)
48321369Sdim    ID.AddInteger(Value);
49193323Sed}
50193323Sed
51193323Sed//===----------------------------------------------------------------------===//
52193323Sed// DIEAbbrev Implementation
53193323Sed//===----------------------------------------------------------------------===//
54193323Sed
55193323Sed/// Profile - Used to gather unique data for the abbreviation folding set.
56193323Sed///
57193323Sedvoid DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
58261991Sdim  ID.AddInteger(unsigned(Tag));
59276479Sdim  ID.AddInteger(unsigned(Children));
60193323Sed
61193323Sed  // For each attribute description.
62193323Sed  for (unsigned i = 0, N = Data.size(); i < N; ++i)
63193323Sed    Data[i].Profile(ID);
64193323Sed}
65193323Sed
66193323Sed/// Emit - Print the abbreviation using the specified asm printer.
67193323Sed///
68288943Sdimvoid DIEAbbrev::Emit(const AsmPrinter *AP) const {
69193323Sed  // Emit its Dwarf tag type.
70314564Sdim  AP->EmitULEB128(Tag, dwarf::TagString(Tag).data());
71193323Sed
72193323Sed  // Emit whether it has children DIEs.
73314564Sdim  AP->EmitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
74193323Sed
75193323Sed  // For each attribute description.
76193323Sed  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
77193323Sed    const DIEAbbrevData &AttrData = Data[i];
78193323Sed
79193323Sed    // Emit attribute type.
80206274Srdivacky    AP->EmitULEB128(AttrData.getAttribute(),
81314564Sdim                    dwarf::AttributeString(AttrData.getAttribute()).data());
82193323Sed
83193323Sed    // Emit form type.
84321369Sdim#ifndef NDEBUG
85321369Sdim    // Could be an assertion, but this way we can see the failing form code
86321369Sdim    // easily, which helps track down where it came from.
87321369Sdim    if (!dwarf::isValidFormForVersion(AttrData.getForm(),
88321369Sdim                                      AP->getDwarfVersion())) {
89341825Sdim      LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
90341825Sdim                        << " for DWARF version " << AP->getDwarfVersion()
91341825Sdim                        << "\n");
92321369Sdim      llvm_unreachable("Invalid form for specified DWARF version");
93321369Sdim    }
94321369Sdim#endif
95206274Srdivacky    AP->EmitULEB128(AttrData.getForm(),
96314564Sdim                    dwarf::FormEncodingString(AttrData.getForm()).data());
97314564Sdim
98314564Sdim    // Emit value for DW_FORM_implicit_const.
99321369Sdim    if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
100314564Sdim      AP->EmitSLEB128(AttrData.getValue());
101193323Sed  }
102193323Sed
103193323Sed  // Mark end of abbreviation.
104206274Srdivacky  AP->EmitULEB128(0, "EOM(1)");
105206274Srdivacky  AP->EmitULEB128(0, "EOM(2)");
106193323Sed}
107193323Sed
108296417SdimLLVM_DUMP_METHOD
109321369Sdimvoid DIEAbbrev::print(raw_ostream &O) const {
110193323Sed  O << "Abbreviation @"
111198090Srdivacky    << format("0x%lx", (long)(intptr_t)this)
112193323Sed    << "  "
113193323Sed    << dwarf::TagString(Tag)
114193323Sed    << " "
115276479Sdim    << dwarf::ChildrenString(Children)
116198090Srdivacky    << '\n';
117193323Sed
118193323Sed  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
119193323Sed    O << "  "
120193323Sed      << dwarf::AttributeString(Data[i].getAttribute())
121193323Sed      << "  "
122321369Sdim      << dwarf::FormEncodingString(Data[i].getForm());
123321369Sdim
124321369Sdim    if (Data[i].getForm() == dwarf::DW_FORM_implicit_const)
125321369Sdim      O << " " << Data[i].getValue();
126321369Sdim
127321369Sdim    O << '\n';
128193323Sed  }
129193323Sed}
130296417Sdim
131321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
132321369SdimLLVM_DUMP_METHOD void DIEAbbrev::dump() const {
133321369Sdim  print(dbgs());
134321369Sdim}
135321369Sdim#endif
136193323Sed
137314564Sdim//===----------------------------------------------------------------------===//
138314564Sdim// DIEAbbrevSet Implementation
139314564Sdim//===----------------------------------------------------------------------===//
140314564Sdim
141314564SdimDIEAbbrevSet::~DIEAbbrevSet() {
142314564Sdim  for (DIEAbbrev *Abbrev : Abbreviations)
143314564Sdim    Abbrev->~DIEAbbrev();
144314564Sdim}
145314564Sdim
146314564SdimDIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {
147314564Sdim
148314564Sdim  FoldingSetNodeID ID;
149314564Sdim  DIEAbbrev Abbrev = Die.generateAbbrev();
150314564Sdim  Abbrev.Profile(ID);
151314564Sdim
152314564Sdim  void *InsertPos;
153314564Sdim  if (DIEAbbrev *Existing =
154314564Sdim          AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
155314564Sdim    Die.setAbbrevNumber(Existing->getNumber());
156314564Sdim    return *Existing;
157314564Sdim  }
158314564Sdim
159314564Sdim  // Move the abbreviation to the heap and assign a number.
160314564Sdim  DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));
161314564Sdim  Abbreviations.push_back(New);
162314564Sdim  New->setNumber(Abbreviations.size());
163314564Sdim  Die.setAbbrevNumber(Abbreviations.size());
164314564Sdim
165314564Sdim  // Store it for lookup.
166314564Sdim  AbbreviationsSet.InsertNode(New, InsertPos);
167314564Sdim  return *New;
168314564Sdim}
169314564Sdim
170314564Sdimvoid DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {
171314564Sdim  if (!Abbreviations.empty()) {
172314564Sdim    // Start the debug abbrev section.
173314564Sdim    AP->OutStreamer->SwitchSection(Section);
174314564Sdim    AP->emitDwarfAbbrevs(Abbreviations);
175314564Sdim  }
176314564Sdim}
177314564Sdim
178314564Sdim//===----------------------------------------------------------------------===//
179314564Sdim// DIE Implementation
180314564Sdim//===----------------------------------------------------------------------===//
181314564Sdim
182314564SdimDIE *DIE::getParent() const {
183314564Sdim  return Owner.dyn_cast<DIE*>();
184314564Sdim}
185314564Sdim
186288943SdimDIEAbbrev DIE::generateAbbrev() const {
187288943Sdim  DIEAbbrev Abbrev(Tag, hasChildren());
188296417Sdim  for (const DIEValue &V : values())
189314564Sdim    if (V.getForm() == dwarf::DW_FORM_implicit_const)
190314564Sdim      Abbrev.AddImplicitConstAttribute(V.getAttribute(),
191314564Sdim                                       V.getDIEInteger().getValue());
192314564Sdim    else
193314564Sdim      Abbrev.AddAttribute(V.getAttribute(), V.getForm());
194288943Sdim  return Abbrev;
195288943Sdim}
196288943Sdim
197314564Sdimunsigned DIE::getDebugSectionOffset() const {
198314564Sdim  const DIEUnit *Unit = getUnit();
199314564Sdim  assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");
200314564Sdim  return Unit->getDebugSectionOffset() + getOffset();
201261991Sdim}
202261991Sdim
203314564Sdimconst DIE *DIE::getUnitDie() const {
204261991Sdim  const DIE *p = this;
205249423Sdim  while (p) {
206276479Sdim    if (p->getTag() == dwarf::DW_TAG_compile_unit ||
207276479Sdim        p->getTag() == dwarf::DW_TAG_type_unit)
208249423Sdim      return p;
209249423Sdim    p = p->getParent();
210249423Sdim  }
211276479Sdim  return nullptr;
212249423Sdim}
213249423Sdim
214353358SdimDIEUnit *DIE::getUnit() const {
215314564Sdim  const DIE *UnitDie = getUnitDie();
216314564Sdim  if (UnitDie)
217314564Sdim    return UnitDie->Owner.dyn_cast<DIEUnit*>();
218314564Sdim  return nullptr;
219314564Sdim}
220314564Sdim
221288943SdimDIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {
222261991Sdim  // Iterate through all the attributes until we find the one we're
223261991Sdim  // looking for, if we can't find it return NULL.
224288943Sdim  for (const auto &V : values())
225288943Sdim    if (V.getAttribute() == Attribute)
226288943Sdim      return V;
227288943Sdim  return DIEValue();
228261991Sdim}
229261991Sdim
230296417SdimLLVM_DUMP_METHOD
231296417Sdimstatic void printValues(raw_ostream &O, const DIEValueList &Values,
232296417Sdim                        StringRef Type, unsigned Size, unsigned IndentCount) {
233296417Sdim  O << Type << ": Size: " << Size << "\n";
234296417Sdim
235296417Sdim  unsigned I = 0;
236296417Sdim  const std::string Indent(IndentCount, ' ');
237296417Sdim  for (const auto &V : Values.values()) {
238296417Sdim    O << Indent;
239296417Sdim    O << "Blk[" << I++ << "]";
240296417Sdim    O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";
241296417Sdim    V.print(O);
242296417Sdim    O << "\n";
243296417Sdim  }
244296417Sdim}
245296417Sdim
246296417SdimLLVM_DUMP_METHOD
247251662Sdimvoid DIE::print(raw_ostream &O, unsigned IndentCount) const {
248193323Sed  const std::string Indent(IndentCount, ' ');
249296417Sdim  O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)
250296417Sdim    << ", Offset: " << Offset << ", Size: " << Size << "\n";
251193323Sed
252296417Sdim  O << Indent << dwarf::TagString(getTag()) << " "
253296417Sdim    << dwarf::ChildrenString(hasChildren()) << "\n";
254193323Sed
255193323Sed  IndentCount += 2;
256296417Sdim  for (const auto &V : values()) {
257193323Sed    O << Indent;
258296417Sdim    O << dwarf::AttributeString(V.getAttribute());
259288943Sdim    O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";
260288943Sdim    V.print(O);
261193323Sed    O << "\n";
262193323Sed  }
263193323Sed  IndentCount -= 2;
264193323Sed
265288943Sdim  for (const auto &Child : children())
266288943Sdim    Child.print(O, IndentCount + 4);
267193323Sed
268296417Sdim  O << "\n";
269193323Sed}
270193323Sed
271321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
272321369SdimLLVM_DUMP_METHOD void DIE::dump() const {
273201360Srdivacky  print(dbgs());
274193323Sed}
275321369Sdim#endif
276193323Sed
277314564Sdimunsigned DIE::computeOffsetsAndAbbrevs(const AsmPrinter *AP,
278314564Sdim                                       DIEAbbrevSet &AbbrevSet,
279314564Sdim                                       unsigned CUOffset) {
280314564Sdim  // Unique the abbreviation and fill in the abbreviation number so this DIE
281314564Sdim  // can be emitted.
282314564Sdim  const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);
283314564Sdim
284314564Sdim  // Set compile/type unit relative offset of this DIE.
285314564Sdim  setOffset(CUOffset);
286314564Sdim
287314564Sdim  // Add the byte size of the abbreviation code.
288314564Sdim  CUOffset += getULEB128Size(getAbbrevNumber());
289314564Sdim
290314564Sdim  // Add the byte size of all the DIE attribute values.
291314564Sdim  for (const auto &V : values())
292314564Sdim    CUOffset += V.SizeOf(AP);
293314564Sdim
294314564Sdim  // Let the children compute their offsets and abbreviation numbers.
295314564Sdim  if (hasChildren()) {
296314564Sdim    (void)Abbrev;
297314564Sdim    assert(Abbrev.hasChildren() && "Children flag not set");
298314564Sdim
299314564Sdim    for (auto &Child : children())
300314564Sdim      CUOffset = Child.computeOffsetsAndAbbrevs(AP, AbbrevSet, CUOffset);
301314564Sdim
302314564Sdim    // Each child chain is terminated with a zero byte, adjust the offset.
303314564Sdim    CUOffset += sizeof(int8_t);
304314564Sdim  }
305314564Sdim
306314564Sdim  // Compute the byte size of this DIE and all of its children correctly. This
307314564Sdim  // is needed so that top level DIE can help the compile unit set its length
308314564Sdim  // correctly.
309314564Sdim  setSize(CUOffset - getOffset());
310314564Sdim  return CUOffset;
311314564Sdim}
312314564Sdim
313314564Sdim//===----------------------------------------------------------------------===//
314314564Sdim// DIEUnit Implementation
315314564Sdim//===----------------------------------------------------------------------===//
316314564SdimDIEUnit::DIEUnit(uint16_t V, uint8_t A, dwarf::Tag UnitTag)
317314564Sdim    : Die(UnitTag), Section(nullptr), Offset(0), Length(0), Version(V),
318314564Sdim      AddrSize(A)
319314564Sdim{
320314564Sdim  Die.Owner = this;
321314564Sdim  assert((UnitTag == dwarf::DW_TAG_compile_unit ||
322360784Sdim          UnitTag == dwarf::DW_TAG_skeleton_unit ||
323314564Sdim          UnitTag == dwarf::DW_TAG_type_unit ||
324360784Sdim          UnitTag == dwarf::DW_TAG_partial_unit) &&
325360784Sdim         "expected a unit TAG");
326314564Sdim}
327314564Sdim
328288943Sdimvoid DIEValue::EmitValue(const AsmPrinter *AP) const {
329288943Sdim  switch (Ty) {
330288943Sdim  case isNone:
331288943Sdim    llvm_unreachable("Expected valid DIEValue");
332288943Sdim#define HANDLE_DIEVALUE(T)                                                     \
333288943Sdim  case is##T:                                                                  \
334288943Sdim    getDIE##T().EmitValue(AP, Form);                                           \
335288943Sdim    break;
336288943Sdim#include "llvm/CodeGen/DIEValue.def"
337288943Sdim  }
338288943Sdim}
339193323Sed
340288943Sdimunsigned DIEValue::SizeOf(const AsmPrinter *AP) const {
341288943Sdim  switch (Ty) {
342288943Sdim  case isNone:
343288943Sdim    llvm_unreachable("Expected valid DIEValue");
344288943Sdim#define HANDLE_DIEVALUE(T)                                                     \
345288943Sdim  case is##T:                                                                  \
346288943Sdim    return getDIE##T().SizeOf(AP, Form);
347288943Sdim#include "llvm/CodeGen/DIEValue.def"
348288943Sdim  }
349288943Sdim  llvm_unreachable("Unknown DIE kind");
350288943Sdim}
351288943Sdim
352296417SdimLLVM_DUMP_METHOD
353288943Sdimvoid DIEValue::print(raw_ostream &O) const {
354288943Sdim  switch (Ty) {
355288943Sdim  case isNone:
356288943Sdim    llvm_unreachable("Expected valid DIEValue");
357288943Sdim#define HANDLE_DIEVALUE(T)                                                     \
358288943Sdim  case is##T:                                                                  \
359288943Sdim    getDIE##T().print(O);                                                      \
360288943Sdim    break;
361288943Sdim#include "llvm/CodeGen/DIEValue.def"
362288943Sdim  }
363288943Sdim}
364288943Sdim
365321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
366321369SdimLLVM_DUMP_METHOD void DIEValue::dump() const {
367201360Srdivacky  print(dbgs());
368193323Sed}
369321369Sdim#endif
370193323Sed
371193323Sed//===----------------------------------------------------------------------===//
372193323Sed// DIEInteger Implementation
373193323Sed//===----------------------------------------------------------------------===//
374193323Sed
375193323Sed/// EmitValue - Emit integer of appropriate size.
376193323Sed///
377288943Sdimvoid DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
378193323Sed  switch (Form) {
379314564Sdim  case dwarf::DW_FORM_implicit_const:
380243830Sdim  case dwarf::DW_FORM_flag_present:
381243830Sdim    // Emit something to keep the lines and comments in sync.
382243830Sdim    // FIXME: Is there a better way to do this?
383288943Sdim    Asm->OutStreamer->AddBlankLine();
384243830Sdim    return;
385314564Sdim  case dwarf::DW_FORM_flag:
386314564Sdim  case dwarf::DW_FORM_ref1:
387314564Sdim  case dwarf::DW_FORM_data1:
388321369Sdim  case dwarf::DW_FORM_strx1:
389321369Sdim  case dwarf::DW_FORM_addrx1:
390314564Sdim  case dwarf::DW_FORM_ref2:
391314564Sdim  case dwarf::DW_FORM_data2:
392321369Sdim  case dwarf::DW_FORM_strx2:
393321369Sdim  case dwarf::DW_FORM_addrx2:
394341825Sdim  case dwarf::DW_FORM_strx3:
395314564Sdim  case dwarf::DW_FORM_strp:
396314564Sdim  case dwarf::DW_FORM_ref4:
397314564Sdim  case dwarf::DW_FORM_data4:
398321369Sdim  case dwarf::DW_FORM_ref_sup4:
399321369Sdim  case dwarf::DW_FORM_strx4:
400321369Sdim  case dwarf::DW_FORM_addrx4:
401314564Sdim  case dwarf::DW_FORM_ref8:
402314564Sdim  case dwarf::DW_FORM_ref_sig8:
403314564Sdim  case dwarf::DW_FORM_data8:
404321369Sdim  case dwarf::DW_FORM_ref_sup8:
405314564Sdim  case dwarf::DW_FORM_GNU_ref_alt:
406314564Sdim  case dwarf::DW_FORM_GNU_strp_alt:
407314564Sdim  case dwarf::DW_FORM_line_strp:
408314564Sdim  case dwarf::DW_FORM_sec_offset:
409314564Sdim  case dwarf::DW_FORM_strp_sup:
410243830Sdim  case dwarf::DW_FORM_addr:
411288943Sdim  case dwarf::DW_FORM_ref_addr:
412314564Sdim    Asm->OutStreamer->EmitIntValue(Integer, SizeOf(Asm, Form));
413314564Sdim    return;
414314564Sdim  case dwarf::DW_FORM_GNU_str_index:
415314564Sdim  case dwarf::DW_FORM_GNU_addr_index:
416314564Sdim  case dwarf::DW_FORM_ref_udata:
417341825Sdim  case dwarf::DW_FORM_strx:
418344779Sdim  case dwarf::DW_FORM_addrx:
419344779Sdim  case dwarf::DW_FORM_rnglistx:
420314564Sdim  case dwarf::DW_FORM_udata:
421314564Sdim    Asm->EmitULEB128(Integer);
422314564Sdim    return;
423314564Sdim  case dwarf::DW_FORM_sdata:
424314564Sdim    Asm->EmitSLEB128(Integer);
425314564Sdim    return;
426198090Srdivacky  default: llvm_unreachable("DIE Value form not supported yet");
427193323Sed  }
428193323Sed}
429193323Sed
430193323Sed/// SizeOf - Determine size of integer value in bytes.
431193323Sed///
432288943Sdimunsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
433341825Sdim  dwarf::FormParams Params = {0, 0, dwarf::DWARF32};
434341825Sdim  if (AP)
435341825Sdim    Params = {AP->getDwarfVersion(), uint8_t(AP->getPointerSize()),
436341825Sdim              AP->OutStreamer->getContext().getDwarfFormat()};
437341825Sdim
438341825Sdim  if (Optional<uint8_t> FixedSize = dwarf::getFixedFormByteSize(Form, Params))
439341825Sdim    return *FixedSize;
440341825Sdim
441193323Sed  switch (Form) {
442314564Sdim  case dwarf::DW_FORM_GNU_str_index:
443314564Sdim  case dwarf::DW_FORM_GNU_addr_index:
444314564Sdim  case dwarf::DW_FORM_ref_udata:
445341825Sdim  case dwarf::DW_FORM_strx:
446344779Sdim  case dwarf::DW_FORM_addrx:
447344779Sdim  case dwarf::DW_FORM_rnglistx:
448314564Sdim  case dwarf::DW_FORM_udata:
449314564Sdim    return getULEB128Size(Integer);
450314564Sdim  case dwarf::DW_FORM_sdata:
451314564Sdim    return getSLEB128Size(Integer);
452234353Sdim  default: llvm_unreachable("DIE Value form not supported yet");
453193323Sed  }
454193323Sed}
455193323Sed
456296417SdimLLVM_DUMP_METHOD
457261991Sdimvoid DIEInteger::print(raw_ostream &O) const {
458234353Sdim  O << "Int: " << (int64_t)Integer << "  0x";
459234353Sdim  O.write_hex(Integer);
460193323Sed}
461193323Sed
462193323Sed//===----------------------------------------------------------------------===//
463261991Sdim// DIEExpr Implementation
464261991Sdim//===----------------------------------------------------------------------===//
465261991Sdim
466261991Sdim/// EmitValue - Emit expression value.
467261991Sdim///
468288943Sdimvoid DIEExpr::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
469344779Sdim  AP->EmitDebugValue(Expr, SizeOf(AP, Form));
470261991Sdim}
471261991Sdim
472261991Sdim/// SizeOf - Determine size of expression value in bytes.
473261991Sdim///
474288943Sdimunsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
475261991Sdim  if (Form == dwarf::DW_FORM_data4) return 4;
476261991Sdim  if (Form == dwarf::DW_FORM_sec_offset) return 4;
477261991Sdim  if (Form == dwarf::DW_FORM_strp) return 4;
478296417Sdim  return AP->getPointerSize();
479261991Sdim}
480261991Sdim
481296417SdimLLVM_DUMP_METHOD
482288943Sdimvoid DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
483261991Sdim
484261991Sdim//===----------------------------------------------------------------------===//
485204961Srdivacky// DIELabel Implementation
486193323Sed//===----------------------------------------------------------------------===//
487193323Sed
488193323Sed/// EmitValue - Emit label value.
489193323Sed///
490288943Sdimvoid DIELabel::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
491261991Sdim  AP->EmitLabelReference(Label, SizeOf(AP, Form),
492261991Sdim                         Form == dwarf::DW_FORM_strp ||
493261991Sdim                             Form == dwarf::DW_FORM_sec_offset ||
494314564Sdim                             Form == dwarf::DW_FORM_ref_addr ||
495314564Sdim                             Form == dwarf::DW_FORM_data4);
496193323Sed}
497193323Sed
498193323Sed/// SizeOf - Determine size of label value in bytes.
499193323Sed///
500288943Sdimunsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
501193323Sed  if (Form == dwarf::DW_FORM_data4) return 4;
502249423Sdim  if (Form == dwarf::DW_FORM_sec_offset) return 4;
503234353Sdim  if (Form == dwarf::DW_FORM_strp) return 4;
504321369Sdim  return AP->MAI->getCodePointerSize();
505193323Sed}
506193323Sed
507296417SdimLLVM_DUMP_METHOD
508288943Sdimvoid DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
509193323Sed
510193323Sed//===----------------------------------------------------------------------===//
511353358Sdim// DIEBaseTypeRef Implementation
512353358Sdim//===----------------------------------------------------------------------===//
513353358Sdim
514353358Sdimvoid DIEBaseTypeRef::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
515353358Sdim  uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
516353358Sdim  assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
517353358Sdim  AP->EmitULEB128(Offset, nullptr, ULEB128PadSize);
518353358Sdim}
519353358Sdim
520353358Sdimunsigned DIEBaseTypeRef::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
521353358Sdim  return ULEB128PadSize;
522353358Sdim}
523353358Sdim
524353358SdimLLVM_DUMP_METHOD
525353358Sdimvoid DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }
526353358Sdim
527353358Sdim//===----------------------------------------------------------------------===//
528193323Sed// DIEDelta Implementation
529193323Sed//===----------------------------------------------------------------------===//
530193323Sed
531193323Sed/// EmitValue - Emit delta value.
532193323Sed///
533288943Sdimvoid DIEDelta::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
534206274Srdivacky  AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
535193323Sed}
536193323Sed
537193323Sed/// SizeOf - Determine size of delta value in bytes.
538193323Sed///
539288943Sdimunsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
540193323Sed  if (Form == dwarf::DW_FORM_data4) return 4;
541261991Sdim  if (Form == dwarf::DW_FORM_sec_offset) return 4;
542234353Sdim  if (Form == dwarf::DW_FORM_strp) return 4;
543321369Sdim  return AP->MAI->getCodePointerSize();
544193323Sed}
545193323Sed
546296417SdimLLVM_DUMP_METHOD
547261991Sdimvoid DIEDelta::print(raw_ostream &O) const {
548204961Srdivacky  O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
549193323Sed}
550193323Sed
551193323Sed//===----------------------------------------------------------------------===//
552261991Sdim// DIEString Implementation
553261991Sdim//===----------------------------------------------------------------------===//
554261991Sdim
555261991Sdim/// EmitValue - Emit string value.
556261991Sdim///
557288943Sdimvoid DIEString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
558288943Sdim  // Index of string in symbol table.
559341825Sdim  switch (Form) {
560341825Sdim  case dwarf::DW_FORM_GNU_str_index:
561341825Sdim  case dwarf::DW_FORM_strx:
562341825Sdim  case dwarf::DW_FORM_strx1:
563341825Sdim  case dwarf::DW_FORM_strx2:
564341825Sdim  case dwarf::DW_FORM_strx3:
565341825Sdim  case dwarf::DW_FORM_strx4:
566288943Sdim    DIEInteger(S.getIndex()).EmitValue(AP, Form);
567288943Sdim    return;
568341825Sdim  case dwarf::DW_FORM_strp:
569341825Sdim    if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
570341825Sdim      DIELabel(S.getSymbol()).EmitValue(AP, Form);
571341825Sdim    else
572341825Sdim      DIEInteger(S.getOffset()).EmitValue(AP, Form);
573288943Sdim    return;
574341825Sdim  default:
575341825Sdim    llvm_unreachable("Expected valid string form");
576288943Sdim  }
577261991Sdim}
578261991Sdim
579261991Sdim/// SizeOf - Determine size of delta value in bytes.
580261991Sdim///
581288943Sdimunsigned DIEString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
582288943Sdim  // Index of string in symbol table.
583341825Sdim  switch (Form) {
584341825Sdim  case dwarf::DW_FORM_GNU_str_index:
585341825Sdim  case dwarf::DW_FORM_strx:
586341825Sdim  case dwarf::DW_FORM_strx1:
587341825Sdim  case dwarf::DW_FORM_strx2:
588341825Sdim  case dwarf::DW_FORM_strx3:
589341825Sdim  case dwarf::DW_FORM_strx4:
590288943Sdim    return DIEInteger(S.getIndex()).SizeOf(AP, Form);
591341825Sdim  case dwarf::DW_FORM_strp:
592341825Sdim    if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
593341825Sdim      return DIELabel(S.getSymbol()).SizeOf(AP, Form);
594341825Sdim    return DIEInteger(S.getOffset()).SizeOf(AP, Form);
595341825Sdim  default:
596341825Sdim    llvm_unreachable("Expected valid string form");
597341825Sdim  }
598261991Sdim}
599261991Sdim
600296417SdimLLVM_DUMP_METHOD
601261991Sdimvoid DIEString::print(raw_ostream &O) const {
602288943Sdim  O << "String: " << S.getString();
603261991Sdim}
604261991Sdim
605261991Sdim//===----------------------------------------------------------------------===//
606314564Sdim// DIEInlineString Implementation
607314564Sdim//===----------------------------------------------------------------------===//
608314564Sdimvoid DIEInlineString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
609314564Sdim  if (Form == dwarf::DW_FORM_string) {
610344779Sdim    AP->OutStreamer->EmitBytes(S);
611341825Sdim    AP->emitInt8(0);
612314564Sdim    return;
613314564Sdim  }
614314564Sdim  llvm_unreachable("Expected valid string form");
615314564Sdim}
616314564Sdim
617314564Sdimunsigned DIEInlineString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
618314564Sdim  // Emit string bytes + NULL byte.
619314564Sdim  return S.size() + 1;
620314564Sdim}
621314564Sdim
622314564SdimLLVM_DUMP_METHOD
623314564Sdimvoid DIEInlineString::print(raw_ostream &O) const {
624314564Sdim  O << "InlineString: " << S;
625314564Sdim}
626314564Sdim
627314564Sdim//===----------------------------------------------------------------------===//
628193323Sed// DIEEntry Implementation
629193323Sed//===----------------------------------------------------------------------===//
630193323Sed
631193323Sed/// EmitValue - Emit debug information entry offset.
632193323Sed///
633288943Sdimvoid DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
634276479Sdim
635314564Sdim  switch (Form) {
636314564Sdim  case dwarf::DW_FORM_ref1:
637314564Sdim  case dwarf::DW_FORM_ref2:
638314564Sdim  case dwarf::DW_FORM_ref4:
639314564Sdim  case dwarf::DW_FORM_ref8:
640314564Sdim    AP->OutStreamer->EmitIntValue(Entry->getOffset(), SizeOf(AP, Form));
641314564Sdim    return;
642314564Sdim
643314564Sdim  case dwarf::DW_FORM_ref_udata:
644314564Sdim    AP->EmitULEB128(Entry->getOffset());
645314564Sdim    return;
646314564Sdim
647314564Sdim  case dwarf::DW_FORM_ref_addr: {
648314564Sdim    // Get the absolute offset for this DIE within the debug info/types section.
649314564Sdim    unsigned Addr = Entry->getDebugSectionOffset();
650321369Sdim    if (const MCSymbol *SectionSym =
651321369Sdim            Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
652321369Sdim      AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
653321369Sdim      return;
654314564Sdim    }
655321369Sdim
656314564Sdim    AP->OutStreamer->EmitIntValue(Addr, SizeOf(AP, Form));
657314564Sdim    return;
658314564Sdim  }
659314564Sdim  default:
660314564Sdim    llvm_unreachable("Improper form for DIE reference");
661314564Sdim  }
662193323Sed}
663193323Sed
664314564Sdimunsigned DIEEntry::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
665314564Sdim  switch (Form) {
666314564Sdim  case dwarf::DW_FORM_ref1:
667314564Sdim    return 1;
668314564Sdim  case dwarf::DW_FORM_ref2:
669314564Sdim    return 2;
670314564Sdim  case dwarf::DW_FORM_ref4:
671314564Sdim    return 4;
672314564Sdim  case dwarf::DW_FORM_ref8:
673314564Sdim    return 8;
674314564Sdim  case dwarf::DW_FORM_ref_udata:
675314564Sdim    return getULEB128Size(Entry->getOffset());
676314564Sdim  case dwarf::DW_FORM_ref_addr:
677314564Sdim    if (AP->getDwarfVersion() == 2)
678321369Sdim      return AP->MAI->getCodePointerSize();
679314564Sdim    switch (AP->OutStreamer->getContext().getDwarfFormat()) {
680314564Sdim    case dwarf::DWARF32:
681314564Sdim      return 4;
682314564Sdim    case dwarf::DWARF64:
683314564Sdim      return 8;
684314564Sdim    }
685314564Sdim    llvm_unreachable("Invalid DWARF format");
686314564Sdim
687314564Sdim  default:
688314564Sdim    llvm_unreachable("Improper form for DIE reference");
689314564Sdim  }
690261991Sdim}
691261991Sdim
692296417SdimLLVM_DUMP_METHOD
693261991Sdimvoid DIEEntry::print(raw_ostream &O) const {
694276479Sdim  O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
695193323Sed}
696193323Sed
697193323Sed//===----------------------------------------------------------------------===//
698276479Sdim// DIELoc Implementation
699276479Sdim//===----------------------------------------------------------------------===//
700276479Sdim
701276479Sdim/// ComputeSize - calculate the size of the location expression.
702276479Sdim///
703288943Sdimunsigned DIELoc::ComputeSize(const AsmPrinter *AP) const {
704276479Sdim  if (!Size) {
705296417Sdim    for (const auto &V : values())
706288943Sdim      Size += V.SizeOf(AP);
707276479Sdim  }
708276479Sdim
709276479Sdim  return Size;
710276479Sdim}
711276479Sdim
712276479Sdim/// EmitValue - Emit location data.
713276479Sdim///
714288943Sdimvoid DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
715276479Sdim  switch (Form) {
716276479Sdim  default: llvm_unreachable("Improper form for block");
717341825Sdim  case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;
718341825Sdim  case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;
719341825Sdim  case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;
720276479Sdim  case dwarf::DW_FORM_block:
721276479Sdim  case dwarf::DW_FORM_exprloc:
722276479Sdim    Asm->EmitULEB128(Size); break;
723276479Sdim  }
724276479Sdim
725296417Sdim  for (const auto &V : values())
726288943Sdim    V.EmitValue(Asm);
727276479Sdim}
728276479Sdim
729276479Sdim/// SizeOf - Determine size of location data in bytes.
730276479Sdim///
731288943Sdimunsigned DIELoc::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
732276479Sdim  switch (Form) {
733276479Sdim  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
734276479Sdim  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
735276479Sdim  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
736276479Sdim  case dwarf::DW_FORM_block:
737276479Sdim  case dwarf::DW_FORM_exprloc:
738276479Sdim    return Size + getULEB128Size(Size);
739276479Sdim  default: llvm_unreachable("Improper form for block");
740276479Sdim  }
741276479Sdim}
742276479Sdim
743296417SdimLLVM_DUMP_METHOD
744276479Sdimvoid DIELoc::print(raw_ostream &O) const {
745296417Sdim  printValues(O, *this, "ExprLoc", Size, 5);
746276479Sdim}
747276479Sdim
748276479Sdim//===----------------------------------------------------------------------===//
749193323Sed// DIEBlock Implementation
750193323Sed//===----------------------------------------------------------------------===//
751193323Sed
752193323Sed/// ComputeSize - calculate the size of the block.
753193323Sed///
754288943Sdimunsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const {
755193323Sed  if (!Size) {
756296417Sdim    for (const auto &V : values())
757288943Sdim      Size += V.SizeOf(AP);
758193323Sed  }
759193323Sed
760193323Sed  return Size;
761193323Sed}
762193323Sed
763193323Sed/// EmitValue - Emit block data.
764193323Sed///
765288943Sdimvoid DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
766193323Sed  switch (Form) {
767234353Sdim  default: llvm_unreachable("Improper form for block");
768341825Sdim  case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;
769341825Sdim  case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;
770341825Sdim  case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;
771206274Srdivacky  case dwarf::DW_FORM_block:  Asm->EmitULEB128(Size); break;
772341825Sdim  case dwarf::DW_FORM_string: break;
773327952Sdim  case dwarf::DW_FORM_data16: break;
774193323Sed  }
775193323Sed
776296417Sdim  for (const auto &V : values())
777288943Sdim    V.EmitValue(Asm);
778193323Sed}
779193323Sed
780193323Sed/// SizeOf - Determine size of block data in bytes.
781193323Sed///
782288943Sdimunsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
783193323Sed  switch (Form) {
784193323Sed  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
785193323Sed  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
786193323Sed  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
787276479Sdim  case dwarf::DW_FORM_block:  return Size + getULEB128Size(Size);
788327952Sdim  case dwarf::DW_FORM_data16: return 16;
789234353Sdim  default: llvm_unreachable("Improper form for block");
790193323Sed  }
791193323Sed}
792193323Sed
793296417SdimLLVM_DUMP_METHOD
794261991Sdimvoid DIEBlock::print(raw_ostream &O) const {
795296417Sdim  printValues(O, *this, "Blk", Size, 5);
796193323Sed}
797276479Sdim
798276479Sdim//===----------------------------------------------------------------------===//
799276479Sdim// DIELocList Implementation
800276479Sdim//===----------------------------------------------------------------------===//
801276479Sdim
802288943Sdimunsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
803360784Sdim  if (Form == dwarf::DW_FORM_loclistx)
804360784Sdim    return getULEB128Size(Index);
805276479Sdim  if (Form == dwarf::DW_FORM_data4)
806276479Sdim    return 4;
807276479Sdim  if (Form == dwarf::DW_FORM_sec_offset)
808276479Sdim    return 4;
809321369Sdim  return AP->MAI->getCodePointerSize();
810276479Sdim}
811276479Sdim
812276479Sdim/// EmitValue - Emit label value.
813276479Sdim///
814288943Sdimvoid DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
815360784Sdim  if (Form == dwarf::DW_FORM_loclistx) {
816360784Sdim    AP->EmitULEB128(Index);
817360784Sdim    return;
818360784Sdim  }
819276479Sdim  DwarfDebug *DD = AP->getDwarfDebug();
820288943Sdim  MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
821288943Sdim  AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());
822276479Sdim}
823276479Sdim
824296417SdimLLVM_DUMP_METHOD
825288943Sdimvoid DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }
826