Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Jim Blandy <jimb@redhat.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: kettenis@jive.nl, drow@false.org, cagney@gnu.org, gdb@sources.redhat.com
Subject: Re: interface to partial support for DW_OP_piece in dwarf2expr.[ch]
Date: Tue, 10 Aug 2004 19:55:00 -0000	[thread overview]
Message-ID: <vt2d61yrcse.fsf@zenia.home> (raw)
In-Reply-To: <9787-Fri06Aug2004123633+0300-eliz@gnu.org>


To put (part of) the discussion of the Dwarf piece support on a
concrete basis, here's a patch that adds the gdbarch method; it
depends on the dwarf2expr piece interface patch I posted earlier.

This change, or something like it, would allow immediate improvements
over GDB's current behavior, and I don't see that it has much
structural cost:

- It doesn't affect the design of full scattered values: when that is
  implemented, dwarf2_evaluate_loc_desc will just become able to
  construct 'struct value' objects for more kinds of Dwarf expression
  results.

- When we do support full scattered values, the clause this patch adds
  to dwarf2_evaluate_loc_desc, the gdbarch method, and whatever
  arch-specific implementations people have written for it can be
  simply deleted, with no change in user-visible behavior.

2004-08-09  Jim Blandy  <jimb@redhat.com>

	* gdbarch.sh (dwarf_simplify_register_pieces): New method.
	Add forward declaration for 'struct dwarf_expr_piece'.
	* gdbarch.c, gdbarch.h: Regenerated.
	* dwarf2loc.c (dwarf2_evaluate_loc_desc): Try to simplify
	multi-piece expression results before giving up.
	* arch-utils.c (dwarf_never_simplify_pieces): New function.
	* arch-utils.h (struct dwarf_expr_piece): Forward decl for struct
	type, used in ...
	(dwarf_never_simplify_pieces): New declaration.

diff -crp -x '*~' -x '.#*' -x CVS gdb/gdbarch.sh gdb/gdbarch.sh
*** gdb/gdbarch.sh	2004-08-09 19:29:28.000000000 -0500
--- gdb/gdbarch.sh	2004-08-10 11:31:22.000000000 -0500
*************** f:=:int:dwarf_reg_to_regnum:int dwarf_re
*** 451,456 ****
--- 451,480 ----
  # Convert from an sdb register number to an internal gdb register number.
  f:=:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr::no_op_reg_to_regnum::0
  f:=:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr::no_op_reg_to_regnum::0
+ 
+ # On some architectures, GDB has registers that Dwarf treats as the
+ # concatenation of two separate registers.  For example, PowerPC
+ # variants implementing the SPE APU have 64-bit general-purpose
+ # registers.  GDB refers to the lower 32 bits of each register as 'r0'
+ # -- 'r31', and the full 64-bit registers as 'ev0' -- 'ev31'.
+ # However, the Dwarf register numbering treats the upper halves as
+ # separate registers.
+ #
+ # Dwarf location expressions describe variables allocated to such
+ # registers using a series of DW_OP_piece operations.  In the case
+ # above, the expressions would have the form:
+ #
+ #   <upper half> DW_OP_piece 4 <lower half> DW_OP_piece 4.
+ #
+ # However, since GDB does have a register that corresponds to the
+ # entire variable, it can simply say the variable lives in that
+ # register; it needn't use a complicated location description.
+ #
+ # Given an array of NUM_PIECES pieces PIECES, return the number of the
+ # register that is equivalent to those pieces, or -1 if there is no
+ # such register.
+ m::int:dwarf_simplify_register_pieces:int num_pieces, struct dwarf_expr_piece *pieces:num_pieces, pieces::dwarf_never_simplify_pieces
+ 
  f:=:const char *:register_name:int regnr:regnr
  
  # REGISTER_TYPE is a direct replacement for DEPRECATED_REGISTER_VIRTUAL_TYPE.
*************** struct regset;
*** 773,778 ****
--- 797,803 ----
  struct disassemble_info;
  struct target_ops;
  struct obstack;
+ struct dwarf_expr_piece;
  
  extern struct gdbarch *current_gdbarch;
  
diff -crp -x '*~' -x '.#*' -x CVS gdb/dwarf2loc.c gdb/dwarf2loc.c
*** gdb/dwarf2loc.c	2004-08-10 02:01:24.000000000 -0500
--- gdb/dwarf2loc.c	2004-08-10 11:34:39.000000000 -0500
*************** dwarf2_evaluate_loc_desc (struct symbol 
*** 230,240 ****
    dwarf_expr_eval (ctx, data, size);
    if (ctx->num_pieces > 0)
      {
!       /* We haven't implemented splicing together pieces from
!          arbitrary sources yet.  */
!       error ("The value of variable '%s' is distributed across several\n"
!              "locations, and GDB cannot access its value.\n",
!              SYMBOL_NATURAL_NAME (var));
      }
    else if (ctx->in_reg)
      {
--- 230,247 ----
    dwarf_expr_eval (ctx, data, size);
    if (ctx->num_pieces > 0)
      {
!       CORE_ADDR simplified
!         = gdbarch_dwarf_simplify_register_pieces (arch, ctx->num_pieces,
!                                                   ctx->pieces);
!       if (simplified >= 0)
!         retval = value_from_register (SYMBOL_TYPE (var), simplified, frame);
! 
!       /* We haven't implemented the more complex case of splicing
!          together pieces from arbitrary sources yet.  */
!       else
!         error ("The value of variable '%s' is distributed across several\n"
!                "locations, and GDB cannot access its value.\n",
!                SYMBOL_NATURAL_NAME (var));
      }
    else if (ctx->in_reg)
      {
diff -crp -x '*~' -x '.#*' -x CVS gdb/arch-utils.h gdb/arch-utils.h
*** gdb/arch-utils.h	2004-08-09 19:29:27.000000000 -0500
--- gdb/arch-utils.h	2004-08-10 11:32:03.000000000 -0500
*************** struct frame_info;
*** 28,33 ****
--- 28,34 ----
  struct minimal_symbol;
  struct type;
  struct gdbarch_info;
+ struct dwarf_expr_piece;
  
  /* gdbarch trace variable */
  extern int gdbarch_debug;
*************** extern gdbarch_convert_from_func_ptr_add
*** 72,77 ****
--- 73,82 ----
  
  extern int no_op_reg_to_regnum (int reg);
  
+ /* Dwarf piece simplifier that never simplifies anything.  */
+ extern int dwarf_never_simplify_pieces (int num_pieces,
+                                         struct dwarf_expr_piece *pieces);
+ 
  /* Do nothing version of elf_make_msymbol_special. */
  
  void default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym);
diff -crp -x '*~' -x '.#*' -x CVS gdb/arch-utils.c gdb/arch-utils.c
*** gdb/arch-utils.c	2004-08-09 19:29:27.000000000 -0500
--- gdb/arch-utils.c	2004-08-10 11:32:17.000000000 -0500
*************** no_op_reg_to_regnum (int reg)
*** 228,233 ****
--- 228,240 ----
    return reg;
  }
  
+ int
+ dwarf_never_simplify_pieces (int num_pieces,
+                              struct dwarf_expr_piece *pieces)
+ {
+   return -1;
+ }
+ 
  void
  default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
  {
diff -crp -x '*~' -x '.#*' -x CVS gdb/gdbarch.c gdb/gdbarch.c
*** gdb/gdbarch.c	2004-08-09 19:29:28.000000000 -0500
--- gdb/gdbarch.c	2004-08-10 11:28:42.000000000 -0500
*************** struct gdbarch
*** 155,160 ****
--- 155,161 ----
    gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum;
    gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum;
    gdbarch_dwarf2_reg_to_regnum_ftype *dwarf2_reg_to_regnum;
+   gdbarch_dwarf_simplify_register_pieces_ftype *dwarf_simplify_register_pieces;
    gdbarch_register_name_ftype *register_name;
    gdbarch_register_type_ftype *register_type;
    gdbarch_deprecated_register_byte_ftype *deprecated_register_byte;
*************** struct gdbarch startup_gdbarch =
*** 281,286 ****
--- 282,288 ----
    0,  /* dwarf_reg_to_regnum */
    0,  /* sdb_reg_to_regnum */
    0,  /* dwarf2_reg_to_regnum */
+   dwarf_never_simplify_pieces,  /* dwarf_simplify_register_pieces */
    0,  /* register_name */
    0,  /* register_type */
    generic_register_byte,  /* deprecated_register_byte */
*************** gdbarch_alloc (const struct gdbarch_info
*** 414,419 ****
--- 416,422 ----
    current_gdbarch->dwarf_reg_to_regnum = no_op_reg_to_regnum;
    current_gdbarch->sdb_reg_to_regnum = no_op_reg_to_regnum;
    current_gdbarch->dwarf2_reg_to_regnum = no_op_reg_to_regnum;
+   current_gdbarch->dwarf_simplify_register_pieces = dwarf_never_simplify_pieces;
    current_gdbarch->deprecated_register_byte = generic_register_byte;
    current_gdbarch->deprecated_fp_regnum = -1;
    current_gdbarch->call_dummy_location = AT_ENTRY_POINT;
*************** verify_gdbarch (struct gdbarch *current_
*** 541,546 ****
--- 544,552 ----
    /* Skip verify of dwarf_reg_to_regnum, invalid_p == 0 */
    /* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */
    /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */
+   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+       && (current_gdbarch->dwarf_simplify_register_pieces == dwarf_never_simplify_pieces))
+     fprintf_unfiltered (log, "\n\tdwarf_simplify_register_pieces");
    /* Skip verify of register_type, has predicate */
    /* Skip verify of deprecated_register_byte, has predicate */
    /* Skip verify of unwind_dummy_id, has predicate */
*************** gdbarch_dump (struct gdbarch *current_gd
*** 1027,1032 ****
--- 1033,1041 ----
    fprintf_unfiltered (file,
                        "gdbarch_dump: dwarf_reg_to_regnum = <0x%lx>\n",
                        (long) current_gdbarch->dwarf_reg_to_regnum);
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: dwarf_simplify_register_pieces = <0x%lx>\n",
+                       (long) current_gdbarch->dwarf_simplify_register_pieces);
  #ifdef ECOFF_REG_TO_REGNUM
    fprintf_unfiltered (file,
                        "gdbarch_dump: %s # %s\n",
*************** set_gdbarch_dwarf2_reg_to_regnum (struct
*** 2220,2225 ****
--- 2229,2251 ----
    gdbarch->dwarf2_reg_to_regnum = dwarf2_reg_to_regnum;
  }
  
+ int
+ gdbarch_dwarf_simplify_register_pieces (struct gdbarch *gdbarch, int num_pieces, struct dwarf_expr_piece *pieces)
+ {
+   gdb_assert (gdbarch != NULL);
+   gdb_assert (gdbarch->dwarf_simplify_register_pieces != NULL);
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf_simplify_register_pieces called\n");
+   return gdbarch->dwarf_simplify_register_pieces (gdbarch, num_pieces, pieces);
+ }
+ 
+ void
+ set_gdbarch_dwarf_simplify_register_pieces (struct gdbarch *gdbarch,
+                                             gdbarch_dwarf_simplify_register_pieces_ftype dwarf_simplify_register_pieces)
+ {
+   gdbarch->dwarf_simplify_register_pieces = dwarf_simplify_register_pieces;
+ }
+ 
  const char *
  gdbarch_register_name (struct gdbarch *gdbarch, int regnr)
  {
diff -crp -x '*~' -x '.#*' -x CVS gdb/gdbarch.h gdb/gdbarch.h
*** gdb/gdbarch.h	2004-08-09 19:29:28.000000000 -0500
--- gdb/gdbarch.h	2004-08-10 11:28:42.000000000 -0500
*************** struct regset;
*** 49,54 ****
--- 49,55 ----
  struct disassemble_info;
  struct target_ops;
  struct obstack;
+ struct dwarf_expr_piece;
  
  extern struct gdbarch *current_gdbarch;
  
*************** extern void set_gdbarch_dwarf2_reg_to_re
*** 461,466 ****
--- 462,493 ----
  #define DWARF2_REG_TO_REGNUM(dwarf2_regnr) (gdbarch_dwarf2_reg_to_regnum (current_gdbarch, dwarf2_regnr))
  #endif
  
+ /* On some architectures, GDB has registers that Dwarf treats as the
+    concatenation of two separate registers.  For example, PowerPC
+    variants implementing the SPE APU have 64-bit general-purpose
+    registers.  GDB refers to the lower 32 bits of each register as 'r0'
+    -- 'r31', and the full 64-bit registers as 'ev0' -- 'ev31'.
+    However, the Dwarf register numbering treats the upper halves as
+    separate registers.
+   
+    Dwarf location expressions describe variables allocated to such
+    registers using a series of DW_OP_piece operations.  In the case
+    above, the expressions would have the form:
+   
+      <upper half> DW_OP_piece 4 <lower half> DW_OP_piece 4.
+   
+    However, since GDB does have a register that corresponds to the
+    entire variable, it can simply say the variable lives in that
+    register; it needn't use a complicated location description.
+   
+    Given an array of NUM_PIECES pieces PIECES, return the number of the
+    register that is equivalent to those pieces, or -1 if there is no
+    such register. */
+ 
+ typedef int (gdbarch_dwarf_simplify_register_pieces_ftype) (struct gdbarch *gdbarch, int num_pieces, struct dwarf_expr_piece *pieces);
+ extern int gdbarch_dwarf_simplify_register_pieces (struct gdbarch *gdbarch, int num_pieces, struct dwarf_expr_piece *pieces);
+ extern void set_gdbarch_dwarf_simplify_register_pieces (struct gdbarch *gdbarch, gdbarch_dwarf_simplify_register_pieces_ftype *dwarf_simplify_register_pieces);
+ 
  typedef const char * (gdbarch_register_name_ftype) (int regnr);
  extern const char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr);
  extern void set_gdbarch_register_name (struct gdbarch *gdbarch, gdbarch_register_name_ftype *register_name);


  reply	other threads:[~2004-08-10 19:55 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-03  7:15 Jim Blandy
2004-08-04 16:53 ` Andrew Cagney
     [not found]   ` <vt2fz7292z3 dot fsf at zenia dot home>
     [not found]     ` <41112BAE dot 9080304 at gnu dot org>
     [not found]       ` <vt2hdri4mi1 dot fsf at zenia dot home>
     [not found]         ` <41115B4F dot 1080700 at gnu dot org>
     [not found]           ` <vt2pt66zgul dot fsf at zenia dot home>
2004-08-04 18:26   ` Jim Blandy
2004-08-04 18:32     ` Andrew Cagney
2004-08-04 21:35       ` Jim Blandy
2004-08-04 21:55         ` Andrew Cagney
2004-08-04 22:22           ` Jim Blandy
2004-08-04 23:04             ` Daniel Jacobowitz
2004-08-04 23:17               ` Jim Blandy
2004-08-05  9:54                 ` Mark Kettenis
2004-08-05 14:31                   ` Jim Blandy
2004-08-05 16:27                     ` Joel Brobecker
2004-08-05 18:45                       ` Jim Blandy
2004-08-05 18:47                         ` Daniel Jacobowitz
2004-08-05 19:56                           ` Andrew Cagney
2004-08-05 20:36                             ` Daniel Jacobowitz
2004-08-05 20:50                               ` Andrew Cagney
2004-08-06  9:39                     ` Eli Zaretskii
2004-08-10 19:55                       ` Jim Blandy [this message]
2004-08-11 20:31                         ` Jim Blandy
2004-08-11 20:33                           ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=vt2d61yrcse.fsf@zenia.home \
    --to=jimb@redhat.com \
    --cc=cagney@gnu.org \
    --cc=drow@false.org \
    --cc=eliz@gnu.org \
    --cc=gdb@sources.redhat.com \
    --cc=kettenis@jive.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox