Newer
Older
const char *Name = GI->getKeyData();
Nick Lewycky
committed
DIE *Entity = GI->second;
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
}
Asm->OutStreamer.AddComment("End Mark");
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
TheCU->getID()));
/// emitDebugStr - Emit visible names into a debug str section.
void DwarfDebug::emitDebugStr() {
// Check to see if it is worth the effort.
if (StringPool.empty()) return;
// Start the dwarf str section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfStrSection());
// Get all of the string pool entries and put them in an array by their ID so
// we can sort them.
SmallVector<std::pair<unsigned,
StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
Entries.push_back(std::make_pair(I->second.second, &*I));
array_pod_sort(Entries.begin(), Entries.end());
for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
// Emit a label for reference from debug information entries.
Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
// Emit the string itself with a terminating null byte.
Benjamin Kramer
committed
Asm->OutStreamer.EmitBytes(StringRef(Entries[i].second->getKeyData(),
Entries[i].second->getKeyLength()+1),
0/*addrspace*/);
/// emitDebugLoc - Emit visible names into a debug loc section.
void DwarfDebug::emitDebugLoc() {
if (DotDebugLocEntries.empty())
return;
for (SmallVector<DotDebugLocEntry, 4>::iterator
I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end();
I != E; ++I) {
DotDebugLocEntry &Entry = *I;
if (I + 1 != DotDebugLocEntries.end())
Entry.Merge(I+1);
}
Daniel Dunbar
committed
// Start the dwarf loc section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfLocSection());
unsigned char Size = Asm->getDataLayout().getPointerSize();
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0));
unsigned index = 1;
for (SmallVector<DotDebugLocEntry, 4>::iterator
I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end();
DotDebugLocEntry &Entry = *I;
if (Entry.isMerged()) continue;
if (Entry.isEmpty()) {
Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
} else {
Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0);
Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0);
Devang Patel
committed
DIVariable DV(Entry.Variable);
Asm->OutStreamer.AddComment("Loc expr size");
MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();
MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
Asm->EmitLabelDifference(end, begin, 2);
Asm->OutStreamer.EmitLabel(begin);
if (Entry.isInt()) {
Devang Patel
committed
DIBasicType BTy(DV.getType());
if (BTy.Verify() &&
Devang Patel
committed
|| BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
Asm->OutStreamer.AddComment("DW_OP_consts");
Asm->EmitInt8(dwarf::DW_OP_consts);
Asm->EmitSLEB128(Entry.getInt());
Devang Patel
committed
} else {
Asm->OutStreamer.AddComment("DW_OP_constu");
Asm->EmitInt8(dwarf::DW_OP_constu);
Asm->EmitULEB128(Entry.getInt());
Devang Patel
committed
}
} else if (Entry.isLocation()) {
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
// Regular entry.
Asm->EmitDwarfRegOp(Entry.Loc);
else {
// Complex address entry.
unsigned N = DV.getNumAddrElements();
unsigned i = 0;
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
if (Entry.Loc.getOffset()) {
i = 2;
Asm->EmitDwarfRegOp(Entry.Loc);
Asm->OutStreamer.AddComment("DW_OP_deref");
Asm->EmitInt8(dwarf::DW_OP_deref);
Asm->OutStreamer.AddComment("DW_OP_plus_uconst");
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
Asm->EmitSLEB128(DV.getAddrElement(1));
} else {
// If first address element is OpPlus then emit
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
Asm->EmitDwarfRegOp(Loc);
i = 2;
}
Asm->EmitDwarfRegOp(Entry.Loc);
}
// Emit remaining complex address elements.
for (; i < N; ++i) {
uint64_t Element = DV.getAddrElement(i);
if (Element == DIBuilder::OpPlus) {
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
Asm->EmitULEB128(DV.getAddrElement(++i));
} else if (Element == DIBuilder::OpDeref) {
Asm->EmitInt8(dwarf::DW_OP_deref);
} else
llvm_unreachable("unknown Opcode found in complex address");
Devang Patel
committed
}
}
// else ... ignore constant fp. There is not any good way to
// to represent them here in dwarf.
Asm->OutStreamer.EmitLabel(end);
/// EmitDebugARanges - Emit visible names into a debug aranges section.
///
void DwarfDebug::EmitDebugARanges() {
// Start the dwarf aranges section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling
committed
}
/// emitDebugRanges - Emit visible names into a debug ranges section.
void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection());
unsigned char Size = Asm->getDataLayout().getPointerSize();
Devang Patel
committed
for (SmallVector<const MCSymbol *, 8>::iterator
I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
Devang Patel
committed
I != E; ++I) {
if (*I)
Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol*>(*I), Size, 0);
Devang Patel
committed
Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
void DwarfDebug::emitDebugMacInfo() {
Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
// Start the dwarf macinfo section.
Asm->OutStreamer.SwitchSection(LineInfo);
/// emitDebugInlineInfo - 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())
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(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
for (SmallVector<const MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
const MDNode *Node = *I;
DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
SmallVector<InlineInfoLabels, 4> &Labels = II->second;
StringRef LName = SP.getLinkageName();
StringRef Name = SP.getName();
Asm->OutStreamer.AddComment("MIPS linkage name");
if (LName.empty())
Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
else
Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
DwarfStrSectionSym);
Asm->OutStreamer.AddComment("Function name");
Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Asm->EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::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(),0);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));