/* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This file is part of GDB.
#include "objfiles.h"
#include "libbfd.h" /* For bfd_default_set_arch_mach (FIXME) */
#include "bfd.h"
-#include "exceptions.h"
#include "gdb-stabs.h"
#include "regcache.h"
#include "arch-utils.h"
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
-#include <errno.h>
#include <a.out.h>
#include <sys/file.h>
# define ARCH64() (register_size (target_gdbarch (), 0) == 8)
#endif
-static void exec_one_dummy_insn (struct regcache *);
-
static target_xfer_partial_ftype rs6000_xfer_shared_libraries;
/* Given REGNO, a gdb register number, return the corresponding
/* Fixed-point registers. */
else
{
- if (regno == gdbarch_sp_regnum (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
- since kernel will get confused about the bottom of the stack
- (%sp). */
- exec_one_dummy_insn (regcache);
-
/* The PT_WRITE_GPR operation is rather odd. For 32-bit inferiors,
the register's value is passed by value, but for 64-bit inferiors,
the address of a buffer containing the value is passed. */
}
}
+/* Implement the to_xfer_partial target_ops method. */
-/* Attempt a transfer all LEN bytes starting at OFFSET between the
- inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
- Return the number of bytes actually transferred. */
-
-static LONGEST
+static enum target_xfer_status
rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len)
+ ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
pid_t pid = ptid_get_pid (inferior_ptid);
int arch64 = ARCH64 ();
case TARGET_OBJECT_LIBRARIES_AIX:
return rs6000_xfer_shared_libraries (ops, object, annex,
readbuf, writebuf,
- offset, len);
+ offset, len, xfered_len);
case TARGET_OBJECT_MEMORY:
{
union
(int *) (uintptr_t) rounded_offset,
buffer.word, NULL);
if (errno)
- return 0;
+ return TARGET_XFER_EOF;
}
if (readbuf)
(int *)(uintptr_t)rounded_offset,
0, NULL);
if (errno)
- return 0;
+ return TARGET_XFER_EOF;
/* Copy appropriate bytes out of the buffer. */
memcpy (readbuf, buffer.byte + (offset - rounded_offset),
partial_len);
}
- return partial_len;
+ *xfered_len = (ULONGEST) partial_len;
+ return TARGET_XFER_OK;
}
default:
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,
- including u_area. */
-
-static void
-exec_one_dummy_insn (struct regcache *regcache)
-{
-#define DUMMY_INSN_ADDR AIX_TEXT_SEGMENT_BASE+0x200
-
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int ret, status, pid;
- CORE_ADDR prev_pc;
- void *bp;
-
- /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We
- assume that this address will never be executed again by the real
- code. */
-
- bp = deprecated_insert_raw_breakpoint (gdbarch, NULL, DUMMY_INSN_ADDR);
-
- /* You might think this could be done with a single ptrace call, and
- you'd be correct for just about every platform I've ever worked
- on. However, rs6000-ibm-aix4.1.3 seems to have screwed this up --
- the inferior never hits the breakpoint (it's also worth noting
- powerpc-ibm-aix4.1.3 works correctly). */
- prev_pc = regcache_read_pc (regcache);
- regcache_write_pc (regcache, DUMMY_INSN_ADDR);
- if (ARCH64 ())
- ret = rs6000_ptrace64 (PT_CONTINUE, ptid_get_pid (inferior_ptid),
- 1, 0, NULL);
- else
- ret = rs6000_ptrace32 (PT_CONTINUE, ptid_get_pid (inferior_ptid),
- (int *) 1, 0, NULL);
-
- if (ret != 0)
- perror (_("pt_continue"));
-
- do
- {
- pid = waitpid (ptid_get_pid (inferior_ptid), &status, 0);
- }
- while (pid != ptid_get_pid (inferior_ptid));
-
- regcache_write_pc (regcache, prev_pc);
- deprecated_remove_raw_breakpoint (gdbarch, bp);
-}
\f
/* Set the current architecture from the host running GDB. Called when
/* Implement the to_xfer_partial target_ops method for
TARGET_OBJECT_LIBRARIES_AIX objects. */
-static LONGEST
+static enum target_xfer_status
rs6000_xfer_shared_libraries
(struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len)
+ ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
gdb_byte *ldi_buf;
ULONGEST result;
xfree (ldi_buf);
do_cleanups (cleanup);
- return result;
+
+ if (result == 0)
+ return TARGET_XFER_EOF;
+ else
+ {
+ *xfered_len = result;
+ return TARGET_XFER_OK;
+ }
}
void _initialize_rs6000_nat (void);