#define DEBUG_TYPE "dwarfdebug"
#include "DwarfDebug.h"
+#include "DIE.h"
+#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/System/Path.h"
using namespace llvm;
+namespace {
+ const char *DWARFGroupName = "DWARF Emission";
+ const char *DbgTimerName = "DWARF Debug Writer";
+} // end anonymous namespace
+
//===----------------------------------------------------------------------===//
/// Configuration values for initial hash set sizes (log2).
void dump() const;
#endif
};
+
+} // end llvm namespace
#ifndef NDEBUG
void DbgScope::dump() const {
delete Variables[j];
}
-} // end llvm namespace
-
-DwarfDebug::DwarfDebug(AsmPrinter *A)
- : DwarfPrinter(A), ModuleCU(0),
- AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
- DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
- CurrentFnDbgScope(0), DebugTimer(0) {
+DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
+ : Asm(A), MMI(Asm->MMI), ModuleCU(0),
+ AbbreviationsSet(InitAbbreviationsSetSize),
+ CurrentFnDbgScope(0) {
NextStringPoolNumber = 0;
- if (TimePassesIsEnabled)
- DebugTimer = new Timer("Dwarf Debug Writer");
+
+ DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
+ DwarfStrSectionSym = TextSectionSym = 0;
+
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T(DbgTimerName, DWARFGroupName);
+ beginModule(M);
+ } else {
+ beginModule(M);
+ }
}
DwarfDebug::~DwarfDebug() {
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
DIEBlocks[j]->~DIEBlock();
-
- delete DebugTimer;
}
MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
Die->addValue(Attribute, Form, Value);
}
+/// addDIEEntry - Add a DIE attribute data and value.
+///
+void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
+ DIE *Entry) {
+ Die->addValue(Attribute, Form, createDIEEntry(Entry));
+}
+
+
/// addBlock - Add block data.
///
void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
DIEBlock *Block) {
- Block->ComputeSize(TD);
+ Block->ComputeSize(Asm);
DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Die->addValue(Attribute, Block->BestForm(), Block);
}
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
/// provided.
void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Offset -= FieldOffset;
// Maybe we need to work from the other end.
- if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size);
+ if (Asm->getTargetData().isLittleEndian())
+ Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
// Here WD_AT_data_member_location points to the anonymous
if (!Parent && !InlinedAt) {
StringRef SPName = DISubprogram(N).getLinkageName();
- if (SPName == MF->getFunction()->getName())
+ if (SPName == Asm->MF->getFunction()->getName())
CurrentFnDbgScope = NScope;
}
return AScope;
}
+/// isSubprogramContext - Return true if Context is either a subprogram
+/// or another context nested inside a subprogram.
+bool isSubprogramContext(MDNode *Context) {
+ if (!Context)
+ return false;
+ DIDescriptor D(Context);
+ if (D.isSubprogram())
+ return true;
+ if (D.isType())
+ return isSubprogramContext(DIType(Context).getContext().getNode());
+ return false;
+}
+
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
/// If there are global variables in this scope then create and insert
/// DIEs for these variables.
DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
- DIE *SPDie = ModuleCU->getDIE(SPNode);
- assert(SPDie && "Unable to find subprogram DIE!");
- DISubprogram SP(SPNode);
+ DIE *SPDie = ModuleCU->getDIE(SPNode);
+ assert(SPDie && "Unable to find subprogram DIE!");
+ DISubprogram SP(SPNode);
- // There is not any need to generate specification DIE for a function
- // defined at compile unit level. If a function is defined inside another
- // function then gdb prefers the definition at top level and but does not
- // expect specification DIE in parent function. So avoid creating
- // specification DIE for a function defined inside a function.
- if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
- !SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
- addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
-
- // Add arguments.
- DICompositeType SPTy = SP.getType();
- DIArray Args = SPTy.getTypeArray();
- unsigned SPTag = SPTy.getTag();
- if (SPTag == dwarf::DW_TAG_subroutine_type)
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
- addType(Arg, ATy);
- if (ATy.isArtificial())
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
- SPDie->addChild(Arg);
- }
- DIE *SPDeclDie = SPDie;
- SPDie = new DIE(dwarf::DW_TAG_subprogram);
- addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
- SPDeclDie);
- ModuleCU->addDie(SPDie);
- }
-
- addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Asm->GetTempSymbol("func_begin", SubprogramCount));
- addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- Asm->GetTempSymbol("func_end", SubprogramCount));
- MachineLocation Location(RI->getFrameRegister(*MF));
- addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
-
- if (!DISubprogram(SPNode).isLocalToUnit())
- addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
-
- return SPDie;
+ // There is not any need to generate specification DIE for a function
+ // defined at compile unit level. If a function is defined inside another
+ // function then gdb prefers the definition at top level and but does not
+ // expect specification DIE in parent function. So avoid creating
+ // specification DIE for a function defined inside a function.
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
+ !SP.getContext().isFile() &&
+ !isSubprogramContext(SP.getContext().getNode())) {
+ addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
+
+ // Add arguments.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+ unsigned SPTag = SPTy.getTag();
+ if (SPTag == dwarf::DW_TAG_subroutine_type)
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+ SPDie->addChild(Arg);
+ }
+ DIE *SPDeclDie = SPDie;
+ SPDie = new DIE(dwarf::DW_TAG_subprogram);
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
+ SPDeclDie);
+ ModuleCU->addDie(SPDie);
+ }
+
+ addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
+ addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ MachineLocation Location(RI->getFrameRegister(*Asm->MF));
+ addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
+
+ if (!DISubprogram(SPNode).isLocalToUnit())
+ addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
+
+ return SPDie;
}
/// constructLexicalScope - Construct new DW_TAG_lexical_block
return ScopeDIE;
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Start ? Start : Asm->GetTempSymbol("func_begin", SubprogramCount));
+ Start ? Start : Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- End ? End : Asm->GetTempSymbol("func_end", SubprogramCount));
+ End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber()));
return ScopeDIE;
}
unsigned Imm = DbgValueInsn->getOperand(0).getImm();
addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
+ } else if (DbgValueInsn->getOperand(0).getType() ==
+ MachineOperand::MO_FPImmediate) {
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
+ APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
+
+ // Get the raw data form of the floating point.
+ const APInt FltVal = FPImm.bitcastToAPInt();
+ const char *FltPtr = (const char*)FltVal.getRawData();
+
+ int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
+ bool LittleEndian = Asm->getTargetData().isLittleEndian();
+ int Incr = (LittleEndian ? 1 : -1);
+ int Start = (LittleEndian ? 0 : NumBytes - 1);
+ int Stop = (LittleEndian ? NumBytes : -1);
+
+ // Output the constant to DWARF one byte at a time.
+ for (; Start != Stop; Start += Incr)
+ addUInt(Block, 0, dwarf::DW_FORM_data1,
+ (unsigned char)0xFF & FltPtr[Start]);
+
+ addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+
if (MCSymbol *VS = DV->getDbgValueLabel())
addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
VS);
} else {
MachineLocation Location;
unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
FrameReg);
Location.set(FrameReg, Offset);
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
DIUnit.getLanguage());
addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
- addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Asm->GetTempSymbol("text_begin"));
+ addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Asm->GetTempSymbol("text_end"));
// DW_AT_stmt_list is a offset of line number information for this
// Do not create specification DIE if context is either compile unit
// or a subprogram.
if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
- !GVContext.isFile() && !GVContext.isSubprogram()) {
+ !GVContext.isFile() &&
+ !isSubprogramContext(GVContext.getNode())) {
// Create specification DIE.
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
/// content. Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
void DwarfDebug::beginModule(Module *M) {
- this->M = M;
-
- if (!MAI->doesSupportDebugInformation())
- return;
-
- TimeRegion Timer(DebugTimer);
-
DebugInfoFinder DbgFinder;
DbgFinder.processModule(*M);
+ bool HasDebugInfo = false;
+
+ // Scan all the compile-units to see if there are any marked as the main unit.
+ // if not, we do not generate debug info.
+ for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
+ E = DbgFinder.compile_unit_end(); I != E; ++I) {
+ if (DICompileUnit(*I).isMain()) {
+ HasDebugInfo = true;
+ break;
+ }
+ }
+
+ if (!HasDebugInfo) return;
+
+ // Tell MMI that we have debug info.
+ MMI->setDebugInfoAvailability(true);
+
+ // Emit initial sections.
+ EmitSectionLabels();
+
// Create all the compile unit DIEs.
for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
E = DbgFinder.compile_unit_end(); I != E; ++I)
constructCompileUnit(*I);
- if (!ModuleCU)
- return;
-
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I)
E = DbgFinder.global_variable_end(); I != E; ++I)
constructGlobalVariableDIE(*I);
- MMI = Asm->MMI;
- shouldEmit = true;
- MMI->setDebugInfoAvailability(true);
-
// Prime section data.
SectionMap.insert(Asm->getObjFileLowering().getTextSection());
// Print out .file directives to specify files for .loc directives. These are
// printed out early so that they precede any .loc directives.
- if (MAI->hasDotLocAndDotFile()) {
+ if (Asm->MAI->hasDotLocAndDotFile()) {
for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
}
}
-
- // Emit initial sections
- emitInitial();
}
/// endModule - Emit all Dwarf sections that should come after the content.
///
void DwarfDebug::endModule() {
- if (!ModuleCU)
- return;
-
- TimeRegion Timer(DebugTimer);
+ if (!ModuleCU) return;
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void DwarfDebug::collectVariableInfo() {
- if (!MMI) return;
-
- const LLVMContext &Ctx = MF->getFunction()->getContext();
+ const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
}
// Collect variable information from DBG_VALUE machine instructions;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
if (DL == PrevInstLoc)
return;
- MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
+ MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
// FIXME: Should only verify each scope once!
if (!DIScope(Scope).Verify())
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
unsigned MIIndex = 0;
- LLVMContext &Ctx = MF->getFunction()->getContext();
+ LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
// Scan each instruction and create scopes. First build working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
// Build scope hierarchy using working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
/// beginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
- this->MF = MF;
-
- if (!ShouldEmitDwarfDebug()) return;
- if (!extractScopeInformation())
- return;
+ if (!MMI->hasDebugInfo()) return;
+ if (!extractScopeInformation()) return;
- TimeRegion Timer(DebugTimer);
-
collectVariableInfo();
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
- ++SubprogramCount));
+ Asm->getFunctionNumber()));
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
/// endFunction - Gather and emit post-function debug information.
///
void DwarfDebug::endFunction(const MachineFunction *MF) {
- if (!ShouldEmitDwarfDebug()) return;
- if (DbgScopeMap.empty()) return;
-
- TimeRegion Timer(DebugTimer);
+ if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
if (CurrentFnDbgScope) {
// Define end label for subprogram.
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
+ Asm->getFunctionNumber()));
// Get function line info.
if (!Lines.empty()) {
constructScopeDIE(CurrentFnDbgScope);
- DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
+ DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
MMI->getFrameMoves()));
}
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
- if (!MMI)
- return 0;
-
- TimeRegion Timer(DebugTimer);
-
StringRef Dir;
StringRef Fn;
return Label;
}
-/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
-/// timed. Look up the source id with the given directory and source file
-/// names. If none currently exists, create a new id and insert it in the
-/// SourceIds map. This can update DirectoryNames and SourceFileNames maps as
-/// well.
-unsigned DwarfDebug::getOrCreateSourceID(const std::string &DirName,
- const std::string &FileName) {
- TimeRegion Timer(DebugTimer);
- return GetOrCreateSourceID(DirName.c_str(), FileName.c_str());
-}
-
//===----------------------------------------------------------------------===//
// Emit Methods
//===----------------------------------------------------------------------===//
// Size the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; ++i)
// Size attribute value.
- Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
// Size the DIE children if any.
if (!Children.empty()) {
CompileUnitOffsets[ModuleCU] = 0;
}
-/// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
-/// tools to recognize the object file contains Dwarf information.
-void DwarfDebug::emitInitial() {
- // Check to see if we already emitted intial headers.
- if (didInitial) return;
- didInitial = true;
+/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
+/// temporary label to it if SymbolStem is specified.
+static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
+ const char *SymbolStem = 0) {
+ Asm->OutStreamer.SwitchSection(Section);
+ if (!SymbolStem) return 0;
+
+ MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
+ Asm->OutStreamer.EmitLabel(TmpSym);
+ return TmpSym;
+}
+/// EmitSectionLabels - Emit initial Dwarf sections with a label at
+/// the start of each one.
+void DwarfDebug::EmitSectionLabels() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
// Dwarf sections base addresses.
- if (MAI->doesDwarfRequireFrameSection()) {
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfFrameSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_debug_frame"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfInfoSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_info"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfAbbrevSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_abbrev"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfARangesSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_aranges"));
-
- if (const MCSection *LineInfoDirective = TLOF.getDwarfMacroInfoSection()) {
- Asm->OutStreamer.SwitchSection(LineInfoDirective);
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_macinfo"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_line"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_loc"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_pubnames"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_pubtypes"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfStrSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_str"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfRangesSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_ranges"));
-
- Asm->OutStreamer.SwitchSection(TLOF.getTextSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_begin"));
- Asm->OutStreamer.SwitchSection(TLOF.getDataSection());
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_begin"));
+ if (Asm->MAI->doesDwarfRequireFrameSection()) {
+ DwarfFrameSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
+ }
+
+ DwarfInfoSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
+ DwarfAbbrevSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
+ EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
+
+ if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
+ EmitSectionSym(Asm, MacroInfo);
+
+ EmitSectionSym(Asm, TLOF.getDwarfLineSection());
+ EmitSectionSym(Asm, TLOF.getDwarfLocSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
+ DwarfStrSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
+ EmitSectionSym(Asm, TLOF.getDwarfRangesSection());
+
+ TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
+ EmitSectionSym(Asm, TLOF.getDataSection());
}
/// emitDIE - Recusively Emits a debug information entry.
}
default:
// Emit an attribute using the defined form.
- Values[i]->EmitValue(this, Form);
+ Values[i]->EmitValue(Asm, Form);
break;
}
}
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
- EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"), "section_abbrev");
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
+ DwarfAbbrevSectionSym);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
emitDIE(Die);
// FIXME - extra padding for gdb bug.
Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
// Emit the abbreviations data.
- Abbrev->Emit(this);
+ Abbrev->Emit(Asm);
}
// Mark end of abbreviations.
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Section end label");
Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
// Mark end of matrix.
Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
void DwarfDebug::emitDebugLines() {
// If the target is using .loc/.file, the assembler will be emitting the
// .debug_line table automatically.
- if (MAI->hasDotLocAndDotFile())
+ if (Asm->MAI->hasDotLocAndDotFile())
return;
// Minimum line delta, thus ranging from -10..(255-10).
Asm->OutStreamer.AddComment("Extended Op");
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Location label");
- Asm->OutStreamer.EmitSymbolValue(Label, TD->getPointerSize(),
+ Asm->OutStreamer.EmitSymbolValue(Label,
+ Asm->getTargetData().getPointerSize(),
0/*AddrSpace*/);
// If change of source, then switch to the new source.
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
///
void DwarfDebug::emitCommonDebugFrame() {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
+ int stackGrowth = Asm->getTargetData().getPointerSize();
+ if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsDown)
+ stackGrowth *= -1;
// Start the dwarf frame section.
Asm->OutStreamer.SwitchSection(
Asm->EmitULEB128(1, "CIE Code Alignment Factor");
Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE RA Column");
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(0, Moves, false);
+ Asm->EmitFrameMoves(Moves, 0, false);
Asm->EmitAlignment(2, 0, 0, false);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
/// section.
void DwarfDebug::
emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
// Start the dwarf frame section.
Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Asm->OutStreamer.AddComment("FDE CIE offset");
- EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
- "section_debug_frame");
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
+ DwarfFrameSectionSym);
Asm->OutStreamer.AddComment("FDE initial location");
MCSymbol *FuncBeginSym =
Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
Asm->OutStreamer.AddComment("FDE address range");
Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
- FuncBeginSym, TD->getPointerSize());
+ FuncBeginSym, Asm->getTargetData().getPointerSize());
- EmitFrameMoves(FuncBeginSym, DebugFrameInfo.Moves, false);
+ Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Asm->EmitAlignment(2, 0, 0, false);
Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
- EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
- "section_info");
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation Unit Length");
Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
- EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
- "section_info");
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
/// __debug_info section, and the low_pc is the starting address for the
/// inlining instance.
void DwarfDebug::emitDebugInlineInfo() {
- if (!MAI->doesDwarfUsesInlineInfoSection())
+ if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
return;
if (!ModuleCU)
Asm->OutStreamer.AddComment("Dwarf Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
Asm->OutStreamer.EmitBytes(Name, 0);
Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
} else
- EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
- "section_str");
+ Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
+ DwarfStrSectionSym);
Asm->OutStreamer.AddComment("Function name");
- EmitSectionOffset(getStringPoolEntry(Name), "section_str");
+ Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Asm->EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Asm->EmitInt32(LI->second->getOffset());
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
- Asm->OutStreamer.EmitSymbolValue(LI->first, TD->getPointerSize(), 0);
+ Asm->OutStreamer.EmitSymbolValue(LI->first,
+ Asm->getTargetData().getPointerSize(),0);
}
}