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#include "DwarfDebug.h" 12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DwarfUnit.h" 13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/STLExtras.h" 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DataLayout.h" 15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCStreamer.h" 16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/LEB128.h" 17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Target/TargetLoweringObjectFile.h" 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace llvm { 204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarDwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA) 214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : Asm(AP), StrPool(DA, *Asm, Pref) {} 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDwarfFile::~DwarfFile() { 246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (DIEAbbrev *Abbrev : Abbreviations) 256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Abbrev->~DIEAbbrev(); 266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Define a unique number for the abbreviation. 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// 306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { 316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FoldingSetNodeID ID; 326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DIEAbbrev Abbrev = Die.generateAbbrev(); 336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Abbrev.Profile(ID); 346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void *InsertPos; 366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (DIEAbbrev *Existing = 376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) { 386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Die.setAbbrevNumber(Existing->getNumber()); 396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return *Existing; 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Move the abbreviation to the heap and assign a number. 436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev)); 446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Abbreviations.push_back(New); 456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar New->setNumber(Abbreviations.size()); 466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Die.setAbbrevNumber(Abbreviations.size()); 476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Store it for lookup. 496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AbbreviationsSet.InsertNode(New, InsertPos); 506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return *New; 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::addUnit(std::unique_ptr<DwarfUnit> U) { 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CUs.push_back(std::move(U)); 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Emit the various dwarf units to the unit section USection with 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// the abbreviations going into ASection. 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfFile::emitUnits(bool UseOffsets) { 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &TheU : CUs) { 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DIE &Die = TheU->getUnitDie(); 626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection *USection = TheU->getSection(); 636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->SwitchSection(USection); 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TheU->emitHeader(UseOffsets); 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->emitDwarfDIE(Die); 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Compute the size and offset for each DIE. 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfFile::computeSizeAndOffsets() { 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Offset from the first CU in the debug info section is 0 initially. 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SecOffset = 0; 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Iterate over each compile unit and set the size and offsets for each 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // DIE within each compile unit. All offsets are CU relative. 78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &TheU : CUs) { 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheU->setDebugInfoOffset(SecOffset); 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // CU-relative offset is reset to 0 here. 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Offset = sizeof(int32_t) + // Length of Unit Info 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheU->getHeaderSize(); // Unit-specific headers 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // EndOffset here is CU-relative, after laying out 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // all of the CU DIE. 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset); 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SecOffset += EndOffset; 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Compute the size and offset of a DIE. The offset is relative to start of the 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// CU. It returns the offset after laying out the DIE. 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Record the abbreviation. 956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const DIEAbbrev &Abbrev = assignAbbrevNumber(Die); 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Set DIE offset 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Die.setOffset(Offset); 99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Start the size with the size of abbreviation code. 101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset += getULEB128Size(Die.getAbbrevNumber()); 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size the DIE attribute values. 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const auto &V : Die.values()) 105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size attribute value. 106cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Offset += V.SizeOf(Asm); 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Size the DIE children if any. 1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Die.hasChildren()) { 1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar (void)Abbrev; 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(Abbrev.hasChildren() && "Children flag not set"); 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &Child : Die.children()) 114cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Offset = computeSizeAndOffset(Child, Offset); 115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // End of children marker. 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset += sizeof(int8_t); 118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Die.setSize(Offset - Die.getOffset()); 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Offset; 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid DwarfFile::emitAbbrevs(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. 1286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->SwitchSection(Section); 1294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->emitDwarfAbbrevs(Abbreviations); 130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Emit strings into a string section. 1346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) { 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StrPool.emit(*Asm, StrSection, OffsetSection); 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS]; 1406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const DILocalVariable *DV = Var->getVariable(); 14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Variables with positive arg numbers are parameters. 1420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (unsigned ArgNum = DV->getArg()) { 14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Keep all parameters in order at the start of the variable list to ensure 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // function types are correct (no out-of-order parameters) 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // This could be improved by only doing it for optimized builds (unoptimized 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // builds have the right order to begin with), searching from the back (this 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // would catch the unoptimized case quickly), or doing a binary search 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // rather than linear search. 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto I = Vars.begin(); 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (I != Vars.end()) { 1520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar unsigned CurNum = (*I)->getVariable()->getArg(); 15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // A local (non-parameter) variable has been found, insert immediately 15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // before it. 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CurNum == 0) 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // A later indexed parameter has been found, insert immediately before it. 15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CurNum > ArgNum) 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurNum == ArgNum) { 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (*I)->addMMIEntry(*Var); 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++I; 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Vars.insert(I, Var); 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Vars.push_back(Var); 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 174