forked from OSchip/llvm-project
Use a pointer to keep track of the skeleton unit for each normal unit
and construct it up front. Add address ranges at the end and a helper routine so that we're not needlessly using an indirction in the case of split dwarf. Update testcases according to the new ordering of attributes on the compile unit. llvm-svn: 198196
This commit is contained in:
parent
94b0f0278e
commit
83fff3fce7
|
@ -773,12 +773,6 @@ DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
|
||||||
DIUnit.getLanguage());
|
DIUnit.getLanguage());
|
||||||
NewCU->addString(Die, dwarf::DW_AT_name, FN);
|
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.
|
// Define start line table label for each Compile Unit.
|
||||||
MCSymbol *LineTableStartSym =
|
MCSymbol *LineTableStartSym =
|
||||||
Asm->GetTempSymbol("line_table_start", NewCU->getUniqueID());
|
Asm->GetTempSymbol("line_table_start", NewCU->getUniqueID());
|
||||||
|
@ -837,6 +831,10 @@ DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
|
||||||
// skeleton units, not full units, if it's going to reference skeletons
|
// skeleton units, not full units, if it's going to reference skeletons
|
||||||
DwarfInfoSectionSym);
|
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));
|
CUMap.insert(std::make_pair(DIUnit, NewCU));
|
||||||
CUDieMap.insert(std::make_pair(Die, NewCU));
|
CUDieMap.insert(std::make_pair(Die, NewCU));
|
||||||
return NewCU;
|
return NewCU;
|
||||||
|
@ -1082,7 +1080,9 @@ void DwarfDebug::finalizeModuleInfo() {
|
||||||
// Add CU specific attributes if we need to add any.
|
// Add CU specific attributes if we need to add any.
|
||||||
if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
|
if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
|
||||||
// If we're splitting the dwarf out now that we've got the entire
|
// 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()) {
|
if (useSplitDwarf()) {
|
||||||
// This should be a unique identifier when we want to build .dwp files.
|
// This should be a unique identifier when we want to build .dwp files.
|
||||||
uint64_t ID = 0;
|
uint64_t ID = 0;
|
||||||
|
@ -1092,19 +1092,22 @@ void DwarfDebug::finalizeModuleInfo() {
|
||||||
}
|
}
|
||||||
TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
|
TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
|
||||||
dwarf::DW_FORM_data8, 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,
|
SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
|
||||||
dwarf::DW_FORM_data8, 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->addLocalLabelAddress(U->getUnitDie(), dwarf::DW_AT_low_pc,
|
||||||
|
TextSectionSym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2997,15 +3000,6 @@ DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) {
|
||||||
else
|
else
|
||||||
NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
|
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
|
// DW_AT_stmt_list is a offset of line number information for this
|
||||||
// compile unit in debug_line section.
|
// compile unit in debug_line section.
|
||||||
// FIXME: Should handle multiple compile units.
|
// FIXME: Should handle multiple compile units.
|
||||||
|
|
|
@ -293,6 +293,23 @@ void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// addLocalLabelAddress - Add a dwarf label attribute data and value using
|
||||||
|
/// DW_FORM_addr.
|
||||||
|
void DwarfCompileUnit::addLocalLabelAddress(DIE *Die,
|
||||||
|
dwarf::Attribute Attribute,
|
||||||
|
MCSymbol *Label) {
|
||||||
|
if (Label)
|
||||||
|
DD->addArangeLabel(SymbolCU(this, Label));
|
||||||
|
|
||||||
|
if (Label != NULL) {
|
||||||
|
DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
|
||||||
|
Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
|
||||||
|
} else {
|
||||||
|
DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
|
||||||
|
Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// addOpAddress - Add a dwarf op address data and value using the
|
/// addOpAddress - Add a dwarf op address data and value using the
|
||||||
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||||
///
|
///
|
||||||
|
|
|
@ -146,12 +146,21 @@ protected:
|
||||||
/// The label for the start of the range sets for the elements of this unit.
|
/// The label for the start of the range sets for the elements of this unit.
|
||||||
MCSymbol *LabelRange;
|
MCSymbol *LabelRange;
|
||||||
|
|
||||||
|
/// Skeleton unit associated with this unit.
|
||||||
|
DwarfUnit *Skeleton;
|
||||||
|
|
||||||
DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
|
DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
|
||||||
DwarfDebug *DW, DwarfFile *DWU);
|
DwarfDebug *DW, DwarfFile *DWU);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~DwarfUnit();
|
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
|
/// 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
|
/// unit (type units will have actually distinct symbols once they're in
|
||||||
/// comdat sections).
|
/// comdat sections).
|
||||||
|
@ -521,6 +530,11 @@ public:
|
||||||
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||||
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
|
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
|
||||||
|
|
||||||
|
/// addLocalLabelAddress - Add a dwarf label attribute data and value using
|
||||||
|
/// DW_FORM_addr.
|
||||||
|
void addLocalLabelAddress(DIE *Die, dwarf::Attribute Attribute,
|
||||||
|
MCSymbol *Label);
|
||||||
|
|
||||||
uint16_t getLanguage() const LLVM_OVERRIDE { return getNode().getLanguage(); }
|
uint16_t getLanguage() const LLVM_OVERRIDE { return getNode().getLanguage(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,19 +25,19 @@
|
||||||
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no
|
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no
|
||||||
; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp
|
; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp
|
||||||
; CHECK: DW_AT_GNU_addr_base DW_FORM_sec_offset
|
; 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_stmt_list DW_FORM_sec_offset
|
||||||
; CHECK: DW_AT_comp_dir DW_FORM_strp
|
; CHECK: DW_AT_comp_dir DW_FORM_strp
|
||||||
; CHECK: DW_AT_GNU_dwo_id DW_FORM_data8
|
; CHECK: DW_AT_GNU_dwo_id DW_FORM_data8
|
||||||
|
; CHECK: DW_AT_low_pc DW_FORM_addr
|
||||||
|
|
||||||
; CHECK: .debug_info contents:
|
; CHECK: .debug_info contents:
|
||||||
; CHECK: DW_TAG_compile_unit
|
; CHECK: DW_TAG_compile_unit
|
||||||
; CHECK: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000000] = "baz.dwo")
|
; 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_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_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_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_GNU_dwo_id [DW_FORM_data8] (0x0000000000000000)
|
||||||
|
; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||||
|
|
||||||
; CHECK: .debug_str contents:
|
; CHECK: .debug_str contents:
|
||||||
; CHECK: 0x00000000: "baz.dwo"
|
; CHECK: 0x00000000: "baz.dwo"
|
||||||
|
@ -110,5 +110,6 @@
|
||||||
; OBJ-NEXT: R_X86_64_32 .debug_addr
|
; OBJ-NEXT: R_X86_64_32 .debug_addr
|
||||||
; OBJ-NEXT: R_X86_64_32 .debug_line
|
; OBJ-NEXT: R_X86_64_32 .debug_line
|
||||||
; OBJ-NEXT: R_X86_64_32 .debug_str
|
; OBJ-NEXT: R_X86_64_32 .debug_str
|
||||||
|
; OBJ-NEXT: R_X86_64_64 .text 0x0
|
||||||
; OBJ-NEXT: }
|
; OBJ-NEXT: }
|
||||||
!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
|
!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
; rdar://13067005
|
; rdar://13067005
|
||||||
; CHECK: .debug_info contents:
|
; CHECK: .debug_info contents:
|
||||||
; CHECK: DW_TAG_compile_unit
|
; 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_stmt_list [DW_FORM_sec_offset] (0x00000000)
|
||||||
|
; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||||
|
|
||||||
; CHECK: DW_TAG_compile_unit
|
; 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_stmt_list [DW_FORM_sec_offset] (0x0000003c)
|
||||||
|
; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||||
|
|
||||||
; CHECK: .debug_line contents:
|
; CHECK: .debug_line contents:
|
||||||
; CHECK-NEXT: Line table prologue:
|
; CHECK-NEXT: Line table prologue:
|
||||||
|
@ -25,12 +25,12 @@
|
||||||
|
|
||||||
; DWARF3: .debug_info contents:
|
; DWARF3: .debug_info contents:
|
||||||
; DWARF3: DW_TAG_compile_unit
|
; 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_stmt_list [DW_FORM_data4] (0x00000000)
|
||||||
|
; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||||
|
|
||||||
; DWARF3: DW_TAG_compile_unit
|
; 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_stmt_list [DW_FORM_data4] (0x0000003c)
|
||||||
|
; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||||
|
|
||||||
; DWARF3: .debug_line contents:
|
; DWARF3: .debug_line contents:
|
||||||
; DWARF3-NEXT: Line table prologue:
|
; DWARF3-NEXT: Line table prologue:
|
||||||
|
|
Loading…
Reference in New Issue