Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com)
authorJim Kingdon <jkingdon@engr.sgi.com>
Thu, 22 Apr 1993 22:27:25 +0000 (22:27 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Thu, 22 Apr 1993 22:27:25 +0000 (22:27 +0000)
* 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.

gdb/ChangeLog
gdb/config/sparc/tm-sparc.h
gdb/printcmd.c
gdb/stabsread.c
gdb/stack.c
gdb/symtab.h

index 6ed895829a2b8b98c29407de71dd40be99bcca0a..9638be573b412f1c3f4e1c91072e24d802528d3c 100644 (file)
@@ -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):
index 9dcc7a423e2d0fcf37bb326a97f212718b2329f3..d4acb9a7712d35093e2da13d1e47500207c615ac 100644 (file)
@@ -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,
index 298de93f838d9bcac34c35ab2c647061e6d769cb..ebb5ccfad848289e714dd22751a9cb0517ec92eb 100644 (file)
@@ -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;
 
index 035725987c375d5b0e063a4cffe3120ba28606a3..9b475bd0f31ecc2c9a267de719e9b32b5bb2cbd1 100644 (file)
@@ -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;
 }
 
index 0d9019f1e9371b84b827ff41d76f0210428ec7ee..37f92e46bd33f0d9015016b71f1308f76f55708f 100644 (file)
@@ -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);
index 82ad9611cf8de15f124d4b2506028b1f38471e0a..f04407d8d9e3ae723276a2a5e522b17e210c36cf 100644 (file)
@@ -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,