aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp43
1 files changed, 41 insertions, 2 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f491d01876..722dd32d7e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -821,6 +821,7 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
InfoHolder.addUnit(NewCU);
CUMap.insert(std::make_pair(N, NewCU));
+ CUDieMap.insert(std::make_pair(Die, NewCU));
return NewCU;
}
@@ -1915,7 +1916,8 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
// Emit Methods
//===----------------------------------------------------------------------===//
-// Compute the size and offset of a DIE.
+// Compute the size and offset of a DIE. The offset is relative to start of the
+// CU. It returns the offset after laying out the DIE.
unsigned
DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) {
// Get the children.
@@ -1960,16 +1962,26 @@ DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) {
// Compute the size and offset for each DIE.
void DwarfUnits::computeSizeAndOffsets() {
+ // Offset from the first CU in the debug info section is 0 initially.
+ unsigned SecOffset = 0;
+
// 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(); I != E; ++I) {
+ (*I)->setDebugInfoOffset(SecOffset);
+
+ // CU-relative offset is reset to 0 here.
unsigned Offset =
sizeof(int32_t) + // Length of Compilation Unit Info
sizeof(int16_t) + // DWARF version number
sizeof(int32_t) + // Offset Into Abbrev. Section
sizeof(int8_t); // Pointer Size (in bytes)
- computeSizeAndOffset((*I)->getCUDie(), Offset);
+
+ // EndOffset here is CU-relative, after laying out
+ // all of the CU DIE.
+ unsigned EndOffset = computeSizeAndOffset((*I)->getCUDie(), Offset);
+ SecOffset += EndOffset;
}
}
@@ -2049,6 +2061,33 @@ void DwarfDebug::emitDIE(DIE *Die, std::vector<DIEAbbrev *> *Abbrevs) {
Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
switch (Attr) {
+ case dwarf::DW_AT_abstract_origin:
+ case dwarf::DW_AT_type:
+ case dwarf::DW_AT_friend:
+ case dwarf::DW_AT_specification:
+ case dwarf::DW_AT_import:
+ case dwarf::DW_AT_containing_type: {
+ DIEEntry *E = cast<DIEEntry>(Values[i]);
+ DIE *Origin = E->getEntry();
+ unsigned Addr = Origin->getOffset();
+ if (Form == dwarf::DW_FORM_ref_addr) {
+ assert(!useSplitDwarf() && "TODO: dwo files can't have relocations.");
+ // 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());
+ assert(CU && "CUDie should belong to a CU.");
+ Addr += CU->getDebugInfoOffset();
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ Asm->EmitLabelPlusOffset(DwarfInfoSectionSym, Addr,
+ DIEEntry::getRefAddrSize(Asm));
+ else
+ Asm->OutStreamer.EmitIntValue(Addr, DIEEntry::getRefAddrSize(Asm));
+ } else {
+ Asm->EmitInt32(Addr);
+ }
+ break;
+ }
case dwarf::DW_AT_ranges: {
// DW_AT_range Value encodes offset in debug_range section.
DIEInteger *V = cast<DIEInteger>(Values[i]);