clEnumVal(Disable, "Disabled"), clEnumValEnd),
cl::init(Default));
-static cl::opt<DefaultOnOff>
-DarwinGDBCompat("darwin-gdb-compat", cl::Hidden,
- cl::desc("Compatibility with Darwin gdb."),
- cl::values(clEnumVal(Default, "Default for platform"),
- clEnumVal(Enable, "Enabled"),
- clEnumVal(Disable, "Disabled"), clEnumValEnd),
- cl::init(Default));
-
static cl::opt<DefaultOnOff>
SplitDwarf("split-dwarf", cl::Hidden,
cl::desc("Output prototype dwarf split debug info."),
cl::init(Default));
static cl::opt<DefaultOnOff>
-DwarfPubNames("generate-dwarf-pubnames", cl::Hidden,
- cl::desc("Generate DWARF pubnames section"),
- cl::values(clEnumVal(Default, "Default for platform"),
- clEnumVal(Enable, "Enabled"),
- clEnumVal(Disable, "Disabled"), clEnumValEnd),
- cl::init(Default));
+DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
+ cl::desc("Generate DWARF pubnames and pubtypes sections"),
+ cl::values(clEnumVal(Default, "Default for platform"),
+ clEnumVal(Enable, "Enabled"),
+ clEnumVal(Disable, "Disabled"), clEnumValEnd),
+ cl::init(Default));
static const char *const DWARFGroupName = "DWARF Emission";
static const char *const DbgTimerName = "DWARF Debug Writer";
DIType subType = Ty;
uint16_t tag = Ty.getTag();
- if (tag == dwarf::DW_TAG_pointer_type) {
- DIDerivedType DTy = DIDerivedType(Ty);
- subType = DTy.getTypeDerivedFrom();
- }
-
- DICompositeType blockStruct = DICompositeType(subType);
- DIArray Elements = blockStruct.getTypeArray();
+ if (tag == dwarf::DW_TAG_pointer_type)
+ subType = DIDerivedType(Ty).getTypeDerivedFrom();
+ DIArray Elements = DICompositeType(subType).getTypeArray();
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
- DIDescriptor Element = Elements.getElement(i);
- DIDerivedType DT = DIDerivedType(Element);
+ DIDerivedType DT = DIDerivedType(Elements.getElement(i));
if (getName() == DT.getName())
return (DT.getTypeDerivedFrom());
}
// and handle split dwarf.
bool IsDarwin = Triple(A->getTargetTriple()).isOSDarwin();
- if (DarwinGDBCompat == Default)
- IsDarwinGDBCompat = IsDarwin;
- else
- IsDarwinGDBCompat = DarwinGDBCompat == Enable;
-
if (DwarfAccelTables == Default)
HasDwarfAccelTables = IsDarwin;
else
else
HasSplitDwarf = SplitDwarf == Enable;
- if (DwarfPubNames == Default)
- HasDwarfPubNames = !IsDarwin;
+ if (DwarfPubSections == Default)
+ HasDwarfPubSections = !IsDarwin;
else
- HasDwarfPubNames = DwarfPubNames == Enable;
+ HasDwarfPubSections = DwarfPubSections == Enable;
DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
TheCU->getUniqueID()));
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
- // Track the start label for this inlined function.
- //.debug_inlined section specification does not clearly state how
- // to emit inlined scopes that are split into multiple instruction ranges.
- // For now, use the first instruction range and emit low_pc/high_pc pair and
- // corresponding the .debug_inlined section entry for this pair.
- if (Asm->MAI->doesDwarfUseInlineInfoSection()) {
- MCSymbol *StartLabel = getLabelBeforeInsn(Ranges.begin()->first);
- InlineInfoMap::iterator I = InlineInfo.find(InlinedSP);
-
- if (I == InlineInfo.end()) {
- InlineInfo[InlinedSP].push_back(std::make_pair(StartLabel, ScopeDIE));
- InlinedSPNodes.push_back(InlinedSP);
- } else
- I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
- }
-
// Add name to the name table, we do this here because we're guaranteed
// to have concrete versions of our DW_TAG_inlined_subprogram nodes.
addSubprogramNames(TheCU, InlinedSP, ScopeDIE);
CompilationDir = DIUnit.getDirectory();
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
- CompileUnit *NewCU = new CompileUnit(GlobalCUIndexCount++,
- DIUnit.getLanguage(), Die, N, Asm,
- this, &InfoHolder);
+ CompileUnit *NewCU =
+ new CompileUnit(GlobalCUIndexCount++, Die, N, Asm, this, &InfoHolder);
FileIDCUMap[NewCU->getUniqueID()] = 0;
// Call this to emit a .file directive if it wasn't emitted for the source
TheCU->addToContextOwner(SubprogramDie, SP.getContext());
// Expose as global, if requested.
- if (HasDwarfPubNames)
+ if (HasDwarfPubSections)
TheCU->addGlobalName(SP.getName(), SubprogramDie);
}
TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
// Now construct the skeleton CU associated.
- CompileUnit *SkCU = constructSkeletonCU(CUI->first);
+ CompileUnit *SkCU = constructSkeletonCU(TheCU);
// This should be a unique identifier when we want to build .dwp files.
SkCU->addUInt(SkCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
// Emit info into a debug macinfo section.
emitDebugMacInfo();
- // Emit inline info.
- // TODO: When we don't need the option anymore we
- // can remove all of the code that this section
- // depends upon.
- if (useDarwinGDBCompat())
- emitDebugInlineInfo();
} else {
// TODO: Fill this in for separated debug sections and separate
// out information into new sections.
// Emit DWO addresses.
InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
- // Emit inline info.
- // TODO: When we don't need the option anymore we
- // can remove all of the code that this section
- // depends upon.
- if (useDarwinGDBCompat())
- emitDebugInlineInfo();
}
// Emit info into the dwarf accelerator table sections.
emitAccelTypes();
}
- // Emit info into a debug pubnames section, if requested.
- if (HasDwarfPubNames)
+ // Emit the pubnames and pubtypes sections if requested.
+ if (HasDwarfPubSections) {
emitDebugPubnames();
-
- // Emit info into a debug pubtypes section.
- // TODO: When we don't need the option anymore we can
- // remove all of the code that adds to the table.
- if (useDarwinGDBCompat())
emitDebugPubTypes();
+ }
// Finally emit string information into a string table.
emitDebugStr();
DwarfLineSectionSym =
emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line");
emitSectionSym(Asm, TLOF.getDwarfLocSection());
- if (HasDwarfPubNames)
+ if (HasDwarfPubSections) {
emitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
- emitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
+ emitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
+ }
DwarfStrSectionSym =
emitSectionSym(Asm, TLOF.getDwarfStrSection(), "info_string");
if (useSplitDwarf()) {
// Emit visible names into a debug aranges section.
void DwarfDebug::emitDebugARanges() {
// Start the dwarf aranges section.
- Asm->OutStreamer.SwitchSection(
- Asm->getObjFileLowering().getDwarfARangesSection());
+ Asm->OutStreamer
+ .SwitchSection(Asm->getObjFileLowering().getDwarfARangesSection());
}
// Emit visible names into a debug ranges section.
void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
- Asm->OutStreamer.SwitchSection(
- Asm->getObjFileLowering().getDwarfRangesSection());
+ Asm->OutStreamer
+ .SwitchSection(Asm->getObjFileLowering().getDwarfRangesSection());
unsigned char Size = Asm->getDataLayout().getPointerSize();
for (SmallVectorImpl<const MCSymbol *>::iterator
I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
}
}
-// Emit inline info using following format.
-// Section Header:
-// 1. length of section
-// 2. Dwarf version number
-// 3. address size.
-//
-// Entries (one "entry" for each function that was inlined):
-//
-// 1. offset into __debug_str section for MIPS linkage name, if exists;
-// otherwise offset into __debug_str for regular function name.
-// 2. offset into __debug_str section for regular function name.
-// 3. an unsigned LEB128 number indicating the number of distinct inlining
-// instances for the function.
-//
-// The rest of the entry consists of a {die_offset, low_pc} pair for each
-// inlined instance; the die_offset points to the inlined_subroutine die in the
-// __debug_info section, and the low_pc is the starting address for the
-// inlining instance.
-void DwarfDebug::emitDebugInlineInfo() {
- if (!Asm->MAI->doesDwarfUseInlineInfoSection())
- return;
-
- if (!FirstCU)
- return;
-
- Asm->OutStreamer.SwitchSection(
- Asm->getObjFileLowering().getDwarfDebugInlineSection());
-
- Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
- Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
- Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
-
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
-
- Asm->OutStreamer.AddComment("Dwarf Version");
- Asm->EmitInt16(DwarfVersion);
- Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
-
- for (SmallVectorImpl<const MDNode *>::iterator I = InlinedSPNodes.begin(),
- E = InlinedSPNodes.end(); I != E; ++I) {
-
- const MDNode *Node = *I;
- InlineInfoMap::iterator II = InlineInfo.find(Node);
- SmallVectorImpl<InlineInfoLabels> &Labels = II->second;
- DISubprogram SP(Node);
- StringRef LName = SP.getLinkageName();
- StringRef Name = SP.getName();
-
- Asm->OutStreamer.AddComment("MIPS linkage name");
- if (LName.empty())
- Asm->EmitSectionOffset(InfoHolder.getStringPoolEntry(Name),
- DwarfStrSectionSym);
- else
- Asm->EmitSectionOffset(
- InfoHolder.getStringPoolEntry(Function::getRealLinkageName(LName)),
- DwarfStrSectionSym);
-
- Asm->OutStreamer.AddComment("Function name");
- Asm->EmitSectionOffset(InfoHolder.getStringPoolEntry(Name),
- DwarfStrSectionSym);
- Asm->EmitULEB128(Labels.size(), "Inline count");
-
- for (SmallVectorImpl<InlineInfoLabels>::iterator LI = Labels.begin(),
- LE = Labels.end(); LI != LE; ++LI) {
- if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
- Asm->EmitInt32(LI->second->getOffset());
-
- if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
- Asm->OutStreamer.EmitSymbolValue(LI->first,
- Asm->getDataLayout().getPointerSize());
- }
- }
-
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
-}
-
// DWARF5 Experimental Separate Dwarf emitters.
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
// DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
// DW_AT_ranges_base, DW_AT_addr_base. If DW_AT_ranges is present,
// DW_AT_low_pc and DW_AT_high_pc are not used, and vice versa.
-CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) {
- DICompileUnit DIUnit(N);
- CompilationDir = DIUnit.getDirectory();
+CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
- CompileUnit *NewCU = new CompileUnit(GlobalCUIndexCount++,
- DIUnit.getLanguage(), Die, N, Asm,
- this, &SkeletonHolder);
+ CompileUnit *NewCU = new CompileUnit(CU->getUniqueID(), Die, CU->getNode(),
+ Asm, this, &SkeletonHolder);
NewCU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name,
- DIUnit.getSplitDebugFilename());
+ DICompileUnit(CU->getNode()).getSplitDebugFilename());
// Relocate to the beginning of the addr_base section, else 0 for the
// beginning of the one for this compile unit.