Add a DW_AT_high_pc for CUs that are a single address range. Update
authorEric Christopher <echristo@apple.com>
Fri, 27 Jul 2012 22:00:05 +0000 (22:00 +0000)
committerEric Christopher <echristo@apple.com>
Fri, 27 Jul 2012 22:00:05 +0000 (22:00 +0000)
all tests accordingly.

Fixes PR13351.

Patch by shinichiro hamaji!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160899 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
test/DebugInfo/X86/DW_AT_specification.ll
test/DebugInfo/X86/DW_TAG_friend.ll
test/DebugInfo/X86/block-capture.ll
test/DebugInfo/X86/concrete_out_of_line.ll
test/DebugInfo/X86/enum-class.ll
test/DebugInfo/X86/low-high-pc-cu.ll [new file with mode: 0644]
test/DebugInfo/X86/low-pc-cu.ll [deleted file]
test/DebugInfo/X86/non-text-cu.ll [new file with mode: 0644]
test/DebugInfo/X86/objc-fwd-decl.ll
test/DebugInfo/X86/pr11300.ll
test/DebugInfo/X86/stringpool.ll

index 649684adbf04ca633a84d2999e2f6e778f2bde97..1a8db3cf19de63727b199408649731241324dde7 100644 (file)
@@ -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<const MDNode *, CompileUnit *>::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.
index d1d651265507d0296718491dfb24e75a02cb5431..5b8f61c52efdf88f17c198b448bc0b257377d035 100644 (file)
@@ -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.
index 078b740a417044b257771ce1906b09bf6921387c..5df4f2a5c74502f1844fa5966d9527941dce3637 100644 (file)
@@ -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
index a0dcec32e6915bf93c1a4b8d36d94b19e22da3f3..c35dcd294fe40c06a19a1c90ece5bb5d16253871 100644 (file)
@@ -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 }
index 4953c421cd32e895c98a545c54bdf55216919d77..432afe064f159c5b414410e6e4d36a182b0574a6 100644 (file)
@@ -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* }
index a22707189b086a02cbb83347ee452ffd570e6694..36a6653bd13e4cff646d33a58987a055e8e1adb9 100644 (file)
@@ -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:
index 6eb715d828727dec7ea3c0caf93eae9d8cbf2b68..aa0b2d088036a10529658341e6e89cde0807add6 100644 (file)
 !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-high-pc-cu.ll b/test/DebugInfo/X86/low-high-pc-cu.ll
new file mode 100644 (file)
index 0000000..53fc46d
--- /dev/null
@@ -0,0 +1,32 @@
+; 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 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 {
+entry:
+  ret i32 undef, !dbg !13
+}
+
+!llvm.dbg.cu = !{!0}
+
+!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", metadata !"clang version 3.1 (trunk 153454) (llvm/trunk 153471)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ]
+!1 = metadata !{metadata !2}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !5, metadata !12}
+!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"q", metadata !"q", metadata !"_Z1qv", metadata !6, i32 5, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1qv, null, null, metadata !10} ; [ DW_TAG_subprogram ]
+!6 = metadata !{i32 786473, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", null} ; [ DW_TAG_file_type ]
+!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
+!8 = metadata !{metadata !9}
+!9 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!10 = metadata !{metadata !11}
+!11 = metadata !{i32 786468}                      ; [ DW_TAG_base_type ]
+!12 = metadata !{i32 786478, i32 0, metadata !6, metadata !"t", metadata !"t", metadata !"", metadata !6, i32 2, metadata !7, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, null, null, null, metadata !10} ; [ DW_TAG_subprogram ]
+!13 = metadata !{i32 7, i32 1, metadata !14, null}
+!14 = metadata !{i32 786443, metadata !5, i32 5, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ]
diff --git a/test/DebugInfo/X86/low-pc-cu.ll b/test/DebugInfo/X86/low-pc-cu.ll
deleted file mode 100644 (file)
index f9d9b91..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-; 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: DW_TAG_compile_unit [1]
-; CHECK: DW_AT_low_pc [DW_FORM_addr]       (0x0000000000000000)
-; CHECK: DW_TAG_subprogram [2]
-
-define i32 @_Z1qv() nounwind uwtable readnone ssp {
-entry:
-  ret i32 undef, !dbg !13
-}
-
-!llvm.dbg.cu = !{!0}
-
-!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", metadata !"clang version 3.1 (trunk 153454) (llvm/trunk 153471)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{metadata !2}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !5, metadata !12}
-!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"q", metadata !"q", metadata !"_Z1qv", metadata !6, i32 5, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1qv, null, null, metadata !10} ; [ DW_TAG_subprogram ]
-!6 = metadata !{i32 786473, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", null} ; [ DW_TAG_file_type ]
-!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
-!8 = metadata !{metadata !9}
-!9 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
-!10 = metadata !{metadata !11}
-!11 = metadata !{i32 786468}                      ; [ DW_TAG_base_type ]
-!12 = metadata !{i32 786478, i32 0, metadata !6, metadata !"t", metadata !"t", metadata !"", metadata !6, i32 2, metadata !7, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, null, null, null, metadata !10} ; [ DW_TAG_subprogram ]
-!13 = metadata !{i32 7, i32 1, metadata !14, null}
-!14 = metadata !{i32 786443, metadata !5, i32 5, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ]
diff --git a/test/DebugInfo/X86/non-text-cu.ll b/test/DebugInfo/X86/non-text-cu.ll
new file mode 100644 (file)
index 0000000..858812b
--- /dev/null
@@ -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 ]
index 1a815f936c175fa07edada7c5f5c3a3f74ac230e..f40770c7e1be71a306825f9f06812391ae01a102 100644 (file)
@@ -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
 
index 5a001eea75a161a705393e9bb37f11e74e634210..f3998c5439eae68c6a17b7b43a9da8189d540dee 100644 (file)
@@ -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 }
 
index 2cd100156aada13acf0aff9b7b49190f0e95c71b..af475402d360c67503f067466dbdb0c384d65e09 100644 (file)
@@ -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