X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frs6000-nat.c;h=ad411f9b19ab4b090f8f2801ec48dfd100aaa05b;hb=e98ee8c458f3a8405eb93e71b00f801b4bbe3635;hp=83e0693d9834cf97863b038e4778405692220265;hpb=7c5ded6a00c4817d56cdf04fbc1969bc33b2a930;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index 83e0693d98..ad411f9b19 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-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -33,7 +33,7 @@ #include "rs6000-tdep.h" #include "rs6000-aix-tdep.h" #include "exec.h" -#include "observer.h" +#include "observable.h" #include "xcoffread.h" #include @@ -74,7 +74,34 @@ # define ARCH64() (register_size (target_gdbarch (), 0) == 8) #endif -static target_xfer_partial_ftype rs6000_xfer_shared_libraries; +class rs6000_nat_target final : public inf_ptrace_target +{ +public: + void fetch_registers (struct regcache *, int) override; + void store_registers (struct regcache *, int) override; + + enum target_xfer_status xfer_partial (enum target_object object, + const char *annex, + gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) override; + + void create_inferior (const char *, const std::string &, + char **, int) override; + + ptid_t wait (ptid_t, struct target_waitstatus *, int) override; + +private: + enum target_xfer_status + xfer_shared_libraries (enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len); +}; + +static rs6000_nat_target the_rs6000_nat_target; /* Given REGNO, a gdb register number, return the corresponding number suitable for use as a ptrace() parameter. Return -1 if @@ -161,10 +188,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)); + pid_t pid = regcache->ptid ().pid (); /* Retrieved values may be -1, so infer errors from errno. */ errno = 0; @@ -204,7 +231,7 @@ fetch_register (struct regcache *regcache, int regno) } if (!errno) - regcache_raw_supply (regcache, regno, (char *) addr); + regcache->raw_supply (regno, (char *) addr); else { #if 0 @@ -220,13 +247,13 @@ 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)); + pid_t pid = regcache->ptid ().pid (); /* Fetch the register's value from the register cache. */ - regcache_raw_collect (regcache, regno, addr); + regcache->raw_collect (regno, addr); /* -1 can be a successful return value, so infer errors from errno. */ errno = 0; @@ -277,11 +304,10 @@ store_register (struct regcache *regcache, int regno) /* Read from the inferior all registers if REGNO == -1 and just register REGNO otherwise. */ -static void -rs6000_fetch_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +rs6000_nat_target::fetch_registers (struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); if (regno != -1) fetch_register (regcache, regno); @@ -320,11 +346,10 @@ rs6000_fetch_inferior_registers (struct target_ops *ops, If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */ -static void -rs6000_store_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +rs6000_nat_target::store_registers (struct regcache *regcache, int regno) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); if (regno != -1) store_register (regcache, regno); @@ -361,21 +386,22 @@ rs6000_store_inferior_registers (struct target_ops *ops, /* Implement the to_xfer_partial target_ops method. */ -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 *xfered_len) +enum target_xfer_status +rs6000_nat_target::xfer_partial (enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) { - pid_t pid = ptid_get_pid (inferior_ptid); + pid_t pid = inferior_ptid.pid (); int arch64 = ARCH64 (); switch (object) { case TARGET_OBJECT_LIBRARIES_AIX: - return rs6000_xfer_shared_libraries (ops, object, annex, - readbuf, writebuf, - offset, len, xfered_len); + return xfer_shared_libraries (object, annex, + readbuf, writebuf, + offset, len, xfered_len); case TARGET_OBJECT_MEMORY: { union @@ -467,9 +493,9 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object, process ID of the child, or MINUS_ONE_PTID in case of error; store the status in *OURSTATUS. */ -static ptid_t -rs6000_wait (struct target_ops *ops, - ptid_t ptid, struct target_waitstatus *ourstatus, int options) +ptid_t +rs6000_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, + int options) { pid_t pid; int status, save_errno; @@ -480,7 +506,7 @@ rs6000_wait (struct target_ops *ops, do { - pid = waitpid (ptid_get_pid (ptid), &status, 0); + pid = waitpid (ptid.pid (), &status, 0); save_errno = errno; } while (pid == -1 && errno == EINTR); @@ -500,7 +526,7 @@ rs6000_wait (struct target_ops *ops, } /* Ignore terminated detached child processes. */ - if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) + if (!WIFSTOPPED (status) && pid != inferior_ptid.pid ()) pid = -1; } while (pid == -1); @@ -517,27 +543,24 @@ rs6000_wait (struct target_ops *ops, else store_waitstatus (ourstatus, status); - return pid_to_ptid (pid); + return ptid_t (pid); } /* Set the current architecture from the host running GDB. Called when starting a child process. */ -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, const char *exec_file, - const std::string &allargs, char **env, int from_tty) +void +rs6000_nat_target::create_inferior (const char *exec_file, + const std::string &allargs, + char **env, int from_tty) { enum bfd_architecture arch; unsigned long mach; bfd abfd; struct gdbarch_info info; - super_create_inferior (ops, exec_file, allargs, env, from_tty); + inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty); if (__power_rs ()) { @@ -583,25 +606,23 @@ rs6000_create_inferior (struct target_ops * ops, const char *exec_file, /* Shared Object support. */ /* Return the LdInfo data for the given process. Raises an error - if the data could not be obtained. - - The returned value must be deallocated after use. */ + if the data could not be obtained. */ -static gdb_byte * +static gdb::byte_vector rs6000_ptrace_ldinfo (ptid_t ptid) { - const int pid = ptid_get_pid (ptid); - int ldi_size = 1024; - void *ldi = xmalloc (ldi_size); + const int pid = ptid.pid (); + gdb::byte_vector ldi (1024); int rc = -1; while (1) { if (ARCH64 ()) - rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, ldi_size, - NULL); + rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (), + ldi.size (), NULL); else - rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, ldi_size, NULL); + rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (), + ldi.size (), NULL); if (rc != -1) break; /* Success, we got the entire ld_info data. */ @@ -610,25 +631,22 @@ rs6000_ptrace_ldinfo (ptid_t ptid) perror_with_name (_("ptrace ldinfo")); /* ldi is not big enough. Double it and try again. */ - ldi_size *= 2; - ldi = xrealloc (ldi, ldi_size); + ldi.resize (ldi.size () * 2); } - return (gdb_byte *) ldi; + return ldi; } /* Implement the to_xfer_partial target_ops method for TARGET_OBJECT_LIBRARIES_AIX objects. */ -static enum target_xfer_status -rs6000_xfer_shared_libraries - (struct target_ops *ops, enum target_object object, +enum target_xfer_status +rs6000_nat_target::xfer_shared_libraries + (enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { - gdb_byte *ldi_buf; ULONGEST result; - struct cleanup *cleanup; /* This function assumes that it is being run with a live process. Core files are handled via gdbarch. */ @@ -637,14 +655,9 @@ rs6000_xfer_shared_libraries if (writebuf) return TARGET_XFER_E_IO; - ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid); - gdb_assert (ldi_buf != NULL); - cleanup = make_cleanup (xfree, ldi_buf); - result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf, + gdb::byte_vector ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid); + result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf.data (), readbuf, offset, len, 1); - xfree (ldi_buf); - - do_cleanups (cleanup); if (result == 0) return TARGET_XFER_EOF; @@ -655,22 +668,8 @@ rs6000_xfer_shared_libraries } } -void _initialize_rs6000_nat (void); - void _initialize_rs6000_nat (void) { - struct target_ops *t; - - t = inf_ptrace_target (); - 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); + add_inf_child_target (&the_rs6000_nat_target); }