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-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9307efbe9eb58fb041d09b1e35cffd377d20e708;p=binutils-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 be5afad904e..f980bac89aa 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 * gdb.dwarf2/rnglists-sec-offset.exp: Add test for DW_AT_ranges diff --git a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c index 924c6ccd412..f8076406463 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c +++ b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c @@ -43,6 +43,20 @@ func4 (void) return 4; } +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) { @@ -50,4 +64,6 @@ main (void) func2 (); func3 (); func4 (); + func5 (); + func6 (); } diff --git a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp index ecd85ee116c..573324af3d1 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp @@ -37,6 +37,8 @@ foreach_with_prefix is_64 {false true} { lassign [function_range func2 $srcdir/$subdir/$srcfile] func2_addr func2_len lassign [function_range func3 $srcdir/$subdir/$srcfile] func3_addr func3_len lassign [function_range func4 $srcdir/$subdir/$srcfile] func4_addr func4_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 { @@ -44,6 +46,8 @@ foreach_with_prefix is_64 {false true} { global func2_addr func2_len global func3_addr func3_len global func4_addr func4_len + global func5_addr func5_len + global func6_addr func6_len global is_64 declare_labels cu_range_list foo_range_list @@ -56,7 +60,10 @@ foreach_with_prefix is_64 {false true} { } { declare_labels int_type1 declare_labels int_type2 - declare_labels foo_location_list bar_location_list + declare_labels int_type3 + declare_labels foo_location_list + declare_labels bar_location_list + declare_labels baz_location_list DW_TAG_compile_unit { } { @@ -123,6 +130,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_AT_high_pc $func5_len DW_FORM_udata} + } + + DW_TAG_subprogram { + {DW_AT_name "func6"} + {DW_AT_low_pc $func6_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). @@ -153,6 +195,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 + } + } + } } } @@ -170,6 +226,8 @@ foreach_with_prefix is_64 {false true} { gdb_breakpoint "func2" gdb_breakpoint "func3" gdb_breakpoint "func4" + gdb_breakpoint "func5" + gdb_breakpoint "func6" gdb_continue_to_breakpoint "func1" with_test_prefix "at func1" { @@ -190,4 +248,14 @@ foreach_with_prefix is_64 {false true} { with_test_prefix "at func4" { gdb_test "print /x bar" " = 0x456789" } + + 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 2bcbe0aeea8..0733e90abc7 100644 --- a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp @@ -35,8 +35,8 @@ foreach_with_prefix is_64 {false true} { Dwarf::assemble $asm_file { global is_64 - declare_labels cu1_range_list cu2_range_list - declare_labels foo_range_list bar_range_list + declare_labels cu1_range_list cu2_range_list cu3_range_list + declare_labels foo_range_list bar_range_list baz_range_list # This CU uses the DW_FORM_sec_offset form to refer to the .debug_rnglists # section. @@ -73,6 +73,23 @@ 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). @@ -99,6 +116,18 @@ foreach_with_prefix is_64 {false true} { start_end 0x5000 0x5010 } } + + 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 + } + } } } @@ -110,4 +139,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 &bar" " = 0x5000" + gdb_test "p/x &baz" " = 0x6000" } diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index b444ef36778..10fd88f6e0f 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -1392,6 +1392,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 @@ -1399,7 +1403,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)" @@ -1477,7 +1484,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 @@ -1487,9 +1499,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. @@ -1565,6 +1579,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 @@ -1572,7 +1590,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)" @@ -1672,7 +1693,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 @@ -1682,9 +1708,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.