Re: [RFA] Locate sparc64 arguments correctly

Kevin Buettner
2002-04-24T16:42:40Z

On Apr 24, 8:23am, David S. Miller wrote:

> From: Kevin Buettner <kevinb@redhat.com>
> Date: Tue, 23 Apr 2002 16:09:40 -0700
>
> I agree that this is the problem, but, when you do this...
>
> > +/* Debugging information stores LOC_ARG/LOC_REF_ARG offsets with the
> > + sparc64 stack bias present, this undoes that so that users of
> > + FRAME_ARGS_ADDRESS use the right location. */
> > +
> > +static CORE_ADDR
> > +sparc64_frame_args_address (struct frame_info *fi)
> > +{
> > + return fi->frame - 2047;
> > +}
>
> ...does the output from ``info frame'' still look reasonable?
>
> You're right, it does the wrong thing for info frame.
>
> This indicates that FRAME_ARGS_ADDRESS is being used for two entirely
> different purposes. One is to interpret debugging information, the
> other is to print arguments on the stack via info frame.
>
> This particular case would be cured by adjusting what we use for
> FRAME_ARGS_SKIP on a 64-bit sparc target such that the STACK bias is
> calcelled back out. I will make that modification to my patch and
> resubmit.

Hmm... I'm not sure this will work. FWIW, when I looked at this problem
a few weeks back, I concluded that LOC_REF_ARG shouldn't really be used
when the debug info contains information about which basereg to use.

I came up with this patch instead. My testing was using dwarf2 debug
info though. I haven't taken a look yet to see if it'll work with
stabs.

* symtab.h (LOC_BASEREG_REF_ARG): New constant for
``enum address_class''.
* dwarf2read.c (new_symbol): Use LOC_BASEREG_REF_ARG instead of
LOC_REF_ARG.
* ax-gdb.c (gen_var_ref): Add case for LOC_BASEREG_REF_ARG.
* buildsym.c (LOC_BASEREG_REF_ARG): Likewise.
* ch-exp.c (ch_lex): Likewise.
* findvar.c (symbol_needs_frame, read_var_value): Likewise.
* m2-exp.y (yylex): Likewise.
* printcmd.c (address_info, print_frame_args): Likewise.
* stack.c (print_frame_args): Likewise.
* symmisc.c (print_symbol): Likewise.
* symtab.c (lookup_block_symbol): Likewise.
* tracepoint.c (collect_symbol, add_local_symbols, scope_info):
Likewise.
* gdbtk-stack.c (gdb_block_vars, gdb_get_blocks, gdb_get_vars_command):
Likewise.
* mi/mi-cmd-stack.c (list_args_or_locals): Likewise.

Index: ax-gdb.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/ax-gdb.c,v
retrieving revision 1.26
diff -u -p -r1.26 ax-gdb.c
--- ax-gdb.c 2002/02/06 17:15:19 1.26
+++ ax-gdb.c 2002/04/24 16:22:33
@@ -573,6 +573,15 @@ gen_var_ref (struct agent_expr *ax, stru
value->kind = axs_lvalue_memory;
break;

+ case LOC_BASEREG_REF_ARG: /* relative to some base register,
+ dereferenced */
+ ax_reg (ax, SYMBOL_BASEREG (var));
+ gen_sym_offset (ax, var);
+ /* Don't assume any particular pointer size. */
+ gen_fetch (ax, lookup_pointer_type (builtin_type_void));
+ value->kind = axs_lvalue_memory;
+ break;
+
case LOC_TYPEDEF:
error ("Cannot compute value of typedef `%s'.",
SYMBOL_SOURCE_NAME (var));
Index: buildsym.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/buildsym.c,v
retrieving revision 2.112
diff -u -p -r2.112 buildsym.c
--- buildsym.c 2002/01/22 17:41:09 2.112
+++ buildsym.c 2002/04/24 16:22:33
@@ -284,6 +284,7 @@ finish_block (struct symbol *symbol, str
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
case LOC_LOCAL_ARG:
nparams++;
break;
@@ -320,6 +321,7 @@ finish_block (struct symbol *symbol, str
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
case LOC_LOCAL_ARG:
TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
Index: ch-exp.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/ch-exp.c,v
retrieving revision 2.28
diff -u -p -r2.28 ch-exp.c
--- ch-exp.c 2002/01/13 00:32:15 2.28
+++ ch-exp.c 2002/04/24 16:22:33
@@ -2156,6 +2156,7 @@ ch_lex (void)
case LOC_LOCAL_ARG:
case LOC_BASEREG:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
if (innermost_block == NULL
|| contained_in (block_found, innermost_block))
{
Index: dwarf2read.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2read.c,v
retrieving revision 2.79
diff -u -p -r2.79 dwarf2read.c
--- dwarf2read.c 2002/02/18 02:40:36 2.79
+++ dwarf2read.c 2002/04/24 16:22:35
@@ -4383,9 +4383,8 @@ new_symbol (struct die_info *die, struct
{
if (isderef)
{
- if (basereg != frame_base_reg)
- complain (&dwarf2_complex_location_expr);
- SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ SYMBOL_CLASS (sym) = LOC_BASEREG_REF_ARG;
+ SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
}
else
{
Index: findvar.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/findvar.c,v
retrieving revision 1.137.10.1
diff -u -p -r1.137.10.1 findvar.c
--- findvar.c 2002/02/27 03:27:18 1.137.10.1
+++ findvar.c 2002/04/24 16:22:35
@@ -378,6 +378,7 @@ symbol_read_needs_frame (struct symbol *
case LOC_LOCAL_ARG:
case LOC_BASEREG:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
case LOC_THREAD_LOCAL_STATIC:
return 1;

@@ -526,6 +527,23 @@ addresses have not been bound by the dyn
error ("Value of base register not available.");
addr = value_as_address (regval);
addr += SYMBOL_VALUE (var);
+ break;
+ }
+
+ case LOC_BASEREG_REF_ARG:
+ {
+ struct value *regval;
+ CORE_ADDR argref;
+ struct value *ref;
+
+ regval = value_from_register (lookup_pointer_type (type),
+ SYMBOL_BASEREG (var), frame);
+ if (regval == NULL)
+ error ("Value of base register not available.");
+ argref = value_as_address (regval);
+ argref += SYMBOL_VALUE (var);
+ ref = value_at (lookup_pointer_type (type), argref, NULL);
+ addr = value_as_address (ref);
break;
}

Index: m2-exp.y
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/m2-exp.y,v
retrieving revision 2.60
diff -u -p -r2.60 m2-exp.y
--- m2-exp.y 2001/03/26 19:54:18 2.60
+++ m2-exp.y 2002/04/24 16:22:35
@@ -1029,6 +1029,7 @@ yylex ()
case LOC_LOCAL_ARG:
case LOC_BASEREG:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
case LOC_CONST:
case LOC_CONST_BYTES:
case LOC_OPTIMIZED_OUT:
Index: printcmd.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/printcmd.c,v
retrieving revision 1.191
diff -u -p -r1.191 printcmd.c
--- printcmd.c 2002/02/06 17:15:20 1.191
+++ printcmd.c 2002/04/24 16:22:35
@@ -1246,6 +1246,11 @@ address_info (char *exp, int from_tty)
val, REGISTER_NAME (basereg));
break;

+ case LOC_BASEREG_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld from register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
case LOC_TYPEDEF:
printf_filtered ("a typedef");
break;
@@ -1840,6 +1845,7 @@ print_frame_args (struct symbol *func, s
case LOC_REGPARM_ADDR:
case LOC_LOCAL_ARG:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
break;

/* Other types of symbols we just skip over. */
Index: stack.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/stack.c,v
retrieving revision 1.149
diff -u -p -r1.149 stack.c
--- stack.c 2002/02/18 02:40:36 1.149
+++ stack.c 2002/04/24 16:22:37
@@ -1399,6 +1399,7 @@ print_frame_arg_vars (register struct fr
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
values_printed = 1;
fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
fputs_filtered (" = ", stream);
Index: symmisc.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/symmisc.c,v
retrieving revision 1.92
diff -u -p -r1.92 symmisc.c
--- symmisc.c 2001/12/03 20:48:52 1.92
+++ symmisc.c 2002/04/24 16:22:37
@@ -678,6 +678,11 @@ print_symbol (PTR args)
SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
break;

+ case LOC_BASEREG_REF_ARG:
+ fprintf_filtered (outfile, "arg at 0x%lx from register %d",
+ SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
+ break;
+
case LOC_TYPEDEF:
break;

Index: symtab.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/symtab.c,v
retrieving revision 1.265
diff -u -p -r1.265 symtab.c
--- symtab.c 2002/02/26 22:18:34 1.265
+++ symtab.c 2002/04/24 16:22:38
@@ -1329,7 +1329,8 @@ lookup_block_symbol (register const stru
SYMBOL_CLASS (sym) != LOC_REF_ARG &&
SYMBOL_CLASS (sym) != LOC_REGPARM &&
SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
- SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+ SYMBOL_CLASS (sym) != LOC_BASEREG_ARG &&
+ SYMBOL_CLASS (sym) != LOC_BASEREG_REF_ARG)
{
break;
}
Index: symtab.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/symtab.h,v
retrieving revision 1.167
diff -u -p -r1.167 symtab.h
--- symtab.h 2002/02/22 21:59:06 1.167
+++ symtab.h 2002/04/24 16:22:38
@@ -632,6 +632,14 @@ enum address_class

LOC_BASEREG_ARG,

+ /* Value address is at SYMBOL_VALUE plus the value of the register
+ indicated by SYMBOL_BASEREG. Note that this is like
+ LOC_BASEREG_ARG, except that an extra dereference is performed.
+ It's also similar to LOC_REF_ARG, but the basereg value has
+ been made explicit. */
+
+ LOC_BASEREG_REF_ARG,
+
/* Value is at fixed address, but the address of the variable has
to be determined from the minimal symbol table whenever the
variable is referenced.
@@ -717,7 +725,7 @@ struct symbol

union
{
- /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
+ /* Used by LOC_BASEREG, LOC_BASEREG_ARG, and LOC_BASEREG_REF_ARG. */
short basereg;
}
aux_value;
Index: tracepoint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/tracepoint.c,v
retrieving revision 2.79
diff -u -p -r2.79 tracepoint.c
--- tracepoint.c 2002/02/26 22:18:34 2.79
+++ tracepoint.c 2002/04/24 16:22:39
@@ -1281,6 +1281,11 @@ collect_symbol (struct collection_list *
}
add_memrange (collect, reg, offset, len);
break;
+ case LOC_BASEREG_REF_ARG:
+ printf_filtered ("Sorry, don't know how to do LOC_BASEREG_REF_ARG yet.\n");
+ printf_filtered (" (will not collect %s)\n",
+ SYMBOL_NAME (sym));
+ break;
case LOC_UNRESOLVED:
printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
break;
@@ -1327,6 +1332,7 @@ add_local_symbols (struct collection_lis
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
+ case LOC_BASEREG_REF_ARG:
if (type == 'A') /* collecting Arguments */
{
count++;
@@ -2433,6 +2439,11 @@ scope_info (char *args, int from_tty)
break;
case LOC_BASEREG_ARG:
printf_filtered ("an argument at offset %ld from register $%s",
+ SYMBOL_VALUE (sym),
+ REGISTER_NAME (SYMBOL_BASEREG (sym)));
+ break;
+ case LOC_BASEREG_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld from register $%s",
SYMBOL_VALUE (sym),
REGISTER_NAME (SYMBOL_BASEREG (sym)));
break;
Index: gdbtk/generic/gdbtk-stack.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk/generic/gdbtk-stack.c,v
retrieving revision 1.5
diff -u -p -r1.5 gdbtk-stack.c
--- gdbtk-stack.c 2002/02/08 22:28:04 1.5
+++ gdbtk-stack.c 2002/04/24 16:22:39
@@ -121,6 +121,7 @@ gdb_block_vars (ClientData clientData, T
case LOC_REGPARM_ADDR: /* indirect register arg */
case LOC_LOCAL_ARG: /* stack arg */
case LOC_BASEREG_ARG: /* basereg arg */
+ case LOC_BASEREG_REF_ARG: /* basereg ref arg */
case LOC_LOCAL: /* stack local */
case LOC_BASEREG: /* basereg local */
case LOC_STATIC: /* static */
@@ -196,6 +197,7 @@ gdb_get_blocks (ClientData clientData, T
case LOC_REGPARM_ADDR: /* indirect register arg */
case LOC_LOCAL_ARG: /* stack arg */
case LOC_BASEREG_ARG: /* basereg arg */
+ case LOC_BASEREG_REF_ARG: /* basereg ref arg */

case LOC_LOCAL: /* stack local */
case LOC_BASEREG: /* basereg local */
@@ -341,6 +343,7 @@ gdb_get_vars_command (ClientData clientD
case LOC_REGPARM_ADDR: /* indirect register arg */
case LOC_LOCAL_ARG: /* stack arg */
case LOC_BASEREG_ARG: /* basereg arg */
+ case LOC_BASEREG_REF_ARG: /* basereg ref arg */
if (arguments)
Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr,
Tcl_NewStringObj (SYMBOL_NAME (sym), -1));
Index: mi/mi-cmd-stack.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/mi/mi-cmd-stack.c,v
retrieving revision 1.13
diff -u -p -r1.13 mi-cmd-stack.c
--- mi-cmd-stack.c 2002/02/06 17:15:23 1.13
+++ mi-cmd-stack.c 2002/04/24 16:22:39
@@ -248,6 +248,7 @@ list_args_or_locals (int locals, int val
case LOC_REGPARM_ADDR: /* indirect register arg */
case LOC_LOCAL_ARG: /* stack arg */
case LOC_BASEREG_ARG: /* basereg arg */
+ case LOC_BASEREG_REF_ARG: /* basereg ref arg */
if (!locals)
print_me = 1;
break;