[PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range

Doug Evans dje@google.com
Tue Nov 4 22:50:00 GMT 2014


Yao Qi writes:
 > This patch addes DW macro attributes MACRO_AT_func and MACRO_AT_range
 > in dwarf assembler, which emits "DW_AT_low_pc func_start addr" and
 > "DW_AT_high_pc func_end addr".  func_start and func_end are computed
 > automatically by proc function_range.
 > 
 > These two attributes are pseudo attribute or macro attribute, which
 > means they are not standard dwarf attribute in dwarf spec.  Then can
 > be substituted or expanded to standard attributes or macro attributes.
 > See details in the comments to them.  Dwarf assembler is extended to
 > handle them.
 > 
 > Now the attributes name/low_pc/high_pc can be replaced with
 > MACRO_AT_func like this:
 > 
 >     subprogram {
 > 	{name main}
 > 	{low_pc main_start addr}
 > 	{high_pc main_end addr}
 >     }
 > 
 > becomes:
 > 
 >     subprogram {
 > 	{MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
 >     }
 > 
 > users don't have to worry about the start and end of function main, and
 > they only need to add a label main_label in main.
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* lib/dwarf.exp (function_range): New procedure.
 > 	(Dwarf::_handle_macro_attribute): New procedure.
 > 	(Dwarf): Handle MACRO_AT_func and MACRO_AT_range.
 > ---
 >  gdb/testsuite/lib/dwarf.exp | 128 +++++++++++++++++++++++++++++++++++++++++---
 >  1 file changed, 122 insertions(+), 6 deletions(-)
 > 
 > diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
 > index 4986f83..401e791 100644
 > --- a/gdb/testsuite/lib/dwarf.exp
 > +++ b/gdb/testsuite/lib/dwarf.exp
 > @@ -86,6 +86,81 @@ proc build_executable_from_fission_assembler { testname executable sources optio
 >      return 0
 >  }
 >  
 > +# Return a list of expressions about function FUNC's address and length.
 > +# The first expression is the address of function FUNC, and the second
 > +# one is FUNC's length.  SRC is the source file having function FUNC.
 > +# An internal label ${func}_label must be defined inside FUNC:
 > +#
 > +#  int main (void)
 > +#  {
 > +#    asm ("main_label: .globl main_label");
 > +#    return 0;
 > +#  }
 > +#
 > +# This label is needed to compute the start address of function FUNC.
 > +# If the compiler is gcc, we can do the following to get function start
 > +# and end address too:
 > +#
 > +# asm ("func_start: .globl func_start");
 > +# static void func (void) {}
 > +# asm ("func_end: .globl func_end");
 > +#
 > +# however, this isn't portable, because other compilers, such as clang,
 > +# may not guarantee the order of global asms and function.  The code
 > +# becomes:
 > +#
 > +# asm ("func_start: .globl func_start");
 > +# asm ("func_end: .globl func_end");
 > +# static void func (void) {}
 > +#
 > +
 > +proc function_range { func src } {
 > +    global decimal gdb_prompt
 > +
 > +    set exe [standard_temp_file func_addr[pid].x]
 > +
 > +    gdb_compile $src $exe executable {debug}
 > +
 > +    gdb_exit
 > +    gdb_start
 > +    gdb_load "$exe"
 > +
 > +    # Compute the label offset, and we can get the function start address
 > +    # by "${func}_label - $func_label_offset".
 > +    set func_label_offset ""
 > +    set test "p ${func}_label - ${func}"
 > +    gdb_test_multiple $test $test {
 > +	-re ".* = ($decimal)\r\n$gdb_prompt $" {
 > +	    set func_label_offset $expect_out(1,string)
 > +	}
 > +    }
 > +
 > +    # Compute the function length.
 > +    global hex
 > +    set func_length ""
 > +    set test "disassemble $func"
 > +    gdb_test_multiple $test $test {
 > +	-re ".*$hex <\\+($decimal)>:\[^\r\n\]+\r\nEnd of assembler dump\.\r\n$gdb_prompt $" {
 > +	    set func_length $expect_out(1,string)
 > +	}
 > +    }
 > +
 > +    # Compute the size of the last instruction.
 > +    set test "x/2i $func+$func_length"
 > +    gdb_test_multiple $test $test {
 > +	-re ".*($hex) <$func\\+$func_length>:\[^\r\n\]+\r\n\[ \]+($hex).*\.\r\n$gdb_prompt $" {
 > +	    set start $expect_out(1,string)
 > +	    set end $expect_out(2,string)
 > +
 > +	    set func_length [expr $func_length + $end - $start]
 > +	}
 > +    }
 > +
 > +    file delete $exe
 > +
 > +    return [list "${func}_label - $func_label_offset" $func_length]
 > +}
 > +
 >  # A DWARF assembler.
 >  #
 >  # All the variables in this namespace are private to the
 > @@ -121,6 +196,17 @@ proc build_executable_from_fission_assembler { testname executable sources optio
 >  # This can either be the full name, like 'DW_AT_name', or a shortened
 >  # name, like 'name'.  These are fully equivalent.
 >  #
 > +# Besides DWARF standard attributes, assembler supports 'macro' attribute
 > +# which will be substituted by one or more standard or macro attributes.
 > +# supported macro attributes are:
 > +#
 > +#  - MACRO_AT_range { FUNC FILE }
 > +#  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.
 > +#
 > +#  - MACRO_AT_func { FUNC FILE }
 > +#  It is substituted by DW_AT_name with FUNC and MACRO_AT_range.
 > +#
 >  # If FORM is given, it should name a DW_FORM_ constant.
 >  # This can either be the short form, like 'DW_FORM_addr', or a
 >  # shortened version, like 'addr'.  If the form is given, VALUE
 > @@ -473,6 +559,31 @@ namespace eval Dwarf {
 >  	}
 >      }
 >  
 > +    proc _handle_macro_attribute { attr_name attr_value } {
 > +	switch -exact -- $attr_name {
 > +	    MACRO_AT_func  {
 > +		_handle_attribute DW_AT_name [lindex $attr_value 0] \
 > +		    DW_FORM_string
 > +
 > +		_handle_macro_attribute MACRO_AT_range $attr_value
 > +	    }
 > +	    MACRO_AT_range {
 > +		if {[llength $attr_value] != 2} {
 > +		    error "usage: $attr_name { func file }"
 > +		}
 > +		set func [lindex $attr_value 0]
 > +		set src [lindex $attr_value 1]
 > +
 > +		set result [function_range $func $src]
 > +		_handle_attribute DW_AT_low_pc [lindex $result 0] \
 > +		    DW_FORM_addr
 > +		_handle_attribute DW_AT_high_pc \
 > +		    "[lindex $result 0] + [lindex $result 1]" DW_FORM_addr
 > +	    }
 > +	    default { error "unknown macro attribute $attr_name" }
 > +	}
 > +    }
 > +
 >      proc _handle_DW_TAG {tag_name {attrs {}} {children {}}} {
 >  	variable _abbrev_section
 >  	variable _abbrev_num
 > @@ -494,14 +605,19 @@ namespace eval Dwarf {
 >  	foreach attr $attrs {
 >  	    set attr_name [_map_name [lindex $attr 0] _AT]
 >  	    set attr_value [uplevel 2 [list subst [lindex $attr 1]]]
 > -	    if {[llength $attr] > 2} {
 > -		set attr_form [lindex $attr 2]
 > +
 > +	    if { [string match "MACRO_AT_*" $attr_name] } {
 > +		_handle_macro_attribute $attr_name $attr_value
 >  	    } else {
 > -		set attr_form [_guess_form $attr_value attr_value]
 > -	    }
 > -	    set attr_form [_map_name $attr_form _FORM]
 > +		if {[llength $attr] > 2} {
 > +		    set attr_form [lindex $attr 2]
 > +		} else {
 > +		    set attr_form [_guess_form $attr_value attr_value]
 > +		}
 > +		set attr_form [_map_name $attr_form _FORM]
 >  
 > -	    _handle_attribute $attr_name $attr_value $attr_form
 > +		_handle_attribute $attr_name $attr_value $attr_form
 > +	    }
 >  	}
 >  
 >  	_defer_output $_abbrev_section {

Hi.

IWBN if one could add new macros simply by writing a new function.

Can _handle_macro_attribute be rewritten such that
MACRO_AT_{func,range} are themselves functions?



More information about the Gdb-patches mailing list