X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fi386-linux-nat.c;h=4fce1acf68b97865b958d8e9c90208be33645ee3;hb=37cc8bfee6166ea05f1fa2e7d9f0f4d90663b7fc;hp=a251907d502c805a1bdead869c96af1463d78d2f;hpb=c131fcee79bd9082762a1699a657949771fa245f;p=binutils-gdb.git diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index a251907d502..4fce1acf68b 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -99,26 +99,6 @@ static int have_ptrace_getregset = -1; those names are now used for the register sets used in the `mcontext_t' type, and have a different size and layout. */ -/* Mapping between the general-purpose registers in `struct user' - format and GDB's register array layout. */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, - -1, -1, -1, -1, /* st0, st1, st2, st3 */ - -1, -1, -1, -1, /* st4, st5, st6, st7 */ - -1, -1, -1, -1, /* fctrl, fstat, ftag, fiseg */ - -1, -1, -1, -1, /* fioff, foseg, fooff, fop */ - -1, -1, -1, -1, /* xmm0, xmm1, xmm2, xmm3 */ - -1, -1, -1, -1, /* xmm4, xmm5, xmm6, xmm6 */ - -1, /* mxcsr */ - -1, -1, -1, -1, /* ymm0h, ymm1h, ymm2h, ymm3h */ - -1, -1, -1, -1, /* ymm4h, ymm5h, ymm6h, ymm6h */ - ORIG_EAX -}; - /* Which ptrace request retrieves which registers? These apply to the corresponding SET requests as well. */ @@ -150,7 +130,7 @@ int have_ptrace_getregs = for this to be a simple variable. */ int have_ptrace_getfpxregs = #ifdef HAVE_PTRACE_GETFPXREGS - 1 + -1 #else 0 #endif @@ -168,7 +148,7 @@ fetch_register (struct regcache *regcache, int regno) int val; gdb_assert (!have_ptrace_getregs); - if (regmap[regno] == -1) + if (i386_linux_gregset_reg_offset[regno] == -1) { regcache_raw_supply (regcache, regno, NULL); return; @@ -180,7 +160,8 @@ fetch_register (struct regcache *regcache, int regno) tid = PIDGET (inferior_ptid); /* Not a threaded program. */ errno = 0; - val = ptrace (PTRACE_PEEKUSER, tid, 4 * regmap[regno], 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), @@ -198,7 +179,7 @@ store_register (const struct regcache *regcache, int regno) int val; gdb_assert (!have_ptrace_getregs); - if (regmap[regno] == -1) + if (i386_linux_gregset_reg_offset[regno] == -1) return; /* GNU/Linux LWP ID's are process ID's. */ @@ -208,7 +189,8 @@ store_register (const struct regcache *regcache, int regno) errno = 0; regcache_raw_collect (regcache, regno, &val); - ptrace (PTRACE_POKEUSER, tid, 4 * regmap[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), @@ -225,16 +207,17 @@ store_register (const struct regcache *regcache, int regno) void supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) { - const elf_greg_t *regp = (const elf_greg_t *) gregsetp; + const gdb_byte *regp = (const gdb_byte *) gregsetp; int i; for (i = 0; i < I386_NUM_GREGS; i++) - regcache_raw_supply (regcache, i, regp + regmap[i]); + regcache_raw_supply (regcache, 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 + ORIG_EAX); + regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); } /* Fill register REGNO (if it is a general-purpose register) in @@ -245,18 +228,19 @@ void fill_gregset (const struct regcache *regcache, elf_gregset_t *gregsetp, int regno) { - elf_greg_t *regp = (elf_greg_t *) gregsetp; + gdb_byte *regp = (gdb_byte *) gregsetp; int i; for (i = 0; i < I386_NUM_GREGS; i++) if (regno == -1 || regno == i) - regcache_raw_collect (regcache, i, regp + regmap[i]); + regcache_raw_collect (regcache, 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 + ORIG_EAX); + regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]); } #ifdef HAVE_PTRACE_GETREGS @@ -429,27 +413,6 @@ store_xstateregs (const struct regcache *regcache, int tid, int regno) #ifdef HAVE_PTRACE_GETFPXREGS -/* Fill GDB's register array with the floating-point and SSE register - values in *FPXREGSETP. */ - -void -supply_fpxregset (struct regcache *regcache, - const elf_fpxregset_t *fpxregsetp) -{ - i387_supply_fxsave (regcache, -1, fpxregsetp); -} - -/* Fill register REGNO (if it is a floating-point or SSE register) in - *FPXREGSETP with the value in GDB's register array. If REGNO is - -1, do this for all registers. */ - -void -fill_fpxregset (const struct regcache *regcache, - elf_fpxregset_t *fpxregsetp, int regno) -{ - i387_collect_fxsave (regcache, regno, fpxregsetp); -} - /* Fetch all registers covered by the PTRACE_GETFPXREGS request from process/thread TID and store their values in GDB's register array. Return non-zero if successful, zero otherwise. */ @@ -473,7 +436,7 @@ fetch_fpxregs (struct regcache *regcache, int tid) perror_with_name (_("Couldn't read floating-point and SSE registers")); } - supply_fpxregset (regcache, (const elf_fpxregset_t *) &fpxregs); + i387_supply_fxsave (regcache, -1, (const elf_fpxregset_t *) &fpxregs); return 1; } @@ -500,7 +463,7 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno) perror_with_name (_("Couldn't read floating-point and SSE registers")); } - fill_fpxregset (regcache, &fpxregs, regno); + i387_collect_fxsave (regcache, regno, &fpxregs); if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1) perror_with_name (_("Couldn't write floating-point and SSE registers")); @@ -946,19 +909,33 @@ i386_linux_child_post_startup_inferior (ptid_t ptid) static const struct target_desc * i386_linux_read_description (struct target_ops *ops) { + int tid; static uint64_t xcr0; + /* GNU/Linux LWP ID's are process ID's. */ + tid = TIDGET (inferior_ptid); + if (tid == 0) + tid = PIDGET (inferior_ptid); /* Not a threaded program. */ + +#ifdef HAVE_PTRACE_GETFPXREGS + if (have_ptrace_getfpxregs == -1) + { + elf_fpxregset_t fpxregs; + + if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) + { + have_ptrace_getfpxregs = 0; + have_ptrace_getregset = 0; + return tdesc_i386_mmx_linux; + } + } +#endif + if (have_ptrace_getregset == -1) { - int tid; uint64_t xstateregs[(I386_XSTATE_SSE_SIZE / sizeof (uint64_t))]; struct iovec iov; - /* GNU/Linux LWP ID's are process ID's. */ - tid = TIDGET (inferior_ptid); - if (tid == 0) - tid = PIDGET (inferior_ptid); /* Not a threaded program. */ - iov.iov_base = xstateregs; iov.iov_len = sizeof (xstateregs);