diff options
author | Pavel Labath <pavel@labath.sk> | 2019-05-24 08:11:12 +0000 |
---|---|---|
committer | Pavel Labath <pavel@labath.sk> | 2019-05-24 08:11:12 +0000 |
commit | f750842c8b35c56b58402c1842869a885bfcff56 (patch) | |
tree | 29fa54e798c5f45c1b4cb364f5e766407c52c52e /lldb/lit/SymbolFile | |
parent | 8ac0bc9832a251837681b3a1cd53085ed8d594dc (diff) | |
download | bcm5719-llvm-f750842c8b35c56b58402c1842869a885bfcff56.tar.gz bcm5719-llvm-f750842c8b35c56b58402c1842869a885bfcff56.zip |
DWARF: Implement DW_AT_signature lookup for type unit support
Summary:
This patch implements the main feature of type units. When completing a
type, if we encounter a DW_AT_signature attribute, we use it's value to
lookup the complete definition of the type in the relevant type unit.
To enable this lookup, we build up a map of all type units in a symbol
file when parsing the units. Then we consult this map when resolving the
DW_AT_signature attribute.
I include add a couple of tests which exercise the type lookup feature,
including one that ensure we do something reasonable in case we fail to
lookup the type.
A lot of the ideas in this patch have been taken from D32167 and D61505.
Reviewers: clayborg, JDevlieghere, aprantl, alexshap
Subscribers: mgrang, lldb-commits
Differential Revision: https://reviews.llvm.org/D62246
llvm-svn: 361603
Diffstat (limited to 'lldb/lit/SymbolFile')
6 files changed, 178 insertions, 4 deletions
diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp b/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp index e28515269b4..defa8ba5c69 100644 --- a/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp +++ b/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp @@ -1,13 +1,15 @@ +enum E { e1, e2, e3 }; +enum class EC { e1, e2, e3 }; + struct A { int i; long l; float f; double d; + E e; + EC ec; }; -enum E { e1, e2, e3 }; -enum class EC { e1, e2, e3 }; - -extern constexpr A a{42, 47l, 4.2f, 4.7}; +extern constexpr A a{42, 47l, 4.2f, 4.7, e1, EC::e3}; extern constexpr E e(e2); extern constexpr EC ec(EC::e2); diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp b/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp index 7bdd79d0973..fe728cf040d 100644 --- a/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp +++ b/lldb/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp @@ -11,11 +11,19 @@ struct B: public A { namespace ns { struct A { int i = 147; + ::A getA(); A(); }; A::A() = default; + +::A A::getA() { + ::A a; + a.i = i - 1; + return a; } +} // namespace ns + int foo(A *a) { return a->f(); } diff --git a/lldb/lit/SymbolFile/DWARF/debug-types-basic.test b/lldb/lit/SymbolFile/DWARF/debug-types-basic.test index 468a4e8567c..bf2c9c69d1d 100644 --- a/lldb/lit/SymbolFile/DWARF/debug-types-basic.test +++ b/lldb/lit/SymbolFile/DWARF/debug-types-basic.test @@ -19,6 +19,8 @@ type lookup A # CHECK-NEXT: long l; # CHECK-NEXT: float f; # CHECK-NEXT: double d; +# CHECK-NEXT: E e; +# CHECK-NEXT: EC ec; # CHECK-NEXT: } type lookup E @@ -44,3 +46,9 @@ print (E) 1 print (EC) 1 # CHECK-LABEL: print (EC) 1 # CHECK: (EC) $1 = e2 + +target variable a e ec +# CHECK-LABEL: target variable a e ec +# CHECK: (const A) a = (i = 42, l = 47, f = 4.{{[12].*}}, d = 4.{{[67].*}}, e = e1, ec = e3) +# CHECK: (const E) e = e2 +# CHECK: (const EC) ec = e2 diff --git a/lldb/lit/SymbolFile/DWARF/debug-types-expressions.test b/lldb/lit/SymbolFile/DWARF/debug-types-expressions.test index db67f8a3958..da40269461a 100644 --- a/lldb/lit/SymbolFile/DWARF/debug-types-expressions.test +++ b/lldb/lit/SymbolFile/DWARF/debug-types-expressions.test @@ -19,6 +19,13 @@ frame variable a # CHECK-LABEL: frame variable a # CHECK: (B *) a = +frame variable *a +# CHECK-LABEL: frame variable *a +# CHECK: (B) *a = { +# CHECK-NEXT: A = (i = 47) +# CHECK-NEXT: j = 42 +# CHECK-NEXT: } + print a->f() # CHECK-LABEL: print a->f() # CHECK: (int) $0 = 47 @@ -26,3 +33,11 @@ print a->f() print ns::A() # CHECK-LABEL: print ns::A() # CHECK: (ns::A) $1 = (i = 147) + +print ns::A().i + a->i +# CHECK-LABEL: print ns::A().i + a->i +# CHECK: (int) $2 = 194 + +print ns::A().getA() +# CHECK-LABEL: ns::A().getA() +# CHECK: (A) $3 = (i = 146) diff --git a/lldb/lit/SymbolFile/DWARF/debug-types-missing-signature.test b/lldb/lit/SymbolFile/DWARF/debug-types-missing-signature.test new file mode 100644 index 00000000000..ca5c759136b --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/debug-types-missing-signature.test @@ -0,0 +1,26 @@ +Create a dangling DW_AT_signature reference by stripping the debug_types +section, and make sure lldb does something reasonable. +RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \ +RUN: -g -gdwarf-4 -fdebug-types-section -c -o %t.o +RUN: llvm-objcopy --remove-section=.debug_types %t.o %t + + +RUN: %lldb %t -b -o "type lookup A" | FileCheck --check-prefix=LOOKUPA %s +LOOKUPA: no type was found matching 'A' + +RUN: %lldb %t -b -o "type lookup E" | FileCheck --check-prefix=LOOKUPE %s +LOOKUPE: no type was found matching 'E' + +RUN: %lldb %t -b -o "type lookup EC" | FileCheck --check-prefix=LOOKUPEC %s +LOOKUPEC: no type was found matching 'EC' + +RUN: %lldb %t -b -o "print (E) 1" 2>&1 | FileCheck --check-prefix=PRINTE %s +PRINTE: use of undeclared identifier 'E' + +RUN: %lldb %t -b -o "print (EC) 1" 2>&1 | FileCheck --check-prefix=PRINTEC %s +PRINTEC: use of undeclared identifier 'EC' + +RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s +VARS: (const (anonymous struct)) a = {} +VARS: (const (anonymous enum)) e = 1 +VARS: (const (anonymous enum)) ec = 1 diff --git a/lldb/lit/SymbolFile/DWARF/debug-types-signature-loop.s b/lldb/lit/SymbolFile/DWARF/debug-types-signature-loop.s new file mode 100644 index 00000000000..d0d0fd5705a --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/debug-types-signature-loop.s @@ -0,0 +1,115 @@ +# REQUIRES: lld + +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux -o %t.o %s +# RUN: ld.lld %t.o -o %t +# RUN: %lldb %t -o "target variable e" -b | FileCheck %s + +# CHECK: e = <could not resolve type> + + .type e,@object # @e + .section .rodata,"a",@progbits + .globl e + .p2align 2 +e: + .long 0 # 0x0 + .size e, 4 + +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "Hand-written DWARF" +.Linfo_string1: + .asciz "a.cpp" +.Linfo_string3: + .asciz "e" +.Linfo_string4: + .asciz "unsigned int" +.Linfo_string5: + .asciz "e1" +.Linfo_string6: + .asciz "E" + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 4 # DW_TAG_enumeration_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 5390450678491038984 # Type Signature + .long .LE-.Ltu_begin0 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x1d DW_TAG_type_unit + .short 4 # DW_AT_language +.LE: + .byte 8 # Abbrev [8] 0x23:0xd DW_TAG_enumeration_type + # DW_AT_declaration + .quad 5390450678491038984 # DW_AT_signature +.Lbase: + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 5 # Abbrev [5] 0xc:0x2c DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 4 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable + .long .Linfo_string3 # DW_AT_name + .long .LE_sig-.Lcu_begin0 # DW_AT_type + .byte 9 # DW_AT_location + .byte 3 + .quad e +.LE_sig: + .byte 8 # Abbrev [8] 0x2e:0x9 DW_TAG_enumeration_type + # DW_AT_declaration + .quad 5390450678491038984 # DW_AT_signature + .byte 0 # End Of Children Mark +.Ldebug_info_end1: |