Home | History | Annotate | Download | only in AsmPrinter
      1 //===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===//
      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 #include "DwarfFile.h"
     11 #include "DwarfCompileUnit.h"
     12 #include "DwarfDebug.h"
     13 #include "DwarfUnit.h"
     14 #include "llvm/ADT/STLExtras.h"
     15 #include "llvm/IR/DataLayout.h"
     16 #include "llvm/MC/MCStreamer.h"
     17 #include "llvm/Support/LEB128.h"
     18 #include "llvm/Target/TargetLoweringObjectFile.h"
     19 
     20 namespace llvm {
     21 DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
     22     : Asm(AP), StrPool(DA, *Asm, Pref) {}
     23 
     24 DwarfFile::~DwarfFile() {
     25   for (DIEAbbrev *Abbrev : Abbreviations)
     26     Abbrev->~DIEAbbrev();
     27 }
     28 
     29 // Define a unique number for the abbreviation.
     30 //
     31 DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) {
     32   FoldingSetNodeID ID;
     33   DIEAbbrev Abbrev = Die.generateAbbrev();
     34   Abbrev.Profile(ID);
     35 
     36   void *InsertPos;
     37   if (DIEAbbrev *Existing =
     38           AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
     39     Die.setAbbrevNumber(Existing->getNumber());
     40     return *Existing;
     41   }
     42 
     43   // Move the abbreviation to the heap and assign a number.
     44   DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev));
     45   Abbreviations.push_back(New);
     46   New->setNumber(Abbreviations.size());
     47   Die.setAbbrevNumber(Abbreviations.size());
     48 
     49   // Store it for lookup.
     50   AbbreviationsSet.InsertNode(New, InsertPos);
     51   return *New;
     52 }
     53 
     54 void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) {
     55   CUs.push_back(std::move(U));
     56 }
     57 
     58 // Emit the various dwarf units to the unit section USection with
     59 // the abbreviations going into ASection.
     60 void DwarfFile::emitUnits(bool UseOffsets) {
     61   for (const auto &TheU : CUs)
     62     emitUnit(TheU.get(), UseOffsets);
     63 }
     64 
     65 void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
     66   DIE &Die = TheU->getUnitDie();
     67   MCSection *USection = TheU->getSection();
     68   Asm->OutStreamer->SwitchSection(USection);
     69 
     70   TheU->emitHeader(UseOffsets);
     71 
     72   Asm->emitDwarfDIE(Die);
     73 }
     74 
     75 // Compute the size and offset for each DIE.
     76 void DwarfFile::computeSizeAndOffsets() {
     77   // Offset from the first CU in the debug info section is 0 initially.
     78   unsigned SecOffset = 0;
     79 
     80   // Iterate over each compile unit and set the size and offsets for each
     81   // DIE within each compile unit. All offsets are CU relative.
     82   for (const auto &TheU : CUs) {
     83     TheU->setDebugInfoOffset(SecOffset);
     84     SecOffset += computeSizeAndOffsetsForUnit(TheU.get());
     85   }
     86 }
     87 
     88 unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
     89   // CU-relative offset is reset to 0 here.
     90   unsigned Offset = sizeof(int32_t) +      // Length of Unit Info
     91                     TheU->getHeaderSize(); // Unit-specific headers
     92 
     93   // The return value here is CU-relative, after laying out
     94   // all of the CU DIE.
     95   return computeSizeAndOffset(TheU->getUnitDie(), Offset);
     96 }
     97 
     98 // Compute the size and offset of a DIE. The offset is relative to start of the
     99 // CU. It returns the offset after laying out the DIE.
    100 unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
    101   // Record the abbreviation.
    102   const DIEAbbrev &Abbrev = assignAbbrevNumber(Die);
    103 
    104   // Set DIE offset
    105   Die.setOffset(Offset);
    106 
    107   // Start the size with the size of abbreviation code.
    108   Offset += getULEB128Size(Die.getAbbrevNumber());
    109 
    110   // Size the DIE attribute values.
    111   for (const auto &V : Die.values())
    112     // Size attribute value.
    113     Offset += V.SizeOf(Asm);
    114 
    115   // Size the DIE children if any.
    116   if (Die.hasChildren()) {
    117     (void)Abbrev;
    118     assert(Abbrev.hasChildren() && "Children flag not set");
    119 
    120     for (auto &Child : Die.children())
    121       Offset = computeSizeAndOffset(Child, Offset);
    122 
    123     // End of children marker.
    124     Offset += sizeof(int8_t);
    125   }
    126 
    127   Die.setSize(Offset - Die.getOffset());
    128   return Offset;
    129 }
    130 
    131 void DwarfFile::emitAbbrevs(MCSection *Section) {
    132   // Check to see if it is worth the effort.
    133   if (!Abbreviations.empty()) {
    134     // Start the debug abbrev section.
    135     Asm->OutStreamer->SwitchSection(Section);
    136     Asm->emitDwarfAbbrevs(Abbreviations);
    137   }
    138 }
    139 
    140 // Emit strings into a string section.
    141 void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) {
    142   StrPool.emit(*Asm, StrSection, OffsetSection);
    143 }
    144 
    145 bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
    146   SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS];
    147   const DILocalVariable *DV = Var->getVariable();
    148   // Variables with positive arg numbers are parameters.
    149   if (unsigned ArgNum = DV->getArg()) {
    150     // Keep all parameters in order at the start of the variable list to ensure
    151     // function types are correct (no out-of-order parameters)
    152     //
    153     // This could be improved by only doing it for optimized builds (unoptimized
    154     // builds have the right order to begin with), searching from the back (this
    155     // would catch the unoptimized case quickly), or doing a binary search
    156     // rather than linear search.
    157     auto I = Vars.begin();
    158     while (I != Vars.end()) {
    159       unsigned CurNum = (*I)->getVariable()->getArg();
    160       // A local (non-parameter) variable has been found, insert immediately
    161       // before it.
    162       if (CurNum == 0)
    163         break;
    164       // A later indexed parameter has been found, insert immediately before it.
    165       if (CurNum > ArgNum)
    166         break;
    167       if (CurNum == ArgNum) {
    168         (*I)->addMMIEntry(*Var);
    169         return false;
    170       }
    171       ++I;
    172     }
    173     Vars.insert(I, Var);
    174     return true;
    175   }
    176 
    177   Vars.push_back(Var);
    178   return true;
    179 }
    180 }
    181