From: Simon Marchi Date: Tue, 2 Feb 2021 15:40:53 +0000 (-0500) Subject: gdb/testsuite: add test for .debug_{rng,loc}lists section without offset array X-Git-Tag: gdb-10.2-release~99 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2da8a05a924969b3d6e04dadee26095bff4fa048;p=thirdparty%2Fbinutils-gdb.git gdb/testsuite: add test for .debug_{rng,loc}lists section without offset array It is possible for the tables in the .debug_{rng,loc}lists sections to not have an array of offsets. In that case, the offset_entry_count field of the header is 0. The forms DW_FORM_{rng,loc}listx (reference by index) can't be used with that table. Instead, the DW_FORM_sec_offset form, which references a {rng,loc}list by direct offset in the section, must be used. From what I saw, this is what GCC currently produces. Add tests for this case. I didn't see any bug related to this, I just think that it would be nice to have coverage for this. A new `-with-offset-array` option is added to the `table` procs, used when generating {rng,loc}lists, to decide whether to generate the offset array. gdb/testsuite/ChangeLog: * lib/dwarf.exp (rnglists): Add -no-offset-array option to table proc. * gdb.dwarf2/rnglists-sec-offset.exp: Add test for .debug_rnglists table without offset array. * gdb.dwarf2/loclists-sec-offset.exp: Add test for .debug_loclists table without offset array. Change-Id: I8e34a7bf68c9682215ffbbf66600da5b7db91ef7 --- diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 637252f1a8e..032ff34b410 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2021-02-02 Simon Marchi + + * lib/dwarf.exp (rnglists): Add -no-offset-array option to + table proc. + * gdb.dwarf2/rnglists-sec-offset.exp: Add test for + .debug_rnglists table without offset array. + * gdb.dwarf2/loclists-sec-offset.exp: Add test for + .debug_loclists table without offset array. + 2021-02-02 Simon Marchi PR gdb/26813 diff --git a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c index 2bffbf2ac4c..af783151829 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c +++ b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c @@ -29,9 +29,25 @@ func2 (void) return 2; } +static int +func5 (void) +{ + asm ("func5_label: .global func5_label\n"); + return 5; +} + +static int +func6 (void) +{ + asm ("func6_label: .global func6_label\n"); + return 6; +} + int main (void) { func1 (); func2 (); + func5 (); + func6 (); } diff --git a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp index 189f527729e..5bbead8d932 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp @@ -35,11 +35,15 @@ foreach_with_prefix is_64 {false true} { # Get the addresses / lengths of func1 and func2. lassign [function_range func1 $srcdir/$subdir/$srcfile] func1_addr func1_len lassign [function_range func2 $srcdir/$subdir/$srcfile] func2_addr func2_len + lassign [function_range func5 $srcdir/$subdir/$srcfile] func5_addr func5_len + lassign [function_range func6 $srcdir/$subdir/$srcfile] func6_addr func6_len set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { global func1_addr func1_len global func2_addr func2_len + global func5_addr func5_len + global func6_addr func6_len global is_64 declare_labels cu_range_list foo_range_list @@ -50,12 +54,14 @@ foreach_with_prefix is_64 {false true} { version 5 is_64 $is_64 } { - declare_labels int_type + declare_labels int_type1 + declare_labels int_type3 declare_labels foo_location_list + declare_labels baz_location_list DW_TAG_compile_unit { } { - int_type: DW_TAG_base_type { + int_type1: DW_TAG_base_type { {DW_AT_byte_size 4 DW_FORM_data1} {DW_AT_encoding @DW_ATE_signed} {DW_AT_name "int"} @@ -64,7 +70,7 @@ foreach_with_prefix is_64 {false true} { DW_TAG_variable { {DW_AT_name "foo"} {DW_AT_location $foo_location_list DW_FORM_sec_offset} - {DW_AT_type :$int_type} + {DW_AT_type :$int_type1} } DW_TAG_subprogram { @@ -81,6 +87,41 @@ foreach_with_prefix is_64 {false true} { } } + # This CU uses the DW_FORM_sec_offset form to refer to the + # .debug_loclists section. The corresponding contribution in the + # .debug_loclists section has no offset array. + cu { + version 5 + is_64 $is_64 + } { + DW_TAG_compile_unit { + } { + int_type3: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_data1} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name "int"} + } + + DW_TAG_variable { + {DW_AT_name "baz"} + {DW_AT_location $baz_location_list DW_FORM_sec_offset} + {DW_AT_type :$int_type3} + } + + DW_TAG_subprogram { + {DW_AT_name "func5"} + {DW_AT_low_pc $func5_addr DW_FORM_addr} + {DW_AT_high_pc $func5_len DW_FORM_udata} + } + + DW_TAG_subprogram { + {DW_AT_name "func6"} + {DW_AT_low_pc $func6_addr DW_FORM_addr} + {DW_AT_high_pc $func6_len DW_FORM_udata} + } + } + } + loclists -is-64 $is_64 { # The lists in this table are accessed by direct offset # (DW_FORM_sec_offset). @@ -97,6 +138,20 @@ foreach_with_prefix is_64 {false true} { } } } + + table -with-offset-array false { + baz_location_list: list_ { + start_length $func5_addr $func5_len { + DW_OP_constu 0x567890 + DW_OP_stack_value + } + + start_length $func6_addr $func6_len { + DW_OP_constu 0x678901 + DW_OP_stack_value + } + } + } } } @@ -112,6 +167,8 @@ foreach_with_prefix is_64 {false true} { gdb_breakpoint "func1" gdb_breakpoint "func2" + gdb_breakpoint "func5" + gdb_breakpoint "func6" gdb_continue_to_breakpoint "func1" with_test_prefix "at func1" { @@ -122,4 +179,14 @@ foreach_with_prefix is_64 {false true} { with_test_prefix "at func2" { gdb_test "print /x foo" " = 0x234567" } + + gdb_continue_to_breakpoint "func5" + with_test_prefix "at func5" { + gdb_test "print /x baz" " = 0x567890" + } + + gdb_continue_to_breakpoint "func6" + with_test_prefix "at func6" { + gdb_test "print /x baz" " = 0x678901" + } } diff --git a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp index d898d11c0dc..01c1429a717 100644 --- a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp @@ -35,7 +35,8 @@ foreach_with_prefix is_64 {false true} { Dwarf::assemble $asm_file { global is_64 - declare_labels cu_range_list foo_range_list + declare_labels cu1_range_list cu3_range_list + declare_labels foo_range_list baz_range_list # This CU uses the DW_FORM_sec_offset form to refer to the .debug_rnglists # section. @@ -44,7 +45,7 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_ranges $cu_range_list DW_FORM_sec_offset} + {DW_AT_ranges $cu1_range_list DW_FORM_sec_offset} } { DW_TAG_subprogram { {DW_AT_name "foo"} @@ -53,12 +54,29 @@ foreach_with_prefix is_64 {false true} { } } + # This CU uses the DW_FORM_sec_offset form to refer to the .debug_rnglists + # section. The corresponding contribution in the .debug_rnglists has no + # offset array. + cu { + version 5 + is_64 $is_64 + } { + DW_TAG_compile_unit { + {DW_AT_ranges $cu3_range_list DW_FORM_sec_offset} + } { + DW_TAG_subprogram { + {DW_AT_name "baz"} + {DW_AT_ranges $baz_range_list DW_FORM_sec_offset} + } + } + } + rnglists -is-64 $is_64 { # The lists in this table are accessed by direct offset # (DW_FORM_sec_offset). table { # For the CU. - cu_range_list: list_ { + cu1_range_list: list_ { start_end 0x4000 0x5000 } @@ -67,6 +85,18 @@ foreach_with_prefix is_64 {false true} { start_end 0x4000 0x4010 } } + + table -with-offset-array false { + # For the third CU. + cu3_range_list: list_ { + start_end 0x6000 0x7000 + } + + # For the baz function. + baz_range_list: list_ { + start_end 0x6000 0x6010 + } + } } } @@ -77,4 +107,5 @@ foreach_with_prefix is_64 {false true} { # Sanity checks to make sure GDB slurped the symbols correctly. gdb_test "p/x &foo" " = 0x4000" + gdb_test "p/x &baz" " = 0x6000" } diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 4ce987a5408..19172778577 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -1367,6 +1367,10 @@ namespace eval Dwarf { # The -post-header-label option can be used to define a label just after # the header of the table. This is the label that a DW_AT_rnglists_base # attribute will usually refer to. + # + # The `-with-offset-array true|false` option can be used to control + # whether the headers of the location list tables have an array of + # offset. The default is true. proc table { args } { variable _debug_rnglists_table_count @@ -1374,7 +1378,10 @@ namespace eval Dwarf { variable _debug_rnglists_offset_size variable _debug_rnglists_is_64_dwarf - parse_args {{post-header-label ""}} + parse_args { + {post-header-label ""} + {with-offset-array true} + } if { [llength $args] != 1 } { error "table proc expects one positional argument (body)" @@ -1452,7 +1459,12 @@ namespace eval Dwarf { _op .2byte 5 "dwarf version" _op .byte $_debug_rnglists_addr_size "address size" _op .byte 0 "segment selector size" - _op .4byte "$_debug_rnglists_list_count" "offset entry count" + + if { ${with-offset-array} } { + _op .4byte "$_debug_rnglists_list_count" "offset entry count" + } else { + _op .4byte 0 "offset entry count" + } define_label $post_header_label @@ -1462,9 +1474,11 @@ namespace eval Dwarf { } # Emit the offset array. - for {set list_idx 0} {$list_idx < $_debug_rnglists_list_count} {incr list_idx} { - set list_label [_compute_list_label $list_idx] - _op .${_debug_rnglists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx" + if { ${with-offset-array} } { + for {set list_idx 0} {$list_idx < $_debug_rnglists_list_count} {incr list_idx} { + set list_label [_compute_list_label $list_idx] + _op .${_debug_rnglists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx" + } } # Emit the actual list data. @@ -1540,6 +1554,10 @@ namespace eval Dwarf { # The -post-header-label option can be used to define a label just after the # header of the table. This is the label that a DW_AT_loclists_base # attribute will usually refer to. + # + # The `-with-offset-array true|false` option can be used to control + # whether the headers of the location list tables have an array of + # offset. The default is true. proc table { args } { variable _debug_loclists_table_count @@ -1547,7 +1565,10 @@ namespace eval Dwarf { variable _debug_loclists_offset_size variable _debug_loclists_is_64_dwarf - parse_args {{post-header-label ""}} + parse_args { + {post-header-label ""} + {with-offset-array true} + } if { [llength $args] != 1 } { error "table proc expects one positional argument (body)" @@ -1647,7 +1668,12 @@ namespace eval Dwarf { _op .2byte 5 "DWARF version" _op .byte $_debug_loclists_addr_size "address size" _op .byte 0 "segment selector size" - _op .4byte $_debug_loclists_list_count "offset entry count" + + if { ${with-offset-array} } { + _op .4byte "$_debug_loclists_list_count" "offset entry count" + } else { + _op .4byte 0 "offset entry count" + } define_label $post_header_label @@ -1657,9 +1683,11 @@ namespace eval Dwarf { } # Emit the offset array. - for {set list_idx 0} {$list_idx < $_debug_loclists_list_count} {incr list_idx} { - set list_label [_compute_list_label $list_idx] - _op .${_debug_loclists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx" + if { ${with-offset-array} } { + for {set list_idx 0} {$list_idx < $_debug_loclists_list_count} {incr list_idx} { + set list_label [_compute_list_label $list_idx] + _op .${_debug_loclists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx" + } } # Emit the actual list data.