public inbox for dwz@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Update dwarf.exp assembler from gdb.
@ 2020-12-14 21:19 Mark Wielaard
  2020-12-20  8:33 ` Tom de Vries
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2020-12-14 21:19 UTC (permalink / raw)
  To: dwz; +Cc: Mark Wielaard

Includes various fixes and features. Specifically it won't emit a block
for a DWARF expression when the version is >= 4.
The DWARF Assembler is used by invalid-dw-at-stmt-list-encoding.exp
(pr24171.sh) and no-multifile-prop.exp (pr25109.sh)

Also fix up the generated varval.S (pr24823.sh) to use DW_FORM_exprloc.
---
 testsuite/dwz.tests/varval.S |  26 ++--
 testsuite/lib/dwarf.exp      | 242 +++++++++++++++++++++++------------
 2 files changed, 176 insertions(+), 92 deletions(-)

diff --git a/testsuite/dwz.tests/varval.S b/testsuite/dwz.tests/varval.S
index be62e8b..126768c 100644
--- a/testsuite/dwz.tests/varval.S
+++ b/testsuite/dwz.tests/varval.S
@@ -241,7 +241,7 @@
         .uleb128        0x3f            /* DW_AT_external */
         .uleb128        0x0c            /* DW_FORM_flag */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        6               /* Abbrev start */
@@ -263,7 +263,7 @@
         .uleb128        0x3f            /* DW_AT_external */
         .uleb128        0x0c            /* DW_FORM_flag */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        8               /* Abbrev start */
@@ -289,7 +289,7 @@
         .uleb128        0x3f            /* DW_AT_external */
         .uleb128        0x0c            /* DW_FORM_flag */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        10              /* Abbrev start */
@@ -397,7 +397,7 @@
         .uleb128        0x3f            /* DW_AT_external */
         .uleb128        0x0c            /* DW_FORM_flag */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        20              /* Abbrev start */
@@ -408,7 +408,7 @@
         .uleb128        0x3f            /* DW_AT_external */
         .uleb128        0x0c            /* DW_FORM_flag */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        21              /* Abbrev start */
@@ -434,7 +434,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        23              /* Abbrev start */
@@ -445,7 +445,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        24              /* Abbrev start */
@@ -454,7 +454,7 @@
         .uleb128        0x31            /* DW_AT_abstract_origin */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        25              /* Abbrev start */
@@ -465,7 +465,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        26              /* Abbrev start */
@@ -476,7 +476,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        27              /* Abbrev start */
@@ -487,7 +487,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        28              /* Abbrev start */
@@ -498,7 +498,7 @@
         .uleb128        0x49            /* DW_AT_type */
         .uleb128        0x13            /* DW_FORM_ref4 */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .uleb128        29              /* Abbrev start */
@@ -507,7 +507,7 @@
         .uleb128        0x03            /* DW_AT_name */
         .uleb128        0x08            /* DW_FORM_string */
         .uleb128        0x02            /* DW_AT_location */
-        .uleb128        0x09            /* SPECIAL_expr */
+        .uleb128        0x18            /* DW_FORM_exprloc */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
         .byte        0x0                /* Terminator */
diff --git a/testsuite/lib/dwarf.exp b/testsuite/lib/dwarf.exp
index d722982..8fc6da6 100644
--- a/testsuite/lib/dwarf.exp
+++ b/testsuite/lib/dwarf.exp
@@ -1,4 +1,4 @@
-# Copyright 2010-2019 Free Software Foundation, Inc.
+# Copyright 2010-2020 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
@@ -117,12 +117,12 @@ proc build_executable_from_fission_assembler { testname executable sources optio
 # static void func (void) {}
 #
 
-proc function_range { func src } {
+proc function_range { func src {options {debug}} } {
     global decimal gdb_prompt
 
     set exe [standard_temp_file func_addr[pid].x]
 
-    gdb_compile $src $exe executable {debug}
+    gdb_compile $src $exe executable $options
 
     gdb_exit
     gdb_start
@@ -167,6 +167,22 @@ proc function_range { func src } {
     return [list "${func}_label - $func_label_offset" $func_length]
 }
 
+# Extract the start, length, and end for function called NAME and
+# create suitable variables in the callers scope.
+proc get_func_info { name {options {debug}} } {
+    global srcdir subdir srcfile
+
+    upvar 1 "${name}_start" func_start
+    upvar 1 "${name}_len" func_len
+    upvar 1 "${name}_end" func_end
+
+    lassign [function_range ${name} \
+		 [list ${srcdir}/${subdir}/$srcfile] \
+		 ${options}]  \
+	func_start func_len
+    set func_end "$func_start + $func_len"
+}
+
 # A DWARF assembler.
 #
 # All the variables in this namespace are private to the
@@ -206,11 +222,11 @@ proc function_range { func src } {
 # which will be substituted by one or more standard or macro attributes.
 # supported macro attributes are:
 #
-#  - MACRO_AT_range { FUNC FILE }
+#  - MACRO_AT_range { FUNC }
 #  It is substituted by DW_AT_low_pc and DW_AT_high_pc with the start and
-#  end address of function FUNC in file FILE.
+#  end address of function FUNC in file $srcdir/$subdir/$srcfile.
 #
-#  - MACRO_AT_func { FUNC FILE }
+#  - MACRO_AT_func { FUNC }
 #  It is substituted by DW_AT_name with FUNC and MACRO_AT_range.
 #
 # If FORM is given, it should name a DW_FORM_ constant.
@@ -221,8 +237,9 @@ proc function_range { func src } {
 # section automatically.
 #
 # If FORM is 'SPECIAL_expr', then VALUE is treated as a location
-# expression.  The effective form is then DW_FORM_block, and VALUE
-# is passed to the (internal) '_location' proc to be translated.
+# expression.  The effective form is then DW_FORM_block or DW_FORM_exprloc
+# for DWARF version >= 4, and VALUE is passed to the (internal)
+# '_location' proc to be translated.
 # This proc implements a miniature DW_OP_ assembler.
 #
 # If FORM is not given, it is guessed:
@@ -234,11 +251,10 @@ proc function_range { func src } {
 #   and DW_FORM_ref4 is used.  See 'new_label' and 'define_label'.
 # * If VALUE starts with the "%" character, then it is a label
 #   reference too, but DW_FORM_ref_addr is used.
-# * Otherwise, VALUE is taken to be a string and DW_FORM_string is
-#   used.  In order to prevent bugs where a numeric value is given but
-#   no form is specified, it is an error if the value looks like a number
-#   (using Tcl's "string is integer") and no form is provided.
-# More form-guessing functionality may be added.
+# * Otherwise, if the attribute name has a default form (f.i. DW_FORM_addr for
+#   DW_AT_low_pc), then that one is used.
+# * Otherwise, an error is reported.  Either specify a form explicitly, or
+#   add a default for the the attribute name in _default_form.
 #
 # CHILDREN is just Tcl code that can be used to define child DIEs.  It
 # is evaluated in the caller's context.
@@ -377,7 +393,6 @@ namespace eval Dwarf {
 
     proc _read_constants {} {
 	global srcdir hex decimal
-	variable _constants
 
 	# DWARF name-matching regexp.
 	set dwrx "DW_\[a-zA-Z0-9_\]+"
@@ -404,8 +419,6 @@ namespace eval Dwarf {
 	    }
 	}
 	close $fd
-
-	set _constants(SPECIAL_expr) $_constants(DW_FORM_block)
     }
 
     proc _quote {string} {
@@ -577,9 +590,25 @@ namespace eval Dwarf {
 	    }
 
 	    default {
+		return ""
+	    }
+	}
+    }
+
+    proc _default_form { attr } {
+	switch -exact -- $attr {
+	    DW_AT_low_pc  {
+		return DW_FORM_addr
+	    }
+	    DW_AT_producer -
+	    DW_AT_comp_dir -
+	    DW_AT_linkage_name -
+	    DW_AT_MIPS_linkage_name -
+	    DW_AT_name {
 		return DW_FORM_string
 	    }
 	}
+	return ""
     }
 
     # Map NAME to its canonical form.
@@ -596,24 +625,35 @@ namespace eval Dwarf {
     proc _handle_attribute { attr_name attr_value attr_form } {
 	variable _abbrev_section
 	variable _constants
+	variable _cu_version
 
 	_handle_DW_FORM $attr_form $attr_value
 
 	_defer_output $_abbrev_section {
+	    if { $attr_form eq "SPECIAL_expr" } {
+		if { $_cu_version < 4 } {
+		    set attr_form_comment "DW_FORM_block"
+		} else {
+		    set attr_form_comment "DW_FORM_exprloc"
+		}
+	    } else {
+		set attr_form_comment $attr_form
+	    }
 	    _op .uleb128 $_constants($attr_name) $attr_name
-	    _op .uleb128 $_constants($attr_form) $attr_form
+	    _op .uleb128 $_constants($attr_form) $attr_form_comment
 	}
     }
 
     # Handle macro attribute MACRO_AT_range.
 
     proc _handle_macro_at_range { attr_value } {
-	if {[llength $attr_value] != 2} {
-	    error "usage: MACRO_AT_range { func file }"
+	if {[llength $attr_value] != 1} {
+	    error "usage: MACRO_AT_range { func }"
 	}
 
 	set func [lindex $attr_value 0]
-	set src [lindex $attr_value 1]
+	global srcdir subdir srcfile
+	set src ${srcdir}/${subdir}/${srcfile}
 	set result [function_range $func $src]
 
 	_handle_attribute DW_AT_low_pc [lindex $result 0] \
@@ -625,7 +665,7 @@ namespace eval Dwarf {
     # Handle macro attribute MACRO_AT_func.
 
     proc _handle_macro_at_func { attr_value } {
-	if {[llength $attr_value] != 2} {
+	if {[llength $attr_value] != 1} {
 	    error "usage: MACRO_AT_func { func file }"
 	}
 	_handle_attribute DW_AT_name [lindex $attr_value 0] DW_FORM_string
@@ -678,11 +718,13 @@ namespace eval Dwarf {
 			_guess_form $attr_value attr_value
 		    }
 		} else {
-		    # If the value looks like an integer, a form is required.
-		    if [string is integer $attr_value] {
-			error "Integer value requires a form"
-		    }
 		    set attr_form [_guess_form $attr_value attr_value]
+		    if { $attr_form eq "" } {
+			set attr_form [_default_form $attr_name]
+		    }
+		    if { $attr_form eq "" } {
+			error "No form for $attr_name $attr_value"
+		    }
 		}
 		set attr_form [_map_name $attr_form _FORM]
 
@@ -692,8 +734,8 @@ namespace eval Dwarf {
 
 	_defer_output $_abbrev_section {
 	    # Terminator.
-	    _op .byte 0x0 Terminator
-	    _op .byte 0x0 Terminator
+	    _op .byte 0x0 "DW_AT - Terminator"
+	    _op .byte 0x0 "DW_FORM - Terminator"
 	}
 
 	if {$has_children} {
@@ -809,15 +851,6 @@ namespace eval Dwarf {
 	_emit "${name}:"
     }
 
-    # Declare a global label.  This is typically used to refer to
-    # labels defined in other files, for example a function defined in
-    # a .c file.
-    proc extern {args} {
-	foreach name $args {
-	    _op .global $name
-	}
-    }
-
     # A higher-level interface to label handling.
     #
     # ARGS is a list of label descriptors.  Each one is either a
@@ -841,13 +874,13 @@ namespace eval Dwarf {
 	    set name [lindex $arg 0]
 	    set text [lindex $arg 1]
 
-	    upvar $name label_var
-	    if {$text == ""} {
-		set label_var [new_label]
-	    } else {
-		set label_var [new_label $text]
+	    if { $text == "" } {
+		set text $name
 	    }
 
+	    upvar $name label_var
+	    set label_var [new_label $text]
+
 	    proc ${name}: {args} [format {
 		define_label %s
 		uplevel $args
@@ -1013,13 +1046,14 @@ namespace eval Dwarf {
     #                default = 0 (32-bit)
     # version n    - DWARF version number to emit
     #                default = 4
-    # addr_size n  - the size of addresses, 32, 64, or default
+    # addr_size n  - the size of addresses in bytes: 4, 8, or default
     #                default = default
     # fission 0|1  - boolean indicating if generating Fission debug info
     #                default = 0
     # BODY is Tcl code that emits the DIEs which make up the body of
     # the CU.  It is evaluated in the caller's context.
     proc cu {options body} {
+	variable _constants
 	variable _cu_count
 	variable _abbrev_section
 	variable _abbrev_num
@@ -1059,6 +1093,12 @@ namespace eval Dwarf {
 	    set _abbrev_section ".debug_abbrev.dwo"
 	}
 
+	if {$_cu_version < 4} {
+	    set _constants(SPECIAL_expr) $_constants(DW_FORM_block)
+	} else {
+	    set _constants(SPECIAL_expr) $_constants(DW_FORM_exprloc)
+	}
+
 	_section $section
 
 	set cu_num [incr _cu_count]
@@ -1089,8 +1129,7 @@ namespace eval Dwarf {
 
 	_defer_output $_abbrev_section {
 	    # Emit the terminator.
-	    _op .byte 0x0 Terminator
-	    _op .byte 0x0 Terminator
+	    _op .byte 0x0 "Abbrev end - Terminator"
 	}
 
 	define_label $end_label
@@ -1104,7 +1143,7 @@ namespace eval Dwarf {
     #                default = 0 (32-bit)
     # version n    - DWARF version number to emit
     #                default = 4
-    # addr_size n  - the size of addresses, 32, 64, or default
+    # addr_size n  - the size of addresses in bytes: 4, 8, or default
     #                default = default
     # fission 0|1  - boolean indicating if generating Fission debug info
     #                default = 0
@@ -1198,8 +1237,7 @@ namespace eval Dwarf {
 
 	_defer_output $_abbrev_section {
 	    # Emit the terminator.
-	    _op .byte 0x0 Terminator
-	    _op .byte 0x0 Terminator
+	    _op .byte 0x0 "Abbrev end - Terminator"
 	}
 
 	define_label $end_label
@@ -1227,42 +1265,37 @@ namespace eval Dwarf {
 	set section ".debug_ranges"
 	_section $section
 
-	proc sequence {{ranges {}}} {
+	proc sequence { body } {
 	    variable _debug_ranges_64_bit
 
 	    # Emit the sequence of addresses.
-	    set base ""
-	    foreach range $ranges {
-		set range [uplevel 1 "subst \"$range\""]
-		set type [lindex $range 0]
-		switch -exact -- $type {
-		    base {
-			set base [lrange $range 1 end]
-
-			if { $_debug_ranges_64_bit } then {
-			    _op .8byte 0xffffffffffffffff "Base Marker"
-			    _op .8byte $base "Base Address"
-			} else {
-			    _op .4byte 0xffffffff "Base Marker"
-			    _op .4byte $base "Base Address"
-			}
-		    }
-		    range {
-			set start [lindex $range 1]
-			set end [lrange $range 2 end]
-
-			if { $_debug_ranges_64_bit } then {
-			    _op .8byte $start "Start Address"
-			    _op .8byte $end "End Address"
-			} else {
-			    _op .4byte $start "Start Address"
-			    _op .4byte $end "End Address"
-			}
-		    }
-		    default { error "unknown range type: $type " }
+
+	    proc base { addr } {
+		variable _debug_ranges_64_bit
+
+		if { $_debug_ranges_64_bit } then {
+		    _op .8byte 0xffffffffffffffff "Base Marker"
+		    _op .8byte $addr "Base Address"
+		} else {
+		    _op .4byte 0xffffffff "Base Marker"
+		    _op .4byte $addr "Base Address"
 		}
 	    }
 
+	    proc range { start end } {
+		variable _debug_ranges_64_bit
+
+		if { $_debug_ranges_64_bit } then {
+		    _op .8byte $start "Start Address"
+		    _op .8byte $end "End Address"
+		} else {
+		    _op .4byte $start "Start Address"
+		    _op .4byte $end "End Address"
+		}
+	    }
+
+	    uplevel $body
+
 	    # End of the sequence.
 	    if { $_debug_ranges_64_bit } then {
 		_op .8byte 0x0 "End of Sequence Marker (Part 1)"
@@ -1285,7 +1318,7 @@ namespace eval Dwarf {
     #                default = 0 (32-bit)
     # version n    - DWARF version number to emit
     #                default = 4
-    # addr_size n  - the size of addresses, 32, 64, or default
+    # addr_size n  - the size of addresses in bytes: 4, 8, or default
     #                default = default
     #
     # LABEL is the label of the current unit (which is probably
@@ -1312,12 +1345,16 @@ namespace eval Dwarf {
 	set is_64 0
 	set _unit_version 4
 	set _unit_addr_size default
+	set _line_saw_program 0
+	set _line_saw_file 0
+	set _default_is_stmt 1
 
 	foreach { name value } $options {
 	    switch -exact -- $name {
 		is_64 { set is_64 $value }
 		version { set _unit_version $value }
 		addr_size { set _unit_addr_size $value }
+		default_is_stmt { set _default_is_stmt $value }
 		default { error "unknown option $name" }
 	    }
 	}
@@ -1364,7 +1401,7 @@ namespace eval Dwarf {
 	define_label $header_len_label
 
 	_op .byte 1 "minimum_instruction_length"
-	_op .byte 1 "default_is_stmt"
+	_op .byte $_default_is_stmt "default_is_stmt"
 	_op .byte 1 "line_base"
 	_op .byte 1 "line_range"
 	_op .byte 10 "opcode_base"
@@ -1406,6 +1443,9 @@ namespace eval Dwarf {
 	proc program {statements} {
 	    variable _line_saw_program
 	    variable _line_header_end_label
+	    variable _line
+
+	    set _line 1
 
 	    if "! $_line_saw_program" {
 		# Terminate the file list.
@@ -1430,23 +1470,67 @@ namespace eval Dwarf {
 	    }
 
 	    proc DW_LNE_end_sequence {} {
+		variable _line
 		_op .byte 0
 		_op .uleb128 1
 		_op .byte 1
+		set _line 1
+	    }
+
+	    proc DW_LNE_user { len opcode } {
+		set DW_LNE_lo_usr 0x80
+		set DW_LNE_hi_usr 0xff
+		if { $DW_LNE_lo_usr <= $opcode
+		     && $opcode <= $DW_LNE_hi_usr } {
+		    _op .byte 0
+		    _op .uleb128 $len
+		    _op .byte $opcode
+		    for {set i 1} {$i < $len} {incr i} {
+			_op .byte 0
+		    }
+		} else {
+		    error "unknown vendor specific extended opcode: $opcode"
+		}
 	    }
 
 	    proc DW_LNS_copy {} {
 		_op .byte 1
 	    }
 
+	    proc DW_LNS_negate_stmt {} {
+		_op .byte 6
+	    }
+
 	    proc DW_LNS_advance_pc {offset} {
 		_op .byte 2
 		_op .uleb128 ${offset}
 	    }
 
 	    proc DW_LNS_advance_line {offset} {
+		variable _line
 		_op .byte 3
 		_op .sleb128 ${offset}
+		set _line [expr $_line + $offset]
+	    }
+
+	    # A pseudo line number program instruction, that can be used instead
+	    # of DW_LNS_advance_line.  Rather than writing:
+	    #   {DW_LNS_advance_line [expr $line1 - 1]}
+	    #   {DW_LNS_advance_line [expr $line2 - $line1]}
+	    #   {DW_LNS_advance_line [expr $line3 - $line2]}
+	    # we can just write:
+	    #   {line $line1}
+	    #   {line $line2}
+	    #   {line $line3}
+	    proc line {line} {
+		variable _line
+		set offset [expr $line - $_line]
+		DW_LNS_advance_line $offset
+	    }
+
+	    proc DW_LNS_set_file {num} {
+		_op .byte 4
+		_op .sleb128 ${num}
 	    }
 
 	    foreach statement $statements {
-- 
2.18.4


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

* Re: [PATCH] Update dwarf.exp assembler from gdb.
  2020-12-14 21:19 [PATCH] Update dwarf.exp assembler from gdb Mark Wielaard
@ 2020-12-20  8:33 ` Tom de Vries
  0 siblings, 0 replies; 2+ messages in thread
From: Tom de Vries @ 2020-12-20  8:33 UTC (permalink / raw)
  To: Mark Wielaard, dwz

On 12/14/20 10:19 PM, Mark Wielaard wrote:
> Includes various fixes and features. Specifically it won't emit a block
> for a DWARF expression when the version is >= 4.
> The DWARF Assembler is used by invalid-dw-at-stmt-list-encoding.exp
> (pr24171.sh) and no-multifile-prop.exp (pr25109.sh)
> 

Thanks for the update.

> Also fix up the generated varval.S (pr24823.sh) to use DW_FORM_exprloc.

Yeah, that's from the time we didn't have the DWARF assembler in dwz
sources yet, I think eventually we want that test-case rewritting to use
dwarf assembly.  Anyway, this is fine for now.

LGTM, please commit.

Thanks,
- Tom

> ---
>  testsuite/dwz.tests/varval.S |  26 ++--
>  testsuite/lib/dwarf.exp      | 242 +++++++++++++++++++++++------------
>  2 files changed, 176 insertions(+), 92 deletions(-)
> 
> diff --git a/testsuite/dwz.tests/varval.S b/testsuite/dwz.tests/varval.S
> index be62e8b..126768c 100644
> --- a/testsuite/dwz.tests/varval.S
> +++ b/testsuite/dwz.tests/varval.S
> @@ -241,7 +241,7 @@
>          .uleb128        0x3f            /* DW_AT_external */
>          .uleb128        0x0c            /* DW_FORM_flag */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        6               /* Abbrev start */
> @@ -263,7 +263,7 @@
>          .uleb128        0x3f            /* DW_AT_external */
>          .uleb128        0x0c            /* DW_FORM_flag */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        8               /* Abbrev start */
> @@ -289,7 +289,7 @@
>          .uleb128        0x3f            /* DW_AT_external */
>          .uleb128        0x0c            /* DW_FORM_flag */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        10              /* Abbrev start */
> @@ -397,7 +397,7 @@
>          .uleb128        0x3f            /* DW_AT_external */
>          .uleb128        0x0c            /* DW_FORM_flag */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        20              /* Abbrev start */
> @@ -408,7 +408,7 @@
>          .uleb128        0x3f            /* DW_AT_external */
>          .uleb128        0x0c            /* DW_FORM_flag */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        21              /* Abbrev start */
> @@ -434,7 +434,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        23              /* Abbrev start */
> @@ -445,7 +445,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        24              /* Abbrev start */
> @@ -454,7 +454,7 @@
>          .uleb128        0x31            /* DW_AT_abstract_origin */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        25              /* Abbrev start */
> @@ -465,7 +465,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        26              /* Abbrev start */
> @@ -476,7 +476,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        27              /* Abbrev start */
> @@ -487,7 +487,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        28              /* Abbrev start */
> @@ -498,7 +498,7 @@
>          .uleb128        0x49            /* DW_AT_type */
>          .uleb128        0x13            /* DW_FORM_ref4 */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .uleb128        29              /* Abbrev start */
> @@ -507,7 +507,7 @@
>          .uleb128        0x03            /* DW_AT_name */
>          .uleb128        0x08            /* DW_FORM_string */
>          .uleb128        0x02            /* DW_AT_location */
> -        .uleb128        0x09            /* SPECIAL_expr */
> +        .uleb128        0x18            /* DW_FORM_exprloc */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
>          .byte        0x0                /* Terminator */
> diff --git a/testsuite/lib/dwarf.exp b/testsuite/lib/dwarf.exp
> index d722982..8fc6da6 100644
> --- a/testsuite/lib/dwarf.exp
> +++ b/testsuite/lib/dwarf.exp
> @@ -1,4 +1,4 @@
> -# Copyright 2010-2019 Free Software Foundation, Inc.
> +# Copyright 2010-2020 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
> @@ -117,12 +117,12 @@ proc build_executable_from_fission_assembler { testname executable sources optio
>  # static void func (void) {}
>  #
>  
> -proc function_range { func src } {
> +proc function_range { func src {options {debug}} } {
>      global decimal gdb_prompt
>  
>      set exe [standard_temp_file func_addr[pid].x]
>  
> -    gdb_compile $src $exe executable {debug}
> +    gdb_compile $src $exe executable $options
>  
>      gdb_exit
>      gdb_start
> @@ -167,6 +167,22 @@ proc function_range { func src } {
>      return [list "${func}_label - $func_label_offset" $func_length]
>  }
>  
> +# Extract the start, length, and end for function called NAME and
> +# create suitable variables in the callers scope.
> +proc get_func_info { name {options {debug}} } {
> +    global srcdir subdir srcfile
> +
> +    upvar 1 "${name}_start" func_start
> +    upvar 1 "${name}_len" func_len
> +    upvar 1 "${name}_end" func_end
> +
> +    lassign [function_range ${name} \
> +		 [list ${srcdir}/${subdir}/$srcfile] \
> +		 ${options}]  \
> +	func_start func_len
> +    set func_end "$func_start + $func_len"
> +}
> +
>  # A DWARF assembler.
>  #
>  # All the variables in this namespace are private to the
> @@ -206,11 +222,11 @@ proc function_range { func src } {
>  # which will be substituted by one or more standard or macro attributes.
>  # supported macro attributes are:
>  #
> -#  - MACRO_AT_range { FUNC FILE }
> +#  - MACRO_AT_range { FUNC }
>  #  It is substituted by DW_AT_low_pc and DW_AT_high_pc with the start and
> -#  end address of function FUNC in file FILE.
> +#  end address of function FUNC in file $srcdir/$subdir/$srcfile.
>  #
> -#  - MACRO_AT_func { FUNC FILE }
> +#  - MACRO_AT_func { FUNC }
>  #  It is substituted by DW_AT_name with FUNC and MACRO_AT_range.
>  #
>  # If FORM is given, it should name a DW_FORM_ constant.
> @@ -221,8 +237,9 @@ proc function_range { func src } {
>  # section automatically.
>  #
>  # If FORM is 'SPECIAL_expr', then VALUE is treated as a location
> -# expression.  The effective form is then DW_FORM_block, and VALUE
> -# is passed to the (internal) '_location' proc to be translated.
> +# expression.  The effective form is then DW_FORM_block or DW_FORM_exprloc
> +# for DWARF version >= 4, and VALUE is passed to the (internal)
> +# '_location' proc to be translated.
>  # This proc implements a miniature DW_OP_ assembler.
>  #
>  # If FORM is not given, it is guessed:
> @@ -234,11 +251,10 @@ proc function_range { func src } {
>  #   and DW_FORM_ref4 is used.  See 'new_label' and 'define_label'.
>  # * If VALUE starts with the "%" character, then it is a label
>  #   reference too, but DW_FORM_ref_addr is used.
> -# * Otherwise, VALUE is taken to be a string and DW_FORM_string is
> -#   used.  In order to prevent bugs where a numeric value is given but
> -#   no form is specified, it is an error if the value looks like a number
> -#   (using Tcl's "string is integer") and no form is provided.
> -# More form-guessing functionality may be added.
> +# * Otherwise, if the attribute name has a default form (f.i. DW_FORM_addr for
> +#   DW_AT_low_pc), then that one is used.
> +# * Otherwise, an error is reported.  Either specify a form explicitly, or
> +#   add a default for the the attribute name in _default_form.
>  #
>  # CHILDREN is just Tcl code that can be used to define child DIEs.  It
>  # is evaluated in the caller's context.
> @@ -377,7 +393,6 @@ namespace eval Dwarf {
>  
>      proc _read_constants {} {
>  	global srcdir hex decimal
> -	variable _constants
>  
>  	# DWARF name-matching regexp.
>  	set dwrx "DW_\[a-zA-Z0-9_\]+"
> @@ -404,8 +419,6 @@ namespace eval Dwarf {
>  	    }
>  	}
>  	close $fd
> -
> -	set _constants(SPECIAL_expr) $_constants(DW_FORM_block)
>      }
>  
>      proc _quote {string} {
> @@ -577,9 +590,25 @@ namespace eval Dwarf {
>  	    }
>  
>  	    default {
> +		return ""
> +	    }
> +	}
> +    }
> +
> +    proc _default_form { attr } {
> +	switch -exact -- $attr {
> +	    DW_AT_low_pc  {
> +		return DW_FORM_addr
> +	    }
> +	    DW_AT_producer -
> +	    DW_AT_comp_dir -
> +	    DW_AT_linkage_name -
> +	    DW_AT_MIPS_linkage_name -
> +	    DW_AT_name {
>  		return DW_FORM_string
>  	    }
>  	}
> +	return ""
>      }
>  
>      # Map NAME to its canonical form.
> @@ -596,24 +625,35 @@ namespace eval Dwarf {
>      proc _handle_attribute { attr_name attr_value attr_form } {
>  	variable _abbrev_section
>  	variable _constants
> +	variable _cu_version
>  
>  	_handle_DW_FORM $attr_form $attr_value
>  
>  	_defer_output $_abbrev_section {
> +	    if { $attr_form eq "SPECIAL_expr" } {
> +		if { $_cu_version < 4 } {
> +		    set attr_form_comment "DW_FORM_block"
> +		} else {
> +		    set attr_form_comment "DW_FORM_exprloc"
> +		}
> +	    } else {
> +		set attr_form_comment $attr_form
> +	    }
>  	    _op .uleb128 $_constants($attr_name) $attr_name
> -	    _op .uleb128 $_constants($attr_form) $attr_form
> +	    _op .uleb128 $_constants($attr_form) $attr_form_comment
>  	}
>      }
>  
>      # Handle macro attribute MACRO_AT_range.
>  
>      proc _handle_macro_at_range { attr_value } {
> -	if {[llength $attr_value] != 2} {
> -	    error "usage: MACRO_AT_range { func file }"
> +	if {[llength $attr_value] != 1} {
> +	    error "usage: MACRO_AT_range { func }"
>  	}
>  
>  	set func [lindex $attr_value 0]
> -	set src [lindex $attr_value 1]
> +	global srcdir subdir srcfile
> +	set src ${srcdir}/${subdir}/${srcfile}
>  	set result [function_range $func $src]
>  
>  	_handle_attribute DW_AT_low_pc [lindex $result 0] \
> @@ -625,7 +665,7 @@ namespace eval Dwarf {
>      # Handle macro attribute MACRO_AT_func.
>  
>      proc _handle_macro_at_func { attr_value } {
> -	if {[llength $attr_value] != 2} {
> +	if {[llength $attr_value] != 1} {
>  	    error "usage: MACRO_AT_func { func file }"
>  	}
>  	_handle_attribute DW_AT_name [lindex $attr_value 0] DW_FORM_string
> @@ -678,11 +718,13 @@ namespace eval Dwarf {
>  			_guess_form $attr_value attr_value
>  		    }
>  		} else {
> -		    # If the value looks like an integer, a form is required.
> -		    if [string is integer $attr_value] {
> -			error "Integer value requires a form"
> -		    }
>  		    set attr_form [_guess_form $attr_value attr_value]
> +		    if { $attr_form eq "" } {
> +			set attr_form [_default_form $attr_name]
> +		    }
> +		    if { $attr_form eq "" } {
> +			error "No form for $attr_name $attr_value"
> +		    }
>  		}
>  		set attr_form [_map_name $attr_form _FORM]
>  
> @@ -692,8 +734,8 @@ namespace eval Dwarf {
>  
>  	_defer_output $_abbrev_section {
>  	    # Terminator.
> -	    _op .byte 0x0 Terminator
> -	    _op .byte 0x0 Terminator
> +	    _op .byte 0x0 "DW_AT - Terminator"
> +	    _op .byte 0x0 "DW_FORM - Terminator"
>  	}
>  
>  	if {$has_children} {
> @@ -809,15 +851,6 @@ namespace eval Dwarf {
>  	_emit "${name}:"
>      }
>  
> -    # Declare a global label.  This is typically used to refer to
> -    # labels defined in other files, for example a function defined in
> -    # a .c file.
> -    proc extern {args} {
> -	foreach name $args {
> -	    _op .global $name
> -	}
> -    }
> -
>      # A higher-level interface to label handling.
>      #
>      # ARGS is a list of label descriptors.  Each one is either a
> @@ -841,13 +874,13 @@ namespace eval Dwarf {
>  	    set name [lindex $arg 0]
>  	    set text [lindex $arg 1]
>  
> -	    upvar $name label_var
> -	    if {$text == ""} {
> -		set label_var [new_label]
> -	    } else {
> -		set label_var [new_label $text]
> +	    if { $text == "" } {
> +		set text $name
>  	    }
>  
> +	    upvar $name label_var
> +	    set label_var [new_label $text]
> +
>  	    proc ${name}: {args} [format {
>  		define_label %s
>  		uplevel $args
> @@ -1013,13 +1046,14 @@ namespace eval Dwarf {
>      #                default = 0 (32-bit)
>      # version n    - DWARF version number to emit
>      #                default = 4
> -    # addr_size n  - the size of addresses, 32, 64, or default
> +    # addr_size n  - the size of addresses in bytes: 4, 8, or default
>      #                default = default
>      # fission 0|1  - boolean indicating if generating Fission debug info
>      #                default = 0
>      # BODY is Tcl code that emits the DIEs which make up the body of
>      # the CU.  It is evaluated in the caller's context.
>      proc cu {options body} {
> +	variable _constants
>  	variable _cu_count
>  	variable _abbrev_section
>  	variable _abbrev_num
> @@ -1059,6 +1093,12 @@ namespace eval Dwarf {
>  	    set _abbrev_section ".debug_abbrev.dwo"
>  	}
>  
> +	if {$_cu_version < 4} {
> +	    set _constants(SPECIAL_expr) $_constants(DW_FORM_block)
> +	} else {
> +	    set _constants(SPECIAL_expr) $_constants(DW_FORM_exprloc)
> +	}
> +
>  	_section $section
>  
>  	set cu_num [incr _cu_count]
> @@ -1089,8 +1129,7 @@ namespace eval Dwarf {
>  
>  	_defer_output $_abbrev_section {
>  	    # Emit the terminator.
> -	    _op .byte 0x0 Terminator
> -	    _op .byte 0x0 Terminator
> +	    _op .byte 0x0 "Abbrev end - Terminator"
>  	}
>  
>  	define_label $end_label
> @@ -1104,7 +1143,7 @@ namespace eval Dwarf {
>      #                default = 0 (32-bit)
>      # version n    - DWARF version number to emit
>      #                default = 4
> -    # addr_size n  - the size of addresses, 32, 64, or default
> +    # addr_size n  - the size of addresses in bytes: 4, 8, or default
>      #                default = default
>      # fission 0|1  - boolean indicating if generating Fission debug info
>      #                default = 0
> @@ -1198,8 +1237,7 @@ namespace eval Dwarf {
>  
>  	_defer_output $_abbrev_section {
>  	    # Emit the terminator.
> -	    _op .byte 0x0 Terminator
> -	    _op .byte 0x0 Terminator
> +	    _op .byte 0x0 "Abbrev end - Terminator"
>  	}
>  
>  	define_label $end_label
> @@ -1227,42 +1265,37 @@ namespace eval Dwarf {
>  	set section ".debug_ranges"
>  	_section $section
>  
> -	proc sequence {{ranges {}}} {
> +	proc sequence { body } {
>  	    variable _debug_ranges_64_bit
>  
>  	    # Emit the sequence of addresses.
> -	    set base ""
> -	    foreach range $ranges {
> -		set range [uplevel 1 "subst \"$range\""]
> -		set type [lindex $range 0]
> -		switch -exact -- $type {
> -		    base {
> -			set base [lrange $range 1 end]
> -
> -			if { $_debug_ranges_64_bit } then {
> -			    _op .8byte 0xffffffffffffffff "Base Marker"
> -			    _op .8byte $base "Base Address"
> -			} else {
> -			    _op .4byte 0xffffffff "Base Marker"
> -			    _op .4byte $base "Base Address"
> -			}
> -		    }
> -		    range {
> -			set start [lindex $range 1]
> -			set end [lrange $range 2 end]
> -
> -			if { $_debug_ranges_64_bit } then {
> -			    _op .8byte $start "Start Address"
> -			    _op .8byte $end "End Address"
> -			} else {
> -			    _op .4byte $start "Start Address"
> -			    _op .4byte $end "End Address"
> -			}
> -		    }
> -		    default { error "unknown range type: $type " }
> +
> +	    proc base { addr } {
> +		variable _debug_ranges_64_bit
> +
> +		if { $_debug_ranges_64_bit } then {
> +		    _op .8byte 0xffffffffffffffff "Base Marker"
> +		    _op .8byte $addr "Base Address"
> +		} else {
> +		    _op .4byte 0xffffffff "Base Marker"
> +		    _op .4byte $addr "Base Address"
>  		}
>  	    }
>  
> +	    proc range { start end } {
> +		variable _debug_ranges_64_bit
> +
> +		if { $_debug_ranges_64_bit } then {
> +		    _op .8byte $start "Start Address"
> +		    _op .8byte $end "End Address"
> +		} else {
> +		    _op .4byte $start "Start Address"
> +		    _op .4byte $end "End Address"
> +		}
> +	    }
> +
> +	    uplevel $body
> +
>  	    # End of the sequence.
>  	    if { $_debug_ranges_64_bit } then {
>  		_op .8byte 0x0 "End of Sequence Marker (Part 1)"
> @@ -1285,7 +1318,7 @@ namespace eval Dwarf {
>      #                default = 0 (32-bit)
>      # version n    - DWARF version number to emit
>      #                default = 4
> -    # addr_size n  - the size of addresses, 32, 64, or default
> +    # addr_size n  - the size of addresses in bytes: 4, 8, or default
>      #                default = default
>      #
>      # LABEL is the label of the current unit (which is probably
> @@ -1312,12 +1345,16 @@ namespace eval Dwarf {
>  	set is_64 0
>  	set _unit_version 4
>  	set _unit_addr_size default
> +	set _line_saw_program 0
> +	set _line_saw_file 0
> +	set _default_is_stmt 1
>  
>  	foreach { name value } $options {
>  	    switch -exact -- $name {
>  		is_64 { set is_64 $value }
>  		version { set _unit_version $value }
>  		addr_size { set _unit_addr_size $value }
> +		default_is_stmt { set _default_is_stmt $value }
>  		default { error "unknown option $name" }
>  	    }
>  	}
> @@ -1364,7 +1401,7 @@ namespace eval Dwarf {
>  	define_label $header_len_label
>  
>  	_op .byte 1 "minimum_instruction_length"
> -	_op .byte 1 "default_is_stmt"
> +	_op .byte $_default_is_stmt "default_is_stmt"
>  	_op .byte 1 "line_base"
>  	_op .byte 1 "line_range"
>  	_op .byte 10 "opcode_base"
> @@ -1406,6 +1443,9 @@ namespace eval Dwarf {
>  	proc program {statements} {
>  	    variable _line_saw_program
>  	    variable _line_header_end_label
> +	    variable _line
> +
> +	    set _line 1
>  
>  	    if "! $_line_saw_program" {
>  		# Terminate the file list.
> @@ -1430,23 +1470,67 @@ namespace eval Dwarf {
>  	    }
>  
>  	    proc DW_LNE_end_sequence {} {
> +		variable _line
>  		_op .byte 0
>  		_op .uleb128 1
>  		_op .byte 1
> +		set _line 1
> +	    }
> +
> +	    proc DW_LNE_user { len opcode } {
> +		set DW_LNE_lo_usr 0x80
> +		set DW_LNE_hi_usr 0xff
> +		if { $DW_LNE_lo_usr <= $opcode
> +		     && $opcode <= $DW_LNE_hi_usr } {
> +		    _op .byte 0
> +		    _op .uleb128 $len
> +		    _op .byte $opcode
> +		    for {set i 1} {$i < $len} {incr i} {
> +			_op .byte 0
> +		    }
> +		} else {
> +		    error "unknown vendor specific extended opcode: $opcode"
> +		}
>  	    }
>  
>  	    proc DW_LNS_copy {} {
>  		_op .byte 1
>  	    }
>  
> +	    proc DW_LNS_negate_stmt {} {
> +		_op .byte 6
> +	    }
> +
>  	    proc DW_LNS_advance_pc {offset} {
>  		_op .byte 2
>  		_op .uleb128 ${offset}
>  	    }
>  
>  	    proc DW_LNS_advance_line {offset} {
> +		variable _line
>  		_op .byte 3
>  		_op .sleb128 ${offset}
> +		set _line [expr $_line + $offset]
> +	    }
> +
> +	    # A pseudo line number program instruction, that can be used instead
> +	    # of DW_LNS_advance_line.  Rather than writing:
> +	    #   {DW_LNS_advance_line [expr $line1 - 1]}
> +	    #   {DW_LNS_advance_line [expr $line2 - $line1]}
> +	    #   {DW_LNS_advance_line [expr $line3 - $line2]}
> +	    # we can just write:
> +	    #   {line $line1}
> +	    #   {line $line2}
> +	    #   {line $line3}
> +	    proc line {line} {
> +		variable _line
> +		set offset [expr $line - $_line]
> +		DW_LNS_advance_line $offset
> +	    }
> +
> +	    proc DW_LNS_set_file {num} {
> +		_op .byte 4
> +		_op .sleb128 ${num}
>  	    }
>  
>  	    foreach statement $statements {
> 

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

end of thread, other threads:[~2020-12-20  8:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-14 21:19 [PATCH] Update dwarf.exp assembler from gdb Mark Wielaard
2020-12-20  8:33 ` Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).