]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Shared library, function calling fixes for GNU/Linux PPC port.
authorKevin Buettner <kevinb@redhat.com>
Thu, 24 Feb 2000 23:06:48 +0000 (23:06 +0000)
committerKevin Buettner <kevinb@redhat.com>
Thu, 24 Feb 2000 23:06:48 +0000 (23:06 +0000)
gdb/ChangeLog
gdb/config/powerpc/tm-linux.h
gdb/ppc-linux-tdep.c
gdb/rs6000-tdep.c

index 99f0db879b951071ec33ba3cb12d3439c20f0068..59dd921e6e8cf8cc8cd9c6cbb17aefe50b064de0 100644 (file)
@@ -1,3 +1,17 @@
+2000-02-24  Kevin Buettner  <kevinb@redhat.com>
+
+       * ppc-linux-tdep.c (ppc_sysv_abi_push_arguments): Put address
+       of return structure in r3 if necessary.
+       (ppc_linux_memory_remove_breakpoints): New function.
+       * rs6000-tdep.c (skip_prologue): Make sure that the cases
+       for storing either cr or lr to the stack only handle those
+       cases.  (I.e, don't let these cases match 0x00000000 which is
+       found found in the shared library trampoline prior to the
+       loading of the shared library.)
+       * config/powerpc/tm-linux.h (ppc_linux_memory_remove_breakpoint):
+       Declare.
+       (MEMORY_REMOVE_BREAKPOINT): Define.
+
 Wed Feb 23 23:27:48 2000  Andrew Cagney  <cagney@behemoth.cygnus.com>
 
        * hppah-nat.c: Include "gdb_wait.h" instead of <wait.h>.
index 271c302c410bec9a08bb433614eb3b6bfbd74381..43fa60ffd44726cf71e587f65daa154b6845ca66 100644 (file)
@@ -93,6 +93,13 @@ CORE_ADDR ppc_sysv_abi_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
 #define PROLOGUE_FIRSTLINE_OVERLAP
 #endif
 
+/* Needed to handled the self-modifying code situation due to the dynamic
+   linker. */
+int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
+#undef MEMORY_REMOVE_BREAKPOINT
+#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) \
+  ppc_linux_memory_remove_breakpoint(addr, contents_cache)
+
 /* N_FUN symbols in shared libaries have 0 for their values and need
    to be relocated. */
 #define SOFUN_ADDRESS_MAYBE_MISSING
index b7182f90daccfe99776dcf93364c125f0c1a7586..0716eddb972a142752542fc46301448dbb37eda2 100644 (file)
@@ -522,6 +522,14 @@ ppc_sysv_abi_push_arguments (nargs, args, sp, struct_return, struct_addr)
   structoffset = argoffset + argstkspace;
   freg = 1;
   greg = 3;
+  /* Fill in r3 with the return structure, if any */
+  if (struct_return)
+    {
+      char val_buf[4];
+      store_address (val_buf, 4, struct_addr);
+      memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+      greg++;
+    }
   /* Now fill in the registers and stack... */
   for (argno = 0; argno < nargs; argno++)
     {
@@ -606,3 +614,29 @@ ppc_sysv_abi_push_arguments (nargs, args, sp, struct_return, struct_addr)
   target_store_registers (-1);
   return sp;
 }
+
+/* This version of ppc_linux_memory_remove_breakpoints handles the
+   case of self modifying code */
+int
+ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+  unsigned char *bp;
+  int val;
+  int bplen;
+  char old_contents[BREAKPOINT_MAX];
+
+  /* Determine appropriate breakpoint contents and size for this address.  */
+  bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+  if (bp == NULL)
+    error ("Software breakpoints not implemented for this target.");
+
+  val = target_read_memory (addr, old_contents, bplen);
+
+  /* If our breakpoint is no longer at the address, this means that the
+     program modified the code on us, so it is wrong to put back the
+     old value */
+  if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
+    val = target_write_memory (addr, contents_cache, bplen);
+
+  return val;
+}
index 29ca4ca6b9444d385ec9b2940e1258df635a78b6..ca094c74cf322af46537ad07a065a8d0afb66cb6 100644 (file)
@@ -313,8 +313,8 @@ skip_prologue (pc, fdata)
   char buf[4];
   unsigned long op;
   long offset = 0;
-  int lr_reg = 0;
-  int cr_reg = 0;
+  int lr_reg = -1;
+  int cr_reg = -1;
   int reg;
   int framep = 0;
   int minimal_toc_loaded = 0;
@@ -391,7 +391,7 @@ skip_prologue (pc, fdata)
          continue;
 
        }
-      else if ((op & 0xffff0000) == lr_reg)
+      else if (lr_reg != -1 && (op & 0xffff0000) == lr_reg)
        {                       /* st Rx,NUM(r1) 
                                   where Rx == lr */
          fdata->lr_offset = SIGNED_SHORT (op) + offset;
@@ -400,7 +400,7 @@ skip_prologue (pc, fdata)
          continue;
 
        }
-      else if ((op & 0xffff0000) == cr_reg)
+      else if (cr_reg != -1 && (op & 0xffff0000) == cr_reg)
        {                       /* st Rx,NUM(r1) 
                                   where Rx == cr */
          fdata->cr_offset = SIGNED_SHORT (op) + offset;