#include "rs6000-tdep.h"
#include "exec.h"
#include "gdb_stdint.h"
+#include "observer.h"
#include <sys/ptrace.h>
#include <sys/reg.h>
# define ARCH64() (register_size (current_gdbarch, 0) == 8)
#endif
-/* Union of 32-bit and 64-bit ".reg" core file sections. */
-
-typedef union {
-#ifdef ARCH3264
- struct __context64 r64;
-#else
- struct mstsave r64;
-#endif
- struct mstsave r32;
-} CoreRegs;
-
/* Union of 32-bit and 64-bit versions of ld_info. */
typedef union {
static void vmap_symtab (struct vmap *);
-static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
-
static void exec_one_dummy_insn (void);
extern void fixup_breakpoints (CORE_ADDR low, CORE_ADDR high, CORE_ADDR delta);
*isfloat = 1;
return regno - tdep->ppc_fp0_regnum + FPR0;
}
- else if (regno == PC_REGNUM)
+ else if (regno == gdbarch_pc_regnum (current_gdbarch))
return IAR;
else if (regno == tdep->ppc_ps_regnum)
return MSR;
/* Fetch register REGNO from the inferior. */
static void
-fetch_register (int regno)
+fetch_register (struct regcache *regcache, int regno)
{
int addr[MAX_REGISTER_SIZE];
int nr, isfloat;
/* Bogus register number. */
else if (nr < 0)
{
- if (regno >= NUM_REGS)
+ if (regno >= gdbarch_num_regs (current_gdbarch))
fprintf_unfiltered (gdb_stderr,
"gdb error: register no %d not implemented.\n",
regno);
}
if (!errno)
- regcache_raw_supply (current_regcache, regno, (char *) addr);
+ regcache_raw_supply (regcache, regno, (char *) addr);
else
{
#if 0
/* Store register REGNO back into the inferior. */
static void
-store_register (int regno)
+store_register (const struct regcache *regcache, int regno)
{
int addr[MAX_REGISTER_SIZE];
int nr, isfloat;
/* Fetch the register's value from the register cache. */
- regcache_raw_collect (current_regcache, regno, addr);
+ regcache_raw_collect (regcache, regno, addr);
/* -1 can be a successful return value, so infer errors from errno. */
errno = 0;
/* Bogus register number. */
else if (nr < 0)
{
- if (regno >= NUM_REGS)
+ if (regno >= gdbarch_num_regs (current_gdbarch))
fprintf_unfiltered (gdb_stderr,
"gdb error: register no %d not implemented.\n",
regno);
/* Fixed-point registers. */
else
{
- if (regno == SP_REGNUM)
+ if (regno == gdbarch_sp_regnum (current_gdbarch))
/* Execute one dummy instruction (which is a breakpoint) in inferior
process to give kernel a chance to do internal housekeeping.
Otherwise the following ptrace(2) calls will mess up user stack
REGNO otherwise. */
static void
-rs6000_fetch_inferior_registers (int regno)
+rs6000_fetch_inferior_registers (struct regcache *regcache, int regno)
{
if (regno != -1)
- fetch_register (regno);
+ fetch_register (regcache, regno);
else
{
regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
regno++)
{
- fetch_register (regno);
+ fetch_register (regcache, regno);
}
/* Read general purpose floating point registers. */
if (tdep->ppc_fp0_regnum >= 0)
for (regno = 0; regno < ppc_num_fprs; regno++)
- fetch_register (tdep->ppc_fp0_regnum + regno);
+ fetch_register (regcache, tdep->ppc_fp0_regnum + regno);
/* Read special registers. */
- fetch_register (PC_REGNUM);
- fetch_register (tdep->ppc_ps_regnum);
- fetch_register (tdep->ppc_cr_regnum);
- fetch_register (tdep->ppc_lr_regnum);
- fetch_register (tdep->ppc_ctr_regnum);
- fetch_register (tdep->ppc_xer_regnum);
+ fetch_register (regcache, gdbarch_pc_regnum (current_gdbarch));
+ fetch_register (regcache, tdep->ppc_ps_regnum);
+ fetch_register (regcache, tdep->ppc_cr_regnum);
+ fetch_register (regcache, tdep->ppc_lr_regnum);
+ fetch_register (regcache, tdep->ppc_ctr_regnum);
+ fetch_register (regcache, tdep->ppc_xer_regnum);
if (tdep->ppc_fpscr_regnum >= 0)
- fetch_register (tdep->ppc_fpscr_regnum);
+ fetch_register (regcache, tdep->ppc_fpscr_regnum);
if (tdep->ppc_mq_regnum >= 0)
- fetch_register (tdep->ppc_mq_regnum);
+ fetch_register (regcache, tdep->ppc_mq_regnum);
}
}
Otherwise, REGNO specifies which register (so we can save time). */
static void
-rs6000_store_inferior_registers (int regno)
+rs6000_store_inferior_registers (struct regcache *regcache, int regno)
{
if (regno != -1)
- store_register (regno);
+ store_register (regcache, regno);
else
{
regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
regno++)
{
- store_register (regno);
+ store_register (regcache, regno);
}
/* Write floating point registers. */
if (tdep->ppc_fp0_regnum >= 0)
for (regno = 0; regno < ppc_num_fprs; regno++)
- store_register (tdep->ppc_fp0_regnum + regno);
+ store_register (regcache, tdep->ppc_fp0_regnum + regno);
/* Write special registers. */
- store_register (PC_REGNUM);
- store_register (tdep->ppc_ps_regnum);
- store_register (tdep->ppc_cr_regnum);
- store_register (tdep->ppc_lr_regnum);
- store_register (tdep->ppc_ctr_regnum);
- store_register (tdep->ppc_xer_regnum);
+ store_register (regcache, gdbarch_pc_regnum (current_gdbarch));
+ store_register (regcache, tdep->ppc_ps_regnum);
+ store_register (regcache, tdep->ppc_cr_regnum);
+ store_register (regcache, tdep->ppc_lr_regnum);
+ store_register (regcache, tdep->ppc_ctr_regnum);
+ store_register (regcache, tdep->ppc_xer_regnum);
if (tdep->ppc_fpscr_regnum >= 0)
- store_register (tdep->ppc_fpscr_regnum);
+ store_register (regcache, tdep->ppc_fpscr_regnum);
if (tdep->ppc_mq_regnum >= 0)
- store_register (tdep->ppc_mq_regnum);
+ store_register (regcache, tdep->ppc_mq_regnum);
}
}
}
}
+/* Wait for the child specified by PTID to do something. Return the
+ process ID of the child, or MINUS_ONE_PTID in case of error; store
+ the status in *OURSTATUS. */
+
+static ptid_t
+rs6000_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ pid_t pid;
+ int status, save_errno;
+
+ do
+ {
+ set_sigint_trap ();
+ set_sigio_trap ();
+
+ do
+ {
+ pid = waitpid (ptid_get_pid (ptid), &status, 0);
+ save_errno = errno;
+ }
+ while (pid == -1 && errno == EINTR);
+
+ clear_sigio_trap ();
+ clear_sigint_trap ();
+
+ if (pid == -1)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ _("Child process unexpectedly missing: %s.\n"),
+ safe_strerror (save_errno));
+
+ /* Claim it exited with unknown signal. */
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return minus_one_ptid;
+ }
+
+ /* Ignore terminated detached child processes. */
+ if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
+ pid = -1;
+ }
+ while (pid == -1);
+
+ /* AIX has a couple of strange returns from wait(). */
+
+ /* stop after load" status. */
+ if (status == 0x57c)
+ ourstatus->kind = TARGET_WAITKIND_LOADED;
+ /* signal 0. I have no idea why wait(2) returns with this status word. */
+ else if (status == 0x7f)
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ /* A normal waitstatus. Let the usual macros deal with it. */
+ else
+ store_waitstatus (ourstatus, status);
+
+ return pid_to_ptid (pid);
+}
/* Execute one dummy breakpoint instruction. This way we give the kernel
a chance to do some housekeeping and update inferior's internal data,
write_pc (prev_pc);
deprecated_remove_raw_breakpoint (bp);
}
-
-/* Fetch registers from the register section in core bfd. */
-
-static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
- int which, CORE_ADDR reg_addr)
-{
- CoreRegs *regs;
- int regi;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
- if (which != 0)
- {
- fprintf_unfiltered
- (gdb_stderr,
- "Gdb error: unknown parameter to fetch_core_registers().\n");
- return;
- }
-
- regs = (CoreRegs *) core_reg_sect;
-
- /* Put the register values from the core file section in the regcache. */
-
- if (ARCH64 ())
- {
- for (regi = 0; regi < ppc_num_gprs; regi++)
- regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + regi,
- (char *) ®s->r64.gpr[regi]);
-
- if (tdep->ppc_fp0_regnum >= 0)
- for (regi = 0; regi < ppc_num_fprs; regi++)
- regcache_raw_supply (current_regcache, tdep->ppc_fp0_regnum + regi,
- (char *) ®s->r64.fpr[regi]);
-
- regcache_raw_supply (current_regcache, PC_REGNUM,
- (char *) ®s->r64.iar);
- regcache_raw_supply (current_regcache, tdep->ppc_ps_regnum,
- (char *) ®s->r64.msr);
- regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum,
- (char *) ®s->r64.cr);
- regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum,
- (char *) ®s->r64.lr);
- regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum,
- (char *) ®s->r64.ctr);
- regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum,
- (char *) ®s->r64.xer);
- if (tdep->ppc_fpscr_regnum >= 0)
- regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
- (char *) ®s->r64.fpscr);
- }
- else
- {
- for (regi = 0; regi < ppc_num_gprs; regi++)
- regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + regi,
- (char *) ®s->r32.gpr[regi]);
-
- if (tdep->ppc_fp0_regnum >= 0)
- for (regi = 0; regi < ppc_num_fprs; regi++)
- regcache_raw_supply (current_regcache, tdep->ppc_fp0_regnum + regi,
- (char *) ®s->r32.fpr[regi]);
-
- regcache_raw_supply (current_regcache, PC_REGNUM,
- (char *) ®s->r32.iar);
- regcache_raw_supply (current_regcache, tdep->ppc_ps_regnum,
- (char *) ®s->r32.msr);
- regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum,
- (char *) ®s->r32.cr);
- regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum,
- (char *) ®s->r32.lr);
- regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum,
- (char *) ®s->r32.ctr);
- regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum,
- (char *) ®s->r32.xer);
- if (tdep->ppc_fpscr_regnum >= 0)
- regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
- (char *) ®s->r32.fpscr);
- if (tdep->ppc_mq_regnum >= 0)
- regcache_raw_supply (current_regcache, tdep->ppc_mq_regnum,
- (char *) ®s->r32.mq);
- }
-}
\f
/* Copy information about text and data sections from LDI to VP for a 64-bit
/* Announce new object files. Doing this after symbol relocation
makes aix-thread.c's job easier. */
- if (deprecated_target_new_objfile_hook && vp->objfile)
- deprecated_target_new_objfile_hook (vp->objfile);
+ if (vp->objfile)
+ observer_notify_new_objfile (vp->objfile);
/* There may be more, so we don't break out of the loop. */
}
/* Set the current architecture from the host running GDB. Called when
starting a child process. */
-void
-rs6000_create_inferior (int pid)
+static void (*super_create_inferior) (char *exec_file, char *allargs,
+ char **env, int from_tty);
+static void
+rs6000_create_inferior (char *exec_file, char *allargs, char **env, int from_tty)
{
enum bfd_architecture arch;
unsigned long mach;
bfd abfd;
struct gdbarch_info info;
+ super_create_inferior (exec_file, allargs, env, from_tty);
+
if (__power_rs ())
{
arch = bfd_arch_rs6000;
\f
/* xcoff_relocate_symtab - hook for symbol table relocation.
- also reads shared libraries. */
+
+ This is only applicable to live processes, and is a no-op when
+ debugging a core file. */
void
xcoff_relocate_symtab (unsigned int pid)
int ldisize = arch64 ? sizeof (ldi->l64) : sizeof (ldi->l32);
int size;
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
do
{
size = load_segs * ldisize;
vmap_symtab (vp);
- if (deprecated_target_new_objfile_hook && vp != vmap && vp->objfile)
- deprecated_target_new_objfile_hook (vp->objfile);
+ if (vp != vmap && vp->objfile)
+ observer_notify_new_objfile (vp->objfile);
}
while (LDI_NEXT (ldi, arch64) != 0);
vmap_exec ();
error (_("Unable to find TOC entry for pc %s."), hex_string (pc));
}
\f
-/* Register that we are able to handle rs6000 core file formats. */
-
-static struct core_fns rs6000_core_fns =
-{
- bfd_target_xcoff_flavour, /* core_flavour */
- default_check_format, /* check_format */
- default_core_sniffer, /* core_sniffer */
- fetch_core_registers, /* core_read_registers */
- NULL /* next */
-};
void
-_initialize_core_rs6000 (void)
+_initialize_rs6000_nat (void)
{
struct target_ops *t;
t->to_fetch_registers = rs6000_fetch_inferior_registers;
t->to_store_registers = rs6000_store_inferior_registers;
t->to_xfer_partial = rs6000_xfer_partial;
+
+ super_create_inferior = t->to_create_inferior;
+ t->to_create_inferior = rs6000_create_inferior;
+
+ t->to_wait = rs6000_wait;
+
add_target (t);
/* Initialize hook in rs6000-tdep.c for determining the TOC address
when calling functions in the inferior. */
rs6000_find_toc_address_hook = find_toc_address;
-
- deprecated_add_core_fns (&rs6000_core_fns);
}