Add a DW_AT_high_pc for CUs that are a single address range. Update

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
This commit is contained in:
Eric Christopher 2012-07-27 22:00:05 +00:00
parent c16bf79303
commit c23b933d5f
12 changed files with 71 additions and 29 deletions

View 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.

View 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.

View 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

View 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 }

View 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* }

View 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:

View File

@ -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")

View File

@ -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 {

View File

@ -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 ]

View 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

View 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 }

View 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