summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2000-02-24 23:06:48 +0000
committerKevin Buettner <kevinb@redhat.com>2000-02-24 23:06:48 +0000
commit07871ea926400766d6098b2221f444e540224261 (patch)
tree42b8bf6578e601c1ae9f4ec49789a777b253e2c6 /gdb
parentbcddc71f6bdf92597e5cd4986f2d9e0a1c74b5b4 (diff)
downloadgdb-07871ea926400766d6098b2221f444e540224261.tar.gz
Shared library, function calling fixes for GNU/Linux PPC port.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/config/powerpc/tm-linux.h7
-rw-r--r--gdb/ppc-linux-tdep.c34
-rw-r--r--gdb/rs6000-tdep.c8
4 files changed, 59 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 99f0db879b9..59dd921e6e8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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>.
diff --git a/gdb/config/powerpc/tm-linux.h b/gdb/config/powerpc/tm-linux.h
index 271c302c410..43fa60ffd44 100644
--- a/gdb/config/powerpc/tm-linux.h
+++ b/gdb/config/powerpc/tm-linux.h
@@ -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
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index b7182f90dac..0716eddb972 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -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;
+}
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 29ca4ca6b94..ca094c74cf3 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -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;