X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Frs6000-nat.c;h=d985fce644dc63ed47f1ce75c2bd2dcf5d716f68;hb=858c9d13240e695bc3b750368f5d4e524b12112e;hp=d0ec0c733e7292b0485630cebcb0428b0d88a4fb;hpb=53ce3c3929c7121f155e0a4a2492c8dba3878dfd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index d0ec0c733e..d985fce644 100644 --- a/gdb/rs6000-nat.c +++ b/gdb/rs6000-nat.c @@ -1,6 +1,6 @@ /* IBM RS/6000 native-dependent code for GDB, the GNU debugger. - Copyright (C) 1986-2013 Free Software Foundation, Inc. + Copyright (C) 1986-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -23,9 +23,7 @@ #include "gdbcore.h" #include "symfile.h" #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" @@ -46,7 +44,6 @@ #include #include #include -#include #include #include @@ -77,12 +74,7 @@ # define ARCH64() (register_size (target_gdbarch (), 0) == 8) #endif -static void exec_one_dummy_insn (struct regcache *); - -static LONGEST rs6000_xfer_shared_libraries - (struct target_ops *ops, enum target_object object, - const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, - ULONGEST offset, LONGEST len); +static target_xfer_partial_ftype rs6000_xfer_shared_libraries; /* Given REGNO, a gdb register number, return the corresponding number suitable for use as a ptrace() parameter. Return -1 if @@ -150,9 +142,9 @@ rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf) { #ifdef ARCH3264 # ifdef HAVE_PTRACE64 - int ret = ptrace64 (req, id, addr, data, buf); + int ret = ptrace64 (req, id, addr, data, (PTRACE_TYPE_ARG5) buf); # else - int ret = ptracex (req, id, addr, data, buf); + int ret = ptracex (req, id, addr, data, (PTRACE_TYPE_ARG5) buf); # endif #else int ret = 0; @@ -169,9 +161,10 @@ rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf) static void fetch_register (struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); - int addr[MAX_REGISTER_SIZE]; + struct gdbarch *gdbarch = regcache->arch (); + int addr[PPC_MAX_REGISTER_SIZE]; int nr, isfloat; + pid_t pid = ptid_get_pid (regcache_get_ptid (regcache)); /* Retrieved values may be -1, so infer errors from errno. */ errno = 0; @@ -180,7 +173,7 @@ fetch_register (struct regcache *regcache, int regno) /* Floating-point registers. */ if (isfloat) - rs6000_ptrace32 (PT_READ_FPR, ptid_get_pid (inferior_ptid), addr, nr, 0); + rs6000_ptrace32 (PT_READ_FPR, pid, addr, nr, 0); /* Bogus register number. */ else if (nr < 0) @@ -196,15 +189,13 @@ fetch_register (struct regcache *regcache, int regno) else { if (!ARCH64 ()) - *addr = rs6000_ptrace32 (PT_READ_GPR, ptid_get_pid (inferior_ptid), - (int *) nr, 0, 0); + *addr = rs6000_ptrace32 (PT_READ_GPR, pid, (int *) nr, 0, 0); else { /* PT_READ_GPR requires the buffer parameter to point to long long, even if the register is really only 32 bits. */ long long buf; - rs6000_ptrace64 (PT_READ_GPR, ptid_get_pid (inferior_ptid), - nr, 0, &buf); + rs6000_ptrace64 (PT_READ_GPR, pid, nr, 0, &buf); if (register_size (gdbarch, regno) == 8) memcpy (addr, &buf, 8); else @@ -229,9 +220,10 @@ fetch_register (struct regcache *regcache, int regno) static void store_register (struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); - int addr[MAX_REGISTER_SIZE]; + struct gdbarch *gdbarch = regcache->arch (); + int addr[PPC_MAX_REGISTER_SIZE]; int nr, isfloat; + pid_t pid = ptid_get_pid (regcache_get_ptid (regcache)); /* Fetch the register's value from the register cache. */ regcache_raw_collect (regcache, regno, addr); @@ -243,7 +235,7 @@ store_register (struct regcache *regcache, int regno) /* Floating-point registers. */ if (isfloat) - rs6000_ptrace32 (PT_WRITE_FPR, ptid_get_pid (inferior_ptid), addr, nr, 0); + rs6000_ptrace32 (PT_WRITE_FPR, pid, addr, nr, 0); /* Bogus register number. */ else if (nr < 0) @@ -257,20 +249,11 @@ store_register (struct regcache *regcache, int regno) /* 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. */ if (!ARCH64 ()) - rs6000_ptrace32 (PT_WRITE_GPR, ptid_get_pid (inferior_ptid), - (int *) nr, *addr, 0); + rs6000_ptrace32 (PT_WRITE_GPR, pid, (int *) nr, *addr, 0); else { /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte @@ -280,8 +263,7 @@ store_register (struct regcache *regcache, int regno) memcpy (&buf, addr, 8); else buf = *addr; - rs6000_ptrace64 (PT_WRITE_GPR, ptid_get_pid (inferior_ptid), - nr, 0, &buf); + rs6000_ptrace64 (PT_WRITE_GPR, pid, nr, 0, &buf); } } @@ -299,7 +281,7 @@ static void rs6000_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); if (regno != -1) fetch_register (regcache, regno); @@ -342,7 +324,7 @@ static void rs6000_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); if (regno != -1) store_register (regcache, regno); @@ -377,16 +359,13 @@ rs6000_store_inferior_registers (struct target_ops *ops, } } +/* 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, LONGEST len) + ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { pid_t pid = ptid_get_pid (inferior_ptid); int arch64 = ARCH64 (); @@ -396,7 +375,7 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object, 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 @@ -454,7 +433,7 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object, (int *) (uintptr_t) rounded_offset, buffer.word, NULL); if (errno) - return 0; + return TARGET_XFER_EOF; } if (readbuf) @@ -468,18 +447,19 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object, (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 -1; + return TARGET_XFER_E_IO; } } @@ -539,63 +519,18 @@ rs6000_wait (struct target_ops *ops, 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); -} /* Set the current architecture from the host running GDB. Called when starting a child process. */ -static void (*super_create_inferior) (struct target_ops *,char *exec_file, - char *allargs, char **env, int from_tty); +static void (*super_create_inferior) (struct target_ops *, + const char *exec_file, + const std::string &allargs, + char **env, int from_tty); static void -rs6000_create_inferior (struct target_ops * ops, char *exec_file, - char *allargs, char **env, int from_tty) +rs6000_create_inferior (struct target_ops * ops, const char *exec_file, + const std::string &allargs, char **env, int from_tty) { enum bfd_architecture arch; unsigned long mach; @@ -657,7 +592,7 @@ rs6000_ptrace_ldinfo (ptid_t ptid) { const int pid = ptid_get_pid (ptid); int ldi_size = 1024; - gdb_byte *ldi = xmalloc (ldi_size); + void *ldi = xmalloc (ldi_size); int rc = -1; while (1) @@ -679,17 +614,17 @@ rs6000_ptrace_ldinfo (ptid_t ptid) ldi = xrealloc (ldi, ldi_size); } - return ldi; + return (gdb_byte *) ldi; } /* 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, LONGEST len) + ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { gdb_byte *ldi_buf; ULONGEST result; @@ -700,7 +635,7 @@ rs6000_xfer_shared_libraries gdb_assert (target_has_execution); if (writebuf) - return -1; + return TARGET_XFER_E_IO; ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid); gdb_assert (ldi_buf != NULL); @@ -710,10 +645,15 @@ rs6000_xfer_shared_libraries xfree (ldi_buf); do_cleanups (cleanup); - return result; -} -void _initialize_rs6000_nat (void); + if (result == 0) + return TARGET_XFER_EOF; + else + { + *xfered_len = result; + return TARGET_XFER_OK; + } +} void _initialize_rs6000_nat (void)