Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH][gdb/testsuite] Add .debug_loc support in dwarf assembler
@ 2021-10-14 12:33 Tom de Vries via Gdb-patches
  2021-10-14 13:32 ` Simon Marchi via Gdb-patches
  0 siblings, 1 reply; 3+ messages in thread
From: Tom de Vries via Gdb-patches @ 2021-10-14 12:33 UTC (permalink / raw)
  To: gdb-patches

Hi,

Add .debug_loc support in the dwarf assembler, and use it in new test-case
gdb.dwarf2/loc-sec-offset.exp (which is based on
gdb.dwarf2/loclists-sec-offset.exp).

Tested on x86_64-linux.

Any comments?

Thanks,
- Tom

[gdb/testsuite] Add .debug_loc support in dwarf assembler

---
 gdb/testsuite/gdb.dwarf2/loc-sec-offset.c   |  37 +++++++++
 gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp | 121 ++++++++++++++++++++++++++++
 gdb/testsuite/lib/dwarf.exp                 |  96 ++++++++++++++++++++++
 3 files changed, 254 insertions(+)

diff --git a/gdb/testsuite/gdb.dwarf2/loc-sec-offset.c b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.c
new file mode 100644
index 00000000000..2bffbf2ac4c
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+static int
+func1 (void)
+{
+  asm ("func1_label: .global func1_label\n");
+  return 1;
+}
+
+static int
+func2 (void)
+{
+  asm ("func2_label: .global func2_label\n");
+  return 2;
+}
+
+int
+main (void)
+{
+  func1 ();
+  func2 ();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp
new file mode 100644
index 00000000000..362b1506e7d
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp
@@ -0,0 +1,121 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test DW_AT_location attribute referencing the .debug_loc section using
+# the DW_FORM_sec_offset form.
+
+load_lib dwarf.exp
+
+if {![dwarf2_support]} {
+    return 0
+}
+
+# Test with 32-bit and 64-bit DWARF.
+foreach_with_prefix is_64 {false true} {
+    if { $is_64 } {
+	standard_testfile .c -dw64.S
+	set testfile ${testfile}-dw64
+    } else {
+	standard_testfile .c -dw32.S
+	set testfile ${testfile}-dw32
+    }
+
+    lassign [function_range func1 $srcdir/$subdir/$srcfile] \
+	func1_addr func1_len
+    lassign [function_range func2 $srcdir/$subdir/$srcfile] \
+	func2_addr func2_len
+
+    set asm_file [standard_output_file $srcfile2]
+    Dwarf::assemble $asm_file {
+	global func1_addr func1_len
+	global func2_addr func2_len
+	global is_64
+
+	set cu_version 4
+
+	cu {
+	    version $cu_version
+	    is_64 $is_64
+	} {
+	    declare_labels int_type1
+	    declare_labels foo_location_list
+
+	    DW_TAG_compile_unit {
+	    } {
+		int_type1: 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 "foo"}
+		    {DW_AT_location $foo_location_list DW_FORM_sec_offset}
+		    {DW_AT_type :$int_type1}
+		}
+
+		DW_TAG_subprogram {
+		    {DW_AT_name "func1"}
+		    {DW_AT_low_pc $func1_addr}
+		    {DW_AT_high_pc $func1_len DW_FORM_udata}
+		}
+
+		DW_TAG_subprogram {
+		    {DW_AT_name "func2"}
+		    {DW_AT_low_pc $func2_addr}
+		    {DW_AT_high_pc $func2_len DW_FORM_udata}
+		}
+	    }
+	}
+
+	# Generate a .debug_loc contribution.
+	loc {
+	    cu_is_64 $is_64
+	    cu_version $cu_version
+	} {
+	    foo_location_list:
+	    loc_entry $func1_addr "$func1_addr + $func1_len" {
+		DW_OP_constu 0x123456
+		DW_OP_stack_value
+	    }
+	    loc_entry $func2_addr "$func2_addr + $func2_len" {
+		DW_OP_constu 0x234567
+		DW_OP_stack_value
+	    }
+	}
+    }
+
+    if { [prepare_for_testing "failed to prepare" ${testfile} \
+	      [list $srcfile $asm_file] {nodebug}] } {
+	return -1
+    }
+
+    if { ![runto_main] } {
+	return
+    }
+
+    gdb_breakpoint "func1"
+    gdb_breakpoint "func2"
+
+    gdb_continue_to_breakpoint "func1"
+    with_test_prefix "at func1" {
+	gdb_test "print /x foo" " = 0x123456"
+    }
+
+    gdb_continue_to_breakpoint "func2"
+    with_test_prefix "at func2" {
+	gdb_test "print /x foo" " = 0x234567"
+    }
+}
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 66f9844fe2e..a15eacfb46c 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -2369,6 +2369,102 @@ namespace eval Dwarf {
 	aranges_end:
     }
 
+    # Emit a .debug_loc entry.
+
+    proc loc_entry { start end location_description } {
+	# Determine how to emit addresses.
+	variable _addr_size
+	if { $_addr_size == 8 } {
+	    set addr_op .8byte
+	} elseif { $_addr_size == 4 } {
+	    set addr_op .4byte
+	}
+
+	# Emit start and end address.
+	_op $addr_op $start "Start address"
+	_op $addr_op $end "End address"
+
+	declare_labels location_description_start
+	declare_labels location_description_end
+
+	# Emit length of location description.
+	set len "$location_description_end - $location_description_start"
+	_op .2byte $len "Location description length"
+
+	# Tag start of location description.
+	define_label $location_description_start
+
+	# Emit location description.
+	variable _cu_version
+	variable _cu_offset_size
+	_location $location_description $_cu_version $_addr_size \
+	    $_cu_offset_size
+
+	# Tag end of location description.
+	define_label $location_description_end
+    }
+
+    # Emit a DWARF .debug_loc contribution.
+    #
+    # OPTIONS is a list with an even number of elements containing
+    # option-name and option-value pairs.
+    # Current options are:
+    # cu_is_64 0|1 - boolean indicating if references from location
+    #                descriptions refer to a 64-bit DWARF CU.
+    #                default = 0 (32-bit)
+    # cu_version n - section version of DWARF CU referenced from location
+    #                descriptions.
+    #                default = 4
+    #
+    # BODY is Tcl code that emits the parts which make up the body of
+    # the debug_loc contribution.  It is evaluated in the caller's context.
+    # The following command is available for the BODY section:
+    #
+    #   loc_entry <start> <end> <location description>
+    #     -- emit a .debug_loc entry
+
+    proc loc { options body } {
+	# Handle options.
+	parse_options {
+	    { cu_version 4 }
+	    { cu_is_64 0 }
+	}
+
+	# Export for use in BODY.
+	variable _addr_size
+	if { [is_64_target] } {
+	    set _addr_size 8
+	} else {
+	    set _addr_size 4
+	}
+	variable _cu_version
+	set _cu_version $cu_version
+	variable _cu_offset_size
+	if { $cu_is_64 == 1 } {
+	    set _cu_offset_size 8
+	} else {
+	    set _cu_offset_size 4
+	}
+
+	# Switch to .debug_loc section.
+	_section .debug_loc
+
+	# Emit entries.
+	uplevel $body
+
+	# Determine how to emit addresses.
+	if { $_addr_size == 8 } {
+	    set addr_op .8byte
+	} elseif { $_addr_size == 4 } {
+	    set addr_op .4byte
+	}
+
+	# Emit <End of list>.
+	set comment "<End of list>"
+	_op $addr_op 0 "$comment (Part 1/2)"
+	_op $addr_op 0 "$comment (Part 2/2)"
+    }
+
     proc _empty_array {name} {
 	upvar $name the_array
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][gdb/testsuite] Add .debug_loc support in dwarf assembler
  2021-10-14 12:33 [PATCH][gdb/testsuite] Add .debug_loc support in dwarf assembler Tom de Vries via Gdb-patches
@ 2021-10-14 13:32 ` Simon Marchi via Gdb-patches
  2021-10-14 15:02   ` Tom de Vries via Gdb-patches
  0 siblings, 1 reply; 3+ messages in thread
From: Simon Marchi via Gdb-patches @ 2021-10-14 13:32 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

> diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
> index 66f9844fe2e..a15eacfb46c 100644
> --- a/gdb/testsuite/lib/dwarf.exp
> +++ b/gdb/testsuite/lib/dwarf.exp
> @@ -2369,6 +2369,102 @@ namespace eval Dwarf {
>  	aranges_end:
>      }
>  
> +    # Emit a .debug_loc entry.
> +
> +    proc loc_entry { start end location_description } {
> +	# Determine how to emit addresses.
> +	variable _addr_size
> +	if { $_addr_size == 8 } {
> +	    set addr_op .8byte
> +	} elseif { $_addr_size == 4 } {
> +	    set addr_op .4byte
> +	}
> +
> +	# Emit start and end address.
> +	_op $addr_op $start "Start address"
> +	_op $addr_op $end "End address"
> +
> +	declare_labels location_description_start
> +	declare_labels location_description_end
> +
> +	# Emit length of location description.
> +	set len "$location_description_end - $location_description_start"
> +	_op .2byte $len "Location description length"
> +
> +	# Tag start of location description.
> +	define_label $location_description_start
> +
> +	# Emit location description.
> +	variable _cu_version
> +	variable _cu_offset_size
> +	_location $location_description $_cu_version $_addr_size \
> +	    $_cu_offset_size
> +
> +	# Tag end of location description.
> +	define_label $location_description_end
> +    }
> +
> +    # Emit a DWARF .debug_loc contribution.
> +    #
> +    # OPTIONS is a list with an even number of elements containing
> +    # option-name and option-value pairs.
> +    # Current options are:
> +    # cu_is_64 0|1 - boolean indicating if references from location
> +    #                descriptions refer to a 64-bit DWARF CU.
> +    #                default = 0 (32-bit)
> +    # cu_version n - section version of DWARF CU referenced from location
> +    #                descriptions.
> +    #                default = 4
> +    #
> +    # BODY is Tcl code that emits the parts which make up the body of
> +    # the debug_loc contribution.  It is evaluated in the caller's context.
> +    # The following command is available for the BODY section:
> +    #
> +    #   loc_entry <start> <end> <location description>
> +    #     -- emit a .debug_loc entry
> +
> +    proc loc { options body } {

I would suggest using the same trick as used for rnglists: rename
loc_entry to _loc_entry (or something like that, to show it's
internal).  And use:

	with_override Dwarf::entry Dwarf::_loc_entry {
	    uplevel $body
	}

Users would then look like:

    loc { ... } {
	entry 0x123 0x456 {
	    ...
        }
    }

I think that looks good: because you are in the "loc" context, it is
obvious enough that entry is a location list entry.  I think that makes
it easy to write.

I would have suggested renaming "loc" to "loclist", because this is
actually generating a "location list", according to the standard.  But
that might become confusing with the DWARF5 "loclists"...

But other than that, the patch LGTM.

Simon

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][gdb/testsuite] Add .debug_loc support in dwarf assembler
  2021-10-14 13:32 ` Simon Marchi via Gdb-patches
@ 2021-10-14 15:02   ` Tom de Vries via Gdb-patches
  0 siblings, 0 replies; 3+ messages in thread
From: Tom de Vries via Gdb-patches @ 2021-10-14 15:02 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 10/14/21 3:32 PM, Simon Marchi wrote:
>> diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
>> index 66f9844fe2e..a15eacfb46c 100644
>> --- a/gdb/testsuite/lib/dwarf.exp
>> +++ b/gdb/testsuite/lib/dwarf.exp
>> @@ -2369,6 +2369,102 @@ namespace eval Dwarf {
>>  	aranges_end:
>>      }
>>  
>> +    # Emit a .debug_loc entry.
>> +
>> +    proc loc_entry { start end location_description } {
>> +	# Determine how to emit addresses.
>> +	variable _addr_size
>> +	if { $_addr_size == 8 } {
>> +	    set addr_op .8byte
>> +	} elseif { $_addr_size == 4 } {
>> +	    set addr_op .4byte
>> +	}
>> +
>> +	# Emit start and end address.
>> +	_op $addr_op $start "Start address"
>> +	_op $addr_op $end "End address"
>> +
>> +	declare_labels location_description_start
>> +	declare_labels location_description_end
>> +
>> +	# Emit length of location description.
>> +	set len "$location_description_end - $location_description_start"
>> +	_op .2byte $len "Location description length"
>> +
>> +	# Tag start of location description.
>> +	define_label $location_description_start
>> +
>> +	# Emit location description.
>> +	variable _cu_version
>> +	variable _cu_offset_size
>> +	_location $location_description $_cu_version $_addr_size \
>> +	    $_cu_offset_size
>> +
>> +	# Tag end of location description.
>> +	define_label $location_description_end
>> +    }
>> +
>> +    # Emit a DWARF .debug_loc contribution.
>> +    #
>> +    # OPTIONS is a list with an even number of elements containing
>> +    # option-name and option-value pairs.
>> +    # Current options are:
>> +    # cu_is_64 0|1 - boolean indicating if references from location
>> +    #                descriptions refer to a 64-bit DWARF CU.
>> +    #                default = 0 (32-bit)
>> +    # cu_version n - section version of DWARF CU referenced from location
>> +    #                descriptions.
>> +    #                default = 4
>> +    #
>> +    # BODY is Tcl code that emits the parts which make up the body of
>> +    # the debug_loc contribution.  It is evaluated in the caller's context.
>> +    # The following command is available for the BODY section:
>> +    #
>> +    #   loc_entry <start> <end> <location description>
>> +    #     -- emit a .debug_loc entry
>> +
>> +    proc loc { options body } {
> 
> I would suggest using the same trick as used for rnglists: rename
> loc_entry to _loc_entry (or something like that, to show it's
> internal).  And use:
> 
> 	with_override Dwarf::entry Dwarf::_loc_entry {
> 	    uplevel $body
> 	}
> 
> Users would then look like:
> 
>     loc { ... } {
> 	entry 0x123 0x456 {
> 	    ...
>         }
>     }
> 
> I think that looks good: because you are in the "loc" context, it is
> obvious enough that entry is a location list entry.  I think that makes
> it easy to write.
> 

Ack, updated that way, thanks for the tip.

> I would have suggested renaming "loc" to "loclist", because this is
> actually generating a "location list", according to the standard.  But
> that might become confusing with the DWARF5 "loclists"...
> 

Ack.  FWIW, I chose the name based on the .debug_loc section, similar to
how .debug_aranges are generated use a proc aranges.

> But other than that, the patch LGTM.
> 

Committed.

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-10-14 15:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-14 12:33 [PATCH][gdb/testsuite] Add .debug_loc support in dwarf assembler Tom de Vries via Gdb-patches
2021-10-14 13:32 ` Simon Marchi via Gdb-patches
2021-10-14 15:02   ` Tom de Vries via Gdb-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox