Patch from Dawn Perchik <dawn@cygnus.com>:
authorMark Alexander <marka@cygnus>
Wed, 23 Sep 1998 05:41:38 +0000 (05:41 +0000)
committerMark Alexander <marka@cygnus>
Wed, 23 Sep 1998 05:41:38 +0000 (05:41 +0000)
* rs6000-tdep.c (pop_frame): Handle generic dummy frames.
(push_arguments): Likewise.
(frame_saved_pc): Likewise.
(rs6000_frame_chain): Likewise.
(ppc_push_return_address): New function.
(get_saved_register): New function.
* config/powerpc/tm-ppc-eabi.h: Add generic dummy frame macros.

gdb/ChangeLog
gdb/rs6000-tdep.c

index 8e916383fe4daf89464dfc56c37e21f01b64f0fc..7da9553d15a0dd47776e7af936c4d92c00a39b24 100644 (file)
@@ -1,3 +1,14 @@
+Tue Sep 22 22:27:24 1998  Mark Alexander  <marka@cygnus.com>
+
+       Patch from Dawn Perchik <dawn@cygnus.com>:
+       * rs6000-tdep.c (pop_frame): Handle generic dummy frames.
+       (push_arguments): Likewise.
+       (frame_saved_pc): Likewise.
+       (rs6000_frame_chain): Likewise.
+       (ppc_push_return_address): New function.
+       (get_saved_register): New function.
+       * config/powerpc/tm-ppc-eabi.h: Add generic dummy frame macros.
+
 Mon Sep 21 19:29:32 1998  Stu Grossman  <grossman@babylon-5.cygnus.com>
 
        * defs.h utils.c (fputc_filtered):  New function.  Does the obvious...
index 6cd30fd2bf049ee32c96052ab9e64d5ab79c3d7d..4bc628d0b4fbdd288f9999b19955d85092c94883 100644 (file)
@@ -19,6 +19,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
+#include "tm.h"
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
@@ -616,10 +617,18 @@ pop_frame ()
   pc = read_pc ();
   sp = FRAME_FP (frame);
 
-  if (stop_stack_dummy && dummy_frame_count) {
-    pop_dummy_frame ();
-    return;
-  }
+  if (stop_stack_dummy)
+    {
+#ifdef USE_GENERIC_DUMMY_FRAMES
+      generic_pop_dummy_frame ();
+      flush_cached_frames ();
+      return;
+#else
+      if (dummy_frame_count) 
+       pop_dummy_frame ();
+      return;
+#endif
+    }
 
   /* Make sure that all registers are valid.  */
   read_register_bytes (0, NULL, REGISTER_BYTES);
@@ -733,13 +742,16 @@ push_arguments (nargs, args, sp, struct_return, struct_addr)
   int argbytes;                                        /* current argument byte */
   char tmp_buffer [50];
   int f_argno = 0;                             /* current floating point argno */
+
   value_ptr arg = 0;
   struct type *type;
 
   CORE_ADDR saved_sp;
 
+#ifndef USE_GENERIC_DUMMY_FRAMES
   if ( dummy_frame_count <= 0)
     printf_unfiltered ("FATAL ERROR -push_arguments()! frame not found!!\n");
+#endif /* GENERIC_DUMMY_FRAMES */
 
   /* The first eight words of ther arguments are passed in registers. Copy
      them appropriately.
@@ -751,6 +763,25 @@ push_arguments (nargs, args, sp, struct_return, struct_addr)
 
   ii =  struct_return ? 1 : 0;
 
+/* 
+effectively indirect call... gcc does...
+
+return_val example( float, int);
+
+eabi: 
+    float in fp0, int in r3
+    offset of stack on overflow 8/16
+    for varargs, must go by type.
+power open:
+    float in r3&r4, int in r5
+    offset of stack on overflow different 
+both: 
+    return in r3 or f0.  If no float, must study how gcc emulates floats;
+    pay attention to arg promotion.  
+    User may have to cast\args to handle promotion correctly 
+    since gdb won't know if prototype supplied or not.
+*/
+
   for (argno=0, argbytes=0; argno < nargs && ii<8; ++ii) {
 
     arg = args[argno];
@@ -798,12 +829,15 @@ push_arguments (nargs, args, sp, struct_return, struct_addr)
 
 ran_out_of_registers_for_arguments:
 
+#ifdef USE_GENERIC_DUMMY_FRAMES
+  saved_sp = read_sp ();
+#else
   /* location for 8 parameters are always reserved. */
   sp -= 4 * 8;
 
   /* another six words for back chain, TOC register, link register, etc. */
   sp -= 24;
-
+#endif /* GENERIC_DUMMY_FRAMES */
   /* if there are more arguments, allocate space for them in 
      the stack, then push them starting from the ninth one. */
 
@@ -873,9 +907,14 @@ ran_out_of_registers_for_arguments:
     /* Secure stack areas first, before doing anything else. */
     write_register (SP_REGNUM, sp);
 
+#ifndef USE_GENERIC_DUMMY_FRAMES
+/* we want to copy 24 bytes of target's frame to dummy's frame,
+   then set back chain to point to new frame. */
+
   saved_sp = dummy_frame_addr [dummy_frame_count - 1];
   read_memory (saved_sp, tmp_buffer, 24);
   write_memory (sp, tmp_buffer, 24);
+#endif /* GENERIC_DUMMY_FRAMES */
 
   /* set back chain properly */
   store_address (tmp_buffer, 4, saved_sp);
@@ -884,6 +923,21 @@ ran_out_of_registers_for_arguments:
   target_store_registers (-1);
   return sp;
 }
+#ifdef ELF_OBJECT_FORMAT
+
+/* Function: ppc_push_return_address (pc, sp)
+   Set up the return address for the inferior function call. */
+
+CORE_ADDR                                      
+ppc_push_return_address (pc, sp)
+     CORE_ADDR pc;
+     CORE_ADDR sp;
+{
+  write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
+  return sp;
+}
+
+#endif
 
 /* a given return value in `regbuf' with a type `valtype', extract and copy its
    value into `valbuf' */
@@ -1023,6 +1077,11 @@ frame_saved_pc (fi)
   if (fi->signal_handler_caller)
     return read_memory_integer (fi->frame + SIG_FRAME_PC_OFFSET, 4);
 
+#ifdef USE_GENERIC_DUMMY_FRAMES
+  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+    return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+#endif /* GENERIC_DUMMY_FRAMES */
+
   func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
 
   /* If we failed to find the start of the function, it is a mistake
@@ -1184,8 +1243,16 @@ rs6000_frame_chain (thisframe)
      struct frame_info *thisframe;
 {
   CORE_ADDR fp;
-  if (inside_entry_file ((thisframe)->pc))
+
+#ifdef USE_GENERIC_DUMMY_FRAMES
+  if (PC_IN_CALL_DUMMY (thisframe->pc, thisframe->frame, thisframe->frame))
+    return thisframe->frame;   /* dummy frame same as caller's frame */
+#endif /* GENERIC_DUMMY_FRAMES */
+
+  if (inside_entry_file (thisframe->pc) || 
+      thisframe->pc == entry_point_address ())
     return 0;
+
   if (thisframe->signal_handler_caller)
     fp = read_memory_integer (thisframe->frame + SIG_FRAME_FP_OFFSET, 4);
   else if (thisframe->next != NULL
@@ -1197,6 +1264,17 @@ rs6000_frame_chain (thisframe)
   else
     fp = read_memory_integer ((thisframe)->frame, 4);
 
+#ifdef USE_GENERIC_DUMMY_FRAMES
+  {
+    CORE_ADDR fpp, lr;
+
+    lr = read_register (LR_REGNUM);
+    if (lr == entry_point_address ())
+      if (fp != 0 && (fpp = read_memory_integer (fp, 4)) != 0)
+       if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
+         return fpp;
+  }
+#endif /* GENERIC_DUMMY_FRAMES */
   return fp;
 }
 \f
@@ -1229,6 +1307,23 @@ gdb_print_insn_powerpc (memaddr, info)
 }
 #endif
 
+/* Function: get_saved_register
+   Just call the generic_get_saved_register function.  */
+
+void
+get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+     char *raw_buffer;
+     int *optimized;
+     CORE_ADDR *addrp;
+     struct frame_info *frame;
+     int regnum;
+     enum lval_type *lval;
+{
+  generic_get_saved_register (raw_buffer, optimized, addrp, 
+                             frame, regnum, lval);
+}
+
+
 void
 _initialize_rs6000_tdep ()
 {