public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Use correct function address in dwarf assembler
@ 2014-10-25  0:17 Yao Qi
  2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:17 UTC (permalink / raw)
  To: gdb-patches

When we use dwarf assembler, it is common to generate DW_AT_low_pc and
DW_AT_high_pc attributes like this:

 	    subprogram {
		{name main}
		{low_pc main addr}
		{high_pc main+0x100 addr}
            }

however, main is not resolved to function main's address on some
targets such as arm thumb mode and powerpc64.  One approach is to
get function address by labels, like this:

  asm ("func_start: .globl func_start");
  static void func (void) {}
  asm ("func_end: .globl func_end");

however, some compiler, such as clang, can't guarantee the order of
these labels and function, so it isn't portable.

In this patch series, we propose a new approach 

 1. get function start and end address correctly in a portable way,
 2. don't affect too much on existing test cases.

In patch 2/6, a new proc function_range is added.  In this proc, the
source file is compiled with debug info.

  int main (void)
  {
    asm ("main_label: .globl main_label");
    return 0;
  }

we can get the offset of main_label in function main, and then compute
the start address of main via main_label - main_label_offset.  This is
portable.

In order to avoid much changes to existing test cases, we have to use
function_range inside dwarf assembler.  Then, I invent some attribute
macros which look like DW attributes, but can be expanded to one or
more standard attributes.  The TAG_subprogram above will be simplified
with macro attribute used, it becomes:

    subprogram {
	{MACRO_AT_func { func ${srcdir}/${subdir}/${srcfile} }}
    }

With this macro attribute, attributes name, low_pc and high_pc are
generated and set correctly.  See more details in patch 2/6.

Patch 4/6 is to use dwarf assembler to generate .S file, which is
identical to .S current one we are using.  Patch 3 and 5 is to use
macro attributes to get function start and end address correctly.
Patch 6 is remove labels and switch to use macro attribute to
get function start address to make clang happy.

I test the whole series by running tests under gdb.dwarf2/ on
powerpc-linux (both 32-bit and 64-bit), arm-none-eabi (arm mode
and thumb mode) and x86_64-linux.

Comments are very welcome!

*** BLURB HERE ***

Yao Qi (6):
  New proc _handle_attribute
  DW attribute macro MACRO_AT_func and MACRO_AT_range
  Get start and end address of main in dwz.exp
  Use Dwarf::assemble in implptr-optimized-out.exp
  Fix implptr-optimized-out.exp fail
  Fix dw2-ifort-parameter.exp fail with clang

 gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c     |   7 +-
 gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp   |   8 +-
 gdb/testsuite/gdb.dwarf2/dwz.exp                   |  60 +-------
 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S   | 166 ---------------------
 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp |  63 +++++++-
 gdb/testsuite/gdb.dwarf2/main.c                    |   1 +
 gdb/testsuite/lib/dwarf.exp                        | 143 ++++++++++++++++--
 7 files changed, 201 insertions(+), 247 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S

-- 
1.9.3

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

* [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
  2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:54   ` Doug Evans
  2014-10-25  0:18 ` [PATCH 3/6] Get start and end address of main in dwz.exp Yao Qi
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

The patch <https://sourceware.org/ml/gdb-patches/2014-03/msg00202.html>
fixed dw2-ifort-parameter.exp on powerpc64 by adding some labels to
get the start and end address of function func.  This should also fix the
fail on thumb mode, however, this style is quite specific to gcc, and
other compiler, such as clang, may not guarantee the order of global
asms and functions.  The test fails with clang:

$ make check RUNTESTFLAGS='dw2-ifort-parameter.exp CC_FOR_TARGET=clang'
(gdb) p/x param^M
No symbol "param" in current context.^M
(gdb) FAIL: gdb.dwarf2/dw2-ifort-parameter.exp: p/x param

With this patch applied, dw2-ifort-parameter.exp still passes for gcc
on arm thumb mode and popwerpc64, and it also passes for clang on
x86_linux.

gdb/testsuite:

2014-10-24  Yao Qi  <yao@codesourcery.com>

	* gdb.dwarf2/dw2-ifort-parameter.c: Remove inline asm.
	(func): Add label func_label.
	* gdb.dwarf2/dw2-ifort-parameter.exp (Dwarf::assemble):
	Replace low_pc and high_pc with MACRO_AT_range.
	Replace name, low_pc and high_pc with MACRO_AT_func.
---
 gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c   | 7 +------
 gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp | 8 +++-----
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c
index 4474814..4918d7e 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.c
@@ -18,17 +18,12 @@
 int value = 0xdeadf00d;
 int *ptr = &value;
 
-asm (".section	\".text\"");
-asm (".balign 8");
-asm ("func_start: .globl func_start");
-
 static void
 func (void)
 {
+  asm ("func_label: .globl func_label");
 }
 
-asm ("func_end: .globl func_end");
-
 int
 main (void)
 {
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp
index 026e071..85a6ddd 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp
@@ -30,13 +30,13 @@ Dwarf::assemble $asm_file {
     declare_labels int_label
 
     extern func_start func_end ptr
+    global srcdir subdir srcfile
 
     cu {} {
 	compile_unit {
 	    {name file1.txt}
 	    {language @DW_LANG_C}
-	    {low_pc func_start addr}
-	    {high_pc func_end addr}
+	    {MACRO_AT_range { func ${srcdir}/${subdir}/${srcfile} }}
 	} {
 	    int_label: base_type {
 		{name int}
@@ -46,9 +46,7 @@ Dwarf::assemble $asm_file {
 
 	    subprogram {
 		{external 1 flag}
-		{name func}
-		{low_pc func_start addr}
-		{high_pc func_end addr}
+		{MACRO_AT_func { func ${srcdir}/${subdir}/${srcfile} }}
 	    } {
 		formal_parameter {
 		    {name param}
-- 
1.9.3

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

* [PATCH 3/6] Get start and end address of main in dwz.exp
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
  2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
  2014-10-25  0:18 ` [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:51   ` Doug Evans
  2014-10-25  0:18 ` [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp Yao Qi
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

On arm-none-eabi target thumb mode, I see the following fail,

p the_int^M
$2 = 99^M
(gdb) FAIL: gdb.dwarf2/dwz.exp: p the_int

and on powerpc64 target, we even can't get function main from object
file,

disassemble main^M
No function contains specified address.^M
(gdb) FAIL: gdb.dwarf2/dwz.exp: disassemble main

This patch is to use MACRO_AT_func attribute to get the main's start
address and end address correctly, and also remove some code dwz.exp
getting main's length.  This patch fixes fails on both thumb mode and
powerpc64 target.

PASS: gdb.dwarf2/dwz.exp: p other_int
PASS: gdb.dwarf2/dwz.exp: p the_int

gdb/testsuite:

2014-10-24  Yao Qi  <yao@codesourcery.com>

	* gdb.dwarf2/dwz.exp: Remove the code to compile main.c to
	object and get function length.
	(Dwarf::assemble): Replace name, low_pc and high_pc attributes
	with MACRO_AT_func.
	(top-level): Replace gdb_compile and clean_restart with
	prepare_for_testing.
	* gdb.dwarf2/main.c (main): Add label main_label.
---
 gdb/testsuite/gdb.dwarf2/dwz.exp | 60 ++--------------------------------------
 gdb/testsuite/gdb.dwarf2/main.c  |  1 +
 2 files changed, 4 insertions(+), 57 deletions(-)

diff --git a/gdb/testsuite/gdb.dwarf2/dwz.exp b/gdb/testsuite/gdb.dwarf2/dwz.exp
index 9175f9e..c7ecc2b 100644
--- a/gdb/testsuite/gdb.dwarf2/dwz.exp
+++ b/gdb/testsuite/gdb.dwarf2/dwz.exp
@@ -22,65 +22,18 @@ if {![dwarf2_support]} {
 
 standard_testfile main.c dwz.S
 
-if  {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
-	  object {nodebug}] != ""} {
-    return -1
-}
-
-# Start GDB and load object file, compute the function length which is
-# needed in the Dwarf Assembler below.
-clean_restart ${testfile}1.o
-
-set main_length ""
-set test "disassemble main"
-gdb_test_multiple $test $test {
-    -re ".*$hex <\\+($decimal)>:\[^\r\n\]+\r\nEnd of assembler dump\.\r\n$gdb_prompt $" {
-	set main_length $expect_out(1,string)
-	pass $test
-    }
-}
-
-if { $main_length == "" } {
-    # Bail out here, because we can't do the following tests if
-    # $main_length is unknown.
-    return -1
-}
-
-# Compute the size of the last instruction.
-
-set test "x/2i main+$main_length"
-gdb_test_multiple $test $test {
-    -re ".*($hex) <main\\+$main_length>:\[^\r\n\]+\r\n\[ \]+($hex).*\.\r\n$gdb_prompt $" {
-	set start $expect_out(1,string)
-	set end $expect_out(2,string)
-
-	set main_length [expr $main_length + $end - $start]
-	pass $test
-    }
-}
-
-if { $main_length == "" } {
-    # Bail out here, because we can't do the following tests if
-    # $main_length is unknown.
-    return -1
-}
-
-gdb_exit
-
 # Create the DWARF.
 set asm_file [standard_output_file $srcfile2]
 Dwarf::assemble $asm_file {
     declare_labels partial_label int_label int_label2
-    global main_length
+    global srcdir subdir srcfile
 
     extern main
 
     cu {} {
 	partial_label: partial_unit {} {
 	    subprogram {
-		{name main}
-		{low_pc main addr}
-		{high_pc "main + $main_length" addr}
+ 		{MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
 	    }
 	}
     }
@@ -128,17 +81,10 @@ Dwarf::assemble $asm_file {
     }
 }
 
-if  {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} {
+if [prepare_for_testing ${testfile}.exp $testfile "${asm_file} ${srcfile}" {}] {
     return -1
 }
 
-if  {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \
-	  "${binfile}" executable {}] != ""} {
-    return -1
-}
-
-clean_restart ${testfile}
-
 if ![runto_main] {
     return -1
 }
diff --git a/gdb/testsuite/gdb.dwarf2/main.c b/gdb/testsuite/gdb.dwarf2/main.c
index 3ddd194..e6d4715 100644
--- a/gdb/testsuite/gdb.dwarf2/main.c
+++ b/gdb/testsuite/gdb.dwarf2/main.c
@@ -20,5 +20,6 @@
 int
 main()
 {
+  asm ("main_label: .globl main_label");
   return 0;
 }
-- 
1.9.3

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

* [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
                   ` (2 preceding siblings ...)
  2014-10-25  0:18 ` [PATCH 3/6] Get start and end address of main in dwz.exp Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:53   ` Doug Evans
  2014-10-25  0:18 ` [PATCH 5/6] Fix implptr-optimized-out.exp fail Yao Qi
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

This patch is to use dwarf::assemble to generate debug information, and
remove implptr-optimized-out.S as a result.

gdb/testsuite:

2014-10-24  Yao Qi  <yao@codesourcery.com>

	* gdb.dwarf2/implptr-optimized-out.exp: Use Dwarf::assemble to
	produce debug information.
	* gdb.dwarf2/implptr-optimized-out.S: Removed.
---
 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S   | 166 ---------------------
 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp |  63 +++++++-
 2 files changed, 60 insertions(+), 169 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S

diff --git a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S
deleted file mode 100644
index eeebd54..0000000
--- a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Copyright 2010-2014 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/>.  */
-
-	.section	.debug_info
-d:
-	.4byte	debug_end - 1f	/* Length of Compilation Unit Info */
-1:
-	.2byte	0x3	/* DWARF version number */
-	.4byte	.Ldebug_abbrev0	/* Offset Into Abbrev. Section */
-	.byte	0x4	/* 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 */
-
-	.uleb128	6			/* Abbrev: DW_TAG_subprogram */
-	.ascii		"main\0"		/* DW_AT_name */
-	.4byte		main			/* DW_AT_low_pc */
-	.4byte		main + 0x100		/* DW_AT_high_pc */
-	.4byte		.Ltype_int - d		/* DW_AT_type */
-	.byte		1			/* DW_AT_external */
-
-.Ltype_structptr:
-	.uleb128 0x5	/* DW_TAG_pointer_type */
-	.byte	0x4	/* 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	0	/* DW_AT_location: DW_FORM_block1 */
-	.4byte	.Ltype_struct - d	/* DW_AT_type */
-
-	.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 */
-	.4byte	.Lvar_out	/* referenced DIE, section-relative! */
-	.sleb128	0	/* offset */
-2:
-	.4byte	.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 0x13	/* (DW_FORM_ref4) */
-	.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	0x13			/* DW_FORM_ref4 */
-	.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-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
index 26ca407..226fc5c 100644
--- a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
+++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
@@ -19,11 +19,68 @@ if {![dwarf2_support]} {
     return 0  
 }
 
-standard_testfile .S
-set mainfile main.c
+standard_testfile main.c .S
 set executable ${testfile}
 
-if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" {}] {
+# Create the DWARF.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    cu { version 3 addr_size 4 } {
+	compile_unit {
+	    {producer "GNU C 4.4.3"}
+	    {language @DW_LANG_C89}
+	    {name 1.c}
+	} {
+	    declare_labels int_label struct_label pointer_label variable_label
+
+	    int_label: base_type {
+		{byte_size 4 sdata}
+		{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}
+		}
+	    }
+
+	    subprogram {
+		{name main}
+		{low_pc main addr}
+		{high_pc main+0x100 addr}
+		{type :$int_label}
+		{external 1 flag}
+	    } {
+		pointer_label: pointer_type {
+		    {byte_size 4 sdata}
+		    {type :$struct_label}
+		}
+
+		variable_label: DW_TAG_variable {
+		    {name v}
+		    {location {} DW_FORM_block1}
+		    {type :$struct_label}
+		}
+
+		DW_TAG_variable {
+		    {name p}
+		    {location {
+			GNU_implicit_pointer $variable_label 0
+		    } SPECIAL_expr}
+		    {type :$pointer_label}
+		}
+	    }
+	}
+    }
+}
+
+if [prepare_for_testing ${testfile}.exp $executable "${asm_file} ${srcfile}" {}] {
     return -1
 }
 
-- 
1.9.3

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

* [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:50   ` Doug Evans
  2014-11-04 22:59   ` Doug Evans
  2014-10-25  0:18 ` [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang Yao Qi
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

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 {
-- 
1.9.3

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

* [PATCH 1/6] New proc _handle_attribute
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
                   ` (4 preceding siblings ...)
  2014-10-25  0:18 ` [PATCH 5/6] Fix implptr-optimized-out.exp fail Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:48   ` Doug Evans
  2014-11-04 23:01 ` [PATCH 0/6] Use correct function address in dwarf assembler Doug Evans
  6 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

This patch is to move some code to a new procedure _handle_attribute,
which will be used in my following patches.

gdb/testsuite:

2014-10-24  Yao Qi  <yao@codesourcery.com>

	* lib/dwarf.exp (_handle_DW_TAG): Move some code to ...
	(_handle_attribute): New procedure.
---
 gdb/testsuite/lib/dwarf.exp | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 1483271..4986f83 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -461,6 +461,18 @@ namespace eval Dwarf {
 	return $name
     }
 
+    proc _handle_attribute { attr_name attr_value attr_form } {
+	variable _abbrev_section
+	variable _constants
+
+	_handle_DW_FORM $attr_form $attr_value
+
+	_defer_output $_abbrev_section {
+	    _op .uleb128 $_constants($attr_name) $attr_name
+	    _op .uleb128 $_constants($attr_form) $attr_form
+	}
+    }
+
     proc _handle_DW_TAG {tag_name {attrs {}} {children {}}} {
 	variable _abbrev_section
 	variable _abbrev_num
@@ -489,12 +501,7 @@ namespace eval Dwarf {
 	    }
 	    set attr_form [_map_name $attr_form _FORM]
 
-	    _handle_DW_FORM $attr_form $attr_value
-
-	    _defer_output $_abbrev_section {
-		_op .uleb128 $_constants($attr_name) $attr_name
-		_op .uleb128 $_constants($attr_form) $attr_form
-	    }
+	    _handle_attribute $attr_name $attr_value $attr_form
 	}
 
 	_defer_output $_abbrev_section {
-- 
1.9.3

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

* [PATCH 5/6] Fix implptr-optimized-out.exp fail
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
                   ` (3 preceding siblings ...)
  2014-10-25  0:18 ` [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp Yao Qi
@ 2014-10-25  0:18 ` Yao Qi
  2014-11-04 22:53   ` Doug Evans
  2014-10-25  0:18 ` [PATCH 1/6] New proc _handle_attribute Yao Qi
  2014-11-04 23:01 ` [PATCH 0/6] Use correct function address in dwarf assembler Doug Evans
  6 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-10-25  0:18 UTC (permalink / raw)
  To: gdb-patches

Hi,
I see the fail in gdb.dwarf2/implptr-optimized-out.exp in thumb mode

(gdb) p p->f^M
No symbol "p" in current context.^M
(gdb) FAIL: gdb.dwarf2/implptr-optimized-out.exp: p p->f

and the crash on powerpc64

(gdb) continue^M
Continuing.^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x7d82100810000828 in ?? ()

The cause of both is that we incorrectly set attribute low_pc, since
main isn't resolved to function start address on these targets.

In this patch, we replace attributes name, low_pc and high_pc with
MACRO_AT_func.  The fail on thumb mode is fixed, and crash on
powerpc64 is fixed too.

gdb/testsuite:

2014-10-24  Yao Qi  <yao@codesourcery.com>

	* gdb.dwarf2/implptr-optimized-out.exp (Dwarf::assemble):
	Replace name, low_pc and high_pc with MACRO_AT_func.
---
 gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
index 226fc5c..dd9c517 100644
--- a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
+++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
@@ -25,6 +25,8 @@ set executable ${testfile}
 # Create the DWARF.
 set asm_file [standard_output_file $srcfile2]
 Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile
+
     cu { version 3 addr_size 4 } {
 	compile_unit {
 	    {producer "GNU C 4.4.3"}
@@ -51,9 +53,7 @@ Dwarf::assemble $asm_file {
 	    }
 
 	    subprogram {
-		{name main}
-		{low_pc main addr}
-		{high_pc main+0x100 addr}
+		{MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
 		{type :$int_label}
 		{external 1 flag}
 	    } {
-- 
1.9.3

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

* Re: [PATCH 1/6] New proc _handle_attribute
  2014-10-25  0:18 ` [PATCH 1/6] New proc _handle_attribute Yao Qi
@ 2014-11-04 22:48   ` Doug Evans
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:48 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > This patch is to move some code to a new procedure _handle_attribute,
 > which will be used in my following patches.
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* lib/dwarf.exp (_handle_DW_TAG): Move some code to ...
 > 	(_handle_attribute): New procedure.

LGTM

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
@ 2014-11-04 22:50   ` Doug Evans
  2014-11-05  1:54     ` Yao Qi
  2014-11-04 22:59   ` Doug Evans
  1 sibling, 1 reply; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:50 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

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?

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

* Re: [PATCH 3/6] Get start and end address of main in dwz.exp
  2014-10-25  0:18 ` [PATCH 3/6] Get start and end address of main in dwz.exp Yao Qi
@ 2014-11-04 22:51   ` Doug Evans
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:51 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > On arm-none-eabi target thumb mode, I see the following fail,
 > 
 > p the_int^M
 > $2 = 99^M
 > (gdb) FAIL: gdb.dwarf2/dwz.exp: p the_int
 > 
 > and on powerpc64 target, we even can't get function main from object
 > file,
 > 
 > disassemble main^M
 > No function contains specified address.^M
 > (gdb) FAIL: gdb.dwarf2/dwz.exp: disassemble main
 > 
 > This patch is to use MACRO_AT_func attribute to get the main's start
 > address and end address correctly, and also remove some code dwz.exp
 > getting main's length.  This patch fixes fails on both thumb mode and
 > powerpc64 target.
 > 
 > PASS: gdb.dwarf2/dwz.exp: p other_int
 > PASS: gdb.dwarf2/dwz.exp: p the_int
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* gdb.dwarf2/dwz.exp: Remove the code to compile main.c to
 > 	object and get function length.
 > 	(Dwarf::assemble): Replace name, low_pc and high_pc attributes
 > 	with MACRO_AT_func.
 > 	(top-level): Replace gdb_compile and clean_restart with
 > 	prepare_for_testing.
 > 	* gdb.dwarf2/main.c (main): Add label main_label.

LGTM

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

* Re: [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp
  2014-10-25  0:18 ` [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp Yao Qi
@ 2014-11-04 22:53   ` Doug Evans
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:53 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > This patch is to use dwarf::assemble to generate debug information, and
 > remove implptr-optimized-out.S as a result.
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* gdb.dwarf2/implptr-optimized-out.exp: Use Dwarf::assemble to
 > 	produce debug information.
 > 	* gdb.dwarf2/implptr-optimized-out.S: Removed.

LGTM

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

* Re: [PATCH 5/6] Fix implptr-optimized-out.exp fail
  2014-10-25  0:18 ` [PATCH 5/6] Fix implptr-optimized-out.exp fail Yao Qi
@ 2014-11-04 22:53   ` Doug Evans
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:53 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > Hi,
 > I see the fail in gdb.dwarf2/implptr-optimized-out.exp in thumb mode
 > 
 > (gdb) p p->f^M
 > No symbol "p" in current context.^M
 > (gdb) FAIL: gdb.dwarf2/implptr-optimized-out.exp: p p->f
 > 
 > and the crash on powerpc64
 > 
 > (gdb) continue^M
 > Continuing.^M
 > ^M
 > Program received signal SIGSEGV, Segmentation fault.^M
 > 0x7d82100810000828 in ?? ()
 > 
 > The cause of both is that we incorrectly set attribute low_pc, since
 > main isn't resolved to function start address on these targets.
 > 
 > In this patch, we replace attributes name, low_pc and high_pc with
 > MACRO_AT_func.  The fail on thumb mode is fixed, and crash on
 > powerpc64 is fixed too.
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* gdb.dwarf2/implptr-optimized-out.exp (Dwarf::assemble):
 > 	Replace name, low_pc and high_pc with MACRO_AT_func.

LGTM

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

* Re: [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang
  2014-10-25  0:18 ` [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang Yao Qi
@ 2014-11-04 22:54   ` Doug Evans
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:54 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > The patch <https://sourceware.org/ml/gdb-patches/2014-03/msg00202.html>
 > fixed dw2-ifort-parameter.exp on powerpc64 by adding some labels to
 > get the start and end address of function func.  This should also fix the
 > fail on thumb mode, however, this style is quite specific to gcc, and
 > other compiler, such as clang, may not guarantee the order of global
 > asms and functions.  The test fails with clang:
 > 
 > $ make check RUNTESTFLAGS='dw2-ifort-parameter.exp CC_FOR_TARGET=clang'
 > (gdb) p/x param^M
 > No symbol "param" in current context.^M
 > (gdb) FAIL: gdb.dwarf2/dw2-ifort-parameter.exp: p/x param
 > 
 > With this patch applied, dw2-ifort-parameter.exp still passes for gcc
 > on arm thumb mode and popwerpc64, and it also passes for clang on
 > x86_linux.
 > 
 > gdb/testsuite:
 > 
 > 2014-10-24  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* gdb.dwarf2/dw2-ifort-parameter.c: Remove inline asm.
 > 	(func): Add label func_label.
 > 	* gdb.dwarf2/dw2-ifort-parameter.exp (Dwarf::assemble):
 > 	Replace low_pc and high_pc with MACRO_AT_range.
 > 	Replace name, low_pc and high_pc with MACRO_AT_func.

LGTM

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
  2014-11-04 22:50   ` Doug Evans
@ 2014-11-04 22:59   ` Doug Evans
  1 sibling, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 22:59 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

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]
 > +}
 > +

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?

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

* Re: [PATCH 0/6] Use correct function address in dwarf assembler
  2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
                   ` (5 preceding siblings ...)
  2014-10-25  0:18 ` [PATCH 1/6] New proc _handle_attribute Yao Qi
@ 2014-11-04 23:01 ` Doug Evans
  6 siblings, 0 replies; 22+ messages in thread
From: Doug Evans @ 2014-11-04 23:01 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi writes:
 > When we use dwarf assembler, it is common to generate DW_AT_low_pc and
 > DW_AT_high_pc attributes like this:
 > 
 >  	    subprogram {
 > 		{name main}
 > 		{low_pc main addr}
 > 		{high_pc main+0x100 addr}
 >             }
 > 
 > however, main is not resolved to function main's address on some
 > targets such as arm thumb mode and powerpc64.  One approach is to
 > get function address by labels, like this:
 > 
 >   asm ("func_start: .globl func_start");
 >   static void func (void) {}
 >   asm ("func_end: .globl func_end");
 > 
 > however, some compiler, such as clang, can't guarantee the order of
 > these labels and function, so it isn't portable.
 > 
 > In this patch series, we propose a new approach 
 > 
 >  1. get function start and end address correctly in a portable way,
 >  2. don't affect too much on existing test cases.
 > 
 > In patch 2/6, a new proc function_range is added.  In this proc, the
 > source file is compiled with debug info.
 > 
 >   int main (void)
 >   {
 >     asm ("main_label: .globl main_label");
 >     return 0;
 >   }
 > 
 > we can get the offset of main_label in function main, and then compute
 > the start address of main via main_label - main_label_offset.  This is
 > portable.
 > 
 > In order to avoid much changes to existing test cases, we have to use
 > function_range inside dwarf assembler.  Then, I invent some attribute
 > macros which look like DW attributes, but can be expanded to one or
 > more standard attributes.  The TAG_subprogram above will be simplified
 > with macro attribute used, it becomes:
 > 
 >     subprogram {
 > 	{MACRO_AT_func { func ${srcdir}/${subdir}/${srcfile} }}
 >     }
 > 
 > With this macro attribute, attributes name, low_pc and high_pc are
 > generated and set correctly.  See more details in patch 2/6.
 > 
 > Patch 4/6 is to use dwarf assembler to generate .S file, which is
 > identical to .S current one we are using.  Patch 3 and 5 is to use
 > macro attributes to get function start and end address correctly.
 > Patch 6 is remove labels and switch to use macro attribute to
 > get function start address to make clang happy.
 > 
 > I test the whole series by running tests under gdb.dwarf2/ on
 > powerpc-linux (both 32-bit and 64-bit), arm-none-eabi (arm mode
 > and thumb mode) and x86_64-linux.
 > 
 > Comments are very welcome!

Hi.
In general I like this a lot.
Just a few outstanding questions mentioned in replies to
the relevant patches.

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-04 22:50   ` Doug Evans
@ 2014-11-05  1:54     ` Yao Qi
  2014-11-07 16:54       ` Doug Evans
  0 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-11-05  1:54 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

Doug Evans <dje@google.com> writes:

Doug,
Thanks for reviewing these patches.

> 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?

After all, in dwarf assembler, all attributes are handled in a single
function, rather than the way that each attribute is handled in the
separate function.  MACRO_AT_{func,range}, as special attributes from
the users' point of view, should be handled in a way consistent with
other attributes, IMO.

-- 
Yao (齐尧)

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-05  1:54     ` Yao Qi
@ 2014-11-07 16:54       ` Doug Evans
  2014-11-10  2:04         ` Yao Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Doug Evans @ 2014-11-07 16:54 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On Tue, Nov 4, 2014 at 5:49 PM, Yao Qi <yao@codesourcery.com> wrote:
> Doug Evans <dje@google.com> writes:
>
> Doug,
> Thanks for reviewing these patches.
>
>> 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.

> After all, in dwarf assembler, all attributes are handled in a single
> function, rather than the way that each attribute is handled in the
> separate function.  MACRO_AT_{func,range}, as special attributes from
> the users' point of view, should be handled in a way consistent with
> other attributes, IMO.

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-07 16:54       ` Doug Evans
@ 2014-11-10  2:04         ` Yao Qi
  2014-11-10 19:44           ` Doug Evans
  0 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-11-10  2:04 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

Doug Evans <dje@google.com> 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.

-- 
Yao (齐尧)

Subject: [PATCH] DW attribute macro MACRO_AT_func and MACRO_AT_range

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-11-10  Yao Qi  <yao@codesourcery.com>

	* lib/dwarf.exp (function_range): New procedure.
	(Dwarf::_handle_macro_at_func): New procedure.
	(Dwarf::_handle_macro_at_range): New procedure.
	(Dwarf): Handle MACRO_AT_func and MACRO_AT_range.

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 {

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-10  2:04         ` Yao Qi
@ 2014-11-10 19:44           ` Doug Evans
  2014-11-11  2:05             ` Yao Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Doug Evans @ 2014-11-10 19:44 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On Sun, Nov 9, 2014 at 6:04 PM, Yao Qi <yao@codesourcery.com> wrote:
> 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.

OTOH, leaving such things around for debug purposes is important,
or at least not making it difficult to keep such things (and editing source
files to, e.g., comment out the "file delete", crosses a threshold of
annoyance for me).

I think the simplicity of implementation and assistance to debugability
of just leaving the file there outweighs the extra code and any perceived
increase in cleanliness.

Plus the more remote file operations we add the more we slow
things down.  There's a *ton* of files we leave behind,
I wouldn't worry about leaving a few more behind.
If there were another reason then that might be something
to consider.

[At least with gcc there is -save-temps.  We *could* have something
like that here, but I'm ok with just leaving them.]

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-10 19:44           ` Doug Evans
@ 2014-11-11  2:05             ` Yao Qi
  2014-11-12  7:01               ` Doug Evans
  0 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2014-11-11  2:05 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

Doug Evans <dje@google.com> writes:

> OTOH, leaving such things around for debug purposes is important,
> or at least not making it difficult to keep such things (and editing source
> files to, e.g., comment out the "file delete", crosses a threshold of
> annoyance for me).

Yeah, I commented out the "file delete" from time to time, but I can
bear with that.

>
> I think the simplicity of implementation and assistance to debugability
> of just leaving the file there outweighs the extra code and any perceived
> increase in cleanliness.
>
> Plus the more remote file operations we add the more we slow
> things down.  There's a *ton* of files we leave behind,
> I wouldn't worry about leaving a few more behind.
> If there were another reason then that might be something
> to consider.
>
> [At least with gcc there is -save-temps.  We *could* have something
> like that here, but I'm ok with just leaving them.]

It has been discussed for several times that these artifacts should be
kept.  Let us have a try and start to do it now.  I'll think about this
problem systematically which I haven't done before, and post something
out when I make some progresses or get some conclusions.

The "remote_file host delete" is removed from the patch below.

-- 
Yao (齐尧)

Subject: [PATCH] DW attribute macro MACRO_AT_func and MACRO_AT_range

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-11-10  Yao Qi  <yao@codesourcery.com>

	* lib/dwarf.exp (function_range): New procedure.
	(Dwarf::_handle_macro_at_func): New procedure.
	(Dwarf::_handle_macro_at_range): New procedure.
	(Dwarf): Handle MACRO_AT_func and MACRO_AT_range.

diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 4986f83..cadda3e 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -86,6 +86,79 @@ 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]
+	}
+    }
+
+    return [list "${func}_label - $func_label_offset" $func_length]
+}
+
 # A DWARF assembler.
 #
 # All the variables in this namespace are private to the
@@ -121,6 +194,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 +557,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 +605,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 {

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-11  2:05             ` Yao Qi
@ 2014-11-12  7:01               ` Doug Evans
  2014-11-14  1:00                 ` Yao Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Doug Evans @ 2014-11-12  7:01 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On Mon, Nov 10, 2014 at 6:05 PM, Yao Qi <yao@codesourcery.com> wrote:
> [...]
> 2014-11-10  Yao Qi  <yao@codesourcery.com>
>
>         * lib/dwarf.exp (function_range): New procedure.
>         (Dwarf::_handle_macro_at_func): New procedure.
>         (Dwarf::_handle_macro_at_range): New procedure.
>         (Dwarf): Handle MACRO_AT_func and MACRO_AT_range.

LGTM, with one nit that can be left for later.

> +
> +           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 {

The sequence of ifs to test for each macro name is akin to the switch
statement we removed.
It's less code of course, but it still involves continual additions
for each new macro.
I was thinking of still having a wrapper function that checks for macros,
but it could do "info proc _handle_$attr_name" or some such and
call(via eval?) the function if it exists or flag an error if it
doesn't.  We don't have to go down this road though until we need to.

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

* Re: [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range
  2014-11-12  7:01               ` Doug Evans
@ 2014-11-14  1:00                 ` Yao Qi
  0 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2014-11-14  1:00 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

Doug Evans <dje@google.com> writes:

Hi Doug,

> The sequence of ifs to test for each macro name is akin to the switch
> statement we removed.
> It's less code of course, but it still involves continual additions
> for each new macro.
> I was thinking of still having a wrapper function that checks for macros,
> but it could do "info proc _handle_$attr_name" or some such and
> call(via eval?) the function if it exists or flag an error if it
> doesn't.  We don't have to go down this road though until we need to.

Yeah, that is a very clear trick.  I'll adapt the code for it when new
macro attribute is added later.

Thanks for your review, and this series is pushed in.

-- 
Yao (齐尧)

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

end of thread, other threads:[~2014-11-14  1:00 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-25  0:17 [PATCH 0/6] Use correct function address in dwarf assembler Yao Qi
2014-10-25  0:18 ` [PATCH 2/6] DW attribute macro MACRO_AT_func and MACRO_AT_range Yao Qi
2014-11-04 22:50   ` Doug Evans
2014-11-05  1:54     ` Yao Qi
2014-11-07 16:54       ` Doug Evans
2014-11-10  2:04         ` Yao Qi
2014-11-10 19:44           ` Doug Evans
2014-11-11  2:05             ` Yao Qi
2014-11-12  7:01               ` Doug Evans
2014-11-14  1:00                 ` Yao Qi
2014-11-04 22:59   ` Doug Evans
2014-10-25  0:18 ` [PATCH 6/6] Fix dw2-ifort-parameter.exp fail with clang Yao Qi
2014-11-04 22:54   ` Doug Evans
2014-10-25  0:18 ` [PATCH 3/6] Get start and end address of main in dwz.exp Yao Qi
2014-11-04 22:51   ` Doug Evans
2014-10-25  0:18 ` [PATCH 4/6] Use Dwarf::assemble in implptr-optimized-out.exp Yao Qi
2014-11-04 22:53   ` Doug Evans
2014-10-25  0:18 ` [PATCH 5/6] Fix implptr-optimized-out.exp fail Yao Qi
2014-11-04 22:53   ` Doug Evans
2014-10-25  0:18 ` [PATCH 1/6] New proc _handle_attribute Yao Qi
2014-11-04 22:48   ` Doug Evans
2014-11-04 23:01 ` [PATCH 0/6] Use correct function address in dwarf assembler Doug Evans

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).