X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fi386-linux-nat.c;h=dd8f141f23b118018a31aad4ca3889d0ecae436a;hb=5d49bf1b698124fe21017105f84b18e29221b262;hp=154cd12849e7fab0739c5b96abf200fafb7a56c5;hpb=040baaf6deeec9f92645169f3f6e84996e23c986;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 154cd12849..dd8f141f23 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for GNU/Linux i386. - Copyright (C) 1999-2014 Free Software Foundation, Inc. + Copyright (C) 1999-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -18,49 +18,36 @@ along with this program. If not, see . */ #include "defs.h" -#include "i386-nat.h" #include "inferior.h" #include "gdbcore.h" #include "regcache.h" -#include "regset.h" -#include "target.h" -#include "linux-nat.h" -#include "nat/linux-btrace.h" -#include "btrace.h" - -#include "gdb_assert.h" -#include #include "elf/common.h" +#include "nat/gdb_ptrace.h" #include -#include -#include -#include - -#ifdef HAVE_SYS_REG_H -#include -#endif - -#ifndef ORIG_EAX -#define ORIG_EAX -1 -#endif - -#ifdef HAVE_SYS_DEBUGREG_H -#include -#endif - -/* Prototypes for supply_gregset etc. */ #include "gregset.h" +#include "gdb_proc_service.h" +#include "i386-linux-nat.h" #include "i387-tdep.h" #include "i386-tdep.h" #include "i386-linux-tdep.h" +#include "gdbsupport/x86-xstate.h" -/* Defines ps_err_e, struct ps_prochandle. */ -#include "gdb_proc_service.h" +#include "x86-linux-nat.h" +#include "nat/linux-ptrace.h" +#include "inf-ptrace.h" -#include "i386-xstate.h" +struct i386_linux_nat_target final : public x86_linux_nat_target +{ + /* Add our register access methods. */ + void fetch_registers (struct regcache *, int) override; + void store_registers (struct regcache *, int) override; -#include "x86-linux-nat.h" + /* Override the default ptrace resume method. */ + void low_resume (ptid_t ptid, int step, enum gdb_signal sig) override; +}; + +static i386_linux_nat_target the_i386_linux_nat_target; /* The register sets used in GNU/Linux ELF core-dumps are identical to the register sets in `struct user' that is used for a.out @@ -84,7 +71,7 @@ (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS) #define GETXSTATEREGS_SUPPLIES(regno) \ - (I386_ST0_REGNUM <= (regno) && (regno) < I386_AVX512_NUM_REGS) + (I386_ST0_REGNUM <= (regno) && (regno) < I386_PKEYS_NUM_REGS) /* Does the current host support the GETREGS request? */ int have_ptrace_getregs = @@ -119,30 +106,27 @@ int have_ptrace_getfpxregs = static void fetch_register (struct regcache *regcache, int regno) { - int tid; + pid_t tid; int val; gdb_assert (!have_ptrace_getregs); if (i386_linux_gregset_reg_offset[regno] == -1) { - regcache_raw_supply (regcache, regno, NULL); + regcache->raw_supply (regno, NULL); return; } - /* GNU/Linux LWP ID's are process ID's. */ - tid = ptid_get_lwp (inferior_ptid); - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ + tid = get_ptrace_pid (regcache->ptid ()); errno = 0; val = ptrace (PTRACE_PEEKUSER, tid, i386_linux_gregset_reg_offset[regno], 0); if (errno != 0) error (_("Couldn't read register %s (#%d): %s."), - gdbarch_register_name (get_regcache_arch (regcache), regno), + gdbarch_register_name (regcache->arch (), regno), regno, safe_strerror (errno)); - regcache_raw_supply (regcache, regno, &val); + regcache->raw_supply (regno, &val); } /* Store one register. */ @@ -150,25 +134,22 @@ fetch_register (struct regcache *regcache, int regno) static void store_register (const struct regcache *regcache, int regno) { - int tid; + pid_t tid; int val; gdb_assert (!have_ptrace_getregs); if (i386_linux_gregset_reg_offset[regno] == -1) return; - /* GNU/Linux LWP ID's are process ID's. */ - tid = ptid_get_lwp (inferior_ptid); - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ + tid = get_ptrace_pid (regcache->ptid ()); errno = 0; - regcache_raw_collect (regcache, regno, &val); + regcache->raw_collect (regno, &val); ptrace (PTRACE_POKEUSER, tid, i386_linux_gregset_reg_offset[regno], val); if (errno != 0) error (_("Couldn't write register %s (#%d): %s."), - gdbarch_register_name (get_regcache_arch (regcache), regno), + gdbarch_register_name (regcache->arch (), regno), regno, safe_strerror (errno)); } @@ -186,13 +167,13 @@ supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) int i; for (i = 0; i < I386_NUM_GREGS; i++) - regcache_raw_supply (regcache, i, - regp + i386_linux_gregset_reg_offset[i]); + regcache->raw_supply (i, regp + i386_linux_gregset_reg_offset[i]); if (I386_LINUX_ORIG_EAX_REGNUM - < gdbarch_num_regs (get_regcache_arch (regcache))) - regcache_raw_supply (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp - + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); + < gdbarch_num_regs (regcache->arch ())) + regcache->raw_supply + (I386_LINUX_ORIG_EAX_REGNUM, + regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); } /* Fill register REGNO (if it is a general-purpose register) in @@ -208,14 +189,14 @@ fill_gregset (const struct regcache *regcache, for (i = 0; i < I386_NUM_GREGS; i++) if (regno == -1 || regno == i) - regcache_raw_collect (regcache, i, - regp + i386_linux_gregset_reg_offset[i]); + regcache->raw_collect (i, regp + i386_linux_gregset_reg_offset[i]); if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM) && I386_LINUX_ORIG_EAX_REGNUM - < gdbarch_num_regs (get_regcache_arch (regcache))) - regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp - + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); + < gdbarch_num_regs (regcache->arch ())) + regcache->raw_collect + (I386_LINUX_ORIG_EAX_REGNUM, + regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); } #ifdef HAVE_PTRACE_GETREGS @@ -349,10 +330,10 @@ store_fpregs (const struct regcache *regcache, int tid, int regno) static int fetch_xstateregs (struct regcache *regcache, int tid) { - char xstateregs[I386_XSTATE_MAX_SIZE]; + char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; - if (!have_ptrace_getregset) + if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; iov.iov_base = xstateregs; @@ -372,10 +353,10 @@ fetch_xstateregs (struct regcache *regcache, int tid) static int store_xstateregs (const struct regcache *regcache, int tid, int regno) { - char xstateregs[I386_XSTATE_MAX_SIZE]; + char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; - if (!have_ptrace_getregset) + if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; iov.iov_base = xstateregs; @@ -476,11 +457,10 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno) this for all registers (including the floating point and SSE registers). */ -static void -i386_linux_fetch_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +i386_linux_nat_target::fetch_registers (struct regcache *regcache, int regno) { - int tid; + pid_t tid; /* Use the old method of peeking around in `struct user' if the GETREGS request isn't available. */ @@ -488,17 +468,14 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops, { int i; - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++) if (regno == -1 || regno == i) fetch_register (regcache, i); return; } - /* GNU/Linux LWP ID's are process ID's. */ - tid = ptid_get_lwp (inferior_ptid); - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ + tid = get_ptrace_pid (regcache->ptid ()); /* Use the PTRACE_GETFPXREGS request whenever possible, since it transfers more registers in one system call, and we'll cache the @@ -511,7 +488,7 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops, /* The call above might reset `have_ptrace_getregs'. */ if (!have_ptrace_getregs) { - i386_linux_fetch_inferior_registers (ops, regcache, regno); + fetch_registers (regcache, regno); return; } @@ -557,11 +534,10 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops, /* Store register REGNO back into the child process. If REGNO is -1, do this for all registers (including the floating point and SSE registers). */ -static void -i386_linux_store_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +i386_linux_nat_target::store_registers (struct regcache *regcache, int regno) { - int tid; + pid_t tid; /* Use the old method of poking around in `struct user' if the SETREGS request isn't available. */ @@ -569,17 +545,14 @@ i386_linux_store_inferior_registers (struct target_ops *ops, { int i; - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++) if (regno == -1 || regno == i) store_register (regcache, i); return; } - /* GNU/Linux LWP ID's are process ID's. */ - tid = ptid_get_lwp (inferior_ptid); - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ + tid = get_ptrace_pid (regcache->ptid ()); /* Use the PTRACE_SETFPXREGS requests whenever possible, since it transfers more registers in one system call. But remember that @@ -628,7 +601,7 @@ i386_linux_store_inferior_registers (struct target_ops *ops, storage (or its descriptor). */ ps_err_e -ps_get_thread_area (const struct ps_prochandle *ph, +ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) { unsigned int base_addr; @@ -671,12 +644,10 @@ static const unsigned char linux_syscall[] = { 0xcd, 0x80 }; If STEP is nonzero, single-step it. If SIGNAL is nonzero, give it that signal. */ -static void -i386_linux_resume (struct target_ops *ops, - ptid_t ptid, int step, enum gdb_signal signal) +void +i386_linux_nat_target::low_resume (ptid_t ptid, int step, enum gdb_signal signal) { - int pid = ptid_get_pid (ptid); - + int pid = ptid.lwp (); int request; if (catch_syscall_enabled () > 0) @@ -686,8 +657,8 @@ i386_linux_resume (struct target_ops *ops, if (step) { - struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid)); - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct regcache *regcache = get_thread_regcache (ptid); + struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST pc; gdb_byte buf[LINUX_SYSCALL_LEN]; @@ -739,24 +710,12 @@ i386_linux_resume (struct target_ops *ops, if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); } - - -/* -Wmissing-prototypes */ -extern initialize_file_ftype _initialize_i386_linux_nat; void _initialize_i386_linux_nat (void) { - /* Create a generic x86 GNU/Linux target. */ - struct target_ops *t = x86_linux_create_target (); - - /* Override the default ptrace resume method. */ - t->to_resume = i386_linux_resume; - - /* Add our register access methods. */ - t->to_fetch_registers = i386_linux_fetch_inferior_registers; - t->to_store_registers = i386_linux_store_inferior_registers; + linux_target = &the_i386_linux_nat_target; /* Add the target. */ - x86_linux_add_target (t); + add_inf_child_target (linux_target); }