U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
}
-// Create new DwarfCompileUnit for the given metadata node with tag
-// DW_TAG_compile_unit.
-DwarfCompileUnit &
-DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
- if (auto *CU = CUMap.lookup(DIUnit))
- return *CU;
- StringRef FN = DIUnit->getFilename();
- CompilationDir = DIUnit->getDirectory();
-
- auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
- InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
- DwarfCompileUnit &NewCU = *OwnedUnit;
+void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
+ DwarfCompileUnit &NewCU) {
DIE &Die = NewCU.getUnitDie();
- InfoHolder.addUnit(std::move(OwnedUnit));
- if (useSplitDwarf()) {
- NewCU.setSkeleton(constructSkeletonCU(NewCU));
- NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name,
- Asm->TM.Options.MCOptions.SplitDwarfFile);
- }
+ StringRef FN = DIUnit->getFilename();
for (auto *IE : DIUnit->getImportedEntities())
NewCU.addImportedEntity(IE);
dwarf::DW_FORM_data1, RVer);
}
- if (useSplitDwarf())
- NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
- else
- NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
-
if (DIUnit->getDWOId()) {
// This CU is either a clang module DWO or a skeleton CU.
NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name,
DIUnit->getSplitDebugFilename());
}
+}
+// Create new DwarfCompileUnit for the given metadata node with tag
+// DW_TAG_compile_unit.
+DwarfCompileUnit &
+DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
+ if (auto *CU = CUMap.lookup(DIUnit))
+ return *CU;
+
+ CompilationDir = DIUnit->getDirectory();
+
+ auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
+ InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
+ DwarfCompileUnit &NewCU = *OwnedUnit;
+ InfoHolder.addUnit(std::move(OwnedUnit));
+
+ if (useSplitDwarf()) {
+ NewCU.setSkeleton(constructSkeletonCU(NewCU));
+ NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
+ } else {
+ finishUnitAttributes(DIUnit, NewCU);
+ NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
+ }
CUMap.insert({DIUnit, &NewCU});
- CUDieMap.insert({&Die, &NewCU});
+ CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
return NewCU;
}
// If we're splitting the dwarf out now that we've got the entire
// CU then add the dwo id to it.
auto *SkCU = TheCU.getSkeleton();
- if (useSplitDwarf()) {
+ if (useSplitDwarf() && !empty(TheCU.getUnitDie().children())) {
+ finishUnitAttributes(TheCU.getCUNode(), TheCU);
+ TheCU.addString(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_name,
+ Asm->TM.Options.MCOptions.SplitDwarfFile);
+ SkCU->addString(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_name,
+ Asm->TM.Options.MCOptions.SplitDwarfFile);
// Emit a unique identifier for this CU.
uint64_t ID =
DIEHash(Asm).computeCUSignature(DWOName, TheCU.getUnitDie());
SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
Sym, Sym);
}
+ } else if (SkCU) {
+ finishUnitAttributes(SkCU->getCUNode(), *SkCU);
}
// If we have code split among multiple sections or non-contiguous
// We don't keep track of which addresses are used in which CU so this
// is a bit pessimistic under LTO.
- if (!AddrPool.isEmpty())
+ if (!AddrPool.isEmpty() &&
+ (getDwarfVersion() >= 5 ||
+ (SkCU && !empty(TheCU.getUnitDie().children()))))
U.addAddrTableBase();
if (unsigned NumRanges = TheCU.getRanges().size()) {
void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
std::unique_ptr<DwarfCompileUnit> NewU) {
- NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name,
- Asm->TM.Options.MCOptions.SplitDwarfFile);
if (!CompilationDir.empty())
NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
/// Create new DwarfCompileUnit for the given metadata node with tag
/// DW_TAG_compile_unit.
DwarfCompileUnit &getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit);
+ void finishUnitAttributes(const DICompileUnit *DIUnit,
+ DwarfCompileUnit &NewCU);
/// Construct imported_module or imported_declaration DIE.
void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
if (TheU->getCUNode()->isDebugDirectivesOnly())
return;
- DIE &Die = TheU->getUnitDie();
- MCSection *USection = TheU->getSection();
- Asm->OutStreamer->SwitchSection(USection);
+ MCSection *S = TheU->getSection();
- TheU->emitHeader(UseOffsets);
+ if (!S)
+ return;
- Asm->emitDwarfDIE(Die);
+ Asm->OutStreamer->SwitchSection(S);
+ TheU->emitHeader(UseOffsets);
+ Asm->emitDwarfDIE(TheU->getUnitDie());
}
// Compute the size and offset for each DIE.
; CHECK: Abbrev table for offset: 0x00000000
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no
; CHECK: DW_AT_stmt_list DW_FORM_sec_offset
-; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp
; CHECK: DW_AT_comp_dir DW_FORM_strp
+; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp
; CHECK: DW_AT_GNU_dwo_id DW_FORM_data8
; Check that we're using the right forms.
; CHECK: .debug_abbrev.dwo contents:
; CHECK: Abbrev table for offset: 0x00000000
; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_yes
-; CHECK: DW_AT_GNU_dwo_name DW_FORM_GNU_str_index
; CHECK: DW_AT_producer DW_FORM_GNU_str_index
; CHECK: DW_AT_language DW_FORM_data2
; CHECK: DW_AT_name DW_FORM_GNU_str_index
+; CHECK: DW_AT_GNU_dwo_name DW_FORM_GNU_str_index
; CHECK-NOT: DW_AT_low_pc
; CHECK-NOT: DW_AT_stmt_list
; CHECK-NOT: DW_AT_comp_dir
; CHECK: .debug_info contents:
; CHECK: DW_TAG_compile_unit
; CHECK-NEXT: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000)
-; CHECK-NEXT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000000] = "baz.dwo")
-; CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000008] = "/usr/local/google/home/echristo/tmp")
+; CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000000] = "/usr/local/google/home/echristo/tmp")
+; CHECK-NEXT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000024] = "baz.dwo")
; CHECK-NEXT: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324)
; Check that the rest of the compile units have information.
; CHECK: .debug_info.dwo contents:
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] ( indexed (00000000) string = "baz.dwo")
-; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000001) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)")
+; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000002) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)")
; CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
-; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000002) string = "baz.c")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "baz.c")
+; CHECK: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "baz.dwo")
; CHECK-NOT: DW_AT_low_pc
; CHECK-NOT: DW_AT_stmt_list
; CHECK-NOT: DW_AT_comp_dir
; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324)
; CHECK: DW_TAG_variable
-; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "a")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000000) string = "a")
; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[0-9a-f]*}} => {[[TYPE:0x[0-9a-f]*]]}
; CHECK: DW_AT_external [DW_FORM_flag_present] (true)
; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01)
; CHECK: DW_AT_decl_line [DW_FORM_data1] (1)
; CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x0)
; CHECK: [[TYPE]]: DW_TAG_base_type
-; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "int")
+; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000001) string = "int")
; CHECK: .debug_str contents:
-; CHECK: 0x00000000: "baz.dwo"
-; CHECK: 0x00000008: "/usr/local/google/home/echristo/tmp"
+; CHECK: 0x00000000: "/usr/local/google/home/echristo/tmp"
+; CHECK: 0x00000024: "baz.dwo"
; CHECK: .debug_str.dwo contents:
-; CHECK: 0x00000000: "baz.dwo"
-; CHECK: 0x00000008: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)"
-; CHECK: 0x0000003d: "baz.c"
-; CHECK: 0x00000043: "a"
-; CHECK: 0x00000045: "int"
+; CHECK: 0x00000000: "a"
+; CHECK: 0x00000002: "int"
+; CHECK: 0x00000006: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)"
+; CHECK: 0x0000003b: "baz.c"
+; CHECK: 0x00000041: "baz.dwo"
; CHECK: .debug_str_offsets.dwo contents:
; CHECK: 0x00000000: 00000000
-; CHECK: 0x00000004: 00000008
-; CHECK: 0x00000008: 0000003d
-; CHECK: 0x0000000c: 00000043
-; CHECK: 0x00000010: 00000045
+; CHECK: 0x00000004: 00000002
+; CHECK: 0x00000008: 00000006
+; CHECK: 0x0000000c: 0000003b
+; CHECK: 0x00000010: 00000041
; Object file checks
; For x86-64-linux we should have this set of relocations for the debug info section
; CHECK: .debug_info contents:
; CHECK: DW_TAG_compile_unit
; CHECK-NEXT: DW_AT_stmt_list
-; CHECK-NEXT: DW_AT_GNU_dwo_name
; CHECK-NEXT: DW_AT_comp_dir
+; CHECK-NEXT: DW_AT_GNU_dwo_name
; CHECK-NEXT: DW_AT_GNU_dwo_id
; CHECK-NEXT: DW_AT_GNU_ranges_base
; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000)
; CHECK: .debug_info contents:
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "X3")
+; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000000) string = "X3")
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000002) string = "X2")
+; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "X2")
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000003) string = "X1")
+; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000002) string = "X1")
; CHECK: .debug_info.dwo contents:
; CHECK: .debug_str contents:
; CHECK: .debug_str_offsets contents:
; CHECK: Format = DWARF32, Version = 5
-; CHECK-NEXT: 00000000 "foo.dwo"
; CHECK-NEXT: [[X3]] "X3"
; CHECK-NEXT: [[X2]] "X2"
; CHECK-NEXT: [[X1]] "X1"
+; CHECK-NEXT: "foo.dwo"
; CHECK-EMPTY:
; SPLIT: DW_TAG_compile_unit
; SPLIT-NOT: {{DW_TAG|contents:}}
; SPLIT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
-; SPLIT: DW_AT_GNU_dwo_name [DW_FORM_strx1] ( indexed (00000000) string = "foo.dwo")
-; SPLIT: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "/home/test")
+; SPLIT: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000000) string = "/home/test")
+; SPLIT: DW_AT_GNU_dwo_name [DW_FORM_strx1] ( indexed (00000001) string = "foo.dwo")
; Check for the split CU in .debug_info.dwo.
; SPLIT: .debug_info.dwo contents:
; SPLIT-NOT: contents:
; SPLIT: DW_TAG_enumerator
; SPLIT-NOT: {{DW_TAG|NULL}}
-; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000004) string = "a")
+; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000001) string = "a")
; SPLIT-NOT: contents:
; SPLIT: DW_TAG_enumerator
; SPLIT-NOT: {{DW_TAG|NULL}}
-; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000005) string = "b")
+; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000002) string = "b")
;
; Extract the string offsets referenced in the main file by the skeleton unit.
; SPLIT: .debug_str contents:
-; SPLIT-NEXT: 0x00000000: "foo.dwo"
-; SPLIT-NEXT: 0x[[STRING2SPLIT:[0-9a-f]*]]: "/home/test"
-; SPLIT-NEXT: 0x[[STRING3SPLIT:[0-9a-f]*]]: "E"
-; SPLIT-NEXT: 0x[[STRING4SPLIT:[0-9a-f]*]]: "glob"
+; SPLIT-NEXT: 0x[[STRHOMETESTSPLIT:[0-9a-f]*]]: "/home/test"
+; SPLIT-NEXT: 0x[[STRESPLIT:[0-9a-f]*]]: "E"
+; SPLIT-NEXT: 0x[[STRGLOBSPLIT:[0-9a-f]*]]: "glob"
+; SPLIT-NEXT: 0x[[STRFOODWOSPLIT:[0-9a-f]*]]: "foo.dwo"
;
; Extract the string offsets referenced in the .dwo file by the split unit.
; SPLIT: .debug_str.dwo contents:
; referenced by the debug info.
; SPLIT: .debug_str_offsets contents:
; SPLIT-NEXT: 0x00000000: Contribution size = 12, Format = DWARF32, Version = 5
-; SPLIT-NEXT: 0x00000008: 00000000 "foo.dwo"
-; SPLIT-NEXT: 0x0000000c: [[STRING2SPLIT]] "/home/test"
+; SPLIT-NEXT: 0x00000008: [[STRHOMETESTSPLIT]] "/home/test"
+; SPLIT-NEXT: 0x0000000c: [[STRFOODWOSPLIT]] "foo.dwo"
; SPLIT-EMPTY:
; SPLIT: .debug_str_offsets.dwo contents: