From acd91c534d994f8fffd5af0a958ecca8ab3747a9 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Fri, 27 Jul 2012 22:00:05 +0000 Subject: [PATCH] Add a DW_AT_high_pc for CUs that are a single address range. Update all tests accordingly. Fixes PR13351. Patch by shinichiro hamaji! llvm-svn: 160899 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 27 ++++++++++++++----- lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 +++ test/DebugInfo/X86/DW_AT_specification.ll | 4 +-- test/DebugInfo/X86/DW_TAG_friend.ll | 8 +++--- test/DebugInfo/X86/block-capture.ll | 8 +++--- test/DebugInfo/X86/concrete_out_of_line.ll | 6 ++--- test/DebugInfo/X86/enum-class.ll | 4 +-- .../X86/{low-pc-cu.ll => low-high-pc-cu.ll} | 3 ++- test/DebugInfo/X86/non-text-cu.ll | 23 ++++++++++++++++ test/DebugInfo/X86/objc-fwd-decl.ll | 6 ++--- test/DebugInfo/X86/pr11300.ll | 4 +-- test/DebugInfo/X86/stringpool.ll | 4 +-- 12 files changed, 71 insertions(+), 29 deletions(-) rename test/DebugInfo/X86/{low-pc-cu.ll => low-high-pc-cu.ll} (94%) create mode 100644 test/DebugInfo/X86/non-text-cu.ll diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 649684adbf0..1a8db3cf19d 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -127,7 +127,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), SourceIdMap(DIEValueAllocator), StringPool(DIEValueAllocator), - PrevLabel(NULL) { + PrevLabel(NULL), + HasNonTextSection(false) { NextStringPoolNumber = 0; DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; @@ -561,9 +562,6 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, 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. - 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. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) @@ -787,12 +785,25 @@ void DwarfDebug::endModule() { FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined); } - // Emit DW_AT_containing_type attribute to connect types with their - // vtable holding type. for (DenseMap::iterator CUI = CUMap.begin(), CUE = CUMap.end(); CUI != CUE; ++CUI) { + // Emit DW_AT_containing_type attribute to connect types with their + // vtable holding type. CompileUnit *TheCU = CUI->second; TheCU->constructContainingTypeDIEs(); + + // Emit low_pc and high_pc for CU. + DIE *Die = TheCU->getCUDie(); + if (HasNonTextSection) { + // 2.17.1 requires that we use DW_AT_low_pc for a single entry point + // into an entity. + TheCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); + } else { + TheCU->addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + Asm->GetTempSymbol("text_begin")); + TheCU->addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + Asm->GetTempSymbol("text_end")); + } } // Standard sections final addresses. @@ -852,6 +863,7 @@ void DwarfDebug::endModule() { E = CUMap.end(); I != E; ++I) delete I->second; FirstCU = NULL; // Reset for the next Module, if any. + HasNonTextSection = false; } /// findAbstractVariable - Find abstract variable, if any, associated with Var. @@ -1220,6 +1232,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { if (LScopes.empty()) return; identifyScopeMarkers(); + if (!Asm->getCurrentSection()->getKind().isText()) + HasNonTextSection = true; + FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); // Assumes in correct section after the entry point. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index d1d65126550..5b8f61c52ef 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -307,6 +307,9 @@ class DwarfDebug { // table for the same directory as DW_at_comp_dir. StringRef CompilationDir; + // True if the current module has non text section. + bool HasNonTextSection; + private: /// assignAbbrevNumber - Define a unique number for the abbreviation. diff --git a/test/DebugInfo/X86/DW_AT_specification.ll b/test/DebugInfo/X86/DW_AT_specification.ll index 078b740a417..5df4f2a5c74 100644 --- a/test/DebugInfo/X86/DW_AT_specification.ll +++ b/test/DebugInfo/X86/DW_AT_specification.ll @@ -3,8 +3,8 @@ ; test that the DW_AT_specification is a back edge in the file. -; CHECK: 0x0000003a: DW_TAG_subprogram [5] * -; CHECK: 0x00000060: DW_AT_specification [DW_FORM_ref4] (cu + 0x003a => {0x0000003a}) +; CHECK: 0x00000042: DW_TAG_subprogram [5] * +; CHECK: 0x00000068: DW_AT_specification [DW_FORM_ref4] (cu + 0x0042 => {0x00000042}) @_ZZN3foo3barEvE1x = constant i32 0, align 4 diff --git a/test/DebugInfo/X86/DW_TAG_friend.ll b/test/DebugInfo/X86/DW_TAG_friend.ll index a0dcec32e69..c35dcd294fe 100644 --- a/test/DebugInfo/X86/DW_TAG_friend.ll +++ b/test/DebugInfo/X86/DW_TAG_friend.ll @@ -3,10 +3,10 @@ ; Check that the friend tag is there and is followed by a DW_AT_friend that has a reference back. -; CHECK: 0x00000032: DW_TAG_class_type [4] -; CHECK: 0x00000077: DW_TAG_class_type [4] -; CHECK: 0x000000a0: DW_TAG_friend [9] -; CHECK: 0x000000a1: DW_AT_friend [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) +; CHECK: 0x0000003a: DW_TAG_class_type [4] +; CHECK: 0x0000007f: DW_TAG_class_type [4] +; CHECK: 0x000000a8: DW_TAG_friend [9] +; CHECK: 0x000000a9: DW_AT_friend [DW_FORM_ref4] (cu + 0x003a => {0x0000003a}) %class.A = type { i32 } diff --git a/test/DebugInfo/X86/block-capture.ll b/test/DebugInfo/X86/block-capture.ll index 4953c421cd3..432afe064f1 100644 --- a/test/DebugInfo/X86/block-capture.ll +++ b/test/DebugInfo/X86/block-capture.ll @@ -2,10 +2,10 @@ ; RUN: llvm-dwarfdump %t | FileCheck %s ; Checks that we emit debug info for the block variable declare. -; CHECK: 0x00000030: DW_TAG_subprogram [3] -; CHECK: 0x0000005b: DW_TAG_variable [5] -; CHECK: 0x0000005c: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000e6] = "block") -; CHECK: 0x00000066: DW_AT_location [DW_FORM_data4] (0x00000023) +; CHECK: 0x00000038: DW_TAG_subprogram [3] +; CHECK: 0x00000063: DW_TAG_variable [5] +; CHECK: 0x00000064: DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000e6] = "block") +; CHECK: 0x0000006e: DW_AT_location [DW_FORM_data4] (0x00000023) %struct.__block_descriptor = type { i64, i64 } %struct.__block_literal_generic = type { i8*, i32, i32, i8*, %struct.__block_descriptor* } diff --git a/test/DebugInfo/X86/concrete_out_of_line.ll b/test/DebugInfo/X86/concrete_out_of_line.ll index a22707189b0..36a6653bd13 100644 --- a/test/DebugInfo/X86/concrete_out_of_line.ll +++ b/test/DebugInfo/X86/concrete_out_of_line.ll @@ -7,7 +7,7 @@ ; first check that we have a TAG_subprogram at a given offset and it has ; AT_inline. -; CHECK: 0x00000134: DW_TAG_subprogram [18] +; CHECK: 0x0000013c: DW_TAG_subprogram [18] ; CHECK-NEXT: DW_AT_MIPS_linkage_name ; CHECK-NEXT: DW_AT_specification ; CHECK-NEXT: DW_AT_inline @@ -15,8 +15,8 @@ ; and then that a TAG_subprogram refers to it with AT_abstract_origin. -; CHECK: 0x00000184: DW_TAG_subprogram [20] -; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x0134 => {0x00000134}) +; CHECK: 0x0000018c: DW_TAG_subprogram [20] +; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x013c => {0x0000013c}) define i32 @_ZN17nsAutoRefCnt7ReleaseEv() { entry: diff --git a/test/DebugInfo/X86/enum-class.ll b/test/DebugInfo/X86/enum-class.ll index 6eb715d8287..aa0b2d08803 100644 --- a/test/DebugInfo/X86/enum-class.ll +++ b/test/DebugInfo/X86/enum-class.ll @@ -31,12 +31,12 @@ !21 = metadata !{i32 786484, i32 0, null, metadata !"c", metadata !"c", metadata !"", metadata !4, i32 6, metadata !12, i32 0, i32 1, i32* @c} ; [ DW_TAG_variable ] ; CHECK: DW_TAG_enumeration_type [3] -; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0026 => {0x00000026}) +; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x002e => {0x0000002e}) ; CHECK: DW_AT_enum_class [DW_FORM_flag] (0x01) ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "A") ; CHECK: DW_TAG_enumeration_type [3] * -; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x0057 => {0x00000057}) +; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x005f => {0x0000005f}) ; CHECK: DW_AT_enum_class [DW_FORM_flag] (0x01) ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "B") diff --git a/test/DebugInfo/X86/low-pc-cu.ll b/test/DebugInfo/X86/low-high-pc-cu.ll similarity index 94% rename from test/DebugInfo/X86/low-pc-cu.ll rename to test/DebugInfo/X86/low-high-pc-cu.ll index f9d9b917149..53fc46dcb87 100644 --- a/test/DebugInfo/X86/low-pc-cu.ll +++ b/test/DebugInfo/X86/low-high-pc-cu.ll @@ -1,10 +1,11 @@ ; RUN: llc -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj ; RUN: llvm-dwarfdump %t | FileCheck %s -; Check that we use DW_AT_low_pc +; Check that we use DW_AT_low_pc and DW_AT_high_pc ; CHECK: DW_TAG_compile_unit [1] ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; CHECK: DW_AT_high_pc [DW_FORM_addr] (0x0000000000000001) ; CHECK: DW_TAG_subprogram [2] define i32 @_Z1qv() nounwind uwtable readnone ssp { diff --git a/test/DebugInfo/X86/non-text-cu.ll b/test/DebugInfo/X86/non-text-cu.ll new file mode 100644 index 00000000000..858812bb485 --- /dev/null +++ b/test/DebugInfo/X86/non-text-cu.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple=x86_64-redhat-linux-gnu %s -o %t -filetype=obj +; RUN: llvm-dwarfdump %t | FileCheck %s + +; Check that we only use DW_AT_low_pc for CU which has non text sections + +; CHECK: DW_TAG_compile_unit [1] +; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; CHECK-NOT: DW_AT_high_pc [DW_FORM_addr] +; CHECK: DW_TAG_subprogram [2] + +define void @in_data() nounwind section ".data" { + ret void, !dbg !5 +} + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"in_data", metadata !"in_data", metadata !"", metadata !1, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, void ()* @in_data} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"in_data.c", metadata !"/home/i/test", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"in_data.c", metadata !"/home/i/test", metadata !"clang version 2.9 (tags/RELEASE_29/final)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 1, i32 51, metadata !6, null} +!6 = metadata !{i32 589835, metadata !0, i32 1, i32 50, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/DebugInfo/X86/objc-fwd-decl.ll b/test/DebugInfo/X86/objc-fwd-decl.ll index 1a815f936c1..f40770c7e1b 100644 --- a/test/DebugInfo/X86/objc-fwd-decl.ll +++ b/test/DebugInfo/X86/objc-fwd-decl.ll @@ -1,9 +1,9 @@ ; RUN: llc -mtriple=x86_64-macosx %s -o %t -filetype=obj ; RUN: llvm-dwarfdump %t | FileCheck %s -; CHECK: 0x00000027: DW_TAG_structure_type -; CHECK: 0x0000002c: DW_AT_declaration -; CHECK: 0x0000002d: DW_AT_APPLE_runtime_class +; CHECK: 0x0000002f: DW_TAG_structure_type +; CHECK: 0x00000034: DW_AT_declaration +; CHECK: 0x00000035: DW_AT_APPLE_runtime_class %0 = type opaque diff --git a/test/DebugInfo/X86/pr11300.ll b/test/DebugInfo/X86/pr11300.ll index 5a001eea75a..f3998c5439e 100644 --- a/test/DebugInfo/X86/pr11300.ll +++ b/test/DebugInfo/X86/pr11300.ll @@ -3,8 +3,8 @@ ; test that the DW_AT_specification is a back edge in the file. -; CHECK: 0x0000005c: DW_TAG_subprogram [5] -; CHECK: 0x0000007c: DW_AT_specification [DW_FORM_ref4] (cu + 0x005c => {0x0000005c}) +; CHECK: 0x00000064: DW_TAG_subprogram [5] +; CHECK: 0x00000084: DW_AT_specification [DW_FORM_ref4] (cu + 0x0064 => {0x00000064}) %struct.foo = type { i8 } diff --git a/test/DebugInfo/X86/stringpool.ll b/test/DebugInfo/X86/stringpool.ll index 2cd100156aa..af475402d36 100644 --- a/test/DebugInfo/X86/stringpool.ll +++ b/test/DebugInfo/X86/stringpool.ll @@ -16,7 +16,7 @@ ; Verify that we refer to 'yyyy' with a relocation. ; LINUX: .long .Lstring3 # DW_AT_name -; LINUX-NEXT: .long 39 # DW_AT_type +; LINUX-NEXT: .long 47 # DW_AT_type ; LINUX-NEXT: .byte 1 # DW_AT_external ; LINUX-NEXT: .byte 1 # DW_AT_decl_file ; LINUX-NEXT: .byte 1 # DW_AT_decl_line @@ -27,7 +27,7 @@ ; Verify that we refer to 'yyyy' without a relocation. ; DARWIN: Lset5 = Lstring3-Lsection_str ## DW_AT_name ; DARWIN-NEXT: .long Lset5 -; DARWIN-NEXT: .long 39 ## DW_AT_type +; DARWIN-NEXT: .long 47 ## DW_AT_type ; DARWIN-NEXT: .byte 1 ## DW_AT_external ; DARWIN-NEXT: .byte 1 ## DW_AT_decl_file ; DARWIN-NEXT: .byte 1 ## DW_AT_decl_line