Shared library, function calling fixes for GNU/Linux PPC port.

This commit is contained in:
Kevin Buettner 2000-02-24 23:06:48 +00:00
parent 60f036a265
commit 482ca3f5dc
4 changed files with 59 additions and 4 deletions

View 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>.

View 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

View 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;
}

View 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;