From patchwork Mon Nov 10 02:04:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 3631 Received: (qmail 24681 invoked by alias); 10 Nov 2014 02:04:24 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 24665 invoked by uid 89); 10 Nov 2014 02:04:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 10 Nov 2014 02:04:21 +0000 Received: from svr-orw-fem-03.mgc.mentorg.com ([147.34.97.39]) by relay1.mentorg.com with esmtp id 1XneL3-0002Ws-RU from Yao_Qi@mentor.com ; Sun, 09 Nov 2014 18:04:17 -0800 Received: from GreenOnly (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.3.181.6; Sun, 9 Nov 2014 18:04:17 -0800 From: Yao Qi To: Doug Evans CC: gdb-patches Subject: Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range References: <1414195968-3333-1-git-send-email-yao@codesourcery.com> <1414195968-3333-3-git-send-email-yao@codesourcery.com> <21593.22575.941029.980760@ruffy2.mtv.corp.google.com> <87fvdypgap.fsf@codesourcery.com> Date: Mon, 10 Nov 2014 10:04:13 +0800 In-Reply-To: (Doug Evans's message of "Fri, 7 Nov 2014 08:54:20 -0800") Message-ID: <87k333izfm.fsf@codesourcery.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Doug Evans writes: >>> 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? >> >> I don't see any difficulties to implement MACRO_AT_{func,range} as >> functions here, but could you tell me why do you prefer to do that? >> Is it because they are macros? > > I was thinking long term I'd rather maintain the individual functions > instead of one large switch statement, all else being equal, and if I > have the choice. OK, that is fine. I add two procedures for MACROS_AT_{func,range} respectively in the updated patch below. As a result, _handle_macro_attribute is no longer needed, so I remove it from the updated patch too. >> + file delete $exe >> + >> + return [list "${func}_label - $func_label_offset" $func_length] >> +} >> + > In the immortal words of Shrek, "Hold the phone." ... > "file delete $exe" is a local operation. > While in general we don't delete test artifacts, > I'm left wondering if something about this won't > work with remote host testing. > Is that true? Or can "file delete $exe" just be deleted? I am inclined to delete them via "remote_file host delete" as many executables func_addr[pid].x are generated. Supposing dwarf assembler works perfectly, people have only to concentrate on their test artifacts instead of func_addr[pid].x. diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 4986f83..dc1ae0f 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] + } + } + + remote_file host 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,33 @@ namespace eval Dwarf { } } + # 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 }" + } + + 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 + } + + # Handle macro attribute MACRO_AT_func. + + proc _handle_macro_at_func { attr_value } { + if {[llength $attr_value] != 2} { + error "usage: MACRO_AT_func { func file }" + } + _handle_attribute DW_AT_name [lindex $attr_value 0] DW_FORM_string + _handle_macro_at_range $attr_value + } + proc _handle_DW_TAG {tag_name {attrs {}} {children {}}} { variable _abbrev_section variable _abbrev_num @@ -494,14 +607,21 @@ 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 equal "MACRO_AT_func" $attr_name] } { + _handle_macro_at_func $attr_value + } elseif { [string equal "MACRO_AT_range" $attr_name] } { + _handle_macro_at_range $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 {