brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.1 KiB · a2252d8 Raw
872 lines · cpp
1//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Data structures for DWARF info entries.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/DIE.h"14#include "DwarfCompileUnit.h"15#include "DwarfDebug.h"16#include "llvm/CodeGen/AsmPrinter.h"17#include "llvm/Config/llvm-config.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCStreamer.h"20#include "llvm/MC/MCSymbol.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/Format.h"24#include "llvm/Support/LEB128.h"25#include "llvm/Support/raw_ostream.h"26using namespace llvm;27 28#define DEBUG_TYPE "dwarfdebug"29 30//===----------------------------------------------------------------------===//31// DIEAbbrevData Implementation32//===----------------------------------------------------------------------===//33 34/// Profile - Used to gather unique data for the abbreviation folding set.35///36void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {37  // Explicitly cast to an integer type for which FoldingSetNodeID has38  // overloads.  Otherwise MSVC 2010 thinks this call is ambiguous.39  ID.AddInteger(unsigned(Attribute));40  ID.AddInteger(unsigned(Form));41  if (Form == dwarf::DW_FORM_implicit_const)42    ID.AddInteger(Value);43}44 45//===----------------------------------------------------------------------===//46// DIEAbbrev Implementation47//===----------------------------------------------------------------------===//48 49/// Profile - Used to gather unique data for the abbreviation folding set.50///51void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {52  ID.AddInteger(unsigned(Tag));53  ID.AddInteger(unsigned(Children));54 55  // For each attribute description.56  for (const DIEAbbrevData &D : Data)57    D.Profile(ID);58}59 60/// Emit - Print the abbreviation using the specified asm printer.61///62void DIEAbbrev::Emit(const AsmPrinter *AP) const {63  // Emit its Dwarf tag type.64  AP->emitULEB128(Tag, dwarf::TagString(Tag).data());65 66  // Emit whether it has children DIEs.67  AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());68 69  // For each attribute description.70  for (const DIEAbbrevData &AttrData : Data) {71    // Emit attribute type.72    AP->emitULEB128(AttrData.getAttribute(),73                    dwarf::AttributeString(AttrData.getAttribute()).data());74 75    // Emit form type.76#ifndef NDEBUG77    // Could be an assertion, but this way we can see the failing form code78    // easily, which helps track down where it came from.79    if (!dwarf::isValidFormForVersion(AttrData.getForm(),80                                      AP->getDwarfVersion())) {81      LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())82                        << " for DWARF version " << AP->getDwarfVersion()83                        << "\n");84      llvm_unreachable("Invalid form for specified DWARF version");85    }86#endif87    AP->emitULEB128(AttrData.getForm(),88                    dwarf::FormEncodingString(AttrData.getForm()).data());89 90    // Emit value for DW_FORM_implicit_const.91    if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)92      AP->emitSLEB128(AttrData.getValue());93  }94 95  // Mark end of abbreviation.96  AP->emitULEB128(0, "EOM(1)");97  AP->emitULEB128(0, "EOM(2)");98}99 100LLVM_DUMP_METHOD101void DIEAbbrev::print(raw_ostream &O) const {102  O << "Abbreviation @"103    << format("0x%lx", (long)(intptr_t)this)104    << "  "105    << dwarf::TagString(Tag)106    << " "107    << dwarf::ChildrenString(Children)108    << '\n';109 110  for (const DIEAbbrevData &D : Data) {111    O << "  " << dwarf::AttributeString(D.getAttribute()) << "  "112      << dwarf::FormEncodingString(D.getForm());113 114    if (D.getForm() == dwarf::DW_FORM_implicit_const)115      O << " " << D.getValue();116 117    O << '\n';118  }119}120 121#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)122LLVM_DUMP_METHOD void DIEAbbrev::dump() const {123  print(dbgs());124}125#endif126 127//===----------------------------------------------------------------------===//128// DIEAbbrevSet Implementation129//===----------------------------------------------------------------------===//130 131DIEAbbrevSet::~DIEAbbrevSet() {132  for (DIEAbbrev *Abbrev : Abbreviations)133    Abbrev->~DIEAbbrev();134}135 136DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {137 138  FoldingSetNodeID ID;139  DIEAbbrev Abbrev = Die.generateAbbrev();140  Abbrev.Profile(ID);141 142  void *InsertPos;143  if (DIEAbbrev *Existing =144          AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {145    Die.setAbbrevNumber(Existing->getNumber());146    return *Existing;147  }148 149  // Move the abbreviation to the heap and assign a number.150  DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));151  Abbreviations.push_back(New);152  New->setNumber(Abbreviations.size());153  Die.setAbbrevNumber(Abbreviations.size());154 155  // Store it for lookup.156  AbbreviationsSet.InsertNode(New, InsertPos);157  return *New;158}159 160void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {161  if (!Abbreviations.empty()) {162    // Start the debug abbrev section.163    AP->OutStreamer->switchSection(Section);164    AP->emitDwarfAbbrevs(Abbreviations);165  }166}167 168//===----------------------------------------------------------------------===//169// DIE Implementation170//===----------------------------------------------------------------------===//171 172DIE *DIE::getParent() const { return dyn_cast_if_present<DIE *>(Owner); }173 174DIEAbbrev DIE::generateAbbrev() const {175  DIEAbbrev Abbrev(Tag, hasChildren());176  for (const DIEValue &V : values())177    if (V.getForm() == dwarf::DW_FORM_implicit_const)178      Abbrev.AddImplicitConstAttribute(V.getAttribute(),179                                       V.getDIEInteger().getValue());180    else181      Abbrev.AddAttribute(V.getAttribute(), V.getForm());182  return Abbrev;183}184 185uint64_t DIE::getDebugSectionOffset() const {186  const DIEUnit *Unit = getUnit();187  assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");188  return Unit->getDebugSectionOffset() + getOffset();189}190 191const DIE *DIE::getUnitDie() const {192  const DIE *p = this;193  while (p) {194    if (p->getTag() == dwarf::DW_TAG_compile_unit ||195        p->getTag() == dwarf::DW_TAG_skeleton_unit ||196        p->getTag() == dwarf::DW_TAG_type_unit)197      return p;198    p = p->getParent();199  }200  return nullptr;201}202 203DIEUnit *DIE::getUnit() const {204  const DIE *UnitDie = getUnitDie();205  if (UnitDie)206    return dyn_cast_if_present<DIEUnit *>(UnitDie->Owner);207  return nullptr;208}209 210DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {211  // Iterate through all the attributes until we find the one we're212  // looking for, if we can't find it return NULL.213  for (const auto &V : values())214    if (V.getAttribute() == Attribute)215      return V;216  return DIEValue();217}218 219LLVM_DUMP_METHOD220static void printValues(raw_ostream &O, const DIEValueList &Values,221                        StringRef Type, unsigned Size, unsigned IndentCount) {222  O << Type << ": Size: " << Size << "\n";223 224  unsigned I = 0;225  const std::string Indent(IndentCount, ' ');226  for (const auto &V : Values.values()) {227    O << Indent;228    O << "Blk[" << I++ << "]";229    O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";230    V.print(O);231    O << "\n";232  }233}234 235LLVM_DUMP_METHOD236void DIE::print(raw_ostream &O, unsigned IndentCount) const {237  const std::string Indent(IndentCount, ' ');238  O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)239    << ", Offset: " << Offset << ", Size: " << Size << "\n";240 241  O << Indent << dwarf::TagString(getTag()) << " "242    << dwarf::ChildrenString(hasChildren()) << "\n";243 244  IndentCount += 2;245  for (const auto &V : values()) {246    O << Indent;247    O << dwarf::AttributeString(V.getAttribute());248    O << "  " << dwarf::FormEncodingString(V.getForm()) << " ";249    V.print(O);250    O << "\n";251  }252  IndentCount -= 2;253 254  for (const auto &Child : children())255    Child.print(O, IndentCount + 4);256 257  O << "\n";258}259 260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)261LLVM_DUMP_METHOD void DIE::dump() const {262  print(dbgs());263}264#endif265 266unsigned DIE::computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams,267                                       DIEAbbrevSet &AbbrevSet,268                                       unsigned CUOffset) {269  // Unique the abbreviation and fill in the abbreviation number so this DIE270  // can be emitted.271  const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);272 273  // Set compile/type unit relative offset of this DIE.274  setOffset(CUOffset);275 276  // Add the byte size of the abbreviation code.277  CUOffset += getULEB128Size(getAbbrevNumber());278 279  // Add the byte size of all the DIE attribute values.280  for (const auto &V : values())281    CUOffset += V.sizeOf(FormParams);282 283  // Let the children compute their offsets and abbreviation numbers.284  if (hasChildren()) {285    (void)Abbrev;286    assert(Abbrev.hasChildren() && "Children flag not set");287 288    for (auto &Child : children())289      CUOffset =290          Child.computeOffsetsAndAbbrevs(FormParams, AbbrevSet, CUOffset);291 292    // Each child chain is terminated with a zero byte, adjust the offset.293    CUOffset += sizeof(int8_t);294  }295 296  // Compute the byte size of this DIE and all of its children correctly. This297  // is needed so that top level DIE can help the compile unit set its length298  // correctly.299  setSize(CUOffset - getOffset());300  return CUOffset;301}302 303//===----------------------------------------------------------------------===//304// DIEUnit Implementation305//===----------------------------------------------------------------------===//306DIEUnit::DIEUnit(dwarf::Tag UnitTag) : Die(UnitTag) {307  Die.Owner = this;308  assert((UnitTag == dwarf::DW_TAG_compile_unit ||309          UnitTag == dwarf::DW_TAG_skeleton_unit ||310          UnitTag == dwarf::DW_TAG_type_unit ||311          UnitTag == dwarf::DW_TAG_partial_unit) &&312         "expected a unit TAG");313}314 315void DIEValue::emitValue(const AsmPrinter *AP) const {316  switch (Ty) {317  case isNone:318    llvm_unreachable("Expected valid DIEValue");319#define HANDLE_DIEVALUE(T)                                                     \320  case is##T:                                                                  \321    getDIE##T().emitValue(AP, Form);                                           \322    break;323#include "llvm/CodeGen/DIEValue.def"324  }325}326 327unsigned DIEValue::sizeOf(const dwarf::FormParams &FormParams) const {328  switch (Ty) {329  case isNone:330    llvm_unreachable("Expected valid DIEValue");331#define HANDLE_DIEVALUE(T)                                                     \332  case is##T:                                                                  \333    return getDIE##T().sizeOf(FormParams, Form);334#include "llvm/CodeGen/DIEValue.def"335  }336  llvm_unreachable("Unknown DIE kind");337}338 339LLVM_DUMP_METHOD340void DIEValue::print(raw_ostream &O) const {341  switch (Ty) {342  case isNone:343    llvm_unreachable("Expected valid DIEValue");344#define HANDLE_DIEVALUE(T)                                                     \345  case is##T:                                                                  \346    getDIE##T().print(O);                                                      \347    break;348#include "llvm/CodeGen/DIEValue.def"349  }350}351 352#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)353LLVM_DUMP_METHOD void DIEValue::dump() const {354  print(dbgs());355}356#endif357 358//===----------------------------------------------------------------------===//359// DIEInteger Implementation360//===----------------------------------------------------------------------===//361 362/// EmitValue - Emit integer of appropriate size.363///364void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {365  switch (Form) {366  case dwarf::DW_FORM_implicit_const:367  case dwarf::DW_FORM_flag_present:368    // Emit something to keep the lines and comments in sync.369    // FIXME: Is there a better way to do this?370    Asm->OutStreamer->addBlankLine();371    return;372  case dwarf::DW_FORM_flag:373  case dwarf::DW_FORM_ref1:374  case dwarf::DW_FORM_data1:375  case dwarf::DW_FORM_strx1:376  case dwarf::DW_FORM_addrx1:377  case dwarf::DW_FORM_ref2:378  case dwarf::DW_FORM_data2:379  case dwarf::DW_FORM_strx2:380  case dwarf::DW_FORM_addrx2:381  case dwarf::DW_FORM_strx3:382  case dwarf::DW_FORM_addrx3:383  case dwarf::DW_FORM_strp:384  case dwarf::DW_FORM_ref4:385  case dwarf::DW_FORM_data4:386  case dwarf::DW_FORM_ref_sup4:387  case dwarf::DW_FORM_strx4:388  case dwarf::DW_FORM_addrx4:389  case dwarf::DW_FORM_ref8:390  case dwarf::DW_FORM_ref_sig8:391  case dwarf::DW_FORM_data8:392  case dwarf::DW_FORM_ref_sup8:393  case dwarf::DW_FORM_GNU_ref_alt:394  case dwarf::DW_FORM_GNU_strp_alt:395  case dwarf::DW_FORM_line_strp:396  case dwarf::DW_FORM_sec_offset:397  case dwarf::DW_FORM_strp_sup:398  case dwarf::DW_FORM_addr:399  case dwarf::DW_FORM_ref_addr:400    Asm->OutStreamer->emitIntValue(Integer,401                                   sizeOf(Asm->getDwarfFormParams(), Form));402    return;403  case dwarf::DW_FORM_GNU_str_index:404  case dwarf::DW_FORM_GNU_addr_index:405  case dwarf::DW_FORM_ref_udata:406  case dwarf::DW_FORM_strx:407  case dwarf::DW_FORM_addrx:408  case dwarf::DW_FORM_rnglistx:409  case dwarf::DW_FORM_udata:410    Asm->emitULEB128(Integer);411    return;412  case dwarf::DW_FORM_sdata:413    Asm->emitSLEB128(Integer);414    return;415  default: llvm_unreachable("DIE Value form not supported yet");416  }417}418 419/// sizeOf - Determine size of integer value in bytes.420///421unsigned DIEInteger::sizeOf(const dwarf::FormParams &FormParams,422                            dwarf::Form Form) const {423  if (std::optional<uint8_t> FixedSize =424          dwarf::getFixedFormByteSize(Form, FormParams))425    return *FixedSize;426 427  switch (Form) {428  case dwarf::DW_FORM_GNU_str_index:429  case dwarf::DW_FORM_GNU_addr_index:430  case dwarf::DW_FORM_ref_udata:431  case dwarf::DW_FORM_strx:432  case dwarf::DW_FORM_addrx:433  case dwarf::DW_FORM_rnglistx:434  case dwarf::DW_FORM_udata:435    return getULEB128Size(Integer);436  case dwarf::DW_FORM_sdata:437    return getSLEB128Size(Integer);438  default: llvm_unreachable("DIE Value form not supported yet");439  }440}441 442LLVM_DUMP_METHOD443void DIEInteger::print(raw_ostream &O) const {444  O << "Int: " << (int64_t)Integer << "  0x";445  O.write_hex(Integer);446}447 448//===----------------------------------------------------------------------===//449// DIEExpr Implementation450//===----------------------------------------------------------------------===//451 452/// EmitValue - Emit expression value.453///454void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {455  AP->emitDebugValue(Expr, sizeOf(AP->getDwarfFormParams(), Form));456}457 458/// SizeOf - Determine size of expression value in bytes.459///460unsigned DIEExpr::sizeOf(const dwarf::FormParams &FormParams,461                         dwarf::Form Form) const {462  switch (Form) {463  case dwarf::DW_FORM_data4:464    return 4;465  case dwarf::DW_FORM_data8:466    return 8;467  case dwarf::DW_FORM_sec_offset:468    return FormParams.getDwarfOffsetByteSize();469  default:470    llvm_unreachable("DIE Value form not supported yet");471  }472}473 474LLVM_DUMP_METHOD475void DIEExpr::print(raw_ostream &O) const {476  O << "Expr: ";477  MCAsmInfo().printExpr(O, *Expr);478}479 480//===----------------------------------------------------------------------===//481// DIELabel Implementation482//===----------------------------------------------------------------------===//483 484/// EmitValue - Emit label value.485///486void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {487  bool IsSectionRelative = Form != dwarf::DW_FORM_addr;488  AP->emitLabelReference(Label, sizeOf(AP->getDwarfFormParams(), Form),489                         IsSectionRelative);490}491 492/// sizeOf - Determine size of label value in bytes.493///494unsigned DIELabel::sizeOf(const dwarf::FormParams &FormParams,495                          dwarf::Form Form) const {496  switch (Form) {497  case dwarf::DW_FORM_data4:498    return 4;499  case dwarf::DW_FORM_data8:500    return 8;501  case dwarf::DW_FORM_sec_offset:502  case dwarf::DW_FORM_strp:503    return FormParams.getDwarfOffsetByteSize();504  case dwarf::DW_FORM_addr:505    return FormParams.AddrSize;506  default:507    llvm_unreachable("DIE Value form not supported yet");508  }509}510 511LLVM_DUMP_METHOD512void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }513 514//===----------------------------------------------------------------------===//515// DIEBaseTypeRef Implementation516//===----------------------------------------------------------------------===//517 518void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {519  uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();520  assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");521  AP->emitULEB128(Offset, nullptr, ULEB128PadSize);522}523 524unsigned DIEBaseTypeRef::sizeOf(const dwarf::FormParams &, dwarf::Form) const {525  return ULEB128PadSize;526}527 528LLVM_DUMP_METHOD529void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }530 531//===----------------------------------------------------------------------===//532// DIEDelta Implementation533//===----------------------------------------------------------------------===//534 535/// EmitValue - Emit delta value.536///537void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {538  AP->emitLabelDifference(LabelHi, LabelLo,539                          sizeOf(AP->getDwarfFormParams(), Form));540}541 542/// SizeOf - Determine size of delta value in bytes.543///544unsigned DIEDelta::sizeOf(const dwarf::FormParams &FormParams,545                          dwarf::Form Form) const {546  switch (Form) {547  case dwarf::DW_FORM_data4:548    return 4;549  case dwarf::DW_FORM_data8:550    return 8;551  case dwarf::DW_FORM_sec_offset:552    return FormParams.getDwarfOffsetByteSize();553  default:554    llvm_unreachable("DIE Value form not supported yet");555  }556}557 558LLVM_DUMP_METHOD559void DIEDelta::print(raw_ostream &O) const {560  O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();561}562 563//===----------------------------------------------------------------------===//564// DIEString Implementation565//===----------------------------------------------------------------------===//566 567/// EmitValue - Emit string value.568///569void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {570  // Index of string in symbol table.571  switch (Form) {572  case dwarf::DW_FORM_GNU_str_index:573  case dwarf::DW_FORM_strx:574  case dwarf::DW_FORM_strx1:575  case dwarf::DW_FORM_strx2:576  case dwarf::DW_FORM_strx3:577  case dwarf::DW_FORM_strx4:578    DIEInteger(S.getIndex()).emitValue(AP, Form);579    return;580  case dwarf::DW_FORM_strp:581    if (AP->doesDwarfUseRelocationsAcrossSections())582      DIELabel(S.getSymbol()).emitValue(AP, Form);583    else584      DIEInteger(S.getOffset()).emitValue(AP, Form);585    return;586  default:587    llvm_unreachable("Expected valid string form");588  }589}590 591/// sizeOf - Determine size of delta value in bytes.592///593unsigned DIEString::sizeOf(const dwarf::FormParams &FormParams,594                           dwarf::Form Form) const {595  // Index of string in symbol table.596  switch (Form) {597  case dwarf::DW_FORM_GNU_str_index:598  case dwarf::DW_FORM_strx:599  case dwarf::DW_FORM_strx1:600  case dwarf::DW_FORM_strx2:601  case dwarf::DW_FORM_strx3:602  case dwarf::DW_FORM_strx4:603    return DIEInteger(S.getIndex()).sizeOf(FormParams, Form);604  case dwarf::DW_FORM_strp:605    if (FormParams.DwarfUsesRelocationsAcrossSections)606      return DIELabel(S.getSymbol()).sizeOf(FormParams, Form);607    return DIEInteger(S.getOffset()).sizeOf(FormParams, Form);608  default:609    llvm_unreachable("Expected valid string form");610  }611}612 613LLVM_DUMP_METHOD614void DIEString::print(raw_ostream &O) const {615  O << "String: " << S.getString();616}617 618//===----------------------------------------------------------------------===//619// DIEInlineString Implementation620//===----------------------------------------------------------------------===//621void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {622  if (Form == dwarf::DW_FORM_string) {623    AP->OutStreamer->emitBytes(S);624    AP->emitInt8(0);625    return;626  }627  llvm_unreachable("Expected valid string form");628}629 630unsigned DIEInlineString::sizeOf(const dwarf::FormParams &, dwarf::Form) const {631  // Emit string bytes + NULL byte.632  return S.size() + 1;633}634 635LLVM_DUMP_METHOD636void DIEInlineString::print(raw_ostream &O) const {637  O << "InlineString: " << S;638}639 640//===----------------------------------------------------------------------===//641// DIEEntry Implementation642//===----------------------------------------------------------------------===//643 644/// EmitValue - Emit debug information entry offset.645///646void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {647 648  switch (Form) {649  case dwarf::DW_FORM_ref1:650  case dwarf::DW_FORM_ref2:651  case dwarf::DW_FORM_ref4:652  case dwarf::DW_FORM_ref8:653    AP->OutStreamer->emitIntValue(Entry->getOffset(),654                                  sizeOf(AP->getDwarfFormParams(), Form));655    return;656 657  case dwarf::DW_FORM_ref_udata:658    AP->emitULEB128(Entry->getOffset());659    return;660 661  case dwarf::DW_FORM_ref_addr: {662    // Get the absolute offset for this DIE within the debug info/types section.663    uint64_t Addr = Entry->getDebugSectionOffset();664    if (const MCSymbol *SectionSym =665            Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {666      AP->emitLabelPlusOffset(SectionSym, Addr,667                              sizeOf(AP->getDwarfFormParams(), Form), true);668      return;669    }670 671    AP->OutStreamer->emitIntValue(Addr, sizeOf(AP->getDwarfFormParams(), Form));672    return;673  }674  default:675    llvm_unreachable("Improper form for DIE reference");676  }677}678 679unsigned DIEEntry::sizeOf(const dwarf::FormParams &FormParams,680                          dwarf::Form Form) const {681  switch (Form) {682  case dwarf::DW_FORM_ref1:683    return 1;684  case dwarf::DW_FORM_ref2:685    return 2;686  case dwarf::DW_FORM_ref4:687    return 4;688  case dwarf::DW_FORM_ref8:689    return 8;690  case dwarf::DW_FORM_ref_udata:691    return getULEB128Size(Entry->getOffset());692  case dwarf::DW_FORM_ref_addr:693    return FormParams.getRefAddrByteSize();694 695  default:696    llvm_unreachable("Improper form for DIE reference");697  }698}699 700LLVM_DUMP_METHOD701void DIEEntry::print(raw_ostream &O) const {702  O << format("Die: 0x%lx", (long)(intptr_t)&Entry);703}704 705//===----------------------------------------------------------------------===//706// DIELoc Implementation707//===----------------------------------------------------------------------===//708 709unsigned DIELoc::computeSize(const dwarf::FormParams &FormParams) const {710  if (!Size) {711    for (const auto &V : values())712      Size += V.sizeOf(FormParams);713  }714 715  return Size;716}717 718/// EmitValue - Emit location data.719///720void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {721  switch (Form) {722  default: llvm_unreachable("Improper form for block");723  case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;724  case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;725  case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;726  case dwarf::DW_FORM_block:727  case dwarf::DW_FORM_exprloc:728    Asm->emitULEB128(Size);729    break;730  }731 732  for (const auto &V : values())733    V.emitValue(Asm);734}735 736/// sizeOf - Determine size of location data in bytes.737///738unsigned DIELoc::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {739  switch (Form) {740  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);741  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);742  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);743  case dwarf::DW_FORM_block:744  case dwarf::DW_FORM_exprloc:745    return Size + getULEB128Size(Size);746  default: llvm_unreachable("Improper form for block");747  }748}749 750LLVM_DUMP_METHOD751void DIELoc::print(raw_ostream &O) const {752  printValues(O, *this, "ExprLoc", Size, 5);753}754 755//===----------------------------------------------------------------------===//756// DIEBlock Implementation757//===----------------------------------------------------------------------===//758 759unsigned DIEBlock::computeSize(const dwarf::FormParams &FormParams) const {760  if (!Size) {761    for (const auto &V : values())762      Size += V.sizeOf(FormParams);763  }764 765  return Size;766}767 768/// EmitValue - Emit block data.769///770void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {771  switch (Form) {772  default: llvm_unreachable("Improper form for block");773  case dwarf::DW_FORM_block1: Asm->emitInt8(Size);    break;774  case dwarf::DW_FORM_block2: Asm->emitInt16(Size);   break;775  case dwarf::DW_FORM_block4: Asm->emitInt32(Size);   break;776  case dwarf::DW_FORM_exprloc:777  case dwarf::DW_FORM_block:778    Asm->emitULEB128(Size);779    break;780  case dwarf::DW_FORM_string: break;781  case dwarf::DW_FORM_data16: break;782  }783 784  for (const auto &V : values())785    V.emitValue(Asm);786}787 788/// sizeOf - Determine size of block data in bytes.789///790unsigned DIEBlock::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {791  switch (Form) {792  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);793  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);794  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);795  case dwarf::DW_FORM_exprloc:796  case dwarf::DW_FORM_block:  return Size + getULEB128Size(Size);797  case dwarf::DW_FORM_data16: return 16;798  default: llvm_unreachable("Improper form for block");799  }800}801 802LLVM_DUMP_METHOD803void DIEBlock::print(raw_ostream &O) const {804  printValues(O, *this, "Blk", Size, 5);805}806 807//===----------------------------------------------------------------------===//808// DIELocList Implementation809//===----------------------------------------------------------------------===//810 811unsigned DIELocList::sizeOf(const dwarf::FormParams &FormParams,812                            dwarf::Form Form) const {813  switch (Form) {814  case dwarf::DW_FORM_loclistx:815    return getULEB128Size(Index);816  case dwarf::DW_FORM_data4:817    assert(FormParams.Format != dwarf::DWARF64 &&818           "DW_FORM_data4 is not suitable to emit a pointer to a location list "819           "in the 64-bit DWARF format");820    return 4;821  case dwarf::DW_FORM_data8:822    assert(FormParams.Format == dwarf::DWARF64 &&823           "DW_FORM_data8 is not suitable to emit a pointer to a location list "824           "in the 32-bit DWARF format");825    return 8;826  case dwarf::DW_FORM_sec_offset:827    return FormParams.getDwarfOffsetByteSize();828  default:829    llvm_unreachable("DIE Value form not supported yet");830  }831}832 833/// EmitValue - Emit label value.834///835void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {836  if (Form == dwarf::DW_FORM_loclistx) {837    AP->emitULEB128(Index);838    return;839  }840  DwarfDebug *DD = AP->getDwarfDebug();841  MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;842  AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());843}844 845LLVM_DUMP_METHOD846void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }847 848//===----------------------------------------------------------------------===//849// DIEAddrOffset Implementation850//===----------------------------------------------------------------------===//851 852unsigned DIEAddrOffset::sizeOf(const dwarf::FormParams &FormParams,853                               dwarf::Form) const {854  return Addr.sizeOf(FormParams, dwarf::DW_FORM_addrx) +855         Offset.sizeOf(FormParams, dwarf::DW_FORM_data4);856}857 858/// EmitValue - Emit label value.859///860void DIEAddrOffset::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {861  Addr.emitValue(AP, dwarf::DW_FORM_addrx);862  Offset.emitValue(AP, dwarf::DW_FORM_data4);863}864 865LLVM_DUMP_METHOD866void DIEAddrOffset::print(raw_ostream &O) const {867  O << "AddrOffset: ";868  Addr.print(O);869  O << " + ";870  Offset.print(O);871}872