]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/testsuite: add test for .debug_{rng,loc}lists section without offset array
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 2 Feb 2021 15:40:53 +0000 (10:40 -0500)
committerSimon Marchi <simon.marchi@polymtl.ca>
Wed, 3 Feb 2021 15:32:43 +0000 (10:32 -0500)
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

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/loclists-sec-offset.c
gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp
gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp
gdb/testsuite/lib/dwarf.exp

index 637252f1a8e884679d6534cde2ea42bf5b4d158d..032ff34b41041c6b0742d17cf8fe9920f8f76c33 100644 (file)
@@ -1,3 +1,12 @@
+2021-02-02  Simon Marchi  <simon.marchi@efficios.com>
+
+       * 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  <simon.marchi@efficios.com>
 
        PR gdb/26813
index 2bffbf2ac4c038db814bd1a90a8da5312f50de2a..af783151829972a7c78ae6253ef1d38be74d3f31 100644 (file)
@@ -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 ();
 }
index 189f527729e25ce0224a3f0cf56337ef266ad80b..5bbead8d932b4be33a31a2c2938c0590185027ff 100644 (file)
@@ -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"
+    }
 }
index d898d11c0dc9c91d940eb7372c1cf6fcdf2b863b..01c1429a7177a3e9ff5b5347fd62cc8b6985c056 100644 (file)
@@ -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"
 }
index 4ce987a54081085d2c6e2d1b51f239e5bf95b047..19172778577aa3870c5d1c23c70c20763d58ad43 100644 (file)
@@ -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.