From patchwork Tue Jan 24 09:42:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 19004 Received: (qmail 15701 invoked by alias); 24 Jan 2017 09:43:01 -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 15610 invoked by uid 89); 24 Jan 2017 09:43:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=UD:dwarf2, Compilation, gdb.dwarf2, UD:gdb.dwarf2 X-HELO: mail-pg0-f65.google.com Received: from mail-pg0-f65.google.com (HELO mail-pg0-f65.google.com) (74.125.83.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 24 Jan 2017 09:42:49 +0000 Received: by mail-pg0-f65.google.com with SMTP id t6so16255449pgt.1 for ; Tue, 24 Jan 2017 01:42:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BGLvP026GM0T98VBIiZ9Nq4jGlKmFEmx/IM74pQ60mM=; b=T4G1+DKmglwsfumg3J3NUgaJrMGpLci31PiMjZsNTjTsV8ya6Io/a+ZgNenEhnldZ1 NS+WFHFa6v4oEM5fc9nW97wI9lYDKTtEtZH40Aw0p1DREdE0pA7h+5cGmzXYd0xCGPfk soIX9Id0HkiNq7lfYlkD+JBZJb+TYcVvgz6oYXUbXO+WFTQTuMzjYxPFUmpRMaeH3mPI y/ufAoBb81iDntDdYxcdnhD3hPFTcNMzNvtZjyD1rLXsnAzmLFGwL1BCwTLs27VfsyXh 8gdhCmly9ftS6p8lbw3iXcdQTHphN2Jj7PoqJU7uf6emm2aAQdq9lbFsD6KwQzevJn7i kDBA== X-Gm-Message-State: AIkVDXL1AsJgBR1lQgGjCJsjb1tjGwgTC1w887N6zJCCMJA67OdYtlj6/VoyG/UCqtoX7Q== X-Received: by 10.84.224.199 with SMTP id k7mr50725229pln.25.1485250967979; Tue, 24 Jan 2017 01:42:47 -0800 (PST) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id f65sm43211760pfk.5.2017.01.24.01.42.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Jan 2017 01:42:47 -0800 (PST) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Cc: arnez@linux.vnet.ibm.com Subject: [PATCH 2/2] Use dwarf assembler in gdb.dwarf2/implptr-64bit.exp Date: Tue, 24 Jan 2017 09:42:25 +0000 Message-Id: <1485250945-17594-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1485250945-17594-1-git-send-email-yao.qi@linaro.org> References: <1485250945-17594-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes This patch adds a DW_OP_implicit_value in dwarf assembler, and uses dwarf assembler in implptr-64bit.exp. Using dwarf assembler in implptr-64bit.exp exposes some limitations in dwarf assembler, - some variables are not evaluated in the caller's context, so we can not pass variable to assembler, like this Dwarf::assemble $asm_file { cu { version $dwarf_version addr_size $addr_size is_64 $is_64 } { } and {DW_AT_type :$struct_label "DW_FORM_ref$ref_addr_size"} this limitation is fixed by adding "uplevel" and "subst". - dwarf assembler doesn't emit DW_FORM_ref_addr for label referencing. this limitation is fixed by adding a new character "%", { type %$int_label } this means we want to emit DW_FORM_ref_addr for label referencing. - we can't set the form of label referencing offset in dwarf assembler. Nowadays, dwarf assembler guesses the form of labels, which is DW_FORM_ref4. However, in implptr-64bit.exp, both DW_FORM_ref4 and DW_FORM_ref8 is used (see REF_ADDR in implptr-64bit.S). This patch adds the flexibility of setting the form of label reference. Both of them below are valid, {DW_AT_type :$struct_label} {DW_AT_type :$struct_label DW_FORM_ref8} the former form is the default DW_FORM_ref4. I compared the .debug_info of objects without and with this patch applied. There is no changes except abbrev numbers. gdb/testsuite: 2017-01-24 Andreas Arnez Yao Qi * gdb.dwarf2/implptr-64bit.exp: Use dwarf assembler. * gdb.dwarf2/implptr-64bit.S: Remove. * lib/dwarf.exp (Dwarf): Handle character "%". Evaluate some variables in caller's context. (Dwarf::_location): Add handling for DW_OP_implicit_value. --- gdb/testsuite/gdb.dwarf2/implptr-64bit.S | 226 ----------------------------- gdb/testsuite/gdb.dwarf2/implptr-64bit.exp | 118 +++++++++++++-- gdb/testsuite/lib/dwarf.exp | 39 ++++- 3 files changed, 147 insertions(+), 236 deletions(-) delete mode 100644 gdb/testsuite/gdb.dwarf2/implptr-64bit.S diff --git a/gdb/testsuite/gdb.dwarf2/implptr-64bit.S b/gdb/testsuite/gdb.dwarf2/implptr-64bit.S deleted file mode 100644 index 003bf20..0000000 --- a/gdb/testsuite/gdb.dwarf2/implptr-64bit.S +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright 2010-2017 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 . */ - - .section .debug_info -d: - /* Length of Compilation Unit Info */ -#if OFFSET_SIZE == 4 -# define OFFSET .4byte -# define HEADER_LINE1 -# define HEADER_LINE2(END) .4byte END - 1f -#elif OFFSET_SIZE == 8 -# define OFFSET .8byte -# define HEADER_LINE1 .4byte 0xffffffff -# define HEADER_LINE2(END) .8byte END - 1f -#else -# error -#endif -#if ADDR_SIZE == 4 -# define ADDR .4byte -#elif ADDR_SIZE == 8 -# define ADDR .8byte -#else -# error -#endif -#if REF_ADDR_SIZE == 4 -# define REF_ADDR .4byte -#elif REF_ADDR_SIZE == 8 -# define REF_ADDR .8byte -#else -# error -#endif - -#if TWO_CU -# define END1 .Lcu_end_1 -#else -# define END1 debug_end -#endif - - HEADER_LINE1 - HEADER_LINE2(END1) - -1: - .2byte DWARF_VERSION /* DWARF version number */ - OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ - .byte ADDR_SIZE /* Pointer Size (in bytes) */ - - .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ - .ascii "GNU C 4.4.3\0" /* DW_AT_producer */ - .byte 0x1 /* DW_AT_language */ - .ascii "1.c\0" /* DW_AT_name */ - -.Ltype_int: - .uleb128 0x7 /* DW_TAG_base_type */ - .byte 0x4 /* DW_AT_byte_size */ - .byte 0x5 /* DW_AT_encoding */ - .ascii "int\0" /* DW_AT_name */ - -.Ltype_struct: - .uleb128 0x2 /* DW_TAG_structure_type */ - .ascii "s\0" /* DW_AT_name */ - .byte 4 /* DW_AT_byte_size */ - - .uleb128 0x3 /* DW_TAG_member */ - .ascii "f\0" /* DW_AT_name */ - .4byte .Ltype_int - d /* DW_AT_type */ - .byte 0 /* DW_AT_data_member_location */ - - .byte 0x0 /* end of children of DW_TAG_structure_type */ - -.Ltype_structptr: - .uleb128 0x5 /* DW_TAG_pointer_type */ - .byte ADDR_SIZE /* DW_AT_byte_size */ - .4byte .Ltype_struct - d /* DW_AT_type */ - -.Lvar_out: - .uleb128 0x4 /* (DW_TAG_variable) */ - .ascii "v\0" /* DW_AT_name */ - .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */ -1: - .byte 0x9e /* DW_OP_implicit_value */ - .uleb128 2f - 3f -3: - .byte 1, 1, 1, 1 -2: - REF_ADDR .Ltype_struct - d /* DW_AT_type */ - -#if TWO_CU - .byte 0x0 /* end of children of CU */ -.Lcu_end_1: - - HEADER_LINE1 - HEADER_LINE2 (debug_end) - -1: - .2byte DWARF_VERSION /* DWARF version number */ - OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ - .byte ADDR_SIZE /* Pointer Size (in bytes) */ - - .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ - .ascii "GNU C 4.4.3\0" /* DW_AT_producer */ - .byte 0x1 /* DW_AT_language */ - .ascii "1.c\0" /* DW_AT_name */ -#endif - - .uleb128 6 /* Abbrev: DW_TAG_subprogram */ - .ascii "main\0" /* DW_AT_name */ - ADDR main /* DW_AT_low_pc */ - ADDR main + 0x100 /* DW_AT_high_pc */ - REF_ADDR .Ltype_int - d /* DW_AT_type */ - .byte 1 /* DW_AT_external */ - - .uleb128 0x4 /* (DW_TAG_variable) */ - .ascii "p\0" /* DW_AT_name */ - .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */ -1: - .byte 0xf2 /* DW_OP_GNU_implicit_pointer */ - REF_ADDR .Lvar_out - d /* referenced DIE */ - .sleb128 0 /* offset */ -2: - REF_ADDR .Ltype_structptr - d /* DW_AT_type */ - - .byte 0x0 /* end of children of main */ - - .byte 0x0 /* end of children of CU */ -debug_end: - - .section .debug_abbrev -.Ldebug_abbrev0: - - .uleb128 0x1 /* (abbrev code) */ - .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ - .byte 0x1 /* DW_children_yes */ - .uleb128 0x25 /* (DW_AT_producer) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .uleb128 0x13 /* (DW_AT_language) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .uleb128 0x3 /* (DW_AT_name) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .byte 0x0 - .byte 0x0 - - .uleb128 0x2 /* (abbrev code) */ - .uleb128 0x13 /* (TAG: DW_TAG_structure_type) */ - .byte 0x1 /* DW_children_yes */ - .uleb128 0x3 /* (DW_AT_name) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .uleb128 0xb /* (DW_AT_byte_size) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .byte 0 - .byte 0 - - .uleb128 0x3 /* (abbrev code) */ - .uleb128 0xd /* (TAG: DW_TAG_member) */ - .byte 0 /* DW_children_no */ - .uleb128 0x3 /* (DW_AT_name) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .uleb128 0x49 /* (DW_AT_type) */ - .uleb128 0x13 /* (DW_FORM_ref4) */ - .uleb128 0x38 /* (DW_AT_data_member_location) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .byte 0 - .byte 0 - - .uleb128 0x4 /* (abbrev code) */ - .uleb128 0x34 /* (TAG: DW_TAG_variable) */ - .byte 0x0 /* DW_children_yes */ - .uleb128 0x3 /* (DW_AT_name) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .uleb128 0x02 /* (DW_AT_location) */ - .uleb128 0xa /* (DW_FORM_block1) */ - .uleb128 0x49 /* (DW_AT_type) */ - .uleb128 0x10 /* (DW_FORM_ref_addr) */ - .byte 0x0 - .byte 0x0 - - .uleb128 0x5 /* (abbrev code) */ - .uleb128 0xf /* (TAG: DW_TAG_pointer_type) */ - .byte 0x0 /* DW_children_no */ - .uleb128 0xb /* (DW_AT_byte_size) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .uleb128 0x49 /* (DW_AT_type) */ - .uleb128 0x13 /* (DW_FORM_ref4) */ - .byte 0x0 - .byte 0x0 - - .uleb128 6 /* Abbrev code */ - .uleb128 0x2e /* DW_TAG_subprogram */ - .byte 1 /* has_children */ - .uleb128 0x3 /* DW_AT_name */ - .uleb128 0x8 /* DW_FORM_string */ - .uleb128 0x11 /* DW_AT_low_pc */ - .uleb128 0x1 /* DW_FORM_addr */ - .uleb128 0x12 /* DW_AT_high_pc */ - .uleb128 0x1 /* DW_FORM_addr */ - .uleb128 0x49 /* DW_AT_type */ - .uleb128 0x10 /* DW_FORM_ref_addr */ - .uleb128 0x3f /* DW_AT_external */ - .uleb128 0xc /* DW_FORM_flag */ - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ - - .uleb128 0x7 /* (abbrev code) */ - .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ - .byte 0 /* DW_children_no */ - .uleb128 0xb /* (DW_AT_byte_size) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .uleb128 0x3e /* (DW_AT_encoding) */ - .uleb128 0xb /* (DW_FORM_data1) */ - .uleb128 0x3 /* (DW_AT_name) */ - .uleb128 0x8 /* (DW_FORM_string) */ - .byte 0 - .byte 0 - - .byte 0x0 diff --git a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp index b4dcbde..9565579 100644 --- a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp +++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp @@ -19,21 +19,121 @@ if {![dwarf2_support]} { return 0 } -standard_testfile .S -set mainfile main.c +standard_testfile main.c proc test { dwarf_version offset_size addr_size ref_addr_size two_cu } { - global testfile srcfile mainfile + global testfile srcfile - # 32-bit targets do not support any of the testcases; keep quiet there. - set opts {quiet} - foreach n { dwarf_version offset_size addr_size ref_addr_size two_cu } { - lappend opts "additional_flags=-D[string toupper $n]=[expr "\$$n"]" + set name "d${dwarf_version}o${offset_size}a${addr_size}r${ref_addr_size}t${two_cu}" + + # Make some DWARF for the test. + set asm_file [standard_output_file ${testfile}-${name}.S] + Dwarf::assemble $asm_file { + upvar dwarf_version dwarf_version + upvar addr_size addr_size + upvar offset_size offset_size + upvar ref_addr_size ref_addr_size + upvar two_cu two_cu + + set is_64 [expr { $offset_size == 4 ? 0 : 1 }] + + cu { + version $dwarf_version + addr_size $addr_size + is_64 $is_64 + } { + compile_unit { + { producer "GNU C 4.4.3" } + { language @DW_LANG_C89 } + { name 1.c } + } { + declare_labels struct_label variable_label int_label pointer_label + + int_label: base_type { + { byte_size 4 DW_FORM_sdata } + { DW_AT_encoding @DW_ATE_signed } + { name int } + } + + struct_label: structure_type { + { name s } + { byte_size 4 sdata } + } { + member { + { name f } + { type :$int_label } + { data_member_location 0 data1 } + } + } + + pointer_label: pointer_type { + { byte_size $Dwarf::_cu_addr_size sdata } + { type :$struct_label } + } + + variable_label: variable { + { name v } + { location { + DW_OP_implicit_value 0x1 0x1 0x1 0x1 + } SPECIAL_expr} + { type :$struct_label "DW_FORM_ref$ref_addr_size" } + } + + if { !$two_cu } { + subprogram { + { name main } + { low_pc main addr } + { high_pc "main+0x100" addr } + { type %$int_label } + { external 1 flag } + } { + variable { + { name p } + { location { + GNU_implicit_pointer $variable_label 0 + } SPECIAL_expr } + { type :$pointer_label "DW_FORM_ref$ref_addr_size" } + } + } + } + } + } + + if { $two_cu } { + cu { + version $dwarf_version + addr_size $addr_size + is_64 $is_64 + } { + compile_unit { + { producer "GNU C 4.4.3" } + { language @DW_LANG_C89 } + { name 1.c } + } { + subprogram { + { name main } + { low_pc main addr } + { high_pc "main+0x100" addr } + { type %$int_label } + { external 1 flag } + } { + DW_TAG_variable { + { name p } + { location { + GNU_implicit_pointer $variable_label 0 + } SPECIAL_expr } + { type %$pointer_label } + } + } + } + } + } } - set name "d${dwarf_version}o${offset_size}a${addr_size}r${ref_addr_size}t${two_cu}" + # 32-bit targets do not support any of the testcases; keep quiet there. + set opts {quiet} set executable ${testfile}-${name} - if [prepare_for_testing "failed to prepare" $executable "${srcfile} ${mainfile}" $opts] { + if [prepare_for_testing "failed to prepare" $executable "${asm_file} ${srcfile}" $opts] { return -1 } diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 1883c86..db51f5d 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -229,6 +229,8 @@ proc function_range { func src } { # * If VALUE starts with the ":" character, then it is a label # reference. The rest of VALUE is taken to be the name of a label, # 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 @@ -559,6 +561,15 @@ namespace eval Dwarf { return DW_FORM_ref4 } + % { + # Label reference, an offset from .debug_info. Assuming + # .Lcu1_begin is on .debug_info. + set cu1_label [_compute_label "cu1_begin"] + set new_value "[string range $value 1 end] - $cu1_label" + + return DW_FORM_ref_addr + } + default { return DW_FORM_string } @@ -654,7 +665,12 @@ namespace eval Dwarf { _handle_macro_at_range $attr_value } else { if {[llength $attr] > 2} { - set attr_form [lindex $attr end] + set attr_form [uplevel 2 [list subst [lindex $attr end]]] + + if { [string index $attr_value 0] == ":" } { + # It is a label, get its value. + _guess_form $attr_value attr_value + } } else { # If the value looks like an integer, a form is required. if [string is integer $attr_value] { @@ -912,6 +928,26 @@ namespace eval Dwarf { _op .2byte [lindex $line 1] } + DW_OP_implicit_value { + set l1 [new_label "value_start"] + set l2 [new_label "value_end"] + _op .uleb128 "$l2 - $l1" + define_label $l1 + foreach value [lrange $line 1 end] { + switch -regexp -- $value { + {^0x[[:xdigit:]]{1}$} {_op .byte $value} + {^0x[[:xdigit:]]{2}$} {_op .byte $value} + {^0x[[:xdigit:]]{4}$} {_op .2byte $value} + {^0x[[:xdigit:]]{8}$} {_op .4byte $value} + {^0x[[:xdigit:]]{16}$} {_op .8byte $value} + default { + error "bad value '$value' in DW_OP_implicit_value" + } + } + } + define_label $l2 + } + DW_OP_GNU_implicit_pointer { if {[llength $line] != 3} { error "usage: DW_OP_GNU_implicit_pointer LABEL OFFSET" @@ -981,6 +1017,7 @@ namespace eval Dwarf { set _abbrev_section ".debug_abbrev" foreach { name value } $options { + set value [uplevel 1 "subst \"$value\""] switch -exact -- $name { is_64 { set is_64 $value } version { set _cu_version $value }