DwarfFile.cpp revision 37ed9c199ca639565f6ce88105f9e39e898d82d0
1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===// 2dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// 3dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// The LLVM Compiler Infrastructure 4dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// 5dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file is distributed under the University of Illinois Open Source 6dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// License. See LICENSE.TXT for details. 7dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// 8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===----------------------------------------------------------------------===// 9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DwarfFile.h" 11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DwarfDebug.h" 13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DwarfUnit.h" 14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCStreamer.h" 15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/LEB128.h" 16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/IR/DataLayout.h" 17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/STLExtras.h" 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Target/TargetLoweringObjectFile.h" 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace llvm { 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDwarfFile::DwarfFile(AsmPrinter *AP, DwarfDebug &DD, StringRef Pref, 2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BumpPtrAllocator &DA) 2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : Asm(AP), DD(DD), StrPool(DA, *Asm, Pref) {} 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDwarfFile::~DwarfFile() {} 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Define a unique number for the abbreviation. 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) { 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check the set for priors. 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev); 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If it's newly added. 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (InSet == &Abbrev) { 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Add to abbreviation list. 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbreviations.push_back(&Abbrev); 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Assign the vector position + 1 as its number. 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbrev.setNumber(Abbreviations.size()); 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Assign existing abbreviation number. 42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbrev.setNumber(InSet->getNumber()); 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::addUnit(std::unique_ptr<DwarfUnit> U) { 47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CUs.push_back(std::move(U)); 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Emit the various dwarf units to the unit section USection with 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// the abbreviations going into ASection. 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DwarfFile::emitUnits(const MCSymbol *ASectionSym) { 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &TheU : CUs) { 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DIE &Die = TheU->getUnitDie(); 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSection *USection = TheU->getSection(); 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Asm->OutStreamer.SwitchSection(USection); 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheU->emitHeader(ASectionSym); 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DD.emitDIE(Die); 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Compute the size and offset for each DIE. 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::computeSizeAndOffsets() { 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Offset from the first CU in the debug info section is 0 initially. 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SecOffset = 0; 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Iterate over each compile unit and set the size and offsets for each 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // DIE within each compile unit. All offsets are CU relative. 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &TheU : CUs) { 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheU->setDebugInfoOffset(SecOffset); 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // CU-relative offset is reset to 0 here. 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Offset = sizeof(int32_t) + // Length of Unit Info 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheU->getHeaderSize(); // Unit-specific headers 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // EndOffset here is CU-relative, after laying out 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // all of the CU DIE. 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset); 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SecOffset += EndOffset; 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Compute the size and offset of a DIE. The offset is relative to start of the 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// CU. It returns the offset after laying out the DIE. 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Record the abbreviation. 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assignAbbrevNumber(Die.getAbbrev()); 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Get the abbreviation for this DIE. 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const DIEAbbrev &Abbrev = Die.getAbbrev(); 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Set DIE offset 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Die.setOffset(Offset); 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Start the size with the size of abbreviation code. 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset += getULEB128Size(Die.getAbbrevNumber()); 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); 100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData(); 101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size the DIE attribute values. 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0, N = Values.size(); i < N; ++i) 104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size attribute value. 105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm()); 106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Get the children. 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto &Children = Die.getChildren(); 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size the DIE children if any. 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Children.empty()) { 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(Abbrev.hasChildren() && "Children flag not set"); 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &Child : Children) 115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset = computeSizeAndOffset(*Child, Offset); 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // End of children marker. 118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset += sizeof(int8_t); 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Die.setSize(Offset - Die.getOffset()); 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Offset; 123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::emitAbbrevs(const MCSection *Section) { 125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check to see if it is worth the effort. 126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Abbreviations.empty()) { 127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Start the debug abbrev section. 128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Asm->OutStreamer.SwitchSection(Section); 129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // For each abbrevation. 131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const DIEAbbrev *Abbrev : Abbreviations) { 132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Emit the abbrevations code (base 1 index.) 133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code"); 134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Emit the abbreviations data. 136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbrev->Emit(Asm); 137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Mark end of abbreviations. 140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Asm->EmitULEB128(0, "EOM(3)"); 141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Emit strings into a string section. 145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::emitStrings(const MCSection *StrSection, 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const MCSection *OffsetSection) { 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StrPool.emit(*Asm, StrSection, OffsetSection); 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS]; 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DIVariable DV = Var->getVariable(); 15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Variables with positive arg numbers are parameters. 15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (unsigned ArgNum = DV.getArgNumber()) { 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Keep all parameters in order at the start of the variable list to ensure 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // function types are correct (no out-of-order parameters) 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // 15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // This could be improved by only doing it for optimized builds (unoptimized 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // builds have the right order to begin with), searching from the back (this 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // would catch the unoptimized case quickly), or doing a binary search 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // rather than linear search. 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto I = Vars.begin(); 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (I != Vars.end()) { 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned CurNum = (*I)->getVariable().getArgNumber(); 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // A local (non-parameter) variable has been found, insert immediately 16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // before it. 16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CurNum == 0) 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // A later indexed parameter has been found, insert immediately before it. 17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CurNum > ArgNum) 17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // FIXME: There are still some cases where two inlined functions are 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // conflated together (two calls to the same function at the same 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // location (eg: via a macro, or without column info, etc)) and then 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // their arguments are conflated as well. 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((LS->getParent() || CurNum != ArgNum) && 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Duplicate argument for top level (non-inlined) function"); 17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++I; 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Vars.insert(I, Var); 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Vars.push_back(Var); 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 187