* symtab.c (find_pc_symtab): some object file formats, notably mips,
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 5bee145831ffcb07448ce123cd44f55bcfda10c5..c775fe9c4759b5b365b4f47d2787d39fb43d3a50 100644 (file)
@@ -23,6 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symtab.h"
 #include "target.h"
 
+#include "xcoffsolib.h"
+
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/user.h>
@@ -30,21 +32,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/ioctl.h>
 #include <fcntl.h>
 
-#include <sys/ptrace.h>
-#include <sys/reg.h>
-
 #include <a.out.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/core.h>
 #include <sys/ldr.h>
 
+
+extern struct obstack frame_cache_obstack;
+
 extern int errno;
 
 /* Nonzero if we just simulated a single step break. */
 int one_stepped;
 
-
 /* Breakpoint shadows for the single step instructions will be kept here. */
 
 static struct sstep_breaks {
@@ -54,9 +55,6 @@ static struct sstep_breaks {
 
 /* Static function prototypes */
 
-static void
-add_text_to_loadinfo PARAMS ((CORE_ADDR textaddr, CORE_ADDR dataaddr));
-
 static CORE_ADDR
 find_toc_address PARAMS ((CORE_ADDR pc));
 
@@ -119,9 +117,9 @@ branch_dest (opcode, instr, pc, safety)
 
 /* AIX does not support PT_STEP. Simulate it. */
 
-int
+void
 single_step (signal)
-int signal;
+     int signal;
 {
 #define        INSNLEN(OPCODE)  4
 
@@ -159,9 +157,7 @@ int signal;
     }  
 
     one_stepped = 1;
-    ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0);
-  }
-  else {
+  } else {
 
     /* remove step breakpoints. */
     for (ii=0; ii < 2; ++ii)
@@ -171,8 +167,7 @@ int signal;
 
     one_stepped = 0;
   }
-  errno = 0;
-  return 1;
+  errno = 0;                   /* FIXME, don't ignore errors! */
 }
 
 
@@ -214,6 +209,11 @@ CORE_ADDR pc;
       return pc - 4;                   /* don't skip over this branch */
   }
 
+  if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
+    pc += 4;                            /* store floating register double */
+    op = read_memory_integer (pc, 4);
+  }
+
   if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
     pc += 4;
     op = read_memory_integer (pc, 4);
@@ -221,7 +221,7 @@ CORE_ADDR pc;
 
   while (((tmp = op >> 16) == 0x9001) || /* st   r0, NUM(r1) */
         (tmp == 0x9421) ||             /* stu  r1, NUM(r1) */
-        (op == 0x93e1fffc))            /* st   r31,-4(r1) */
+        (tmp == 0x93e1))               /* st   r31,NUM(r1) */
   {
     pc += 4;
     op = read_memory_integer (pc, 4);
@@ -275,7 +275,7 @@ CORE_ADDR pc;
          function as well. */
 
       tmp = find_pc_misc_function (pc);
-      if (tmp >= 0 && !strcmp (misc_function_vector [tmp].name, "main"))
+      if (tmp >= 0 && STREQ (misc_function_vector [tmp].name, "main"))
         return pc + 8;
     }
   }
@@ -321,7 +321,7 @@ push_dummy_frame ()
   int sp, pc;                          /* stack pointer and link register */
   int ii;
 
-  fetch_inferior_registers (-1);
+  target_fetch_registers (-1);
 
   if (dummy_frame_count >= dummy_frame_size) {
     dummy_frame_size += DUMMY_FRAME_ADDR_SIZE;
@@ -399,7 +399,7 @@ FIXME:  This whole concept is broken.  You should be able to detect
 a dummy stack frame *on the user's stack itself*.  When you do,
 then you know the format of that stack frame -- including its
 saved SP register!  There should *not* be a separate stack in the
-GDB process that keeps track of these dummy frames!  -- gnu@cygnus.com Aug92 */
+GDB process that keeps track of these dummy frames!  -- gnu@cygnus.com Aug92
  */
    
 pop_dummy_frame ()
@@ -433,7 +433,7 @@ pop_dummy_frame ()
 
   /* Now we can restore all registers. */
 
-  store_inferior_registers (-1);
+  target_store_registers (-1);
   pc = read_pc ();
   flush_cached_frames ();
   set_current_frame (create_new_frame (sp, pc));
@@ -480,7 +480,7 @@ pop_frame ()
   if (fdata.saved_gpr != -1)
     for (ii=fdata.saved_gpr; ii <= 31; ++ii) {
       read_memory (addr, &registers [REGISTER_BYTE (ii)], 4);
-      addr += sizeof (int);
+      addr += 4;
     }
 
   if (fdata.saved_fpr != -1)
@@ -490,7 +490,7 @@ pop_frame ()
   }
 
   write_register (SP_REGNUM, prev_sp);
-  store_inferior_registers (-1);
+  target_store_registers (-1);
   flush_cached_frames ();
   set_current_frame (create_new_frame (prev_sp, lr));
 }
@@ -537,7 +537,8 @@ fix_call_dummy(dummyname, pc, fun, nargs, type)
 
 /* return information about a function frame.
    in struct aix_frameinfo fdata:
-    - frameless is TRUE, if function does not save %pc value in its frame.
+    - frameless is TRUE, if function does not have a frame.
+    - nosavedpc is TRUE, if function does not save %pc value in its frame.
     - offset is the number of bytes used in the frame to save registers.
     - saved_gpr is the number of the first saved gpr.
     - saved_fpr is the number of the first saved fpr.
@@ -546,7 +547,7 @@ fix_call_dummy(dummyname, pc, fun, nargs, type)
  */
 void
 function_frame_info (pc, fdata)
-  int pc;
+  CORE_ADDR pc;
   struct aix_framedata *fdata;
 {
   unsigned int tmp;
@@ -554,20 +555,22 @@ function_frame_info (pc, fdata)
 
   fdata->offset = 0;
   fdata->saved_gpr = fdata->saved_fpr = fdata->alloca_reg = -1;
+  fdata->frameless = 1;
 
   op  = read_memory_integer (pc, 4);
   if (op == 0x7c0802a6) {              /* mflr r0 */
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->nosavedpc = 0;
     fdata->frameless = 0;
   }
-  else                         /* else, this is a frameless invocation */
-    fdata->frameless = 1;
-
+  else                         /* else, pc is not saved */
+    fdata->nosavedpc = 1;
 
   if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
@@ -581,11 +584,13 @@ function_frame_info (pc, fdata)
     if (op == 0x4def7b82 ||            /* crorc 15, 15, 15 */
        op == 0x0)
       return;                          /* prologue is over */
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
     pc += 4;                            /* store floating register double */
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
@@ -593,7 +598,7 @@ function_frame_info (pc, fdata)
     fdata->saved_gpr = (op >> 21) & 0x1f;
     tmp2 = op & 0xffff;
     if (tmp2 > 0x7fff)
-      tmp2 = 0xffff0000 | tmp2;
+      tmp2 = (~0 &~ 0xffff) | tmp2;
 
     if (tmp2 < 0) {
       tmp2 = tmp2 * -1;
@@ -606,29 +611,43 @@ function_frame_info (pc, fdata)
     fdata->offset = tmp2;
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   while (((tmp = op >> 16) == 0x9001) ||       /* st   r0, NUM(r1) */
         (tmp == 0x9421) ||                     /* stu  r1, NUM(r1) */
-        (op == 0x93e1fffc))                    /* st   r31,-4(r1) */
+        (tmp == 0x93e1))                       /* st r31, NUM(r1) */
   {
+    int tmp2;
+
     /* gcc takes a short cut and uses this instruction to save r31 only. */
 
-    if (op == 0x93e1fffc) {
+    if (tmp == 0x93e1) {
       if (fdata->offset)
 /*        fatal ("Unrecognized prolog."); */
         printf ("Unrecognized prolog!\n");
 
       fdata->saved_gpr = 31;
-      fdata->offset = 4;
+      tmp2 = op & 0xffff;
+      if (tmp2 > 0x7fff) {
+       tmp2 = - ((~0 &~ 0xffff) | tmp2);
+       fdata->saved_fpr = (tmp2 - ((32 - 31) * 4)) / 8;
+       if ( fdata->saved_fpr > 0)
+         fdata->saved_fpr = 32 - fdata->saved_fpr;
+       else
+         fdata->saved_fpr = -1;
+      }
+      fdata->offset = tmp2;
     }
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   while ((tmp = (op >> 22)) == 0x20f) {        /* l    r31, ... or */
     pc += 4;                           /* l    r30, ...    */
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   /* store parameters into stack */
@@ -640,10 +659,13 @@ function_frame_info (pc, fdata)
     {
       pc += 4;                                 /* store fpr double */
       op = read_memory_integer (pc, 4);
+      fdata->frameless = 0;
     }
 
-  if (op == 0x603f0000)                                /* oril r31, r1, 0x0 */
+  if (op == 0x603f0000) {                      /* oril r31, r1, 0x0 */
     fdata->alloca_reg = 31;
+    fdata->frameless = 0;
+  }
 }
 
 
@@ -814,7 +836,7 @@ ran_out_of_registers_for_arguments:
 
     write_memory (sp, &saved_sp, 4);   /* set back chain properly */
 
-  store_inferior_registers (-1);
+  target_store_registers (-1);
   return sp;
 }
 
@@ -910,11 +932,14 @@ CORE_ADDR pc;
 
 
 /* Determines whether the function FI has a frame on the stack or not.
-   Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h.  */
+   Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h with a
+   second argument of 0, and from the FRAME_SAVED_PC macro with a
+   second argument of 1.  */
 
 int
-frameless_function_invocation (fi)
+frameless_function_invocation (fi, pcsaved)
 struct frame_info *fi;
+int pcsaved;
 {
   CORE_ADDR func_start;
   struct aix_framedata fdata;
@@ -928,7 +953,7 @@ struct frame_info *fi;
     return 0;
 
   function_frame_info (func_start, &fdata);
-  return fdata.frameless;
+  return pcsaved ? fdata.nosavedpc : fdata.frameless;
 }
 
 
@@ -1030,7 +1055,7 @@ frame_initial_stack_address (fi)
   for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
 
     if (!callee_fi->cache_fsr)
-      frame_get_cache_fsr (fi, NULL);
+      frame_get_cache_fsr (callee_fi, NULL);
 
     /* this is the address in which alloca register is saved. */
 
@@ -1153,7 +1178,7 @@ xcoff_add_toc_to_loadinfo (unsigned long tocoff)
 }
 
 
-static void
+void
 add_text_to_loadinfo (textaddr, dataaddr)
      CORE_ADDR textaddr;
      CORE_ADDR dataaddr;
This page took 0.027652 seconds and 4 git commands to generate.