aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Kingdon <jkingdon@engr.sgi.com>1993-04-22 22:27:25 +0000
committerJim Kingdon <jkingdon@engr.sgi.com>1993-04-22 22:27:25 +0000
commit5afa2040f45d3772e759c2e148ad8bf33115c80a (patch)
tree1daadfad56d3ec827d2fe2e70f97b98abafb2117
parent4365c36c9b87e20565b20c52809c781c50831a18 (diff)
downloadgdb-5afa2040f45d3772e759c2e148ad8bf33115c80a.zip
gdb-5afa2040f45d3772e759c2e148ad8bf33115c80a.tar.gz
gdb-5afa2040f45d3772e759c2e148ad8bf33115c80a.tar.bz2
Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com)
* symtab.h: Fix LOC_REF_ARG comment. Wed Apr 22 20:21:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) and Jim Kingdon (kingdon@cygnus.com) * stabsread.c (define_symbol): Combine a 'p', 'r' arg pair to a LOC_REGPARM symbol. * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Revise comments. symfile.c (compare_symbols): Don't check first character; STRCMP does that. * stabsread.c (define_symbol): Generate a LOC_REGPARM_ADDR for structures that are passed by address in a register. * symtab.h (enum address_class): Add LOC_REGPARM_ADDR. * findvar.c (read_var_value), printcmd.c (address_info, print_frame_args), stack.c (print_frame_arg_vars), symmisc.c (print_{,partial_}symbol), * symtab.c (lookup_block_symbol): Deal with it.
-rw-r--r--gdb/ChangeLog21
-rw-r--r--gdb/config/sparc/tm-sparc.h12
-rw-r--r--gdb/printcmd.c5
-rw-r--r--gdb/stabsread.c43
-rw-r--r--gdb/stack.c3
-rw-r--r--gdb/symtab.h20
6 files changed, 86 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6ed8958..9638be5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,24 @@
+Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * symtab.h: Fix LOC_REF_ARG comment.
+
+Wed Apr 22 20:21:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * stabsread.c (define_symbol): Combine a 'p', 'r' arg pair to a
+ LOC_REGPARM symbol.
+ * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Revise comments.
+ symfile.c (compare_symbols): Don't check first character; STRCMP
+ does that.
+
+ * stabsread.c (define_symbol): Generate a LOC_REGPARM_ADDR for
+ structures that are passed by address in a register.
+ * symtab.h (enum address_class): Add LOC_REGPARM_ADDR.
+ * findvar.c (read_var_value),
+ printcmd.c (address_info, print_frame_args),
+ stack.c (print_frame_arg_vars), symmisc.c (print_{,partial_}symbol),
+ * symtab.c (lookup_block_symbol): Deal with it.
+
Thu Apr 22 09:07:24 1993 Jim Kingdon (kingdon@cygnus.com)
* objfiles.h (obj_section), objfiles.c (build_objfile_section_table):
diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h
index 9dcc7a4..d4acb9a 100644
--- a/gdb/config/sparc/tm-sparc.h
+++ b/gdb/config/sparc/tm-sparc.h
@@ -25,18 +25,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define IEEE_FLOAT
/* When passing a structure to a function, Sun cc passes the address
- in a register, not the structure itself. It (under SunOS4) creates
- two symbols, so we get a LOC_ARG saying the address is on the stack
- (a lie, and a serious one since we don't know which register to
- use), and a LOC_REGISTER saying that the struct is in a register
- (sort of a lie, but fixable with REG_STRUCT_HAS_ADDR). Gcc version
- two (as of 1.92) behaves like sun cc. REG_STRUCT_HAS_ADDR is smart
- enough to distinguish between Sun cc, gcc version 1 and gcc version 2.
+ not the structure itself. It (under SunOS4) creates two symbols,
+ which we need to combine to a LOC_REGPARM. Gcc version two (as of
+ 1.92) behaves like sun cc. REG_STRUCT_HAS_ADDR is smart enough to
+ distinguish between Sun cc, gcc version 1 and gcc version 2.
This still doesn't work if the argument is not one passed in a
register (i.e. it's the 7th or later argument). */
#define REG_STRUCT_HAS_ADDR(gcc_p) (gcc_p != 1)
-#define STRUCT_ARG_SYM_GARBAGE(gcc_p) (gcc_p != 1)
/* If Pcc says that a parameter is a short, it's a short. This is
because the parameter does get passed in in a register as an int,
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 298de93..ebb5ccf 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -951,6 +951,10 @@ address_info (exp, from_tty)
case LOC_REGPARM:
printf ("an argument in register %s", reg_names[val]);
break;
+
+ case LOC_REGPARM_ADDR:
+ printf ("address of an argument in register %s", reg_names[val]);
+ break;
case LOC_ARG:
if (SYMBOL_BASEREG_VALID (sym))
@@ -1513,6 +1517,7 @@ print_frame_args (func, fi, num, stream)
/* We care about types of symbols, but don't need to keep track of
stack offsets in them. */
case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
case LOC_LOCAL_ARG:
break;
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 0357259..9b475bd 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -864,7 +864,31 @@ define_symbol (valu, string, desc, type, objfile)
}
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
if (within_function)
- add_symbol_to_list (sym, &local_symbols);
+ {
+ /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same
+ name to represent an argument passed in a register.
+ GCC uses 'P' for the same case. So if we find such a symbol pair
+ we combine it into one 'P' symbol.
+ Note that this code illegally combines
+ main(argc) int argc; { register int argc = 1; }
+ but this case is considered pathological and causes a warning
+ from a decent compiler. */
+ if (local_symbols
+ && local_symbols->nsyms > 0)
+ {
+ struct symbol *prev_sym;
+ prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
+ if (SYMBOL_CLASS (prev_sym) == LOC_ARG
+ && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym)))
+ {
+ SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
+ SYMBOL_VALUE (prev_sym) = SYMBOL_VALUE (sym);
+ sym = prev_sym;
+ break;
+ }
+ }
+ add_symbol_to_list (sym, &local_symbols);
+ }
else
add_symbol_to_list (sym, &file_symbols);
break;
@@ -965,6 +989,23 @@ define_symbol (valu, string, desc, type, objfile)
default:
error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum);
}
+
+ /* When passing structures to a function, some systems sometimes pass
+ the address in a register, not the structure itself.
+
+ If REG_STRUCT_HAS_ADDR yields non-zero we have to convert LOC_REGPARM
+ to LOC_REGPARM_ADDR for structures and unions. */
+
+#if !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p) 0
+#endif
+
+ if (SYMBOL_CLASS (sym) == LOC_REGPARM
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
+ && ( (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
+ || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+
return sym;
}
diff --git a/gdb/stack.c b/gdb/stack.c
index 0d9019f..37f92e4 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -882,7 +882,8 @@ print_frame_arg_vars (frame, stream)
if (SYMBOL_CLASS (sym) == LOC_ARG
|| SYMBOL_CLASS (sym) == LOC_LOCAL_ARG
|| SYMBOL_CLASS (sym) == LOC_REF_ARG
- || SYMBOL_CLASS (sym) == LOC_REGPARM)
+ || SYMBOL_CLASS (sym) == LOC_REGPARM
+ || SYMBOL_CLASS (sym) == LOC_REGPARM_ADDR)
{
values_printed = 1;
fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 82ad961..f04407d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -448,10 +448,7 @@ enum address_class
LOC_ARG,
- /* Value address is at SYMBOL_VALUE offset in arglist. Currently
- this is used for C++ references (and presumably will be used for
- Pascal VAR parameters), and is only dereferenced in certain
- contexts. */
+ /* Value address is at SYMBOL_VALUE offset in arglist. */
LOC_REF_ARG,
@@ -462,13 +459,20 @@ enum address_class
FRAME_LOCALS_ADDRESS), and an is_argument flag.
For some symbol formats (stabs, for some compilers at least),
- gdb generates a LOC_ARG and a LOC_REGISTER rather than a LOC_REGPARM.
- This is because that's what the compiler does, but perhaps it would
- be better if the symbol-reading code detected this (is it possible?)
- and generated a LOC_REGPARM. */
+ the compiler generates two symbols, an argument and a register.
+ In some cases we combine them to a single LOC_REGPARM in symbol
+ reading, but I'm not sure whether we do for all cases (I'm thinking
+ of when it's passed on the stack and then loaded into a register). */
LOC_REGPARM,
+ /* Value is in specified register. Just like LOC_REGPARM except the
+ register holds the address of the argument instead of the argument
+ itself. This is currently used for the passing of structs and unions
+ on sparc and hppa. */
+
+ LOC_REGPARM_ADDR,
+
/* Value is a local variable at SYMBOL_VALUE offset in stack frame. */
LOC_LOCAL,