#include "DIE.h"
#include "DIEHash.h"
#include "DwarfAccelTable.h"
-#include "DwarfCompileUnit.h"
+#include "DwarfUnit.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
clEnumVal(Disable, "Disabled"), clEnumValEnd),
cl::init(Default));
+static cl::opt<unsigned>
+DwarfVersionNumber("dwarf-version", cl::Hidden,
+ cl::desc("Generate DWARF for dwarf version."),
+ cl::init(0));
+
static const char *const DWARFGroupName = "DWARF Emission";
static const char *const DbgTimerName = "DWARF Debug Writer";
else
HasDwarfPubSections = DwarfPubSections == Enable;
- DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
+ DwarfVersion = DwarfVersionNumber
+ ? DwarfVersionNumber
+ : getDwarfVersionFromModule(MMI->getModule());
{
NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
return TmpSym;
}
+DwarfUnits::~DwarfUnits() {
+ for (SmallVectorImpl<Unit *>::iterator I = CUs.begin(), E = CUs.end(); I != E;
+ ++I)
+ delete *I;
+}
+
MCSymbol *DwarfUnits::getStringPoolSym() {
return Asm->GetTempSymbol(StringPref);
}
// TODO: Determine whether or not we should add names for programs
// that do not have a DW_AT_name or DW_AT_linkage_name field - this
// is only slightly different than the lookup of non-standard ObjC names.
-static void addSubprogramNames(CompileUnit *TheCU, DISubprogram SP, DIE *Die) {
+static void addSubprogramNames(Unit *TheCU, DISubprogram SP, DIE *Die) {
if (!SP.isDefinition())
return;
TheCU->addAccelName(SP.getName(), Die);
// If we have multiple ranges, emit them into the range section.
if (Ranges.size() > 1) {
// .debug_range section has not been laid out yet. Emit offset in
- // .debug_range as a uint, size 4, for now. emitDIE will handle
- // DW_AT_ranges appropriately.
- TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
- DebugRangeSymbols.size() *
- Asm->getDataLayout().getPointerSize());
+ // .debug_range as a relocatable label. emitDIE will handle
+ // emitting it appropriately.
+ unsigned Offset = DebugRangeSymbols.size();
+ TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("debug_ranges", Offset));
for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
RE = Ranges.end();
RI != RE; ++RI) {
if (Ranges.size() > 1) {
// .debug_range section has not been laid out yet. Emit offset in
- // .debug_range as a uint, size 4, for now. emitDIE will handle
- // DW_AT_ranges appropriately.
- TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
- DebugRangeSymbols.size() *
- Asm->getDataLayout().getPointerSize());
+ // .debug_range as a relocatable label. emitDIE will handle
+ // emitting it appropriately.
+ unsigned Offset = DebugRangeSymbols.size();
+ TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("debug_ranges", Offset));
for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
RE = Ranges.end();
RI != RE; ++RI) {
if (DS.isSubprogram() && ObjectPointer != NULL)
TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer);
- if (DS.isSubprogram())
- TheCU->addPubTypes(DISubprogram(DS));
-
return ScopeDIE;
}
// 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->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
- UseTheFirstCU ? Asm->GetTempSymbol("section_line")
- : LineTableStartSym);
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_stmt_list,
+ UseTheFirstCU ? Asm->GetTempSymbol("section_line")
+ : LineTableStartSym);
else if (UseTheFirstCU)
- NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
+ NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
else
- NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
- LineTableStartSym, DwarfLineSectionSym);
+ NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list,
+ LineTableStartSym, 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.
// emit it here if we don't have a skeleton CU for split dwarf.
if (GenerateGnuPubSections) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(
- Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset,
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_GNU_pubnames,
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
else
- NewCU->addDelta(
- Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
+ NewCU->addSectionDelta(
+ Die, dwarf::DW_AT_GNU_pubnames,
Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
DwarfGnuPubNamesSectionSym);
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(
- Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset,
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_GNU_pubtypes,
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
else
- NewCU->addDelta(
- Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
+ NewCU->addSectionDelta(
+ Die, dwarf::DW_AT_GNU_pubtypes,
Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
DwarfGnuPubTypesSectionSym);
}
continue;
// Construct subprogram DIE and add variables DIEs.
- CompileUnit *SPCU = CUMap.lookup(TheCU);
+ CompileUnit *SPCU = static_cast<CompileUnit *>(CUMap.lookup(TheCU));
assert(SPCU && "Unable to find Compile Unit!");
// FIXME: See the comment in constructSubprogramDIE about duplicate
// subprogram DIEs.
/// Test if the current CU language is C++ and that we have
/// a named type that is not contained in an anonymous namespace.
-static bool shouldAddODRHash(CompileUnit *CU, DIE *Die) {
+static bool shouldAddODRHash(TypeUnit *CU, DIE *Die) {
return CU->getLanguage() == dwarf::DW_LANG_C_plus_plus &&
getDIEStringAttr(Die, dwarf::DW_AT_name) != "" &&
!isContainedInAnonNamespace(Die);
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
computeInlinedDIEs();
- // Split out type units and conditionally add an ODR tag to the split
- // out type.
- // FIXME: Do type splitting.
- for (unsigned i = 0, e = TypeUnits.size(); i != e; ++i) {
- DIE *Die = TypeUnits[i];
- DIEHash Hash;
- // If we've requested ODR hashes and it's applicable for an ODR hash then
- // add the ODR signature now.
- // FIXME: This should be added onto the type unit, not the type, but this
- // works as an intermediate stage.
- if (GenerateODRHash && shouldAddODRHash(CUMap.begin()->second, Die))
- CUMap.begin()->second->addUInt(Die, dwarf::DW_AT_GNU_odr_signature,
- dwarf::DW_FORM_data8,
- Hash.computeDIEODRSignature(*Die));
- }
-
// Handle anything that needs to be done on a per-cu basis.
- for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),
- CUE = CUMap.end();
- CUI != CUE; ++CUI) {
- CompileUnit *TheCU = CUI->second;
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
+ I != E; ++I) {
+ Unit *TheCU = *I;
// Emit DW_AT_containing_type attribute to connect types with their
// vtable holding type.
TheCU->constructContainingTypeDIEs();
// If we're splitting the dwarf out now that we've got the entire
// CU then construct a skeleton CU based upon it.
- if (useSplitDwarf()) {
+ if (useSplitDwarf() &&
+ TheCU->getCUDie()->getTag() == dwarf::DW_TAG_compile_unit) {
uint64_t ID = 0;
if (GenerateCUHash) {
DIEHash CUHash;
TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
// Now construct the skeleton CU associated.
- CompileUnit *SkCU = constructSkeletonCU(TheCU);
+ CompileUnit *SkCU =
+ constructSkeletonCU(static_cast<CompileUnit *>(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);
// Finalize the debug info for the module.
finalizeModuleInfo();
- if (!useSplitDwarf()) {
- emitDebugStr();
+ emitDebugStr();
- // Emit all the DIEs into a debug info section.
- emitDebugInfo();
+ // Emit all the DIEs into a debug info section.
+ emitDebugInfo();
- // Corresponding abbreviations into a abbrev section.
- emitAbbreviations();
+ // Corresponding abbreviations into a abbrev section.
+ emitAbbreviations();
- // Emit info into a debug loc section.
- emitDebugLoc();
+ // Emit info into a debug loc section.
+ emitDebugLoc();
- // Emit info into a debug aranges section.
- emitDebugARanges();
+ // Emit info into a debug aranges section.
+ emitDebugARanges();
- // Emit info into a debug ranges section.
- emitDebugRanges();
+ // Emit info into a debug ranges section.
+ emitDebugRanges();
- // Emit info into a debug macinfo section.
- emitDebugMacInfo();
+ // Emit info into a debug macinfo section.
+ emitDebugMacInfo();
- } else {
- // TODO: Fill this in for separated debug sections and separate
- // out information into new sections.
- emitDebugStr();
- if (useSplitDwarf())
- emitDebugStrDWO();
-
- // Emit the debug info section and compile units.
- emitDebugInfo();
+ if (useSplitDwarf()) {
+ emitDebugStrDWO();
emitDebugInfoDWO();
-
- // Corresponding abbreviations into a abbrev section.
- emitAbbreviations();
emitDebugAbbrevDWO();
-
- // Emit info into a debug loc section.
- emitDebugLoc();
-
- // Emit info into a debug aranges section.
- emitDebugARanges();
-
- // Emit info into a debug ranges section.
- emitDebugRanges();
-
- // Emit info into a debug macinfo section.
- emitDebugMacInfo();
-
// Emit DWO addresses.
InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
}
// clean up.
SPMap.clear();
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
- I != E; ++I)
- delete I->second;
-
- for (SmallVectorImpl<CompileUnit *>::iterator I = SkeletonCUs.begin(),
- E = SkeletonCUs.end();
- I != E; ++I)
- delete *I;
// Reset these for the next Module if we have one.
FirstCU = NULL;
// Iterate over each compile unit and set the size and offsets for each
// DIE within each compile unit. All offsets are CU relative.
- for (SmallVectorImpl<CompileUnit *>::iterator I = CUs.begin(), E = CUs.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = CUs.begin(), E = CUs.end();
I != E; ++I) {
(*I)->setDebugInfoOffset(SecOffset);
// For DW_FORM_ref_addr, output the offset from beginning of debug info
// section. Origin->getOffset() returns the offset from start of the
// compile unit.
- CompileUnit *CU = CUDieMap.lookup(Origin->getCompileUnit());
+ CompileUnit *CU = CUDieMap.lookup(Origin->getUnit());
assert(CU && "CUDie should belong to a CU.");
Addr += CU->getDebugInfoOffset();
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
DIEEntry::getRefAddrSize(Asm));
} else {
// Make sure Origin belong to the same CU.
- assert(Die->getCompileUnit() == Origin->getCompileUnit() &&
+ assert(Die->getUnit() == Origin->getUnit() &&
"The referenced DIE should belong to the same CU in ref4");
Asm->EmitInt32(Addr);
}
}
case dwarf::DW_AT_ranges: {
// DW_AT_range Value encodes offset in debug_range section.
- DIEInteger *V = cast<DIEInteger>(Values[i]);
+ DIELabel *V = cast<DIELabel>(Values[i]);
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) {
- Asm->EmitLabelPlusOffset(DwarfDebugRangeSectionSym, V->getValue(), 4);
- } else {
- Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym, V->getValue(),
- DwarfDebugRangeSectionSym, 4);
- }
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ Asm->EmitSectionOffset(V->getValue(), DwarfDebugRangeSectionSym);
+ else
+ Asm->EmitLabelDifference(V->getValue(), DwarfDebugRangeSectionSym, 4);
break;
}
case dwarf::DW_AT_location: {
const MCSection *ASection,
const MCSymbol *ASectionSym) {
Asm->OutStreamer.SwitchSection(USection);
- for (SmallVectorImpl<CompileUnit *>::iterator I = CUs.begin(), E = CUs.end();
- I != E; ++I) {
- CompileUnit *TheCU = *I;
+ for (SmallVectorImpl<Unit *>::iterator I = CUs.begin(), E = CUs.end(); I != E;
+ ++I) {
+ Unit *TheCU = *I;
DIE *Die = TheCU->getCUDie();
// Emit the compile units header.
void DwarfDebug::emitAccelNames() {
DwarfAccelTable AT(
DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
I != E; ++I) {
- CompileUnit *TheCU = I->second;
- const StringMap<std::vector<DIE *> > &Names = TheCU->getAccelNames();
- for (StringMap<std::vector<DIE *> >::const_iterator GI = Names.begin(),
- GE = Names.end();
+ Unit *TheCU = *I;
+ const StringMap<std::vector<const DIE *> > &Names = TheCU->getAccelNames();
+ for (StringMap<std::vector<const DIE *> >::const_iterator
+ GI = Names.begin(),
+ GE = Names.end();
GI != GE; ++GI) {
StringRef Name = GI->getKey();
- const std::vector<DIE *> &Entities = GI->second;
- for (std::vector<DIE *>::const_iterator DI = Entities.begin(),
- DE = Entities.end();
+ const std::vector<const DIE *> &Entities = GI->second;
+ for (std::vector<const DIE *>::const_iterator DI = Entities.begin(),
+ DE = Entities.end();
DI != DE; ++DI)
- AT.AddName(Name, (*DI));
+ AT.AddName(Name, *DI);
}
}
void DwarfDebug::emitAccelObjC() {
DwarfAccelTable AT(
DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
I != E; ++I) {
- CompileUnit *TheCU = I->second;
- const StringMap<std::vector<DIE *> > &Names = TheCU->getAccelObjC();
- for (StringMap<std::vector<DIE *> >::const_iterator GI = Names.begin(),
- GE = Names.end();
+ Unit *TheCU = *I;
+ const StringMap<std::vector<const DIE *> > &Names = TheCU->getAccelObjC();
+ for (StringMap<std::vector<const DIE *> >::const_iterator
+ GI = Names.begin(),
+ GE = Names.end();
GI != GE; ++GI) {
StringRef Name = GI->getKey();
- const std::vector<DIE *> &Entities = GI->second;
- for (std::vector<DIE *>::const_iterator DI = Entities.begin(),
- DE = Entities.end();
+ const std::vector<const DIE *> &Entities = GI->second;
+ for (std::vector<const DIE *>::const_iterator DI = Entities.begin(),
+ DE = Entities.end();
DI != DE; ++DI)
- AT.AddName(Name, (*DI));
+ AT.AddName(Name, *DI);
}
}
void DwarfDebug::emitAccelNamespaces() {
DwarfAccelTable AT(
DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
I != E; ++I) {
- CompileUnit *TheCU = I->second;
- const StringMap<std::vector<DIE *> > &Names = TheCU->getAccelNamespace();
- for (StringMap<std::vector<DIE *> >::const_iterator GI = Names.begin(),
- GE = Names.end();
+ Unit *TheCU = *I;
+ const StringMap<std::vector<const DIE *> > &Names =
+ TheCU->getAccelNamespace();
+ for (StringMap<std::vector<const DIE *> >::const_iterator
+ GI = Names.begin(),
+ GE = Names.end();
GI != GE; ++GI) {
StringRef Name = GI->getKey();
- const std::vector<DIE *> &Entities = GI->second;
- for (std::vector<DIE *>::const_iterator DI = Entities.begin(),
- DE = Entities.end();
+ const std::vector<const DIE *> &Entities = GI->second;
+ for (std::vector<const DIE *>::const_iterator DI = Entities.begin(),
+ DE = Entities.end();
DI != DE; ++DI)
- AT.AddName(Name, (*DI));
+ AT.AddName(Name, *DI);
}
}
Atoms.push_back(
DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1));
DwarfAccelTable AT(Atoms);
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
I != E; ++I) {
- CompileUnit *TheCU = I->second;
- const StringMap<std::vector<std::pair<DIE *, unsigned> > > &Names =
+ Unit *TheCU = *I;
+ const StringMap<std::vector<std::pair<const DIE *, unsigned> > > &Names =
TheCU->getAccelTypes();
- for (StringMap<std::vector<std::pair<DIE *, unsigned> > >::const_iterator
+ for (StringMap<
+ std::vector<std::pair<const DIE *, unsigned> > >::const_iterator
GI = Names.begin(),
GE = Names.end();
GI != GE; ++GI) {
StringRef Name = GI->getKey();
- const std::vector<std::pair<DIE *, unsigned> > &Entities = GI->second;
- for (std::vector<std::pair<DIE *, unsigned> >::const_iterator
+ const std::vector<std::pair<const DIE *, unsigned> > &Entities =
+ GI->second;
+ for (std::vector<std::pair<const DIE *, unsigned> >::const_iterator
DI = Entities.begin(),
DE = Entities.end();
DI != DE; ++DI)
- AT.AddName(Name, (*DI).first, (*DI).second);
+ AT.AddName(Name, DI->first, DI->second);
}
}
// reference in the pubname header doesn't change.
/// computeIndexValue - Compute the gdb index value for the DIE and CU.
-static dwarf::PubIndexEntryDescriptor computeIndexValue(CompileUnit *CU,
- DIE *Die) {
+static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU,
+ const DIE *Die) {
dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC;
// We could have a specification DIE that has our most of our knowledge,
GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
: Asm->getObjFileLowering().getDwarfPubNamesSection();
- typedef DenseMap<const MDNode *, CompileUnit *> CUMapType;
- for (CUMapType::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) {
- CompileUnit *TheCU = I->second;
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
+ I != E; ++I) {
+ Unit *TheCU = *I;
unsigned ID = TheCU->getUniqueID();
// Start the dwarf pubnames section.
4);
// Emit the pubnames for this compilation unit.
- const StringMap<DIE *> &Globals = TheCU->getGlobalNames();
- for (StringMap<DIE *>::const_iterator GI = Globals.begin(),
- GE = Globals.end();
+ const StringMap<const DIE *> &Globals = TheCU->getGlobalNames();
+ for (StringMap<const DIE *>::const_iterator GI = Globals.begin(),
+ GE = Globals.end();
GI != GE; ++GI) {
const char *Name = GI->getKeyData();
- DIE *Entity = GI->second;
+ const DIE *Entity = GI->second;
Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
: Asm->getObjFileLowering().getDwarfPubTypesSection();
- for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+ E = getUnits().end();
I != E; ++I) {
- CompileUnit *TheCU = I->second;
+ Unit *TheCU = *I;
// Start the dwarf pubtypes section.
Asm->OutStreamer.SwitchSection(PSec);
Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), 4);
// Emit the pubtypes.
- const StringMap<DIE *> &Globals = TheCU->getGlobalTypes();
- for (StringMap<DIE *>::const_iterator GI = Globals.begin(),
- GE = Globals.end();
+ const StringMap<const DIE *> &Globals = TheCU->getGlobalTypes();
+ for (StringMap<const DIE *>::const_iterator GI = Globals.begin(),
+ GE = Globals.end();
GI != GE; ++GI) {
const char *Name = GI->getKeyData();
- DIE *Entity = GI->second;
+ const DIE *Entity = GI->second;
if (Asm->isVerbose())
Asm->OutStreamer.AddComment("DIE offset");
}
}
-// Emit strings into a string section.
+
+// Emit addresses into the section given.
void DwarfUnits::emitAddresses(const MCSection *AddrSection) {
if (AddressPool.empty())
}
};
-static bool CUSort(const CompileUnit *A, const CompileUnit *B) {
+static bool CUSort(const Unit *A, const Unit *B) {
return (A->getUniqueID() < B->getUniqueID());
}
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection());
unsigned char Size = Asm->getDataLayout().getPointerSize();
- for (SmallVectorImpl<const MCSymbol *>::iterator
- I = DebugRangeSymbols.begin(),
- E = DebugRangeSymbols.end();
- I != E; ++I) {
- if (*I)
- Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol *>(*I), Size);
+ for (uint32_t i = 0, e = DebugRangeSymbols.size(); i < e; ++i) {
+ // Only emit a symbol for every range pair for now.
+ // FIXME: Make this per range list.
+ if ((i % 2) == 0)
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_ranges", i));
+
+ const MCSymbol *I = DebugRangeSymbols[i];
+ if (I)
+ Asm->OutStreamer.EmitSymbolValue(I, Size);
else
Asm->OutStreamer.EmitIntValue(0, Size);
}
// Relocate to the beginning of the addr_base section, else 0 for the
// beginning of the one for this compile unit.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset,
- DwarfAddrSectionSym);
+ NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base,
+ DwarfAddrSectionSym);
else
- NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset,
- 0);
+ NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
// into an entity. We're using 0, or a NULL label for this.
// compile unit in debug_line section.
// FIXME: Should handle multiple compile units.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
- DwarfLineSectionSym);
+ NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list,
+ DwarfLineSectionSym);
else
- NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0);
+ NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
if (!CompilationDir.empty())
NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
// Flags to let the linker know we have emitted new style pubnames.
if (GenerateGnuPubSections) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset,
- Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_GNU_pubnames,
+ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
else
- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
- Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
- DwarfGnuPubNamesSectionSym);
+ NewCU->addSectionDelta(
+ Die, dwarf::DW_AT_GNU_pubnames,
+ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
+ DwarfGnuPubNamesSectionSym);
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset,
- Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
+ NewCU->addSectionLabel(
+ Die, dwarf::DW_AT_GNU_pubtypes,
+ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
else
- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
- Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
- DwarfGnuPubTypesSectionSym);
+ NewCU->addSectionDelta(
+ Die, dwarf::DW_AT_GNU_pubtypes,
+ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
+ DwarfGnuPubTypesSectionSym);
}
// Flag if we've emitted any ranges and their location for the compile unit.
if (DebugRangeSymbols.size()) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_GNU_ranges_base,
- dwarf::DW_FORM_sec_offset, DwarfDebugRangeSectionSym);
+ NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base,
+ DwarfDebugRangeSectionSym);
else
NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
0);
}
SkeletonHolder.addUnit(NewCU);
- SkeletonCUs.push_back(NewCU);
return NewCU;
}
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
OffSec, StrSym);
}
+
+void DwarfDebug::addTypeUnitType(uint16_t Language, DIE *RefDie,
+ DICompositeType CTy) {
+ DenseMap<const MDNode *,
+ std::pair<uint64_t, SmallVectorImpl<DIE *> *> >::iterator I =
+ TypeUnits.find(CTy);
+ SmallVector<DIE *, 8> References;
+ References.push_back(RefDie);
+ if (I != TypeUnits.end()) {
+ if (I->second.second) {
+ I->second.second->push_back(RefDie);
+ return;
+ }
+ } else {
+ DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
+ TypeUnit *NewTU = new TypeUnit(GlobalCUIndexCount++, UnitDie, Language, Asm,
+ this, &InfoHolder);
+ NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+ Language);
+
+ // Register the type in the TypeUnits map with a vector of references to be
+ // populated whenever a reference is required.
+ I = TypeUnits.insert(std::make_pair(CTy, std::make_pair(0, &References)))
+ .first;
+
+ // Construct the type, this may, recursively, require more type units that
+ // may in turn require this type again - in which case they will add DIEs to
+ // the References vector.
+ DIE *Die = NewTU->createTypeDIE(CTy);
+
+ if (GenerateODRHash && shouldAddODRHash(NewTU, Die))
+ NewTU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,
+ dwarf::DW_FORM_data8,
+ DIEHash().computeDIEODRSignature(*Die));
+ // FIXME: This won't handle circularly referential structures, as the DIE
+ // may have references to other DIEs still under construction and missing
+ // their signature. Hashing should walk through the signatures to their
+ // referenced type, or possibly walk the precomputed hashes of related types
+ // at the end.
+ uint64_t Signature = DIEHash().computeTypeSignature(*Die);
+
+ // Remove the References vector and add the type hash.
+ I->second.first = Signature;
+ I->second.second = NULL;
+
+ InfoHolder.addUnit(NewTU);
+ }
+
+ // Populate all the signatures.
+ for (unsigned i = 0, e = References.size(); i != e; ++i) {
+ CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature,
+ dwarf::DW_FORM_ref_sig8, I->second.first);
+ }
+}