#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Timer.h"
cl::desc("Generate GNU-style pubnames and pubtypes"),
cl::init(false));
+static cl::opt<bool> GenerateARangeSection("generate-arange-section",
+ cl::Hidden,
+ cl::desc("Generate dwarf aranges"),
+ cl::init(false));
+
namespace {
enum DefaultOnOff { Default, Enable, Disable };
}
return Entry.second;
}
-unsigned DwarfFile::getAddrPoolIndex(const MCSymbol *Sym) {
- return getAddrPoolIndex(MCSymbolRefExpr::Create(Sym, Asm->OutContext));
-}
-
-unsigned DwarfFile::getAddrPoolIndex(const MCExpr *Sym) {
- std::pair<DenseMap<const MCExpr *, unsigned>::iterator, bool> P =
- AddressPool.insert(std::make_pair(Sym, NextAddrPoolNumber));
+unsigned DwarfFile::getAddrPoolIndex(const MCSymbol *Sym, bool TLS) {
+ std::pair<AddrPool::iterator, bool> P = AddressPool.insert(
+ std::make_pair(Sym, AddressPoolEntry(NextAddrPoolNumber, TLS)));
if (P.second)
++NextAddrPoolNumber;
- return P.first->second;
+ return P.first->second.Number;
}
// Define a unique number for the abbreviation.
DIArray Args = SPTy.getTypeArray();
uint16_t SPTag = SPTy.getTag();
if (SPTag == dwarf::DW_TAG_subroutine_type)
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg =
- SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
- DIType ATy(Args.getElement(i));
- SPCU->addType(Arg, ATy);
- if (ATy.isArtificial())
- SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
- if (ATy.isObjectPointer())
- SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
- }
+ SPCU->constructSubprogramArguments(*SPDie, Args);
DIE *SPDeclDie = SPDie;
SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
*SPCU->getUnitDie());
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FunctionBeginSym);
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FunctionEndSym);
- // Add this range to the list of ranges for the CU.
- RangeSpan Span(FunctionBeginSym, FunctionEndSym);
- SPCU->addRange(llvm_move(Span));
-
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
RI != RE; ++RI) {
RangeSpan Span(getLabelBeforeInsn(RI->first),
getLabelAfterInsn(RI->second));
- List.addRange(llvm_move(Span));
+ List.addRange(std::move(Span));
}
// Add the range list to the set of ranges to be emitted.
- TheCU->addRangeList(llvm_move(List));
+ TheCU->addRangeList(std::move(List));
}
// Construct new DW_TAG_lexical_block for this scope and attach
DIE *ObjectPointer = NULL;
// Collect arguments for current function.
- if (LScopes.isCurrentFunctionScope(Scope))
+ if (LScopes.isCurrentFunctionScope(Scope)) {
for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
if (DbgVariable *ArgDV = CurrentFnArguments[i])
if (DIE *Arg =
ObjectPointer = Arg;
}
+ // If this is a variadic function, add an unspecified parameter.
+ DISubprogram SP(Scope->getScopeNode());
+ DIArray FnArgs = SP.getType().getTypeArray();
+ if (FnArgs.getElement(FnArgs.getNumElements() - 1)
+ .isUnspecifiedParameter()) {
+ DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
+ Children.push_back(Ellipsis);
+ }
+ }
+
// Collect lexical scope children first.
const SmallVectorImpl<DbgVariable *> &Variables =
ScopeVariables.lookup(Scope);
// as well.
unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, StringRef DirName,
unsigned CUID) {
- // If we use .loc in assembly, we can't separate .file entries according to
+ // If we print assembly, we can't separate .file entries according to
// compile units. Thus all files will belong to the default compile unit.
// FIXME: add a better feature test than hasRawTextSupport. Even better,
// extend .file to support this.
- if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport())
+ if (Asm->OutStreamer.hasRawTextSupport())
CUID = 0;
// If FE did not provide a file name, then assume stdin.
InfoHolder.addUnit(NewCU);
FileIDCUMap[NewCU->getUniqueID()] = 0;
- // Call this to emit a .file directive if it wasn't emitted for the source
- // file this CU comes from yet.
- getOrCreateSourceID(FN, CompilationDir, NewCU->getUniqueID());
NewCU->addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
DIUnit.getLanguage());
NewCU->addString(Die, dwarf::DW_AT_name, FN);
- // Define start line table label for each Compile Unit.
- MCSymbol *LineTableStartSym =
- Asm->GetTempSymbol("line_table_start", NewCU->getUniqueID());
- Asm->OutStreamer.getContext().setMCLineTableSymbol(LineTableStartSym,
- NewCU->getUniqueID());
-
- // Use a single line table if we are using .loc and generating assembly.
- bool UseTheFirstCU =
- (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) ||
- (NewCU->getUniqueID() == 0);
-
if (!useSplitDwarf()) {
- // DW_AT_stmt_list is a offset of line number information for this
- // compile unit in debug_line section. For split dwarf this is
- // left in the skeleton CU and so not included.
- // The line table entries are not always emitted in assembly, so it
- // is not okay to use line_table_start here.
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list,
- UseTheFirstCU ? Asm->GetTempSymbol("section_line")
- : LineTableStartSym);
- else if (UseTheFirstCU)
- NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
- else
- NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list, LineTableStartSym,
- DwarfLineSectionSym);
+ NewCU->initStmtList(DwarfLineSectionSym);
// If we're using split dwarf the compilation dir is going to be in the
// skeleton CU and so we don't need to duplicate it here.
void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
const MDNode *N) {
DIImportedEntity Module(N);
- if (!Module.Verify())
- return;
+ assert(Module.Verify());
if (DIE *D = TheCU->getOrCreateContextDIE(Module.getContext()))
constructImportedEntityDIE(TheCU, Module, D);
}
void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
const MDNode *N, DIE *Context) {
DIImportedEntity Module(N);
- if (!Module.Verify())
- return;
+ assert(Module.Verify());
return constructImportedEntityDIE(TheCU, Module, Context);
}
// This should be a unique identifier when we want to build .dwp files.
uint64_t ID = 0;
if (GenerateCUHash) {
- DIEHash CUHash;
+ DIEHash CUHash(Asm);
ID = CUHash.computeCUSignature(*TheU->getUnitDie());
}
TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
// FIXME: We should use ranges if we have multiple compile units or
// allow reordering of code ala .subsections_via_symbols in mach-o.
DwarfCompileUnit *U = SkCU ? SkCU : static_cast<DwarfCompileUnit *>(TheU);
- if (useCURanges() && TheU->getRanges().size())
+ if (useCURanges() && TheU->getRanges().size()) {
addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges,
Asm->GetTempSymbol("cu_ranges", U->getUniqueID()),
DwarfDebugRangeSectionSym);
- else
+
+ // A DW_AT_low_pc attribute may also be specified in combination with
+ // DW_AT_ranges to specify the default base address for use in location
+ // lists (see Section 2.6.2) and range lists (see Section 2.17.3).
+ U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ 0);
+ } else
U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
0);
}
if (Section) {
// We can't call MCSection::getLabelEndName, as it's only safe to do so
// if we know the section name up-front. For user-created sections, the
- // resulting
- // label may not be valid to use as a label. (section names can use a
- // greater
- // set of characters on some systems)
+ // resulting label may not be valid to use as a label. (section names can
+ // use a greater set of characters on some systems)
Sym = Asm->GetTempSymbol("debug_end", ID);
Asm->OutStreamer.SwitchSection(Section);
Asm->OutStreamer.EmitLabel(Sym);
}
// For now only turn on CU ranges if we've explicitly asked for it,
- // we have -ffunction-sections enabled, or we've emitted a function
- // into a unique section. At this point all sections should be finalized
- // except for dwarf sections.
- HasCURanges = DwarfCURanges || UsedNonDefaultText ||
+ // we have -ffunction-sections enabled, we've emitted a function
+ // into a unique section, or we're using LTO. If we're using LTO then
+ // we can't know that any particular function in the module is correlated
+ // to a particular CU and so we need to be conservative. At this point all
+ // sections should be finalized except for dwarf sections.
+ HasCURanges = DwarfCURanges || UsedNonDefaultText || (CUMap.size() > 1) ||
TargetMachine::getFunctionSections();
}
emitDebugLoc();
// Emit info into a debug aranges section.
- emitDebugARanges();
+ if (GenerateARangeSection)
+ emitDebugARanges();
// Emit info into a debug ranges section.
emitDebugRanges();
}
}
-// Get MDNode for DebugLoc's scope.
-static MDNode *getScopeNode(DebugLoc DL, const LLVMContext &Ctx) {
- if (MDNode *InlinedAt = DL.getInlinedAt(Ctx))
- return getScopeNode(DebugLoc::getFromDILocation(InlinedAt), Ctx);
- return DL.getScope(Ctx);
-}
-
-// Walk up the scope chain of given debug loc and find line number info
-// for the function.
-static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) {
- const MDNode *Scope = getScopeNode(DL, Ctx);
- DISubprogram SP = getDISubprogram(Scope);
- if (SP.isSubprogram()) {
- // Check for number of operands since the compatibility is
- // cheap here.
- if (SP->getNumOperands() > 19)
- return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
- else
- return DebugLoc::get(SP.getLineNumber(), 0, SP);
- }
-
- return DebugLoc();
-}
-
// Gather pre-function debug information. Assumes being called immediately
// after the function entry point has been emitted.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
assert(TheCU && "Unable to find compile unit!");
- if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport())
- // Use a single line table if we are using .loc and generating assembly.
+ if (Asm->OutStreamer.hasRawTextSupport())
+ // Use a single line table if we are generating assembly.
Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
else
Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID());
// Record beginning of function.
if (!PrologEndLoc.isUnknown()) {
DebugLoc FnStartDL =
- getFnDebugLoc(PrologEndLoc, MF->getFunction()->getContext());
+ PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext());
recordSourceLine(
FnStartDL.getLine(), FnStartDL.getCol(),
FnStartDL.getScope(MF->getFunction()->getContext()),
FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(FunctionEndSym);
+
// Set DwarfDwarfCompileUnitID in MCContext to default value.
Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
}
DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
-
if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
+ // Add the range of this function to the list of ranges for the CU.
+ RangeSpan Span(FunctionBeginSym, FunctionEndSym);
+ TheCU->addRange(std::move(Span));
+
// Clear debug info
for (ScopeVariablesMap::iterator I = ScopeVariables.begin(),
E = ScopeVariables.end();
Die->setOffset(Offset);
// Start the size with the size of abbreviation code.
- Offset += MCAsmInfo::getULEB128Size(Die->getAbbrevNumber());
+ Offset += getULEB128Size(Die->getAbbrevNumber());
const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
if (useSplitDwarf())
DwarfAbbrevDWOSectionSym = emitSectionSym(
Asm, TLOF.getDwarfAbbrevDWOSection(), "section_abbrev_dwo");
- emitSectionSym(Asm, TLOF.getDwarfARangesSection());
-
- if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
- emitSectionSym(Asm, MacroInfo);
+ if (GenerateARangeSection)
+ emitSectionSym(Asm, TLOF.getDwarfARangesSection());
DwarfLineSectionSym =
emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line");
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(AddressPool.size());
- for (DenseMap<const MCExpr *, unsigned>::iterator I = AddressPool.begin(),
- E = AddressPool.end();
+ for (AddrPool::iterator I = AddressPool.begin(), E = AddressPool.end();
I != E; ++I)
- Entries[I->second] = I->first;
+ Entries[I->second.Number] =
+ I->second.TLS
+ ? Asm->getObjFileLowering().getDebugThreadLocalSymbol(I->first)
+ : MCSymbolRefExpr::Create(I->first, Asm->OutContext);
- for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
- // Emit an expression for reference from debug information entries.
- if (const MCExpr *Expr = Entries[i])
- Asm->OutStreamer.EmitValue(Expr, Asm->getDataLayout().getPointerSize());
- else
- Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize());
- }
+ for (unsigned i = 0, e = Entries.size(); i != e; ++i)
+ Asm->OutStreamer.EmitValue(Entries[i],
+ Asm->getDataLayout().getPointerSize());
}
// Emit visible names into a debug str section.
unsigned char Size = Asm->getDataLayout().getPointerSize();
// Grab the specific ranges for the compile units in the module.
- for (DenseMap<const MDNode *, DwarfCompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (MapVector<const MDNode *, DwarfCompileUnit *>::iterator
+ I = CUMap.begin(),
+ E = CUMap.end();
I != E; ++I) {
DwarfCompileUnit *TheCU = I->second;
}
// Now emit a range for the CU itself.
- if (useCURanges()) {
+ if (useCURanges() && TheCU->getRanges().size()) {
Asm->OutStreamer.EmitLabel(
Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID()));
const SmallVectorImpl<RangeSpan> &Ranges = TheCU->getRanges();
NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoSection(),
DwarfInfoSectionSym);
- // DW_AT_stmt_list is a offset of line number information for this
- // compile unit in debug_line section.
- // FIXME: Should handle multiple compile units.
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list, DwarfLineSectionSym);
- else
- NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
+ NewCU->initStmtList(DwarfLineSectionSym);
initSkeletonUnit(CU, Die, NewCU);
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_dwo_name,
// DW_AT_addr_base.
-DwarfTypeUnit *DwarfDebug::constructSkeletonTU(const DwarfTypeUnit *TU) {
+DwarfTypeUnit *DwarfDebug::constructSkeletonTU(DwarfTypeUnit *TU) {
+ DwarfCompileUnit &CU = static_cast<DwarfCompileUnit &>(
+ *SkeletonHolder.getUnits()[TU->getCU().getUniqueID()]);
DIE *Die = new DIE(dwarf::DW_TAG_type_unit);
- DwarfTypeUnit *NewTU = new DwarfTypeUnit(
- TU->getUniqueID(), Die, TU->getCUNode(), Asm, this, &SkeletonHolder);
+ DwarfTypeUnit *NewTU =
+ new DwarfTypeUnit(TU->getUniqueID(), Die, CU, Asm, this, &SkeletonHolder);
NewTU->setTypeSignature(TU->getTypeSignature());
NewTU->setType(NULL);
NewTU->initSection(
Asm->getObjFileLowering().getDwarfTypesSection(TU->getTypeSignature()));
+ CU.applyStmtList(*Die);
initSkeletonUnit(TU, Die, NewTU);
return NewTU;
OffSec, StrSym);
}
-void DwarfDebug::addDwarfTypeUnitType(DICompileUnit CUNode,
+void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
StringRef Identifier, DIE *RefDie,
DICompositeType CTy) {
+ // Flag the type unit reference as a declaration so that if it contains
+ // members (implicit special members, static data member definitions, member
+ // declarations for definitions in this CU, etc) consumers don't get confused
+ // and think this is a full definition.
+ CU.addFlag(RefDie, dwarf::DW_AT_declaration);
const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy];
if (TU) {
- CUMap.begin()->second->addDIETypeSignature(RefDie, *TU);
+ CU.addDIETypeSignature(RefDie, *TU);
return;
}
DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
- DwarfTypeUnit *NewTU = new DwarfTypeUnit(
- InfoHolder.getUnits().size(), UnitDie, CUNode, Asm, this, &InfoHolder);
+ DwarfTypeUnit *NewTU = new DwarfTypeUnit(InfoHolder.getUnits().size(),
+ UnitDie, CU, Asm, this, &InfoHolder);
TU = NewTU;
InfoHolder.addUnit(NewTU);
NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
- CUNode.getLanguage());
+ CU.getLanguage());
MD5 Hash;
Hash.update(Identifier);
NewTU->setTypeSignature(Signature);
if (useSplitDwarf())
NewTU->setSkeleton(constructSkeletonTU(NewTU));
+ else
+ CU.applyStmtList(*UnitDie);
NewTU->setType(NewTU->createTypeDIE(CTy));
? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature)
: Asm->getObjFileLowering().getDwarfTypesSection(Signature));
- CUMap.begin()->second->addDIETypeSignature(RefDie, *NewTU);
+ CU.addDIETypeSignature(RefDie, *NewTU);
}