DIUnit.getLanguage());
NewCU->addString(Die, dwarf::DW_AT_name, FN);
- // 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. For
- // split dwarf it's in the skeleton CU so omit it here.
- if (!useSplitDwarf())
- NewCU->addLabelAddress(Die, dwarf::DW_AT_low_pc, NULL);
-
// Define start line table label for each Compile Unit.
MCSymbol *LineTableStartSym =
Asm->GetTempSymbol("line_table_start", NewCU->getUniqueID());
NewCU->initSection(
useSplitDwarf() ? Asm->getObjFileLowering().getDwarfInfoDWOSection()
: Asm->getObjFileLowering().getDwarfInfoSection(),
- // FIXME: This is subtle (using the info section even when
- // this CU is in the dwo section) and necessary for the
- // current arange code - ideally it should iterate
- // skeleton units, not full units, if it's going to reference skeletons
- DwarfInfoSectionSym);
+ useSplitDwarf() ? DwarfInfoDWOSectionSym : DwarfInfoSectionSym);
+
+ // If we're splitting the dwarf then construct the skeleton CU now.
+ if (useSplitDwarf())
+ NewCU->setSkeleton(constructSkeletonCU(NewCU));
CUMap.insert(std::make_pair(DIUnit, NewCU));
CUDieMap.insert(std::make_pair(Die, NewCU));
// Add CU specific attributes if we need to add any.
if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
// If we're splitting the dwarf out now that we've got the entire
- // CU then construct a skeleton CU based upon it.
+ // CU then add the dwo id to it.
+ DwarfCompileUnit *SkCU =
+ static_cast<DwarfCompileUnit *>(TheU->getSkeleton());
if (useSplitDwarf()) {
// This should be a unique identifier when we want to build .dwp files.
uint64_t ID = 0;
}
TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
- // Now construct the skeleton CU associated.
- DwarfCompileUnit *SkCU =
- constructSkeletonCU(static_cast<DwarfCompileUnit *>(TheU));
SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
- } else {
- // Attribute if we've emitted a range list for the compile unit, this
- // will get constructed for the skeleton CU separately if we have one.
- if (DwarfCURanges && TheU->getRanges().size())
- addSectionLabel(Asm, TheU, TheU->getUnitDie(), dwarf::DW_AT_ranges,
- Asm->GetTempSymbol("cu_ranges", TheU->getUniqueID()),
- DwarfDebugRangeSectionSym);
}
+
+ // If we've requested ranges and have them emit a DW_AT_ranges attribute
+ // on the unit that will remain in the .o file, otherwise add a DW_AT_low_pc.
+ // FIXME: Also add a high pc if we can.
+ // FIXME: We should use ranges if we have multiple compile units.
+ DwarfCompileUnit *U = SkCU ? SkCU : static_cast<DwarfCompileUnit *>(TheU);
+ if (DwarfCURanges && TheU->getRanges().size())
+ addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("cu_ranges", U->getUniqueID()),
+ DwarfDebugRangeSectionSym);
+ else
+ U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
}
}
// Dwarf sections base addresses.
DwarfInfoSectionSym =
emitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
+ if (useSplitDwarf())
+ DwarfInfoDWOSectionSym =
+ emitSectionSym(Asm, TLOF.getDwarfInfoDWOSection(), "section_info_dwo");
DwarfAbbrevSectionSym =
emitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
if (useSplitDwarf())
Asm->OutStreamer.AddComment("DWARF Arange version number");
Asm->EmitInt16(dwarf::DW_ARANGES_VERSION);
Asm->OutStreamer.AddComment("Offset Into Debug Info Section");
- Asm->EmitSectionOffset(CU->getLabelBegin(), CU->getSectionSym());
+ Asm->EmitSectionOffset(CU->getLocalLabelBegin(), CU->getLocalSectionSym());
Asm->OutStreamer.AddComment("Address Size (in bytes)");
Asm->EmitInt8(PtrSize);
Asm->OutStreamer.AddComment("Segment Size (in bytes)");
else
NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
- // Attribute if we've emitted a range list for the compile unit, this
- // will get constructed for the skeleton CU separately if we have one.
- if (DwarfCURanges && CU->getRanges().size())
- addSectionLabel(Asm, NewCU, Die, dwarf::DW_AT_ranges,
- Asm->GetTempSymbol("cu_ranges", CU->getUniqueID()),
- DwarfDebugRangeSectionSym);
- else
- NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
-
// 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.
/// The label for the start of the range sets for the elements of this unit.
MCSymbol *LabelRange;
+ /// Skeleton unit associated with this unit.
+ DwarfUnit *Skeleton;
+
DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
public:
virtual ~DwarfUnit();
+ /// Set the skeleton unit associated with this unit.
+ void setSkeleton(DwarfUnit *Skel) { Skeleton = Skel; }
+
+ /// Get the skeleton unit associated with this unit.
+ DwarfUnit *getSkeleton() const { return Skeleton; }
+
/// Pass in the SectionSym even though we could recreate it in every compile
/// unit (type units will have actually distinct symbols once they're in
/// comdat sections).
return Section;
}
+ /// If there's a skeleton then return the section symbol for the skeleton
+ /// unit, otherwise return the section symbol for this unit.
+ MCSymbol *getLocalSectionSym() const {
+ if (Skeleton)
+ return Skeleton->getSectionSym();
+ return SectionSym;
+ }
+
MCSymbol *getSectionSym() const {
assert(Section);
return SectionSym;
}
+ /// If there's a skeleton then return the begin label for the skeleton unit,
+ /// otherwise return the local label for this unit.
+ MCSymbol *getLocalLabelBegin() const {
+ if (Skeleton)
+ return Skeleton->getLabelBegin();
+ return LabelBegin;
+ }
+
MCSymbol *getLabelBegin() const {
assert(Section);
return LabelBegin;
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no
; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp
; CHECK: DW_AT_GNU_addr_base DW_FORM_sec_offset
-; CHECK: DW_AT_low_pc DW_FORM_addr
; CHECK: DW_AT_stmt_list DW_FORM_sec_offset
; CHECK: DW_AT_comp_dir DW_FORM_strp
; CHECK: DW_AT_GNU_dwo_id DW_FORM_data8
+; CHECK: DW_AT_low_pc DW_FORM_addr
; CHECK: .debug_info contents:
; CHECK: DW_TAG_compile_unit
; CHECK: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000000] = "baz.dwo")
; CHECK: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000)
-; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000)
; CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000008] = "/usr/local/google/home/echristo/tmp")
; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x0000000000000000)
+; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: .debug_str contents:
; CHECK: 0x00000000: "baz.dwo"
; OBJ-NEXT: R_X86_64_32 .debug_line
; OBJ-NEXT: R_X86_64_32 .debug_str
; OBJ-NEXT: }
+; OBJ: .debug_aranges
+; OBJ-NEXT: R_X86_64_32 .debug_info 0x0
+
!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
; rdar://13067005
; CHECK: .debug_info contents:
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000)
+; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000003c)
+; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; CHECK: .debug_line contents:
; CHECK-NEXT: Line table prologue:
; DWARF3: .debug_info contents:
; DWARF3: DW_TAG_compile_unit
-; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x00000000)
+; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; DWARF3: DW_TAG_compile_unit
-; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x0000003c)
+; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
; DWARF3: .debug_line contents:
; DWARF3-NEXT: Line table prologue: