// This file contains support for writing dwarf debug info into asm files.
//
//===----------------------------------------------------------------------===//
+
#define DEBUG_TYPE "dwarfdebug"
#include "DwarfDebug.h"
#include "llvm/Module.h"
} // end llvm namespace
DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
- : DwarfPrinter(OS, A, T, "dbg"), ModuleCU(0),
+ : DwarfPrinter(OS, A, T), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
DIEValues(), StringPool(),
SectionSourceLines(), didInitial(false), shouldEmit(false),
///
void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Label) {
- // FIXME: Merge into DIEObjectLabel?
- DIEValue *Value = new DIEDwarfLabel(Label);
- DIEValues.push_back(Value);
- Die->addValue(Attribute, Form, Value);
-}
-
-/// addObjectLabel - Add an non-Dwarf label attribute data and value.
-///
-void DwarfDebug::addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
- const MCSymbol *Sym) {
- DIEValue *Value = new DIEObjectLabel(Sym);
+ DIEValue *Value = new DIELabel(Label);
DIEValues.push_back(Value);
Die->addValue(Attribute, Form, Value);
}
///
void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Label,const MCSymbol *Section,
- bool isEH, bool useSet) {
- DIEValue *Value = new DIESectionOffset(Label, Section, isEH, useSet);
+ bool isEH) {
+ DIEValue *Value = new DIESectionOffset(Label, Section, isEH);
DIEValues.push_back(Value);
Die->addValue(Attribute, Form, Value);
}
/// constructLexicalScope - Construct new DW_TAG_lexical_block
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
- unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
- unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
+ unsigned StartID = Scope->getStartLabelID();
+ unsigned EndID = Scope->getEndLabelID();
+ assert(!MMI->isLabelDeleted(StartID) &&
+ "Invalid starting label for an inlined scope!");
+ assert(!MMI->isLabelDeleted(EndID) &&
+ "Invalid end label for an inlined scope!");
+
// Ignore empty scopes.
if (StartID == EndID && StartID != 0)
return NULL;
/// a function. Construct DIE to represent this concrete inlined copy
/// of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
- unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
- unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
- assert (StartID && "Invalid starting label for an inlined scope!");
- assert (EndID && "Invalid end label for an inlined scope!");
+ unsigned StartID = Scope->getStartLabelID();
+ unsigned EndID = Scope->getEndLabelID();
+ assert(!MMI->isLabelDeleted(StartID) &&
+ "Invalid starting label for an inlined scope!");
+ assert(!MMI->isLabelDeleted(EndID) &&
+ "Invalid end label for an inlined scope!");
// Ignore empty scopes.
- if (StartID == EndID && StartID != 0)
+ if (StartID == EndID)
return NULL;
if (!Scope->getScopeNode())
return NULL;
addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, OriginDIE);
- addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- getDWLabel("label", StartID));
+ MCSymbol *StartLabel = getDWLabel("label", StartID);
+
+ addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
getDWLabel("label", EndID));
I = InlineInfo.find(InlinedSP.getNode());
if (I == InlineInfo.end()) {
- InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartID,
+ InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel,
ScopeDIE));
InlinedSPNodes.push_back(InlinedSP.getNode());
} else
- I->second.push_back(std::make_pair(StartID, ScopeDIE));
+ I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
StringPool.insert(InlinedSP.getName());
StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName()));
dwarf::DW_FORM_ref4, VariableDie);
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
- addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
- Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
+ addLabel(Block, 0, dwarf::DW_FORM_udata,
+ Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
ModuleCU->addDie(VariableSpecDIE);
} else {
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
- addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
- Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
+ addLabel(Block, 0, dwarf::DW_FORM_udata,
+ Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
}
addToContextOwner(VariableDie, GVContext);
// Standard sections final addresses.
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
- EmitLabel("text_end", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("text_end"));
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
- EmitLabel("data_end", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("data_end"));
// End text sections.
for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Asm->OutStreamer.SwitchSection(SectionMap[i]);
- EmitLabel("section_end", i);
+ Asm->OutStreamer.EmitLabel(getDWLabel("section_end", i));
}
// Emit common frame information.
unsigned Label = MMI->NextLabelID();
Asm->printLabel(Label);
- O << '\n';
SmallVector<DbgScope *, 2> &SD = I->second;
for (SmallVector<DbgScope *, 2>::iterator SDI = SD.begin(), SDE = SD.end();
collectVariableInfo();
// Assumes in correct section after the entry point.
- EmitLabel("func_begin", ++SubprogramCount);
+ Asm->OutStreamer.EmitLabel(getDWLabel("func_begin", ++SubprogramCount));
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
DLT.getColumnNumber(),
DLT.getScope().getNode());
Asm->printLabel(LabelID);
- O << '\n';
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
if (CurrentFnDbgScope) {
// Define end label for subprogram.
- EmitLabel("func_end", SubprogramCount);
+ Asm->OutStreamer.EmitLabel(getDWLabel("func_end", SubprogramCount));
// Get function line info.
if (!Lines.empty()) {
// Dwarf sections base addresses.
if (MAI->doesDwarfRequireFrameSection()) {
Asm->OutStreamer.SwitchSection(TLOF.getDwarfFrameSection());
- EmitLabel("section_debug_frame", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_debug_frame"));
}
Asm->OutStreamer.SwitchSection(TLOF.getDwarfInfoSection());
- EmitLabel("section_info", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_info"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfAbbrevSection());
- EmitLabel("section_abbrev", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_abbrev"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfARangesSection());
- EmitLabel("section_aranges", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_aranges"));
if (const MCSection *LineInfoDirective = TLOF.getDwarfMacroInfoSection()) {
Asm->OutStreamer.SwitchSection(LineInfoDirective);
- EmitLabel("section_macinfo", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_macinfo"));
}
Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection());
- EmitLabel("section_line", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_line"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection());
- EmitLabel("section_loc", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_loc"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection());
- EmitLabel("section_pubnames", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_pubnames"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection());
- EmitLabel("section_pubtypes", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_pubtypes"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfStrSection());
- EmitLabel("section_str", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_str"));
Asm->OutStreamer.SwitchSection(TLOF.getDwarfRangesSection());
- EmitLabel("section_ranges", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("section_ranges"));
Asm->OutStreamer.SwitchSection(TLOF.getTextSection());
- EmitLabel("text_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("text_begin"));
Asm->OutStreamer.SwitchSection(TLOF.getDataSection());
- EmitLabel("data_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("data_begin"));
}
/// emitDIE - Recusively Emits a debug information entry.
DIE *Die = ModuleCU->getCUDie();
// Emit the compile units header.
- EmitLabel("info_begin", ModuleCU->getID());
+ Asm->OutStreamer.EmitLabel(getDWLabel("info_begin", ModuleCU->getID()));
// Emit size of content not including length itself
unsigned ContentSize = Die->getSize() +
Asm->EmitInt8(0); EOL("Extra Pad For GDB");
Asm->EmitInt8(0); EOL("Extra Pad For GDB");
Asm->EmitInt8(0); EOL("Extra Pad For GDB");
- EmitLabel("info_end", ModuleCU->getID());
+ Asm->OutStreamer.EmitLabel(getDWLabel("info_end", ModuleCU->getID()));
Asm->O << '\n';
}
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAbbrevSection());
- EmitLabel("abbrev_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_begin"));
// For each abbrevation.
for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
// Mark end of abbreviations.
EmitULEB128(0, "EOM(3)");
- EmitLabel("abbrev_end", 0);
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_end"));
}
}
Asm->EmitInt8(0); EOL("Extended Op");
Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size");
Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address");
- EmitReference("section_end", SectionEnd); EOL("Section end label");
+ EmitReference(getDWLabel("section_end", SectionEnd));
+ EOL("Section end label");
// Mark end of matrix.
Asm->EmitInt8(0); EOL("DW_LNE_end_sequence");
Asm->getObjFileLowering().getDwarfLineSection());
// Construct the section header.
- EmitDifference("line_end", 0, "line_begin", 0, true);
+ EmitDifference(getTempLabel("line_end"), getTempLabel("line_begin"), true);
EOL("Length of Source Line Info");
- EmitLabel("line_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("line_begin"));
Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number");
- EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true);
+ EmitDifference(getTempLabel("line_prolog_end"),
+ getTempLabel("line_prolog_begin"), true);
EOL("Prolog Length");
- EmitLabel("line_prolog_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_begin"));
Asm->EmitInt8(1); EOL("Minimum Instruction Length");
Asm->EmitInt8(1); EOL("Default is_stmt_start flag");
Asm->EmitInt8(0); EOL("End of files");
- EmitLabel("line_prolog_end", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_end"));
// A sequence for each text section.
unsigned SecSrcLinesSize = SectionSourceLines.size();
// Construct rows of the address, source, line, column matrix.
for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
const SrcLineInfo &LineInfo = LineInfos[i];
- unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID());
- if (!LabelID) continue;
+ unsigned LabelID = LineInfo.getLabelID();
+ if (MMI->isLabelDeleted(LabelID)) continue;
if (LineInfo.getLine() == 0) continue;
Asm->EmitInt8(0); EOL("Extended Op");
Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size");
Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address");
- EmitReference("label", LabelID); EOL("Location label");
+ EmitReference(getDWLabel("label", LabelID)); EOL("Location label");
// If change of source, then switch to the new source.
if (Source != LineInfo.getSourceID()) {
// put into it, emit an empty table.
emitEndOfLineMatrix(1);
- EmitLabel("line_end", 0);
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getTempLabel("line_end"));
}
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfFrameSection());
- EmitLabel("debug_frame_common", 0);
- EmitDifference("debug_frame_common_end", 0,
- "debug_frame_common_begin", 0, true);
+ Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common"));
+ EmitDifference(getTempLabel("debug_frame_common_end"),
+ getTempLabel("debug_frame_common_begin"), true);
EOL("Length of Common Information Entry");
- EmitLabel("debug_frame_common_begin", 0);
+ Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_begin"));
Asm->EmitInt32((int)dwarf::DW_CIE_ID);
EOL("CIE Identifier Tag");
Asm->EmitInt8(dwarf::DW_CIE_VERSION);
EmitFrameMoves(NULL, 0, Moves, false);
Asm->EmitAlignment(2, 0, 0, false);
- EmitLabel("debug_frame_common_end", 0);
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_end"));
}
/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfFrameSection());
- EmitDifference("debug_frame_end", DebugFrameInfo.Number,
- "debug_frame_begin", DebugFrameInfo.Number, true);
+ EmitDifference(getDWLabel("debug_frame_end", DebugFrameInfo.Number),
+ getDWLabel("debug_frame_begin", DebugFrameInfo.Number), true);
EOL("Length of Frame Information Entry");
- EmitLabel("debug_frame_begin", DebugFrameInfo.Number);
+ Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_begin",
+ DebugFrameInfo.Number));
EmitSectionOffset(getTempLabel("debug_frame_common"),
getTempLabel("section_debug_frame"), true, false);
EOL("FDE CIE offset");
- EmitReference("func_begin", DebugFrameInfo.Number);
+ EmitReference(getDWLabel("func_begin", DebugFrameInfo.Number));
EOL("FDE initial location");
- EmitDifference("func_end", DebugFrameInfo.Number,
- "func_begin", DebugFrameInfo.Number);
+ EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number),
+ getDWLabel("func_begin", DebugFrameInfo.Number));
EOL("FDE address range");
EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves,
false);
Asm->EmitAlignment(2, 0, 0, false);
- EmitLabel("debug_frame_end", DebugFrameInfo.Number);
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_end",
+ DebugFrameInfo.Number));
}
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubNamesSection());
- EmitDifference("pubnames_end", ModuleCU->getID(),
- "pubnames_begin", ModuleCU->getID(), true);
+ EmitDifference(getDWLabel("pubnames_end", ModuleCU->getID()),
+ getDWLabel("pubnames_begin", ModuleCU->getID()), true);
EOL("Length of Public Names Info");
- EmitLabel("pubnames_begin", ModuleCU->getID());
+ Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_begin", ModuleCU->getID()));
Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version");
true, false);
EOL("Offset of Compilation Unit Info");
- EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
+ EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
+ getDWLabel("info_begin", ModuleCU->getID()),
true);
EOL("Compilation Unit Length");
}
Asm->EmitInt32(0); EOL("End Mark");
- EmitLabel("pubnames_end", ModuleCU->getID());
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_end", ModuleCU->getID()));
}
void DwarfDebug::emitDebugPubTypes() {
// Start the dwarf pubnames section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubTypesSection());
- EmitDifference("pubtypes_end", ModuleCU->getID(),
- "pubtypes_begin", ModuleCU->getID(), true);
+ EmitDifference(getDWLabel("pubtypes_end", ModuleCU->getID()),
+ getDWLabel("pubtypes_begin", ModuleCU->getID()), true);
EOL("Length of Public Types Info");
- EmitLabel("pubtypes_begin", ModuleCU->getID());
+ Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_begin", ModuleCU->getID()));
if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
getTempLabel("section_info"), true, false);
EOL("Offset of Compilation ModuleCU Info");
- EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
+ EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
+ getDWLabel("info_begin", ModuleCU->getID()),
true);
EOL("Compilation ModuleCU Length");
}
Asm->EmitInt32(0); EOL("End Mark");
- EmitLabel("pubtypes_end", ModuleCU->getID());
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_end", ModuleCU->getID()));
}
/// emitDebugStr - Emit visible names into a debug str section.
for (unsigned StringID = 1, N = StringPool.size();
StringID <= N; ++StringID) {
// Emit a label for reference from debug information entries.
- EmitLabel("string", StringID);
+ Asm->OutStreamer.EmitLabel(getDWLabel("string", StringID));
// Emit the string itself.
const std::string &String = StringPool[StringID];
// Range 1
EmitReference("text_begin", 0); EOL("Address");
- EmitDifference("text_end", 0, "text_begin", 0, true); EOL("Length");
+ EmitDifference(getTempLabel("text_end"), getTempLabel("text_begin"),
+ true); EOL("Length");
Asm->EmitInt32(0); EOL("EOM (1)");
Asm->EmitInt32(0); EOL("EOM (2)");
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfDebugInlineSection());
- EmitDifference("debug_inlined_end", 1,
- "debug_inlined_begin", 1, true);
+ EmitDifference(getDWLabel("debug_inlined_end", 1),
+ getDWLabel("debug_inlined_begin", 1), true);
EOL("Length of Debug Inlined Information Entry");
- EmitLabel("debug_inlined_begin", 1);
+ Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_begin", 1));
Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version");
Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
LE = Labels.end(); LI != LE; ++LI) {
- DIE *SP = LI->second;
- Asm->EmitInt32(SP->getOffset()); EOL("DIE offset");
-
- if (TD->getPointerSize() == sizeof(int32_t))
- O << MAI->getData32bitsDirective();
- else
- O << MAI->getData64bitsDirective();
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ Asm->EmitInt32(LI->second->getOffset());
- PrintLabelName("label", LI->first); EOL("low_pc");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("low_pc");
+ Asm->OutStreamer.EmitSymbolValue(LI->first, TD->getPointerSize(), 0);
}
}
- EmitLabel("debug_inlined_end", 1);
- Asm->O << '\n';
+ Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_end", 1));
}