From: Jim Kingdon Date: Thu, 22 Apr 1993 22:27:25 +0000 (+0000) Subject: Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5afa2040f45d3772e759c2e148ad8bf33115c80a;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6ed895829a2..9638be573b4 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 9dcc7a423e2..d4acb9a7712 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 298de93f838..ebb5ccfad84 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 035725987c3..9b475bd0f31 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 0d9019f1e93..37f92e46bd3 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 82ad9611cf8..f04407d8d9e 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,