From: Mark Kettenis Date: Fri, 29 Aug 2003 13:58:26 +0000 (+0000) Subject: * amd64-nat.h: New file. X-Git-Tag: ezannoni_pie-20030916-branchpoint~195 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ad71136386edd1d113b3d4bc838f731499487ca6;p=pf3gnuchains%2Fpf3gnuchains4x.git * amd64-nat.h: New file. * amd64-nat.c: New file. * amd64fbsd-nat.c: Include "amd64-nat.h". (REG_ADDR, GETREGS_SUPPLIES): Remove macros. (amd64fbsd32_r_reg_offset): New variable. (supply_gregset): Simply call amd64_supply_native_gregset. (fill_gregset): Rename `regno' to `regnum'. Simply call amd64_collect_native_gregset. (fill_fpregset): Rename `regno' to `regnum'. (fetch_inferior_registers): Rename `regno' to `regnum'. Replace usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p. Use `struct reg' and `struct fpreg' instead of `gregset_t' and `fpregset_t'. Call amd64_supply_native_gregset instead of supply_gregset. Call x86_64_supply_fxsave instead of supply_fpregset. (store_inferior_registers): Rename `regno' to `regnum'. Replace usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p. Use `struct reg' and `struct fpreg' instead of `gregset_t' and `fpregset_t'. Call amd64_collect_native_gregset instead of fill_gregset. Call x86_64_collect_fxsave instead of fill_fpregset. (_initialize_am64fbsd_nat): Initialize amd64_native_gregset32_reg_offset and amd64_native_gregset64_reg_offset. * config/i386/fbsd64.mh (NATDEPFILES): Add amd64-nat.o. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e7d670d7bf..4bd50aa8aa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,31 @@ 2003-08-29 Mark Kettenis + * amd64-nat.h: New file. + * amd64-nat.c: New file. + * amd64fbsd-nat.c: Include "amd64-nat.h". + (REG_ADDR, GETREGS_SUPPLIES): Remove macros. + (amd64fbsd32_r_reg_offset): New variable. + (supply_gregset): Simply call amd64_supply_native_gregset. + (fill_gregset): Rename `regno' to `regnum'. Simply call + amd64_collect_native_gregset. + (fill_fpregset): Rename `regno' to `regnum'. + (fetch_inferior_registers): Rename `regno' to `regnum'. Replace + usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p. + Use `struct reg' and `struct fpreg' instead of `gregset_t' and + `fpregset_t'. Call amd64_supply_native_gregset instead of + supply_gregset. Call x86_64_supply_fxsave instead of + supply_fpregset. + (store_inferior_registers): Rename `regno' to `regnum'. Replace + usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p. + Use `struct reg' and `struct fpreg' instead of `gregset_t' and + `fpregset_t'. Call amd64_collect_native_gregset instead of + fill_gregset. Call x86_64_collect_fxsave instead of + fill_fpregset. + (_initialize_am64fbsd_nat): Initialize + amd64_native_gregset32_reg_offset and + amd64_native_gregset64_reg_offset. + * config/i386/fbsd64.mh (NATDEPFILES): Add amd64-nat.o. + * regcache.c (regcache_raw_supply): Don't assert that BUF isn't a null pointer. Fix typo in comment. diff --git a/gdb/amd64-nat.c b/gdb/amd64-nat.c new file mode 100644 index 0000000000..fb0efcf8de --- /dev/null +++ b/gdb/amd64-nat.c @@ -0,0 +1,144 @@ +/* Native-dependent code for AMD64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbarch.h" +#include "regcache.h" + +#include "gdb_assert.h" + +#include "i386-tdep.h" +#include "x86-64-tdep.h" + +/* The following bits of code help with implementing debugging 32-bit + code natively on AMD64. The idea is to define two mappings between + the register number as used by GDB and the register set used by the + host to represent the general-purpose registers; one for 32-bit + code and one for 64-bit code. The mappings are specified by the + follwing variables and consist of an array of offsets within the + register set indexed by register number, and the number of + registers supported by the mapping. We don't need mappings for the + floating-point and SSE registers, since the difference between + 64-bit and 32-bit variants are negligable. The difference in the + number of SSE registers is already handled by the target code. */ + +/* General-purpose register mapping for native 32-bit code. */ +int *amd64_native_gregset32_reg_offset; +int amd64_native_gregset32_num_regs = I386_NUM_GREGS; + +/* General-purpose register mapping for native 64-bit code. */ +int *amd64_native_gregset64_reg_offset; +int amd64_native_gregset64_num_regs = X86_64_NUM_GREGS; + +/* Return the offset of REGNUM within the appropriate native + general-purpose register set. */ + +static int +amd64_native_gregset_reg_offset (int regnum) +{ + int *reg_offset = amd64_native_gregset64_reg_offset; + int num_regs = amd64_native_gregset64_num_regs; + + gdb_assert (regnum >= 0); + + if (gdbarch_ptr_bit (current_gdbarch) == 32) + { + reg_offset = amd64_native_gregset32_reg_offset; + num_regs = amd64_native_gregset32_num_regs; + } + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + if (regnum < num_regs && regnum < NUM_REGS) + return reg_offset[regnum]; + + return -1; +} + +/* Return whether the native general-purpose register set supplies + register REGNUM. */ + +int +amd64_native_gregset_supplies_p (int regnum) +{ + return (amd64_native_gregset_reg_offset (regnum) != -1); +} + + +/* Supply register REGNUM, whose contents are store in BUF, to + REGCACHE. If REGNUM is -1, supply all appropriate registers. */ + +void +amd64_supply_native_gregset (struct regcache *regcache, + const void *gregs, int regnum) +{ + const char *regs = gregs; + int num_regs = amd64_native_gregset64_num_regs; + int i; + + if (gdbarch_ptr_bit (current_gdbarch) == 32) + num_regs = amd64_native_gregset32_num_regs; + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + for (i = 0; i < num_regs; i++) + { + if (regnum == -1 || regnum == i) + { + int offset = amd64_native_gregset_reg_offset (i); + + if (offset != -1) + regcache_raw_supply (current_regcache, i, regs + offset); + } + } +} + +/* Collect register REGNUM from REGCACHE and store its contents in + GREGS. If REGNUM is -1, collect and store all appropriate + registers. */ + +void +amd64_collect_native_gregset (const struct regcache *regcache, + void *gregs, int regnum) +{ + char *regs = gregs; + int num_regs = amd64_native_gregset64_num_regs; + int i; + + if (gdbarch_ptr_bit (current_gdbarch) == 32) + num_regs = amd64_native_gregset32_num_regs; + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + for (i = 0; i < num_regs; i++) + { + if (regnum == -1 || regnum == i) + { + int offset = amd64_native_gregset_reg_offset (i); + + if (offset != -1) + regcache_raw_collect (current_regcache, i, regs + offset); + } + } +} diff --git a/gdb/amd64-nat.h b/gdb/amd64-nat.h new file mode 100644 index 0000000000..e2c9379f94 --- /dev/null +++ b/gdb/amd64-nat.h @@ -0,0 +1,51 @@ +/* Native-dependent code for AMD64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef AMD64_NAT_H +#define AMD64_NAT_H 1 + +/* General-purpose register set description for native 32-bit code. */ +extern int *amd64_native_gregset32_reg_offset; +extern int amd64_native_gregset32_num_regs; + +/* General-purpose register set description for native 64-bit code. */ +extern int *amd64_native_gregset64_reg_offset; +extern int amd64_native_gregset64_num_regs; + +/* Return whether the native general-purpose register set supplies + register REGNUM. */ + +extern int amd64_native_gregset_supplies_p (int regnum); + +/* Supply register REGNUM, whose contents are store in BUF, to + REGCACHE. If REGNUM is -1, supply all appropriate registers. */ + +extern void amd64_supply_native_gregset (struct regcache *regcache, + const void *gregs, int regnum); + +/* Collect register REGNUM from REGCACHE and store its contents in + GREGS. If REGNUM is -1, collect and store all appropriate + registers. */ + +extern void amd64_collect_native_gregset (const struct regcache *regcache, + void *gregs, int regnum); + +#endif /* amd64-nat.h */ diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c index e90d8fac06..dee2c8dea1 100644 --- a/gdb/amd64fbsd-nat.c +++ b/gdb/amd64fbsd-nat.c @@ -1,4 +1,5 @@ /* Native-dependent code for FreeBSD/amd64. + Copyright 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -44,13 +45,14 @@ typedef struct fpreg fpregset_t; #include "gregset.h" #include "x86-64-tdep.h" +#include "amd64-nat.h" /* Offset to the gregset_t location where REG is stored. */ #define REG_OFFSET(reg) offsetof (gregset_t, reg) -/* At reg_offset[REGNO] you'll find the offset to the gregset_t - location where the GDB register REGNO is stored. Unsupported +/* At reg_offset[REGNUM] you'll find the offset to the gregset_t + location where the GDB register REGNUM is stored. Unsupported registers are marked with `-1'. */ static int reg_offset[] = { @@ -77,12 +79,27 @@ static int reg_offset[] = -1, -1 }; + + +/* Mapping between the general-purpose registers in FreeBSD/amd64 + `struct reg' format and GDB's register cache layout for + FreeBSD/i386. -#define REG_ADDR(regset, regno) ((char *) (regset) + reg_offset[regno]) + Note that most FreeBSD/amd64 registers are 64-bit, while the + FreeBSD/i386 registers are all 32-bit, but since we're + little-endian we get away with that. */ -/* Macro to determine if a register is fetched with PT_GETREGS. */ -#define GETREGS_SUPPLIES(regno) \ - ((0 <= (regno) && (regno) < X86_64_NUM_GREGS)) +/* From . */ +static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] = +{ + 14 * 8, 13 * 8, /* %eax, %ecx */ + 12 * 8, 11 * 8, /* %edx, %ebx */ + 20 * 8, 10 * 8, /* %esp, %ebp */ + 9 * 8, 8 * 8, /* %esi, %edi */ + 17 * 8, 19 * 8, /* %eip, %eflags */ + 18 * 8, 21 * 8, /* %cs, %ss */ + -1, -1, -1, -1 /* %ds, %es, %fs, %gs */ +}; /* Transfering the registers between GDB, inferiors and core files. */ @@ -93,29 +110,17 @@ static int reg_offset[] = void supply_gregset (gregset_t *gregsetp) { - int i; - - for (i = 0; i < X86_64_NUM_GREGS; i++) - { - if (reg_offset[i] == -1) - supply_register (i, NULL); - else - supply_register (i, REG_ADDR (gregsetp, i)); - } + amd64_supply_native_gregset (current_regcache, gregsetp, -1); } -/* Fill register REGNO (if it is a general-purpose register) in - *GREGSETPS with the value in GDB's register array. If REGNO is -1, +/* Fill register REGNUM (if it is a general-purpose register) in + *GREGSETPS with the value in GDB's register array. If REGNUM is -1, do this for all registers. */ void -fill_gregset (gregset_t *gregsetp, int regno) +fill_gregset (gregset_t *gregsetp, int regnum) { - int i; - - for (i = 0; i < X86_64_NUM_GREGS; i++) - if ((regno == -1 || regno == i) && reg_offset[i] != -1) - regcache_collect (i, REG_ADDR (gregsetp, i)); + amd64_collect_native_gregset (current_regcache, gregsetp, regnum); } /* Fill GDB's register array with the floating-point register values @@ -127,80 +132,80 @@ supply_fpregset (fpregset_t *fpregsetp) x86_64_supply_fxsave ((const char *) fpregsetp, -1); } -/* Fill register REGNO (if it is a floating-point register) in - *FPREGSETP with the value in GDB's register array. If REGNO is -1, +/* Fill register REGNUM (if it is a floating-point register) in + *FPREGSETP with the value in GDB's register array. If REGNUM is -1, do this for all registers. */ void -fill_fpregset (fpregset_t *fpregsetp, int regno) +fill_fpregset (fpregset_t *fpregsetp, int regnum) { - x86_64_fill_fxsave ((char *) fpregsetp, regno); + x86_64_fill_fxsave ((char *) fpregsetp, regnum); } -/* Fetch register REGNO from the inferior. If REGNO is -1, do this +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers (including the floating point registers). */ void -fetch_inferior_registers (int regno) +fetch_inferior_registers (int regnum) { - if (regno == -1 || GETREGS_SUPPLIES (regno)) + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) { - gregset_t gregs; + struct reg regs; if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) &gregs, 0) == -1) + (PTRACE_ARG3_TYPE) ®s, 0) == -1) perror_with_name ("Couldn't get registers"); - supply_gregset (&gregs); - if (regno != -1) + amd64_supply_native_gregset (current_regcache, ®s, -1); + if (regnum != -1) return; } - if (regno == -1 || regno >= FP0_REGNUM) + if (regnum == -1 || regnum >= FP0_REGNUM) { - fpregset_t fpregs; + struct fpreg fpregs; if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - supply_fpregset (&fpregs); + x86_64_supply_fxsave ((const char *) &fpregs, -1); } } -/* Store register REGNO back into the inferior. If REGNO is -1, do +/* Store register REGNUM back into the inferior. If REGNUM is -1, do this for all registers (including the floating point registers). */ void -store_inferior_registers (int regno) +store_inferior_registers (int regnum) { - if (regno == -1 || GETREGS_SUPPLIES (regno)) + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) { - gregset_t gregs; + struct reg regs; if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) &gregs, 0) == -1) + (PTRACE_ARG3_TYPE) ®s, 0) == -1) perror_with_name ("Couldn't get registers"); - fill_gregset (&gregs, regno); + amd64_collect_native_gregset (current_regcache, ®s, regnum); if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) &gregs, 0) == -1) + (PTRACE_ARG3_TYPE) ®s, 0) == -1) perror_with_name ("Couldn't write registers"); - if (regno != -1) + if (regnum != -1) return; } - if (regno == -1 || regno >= FP0_REGNUM) + if (regnum == -1 || regnum >= FP0_REGNUM) { - fpregset_t fpregs; + struct fpreg fpregs; if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - fill_fpregset (&fpregs, regno); + x86_64_fill_fxsave ((char *) &fpregs, regnum); if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) @@ -217,6 +222,9 @@ _initialize_am64fbsd_nat (void) { int offset; + amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset; + amd64_native_gregset64_reg_offset = reg_offset; + /* To support the recognition of signal handlers, i386bsd-tdep.c hardcodes some constants. Inclusion of this file means that we are compiling a native debugger, which means that we can use the diff --git a/gdb/config/i386/fbsd64.mh b/gdb/config/i386/fbsd64.mh index a1a79a3349..7e42aaa2cd 100644 --- a/gdb/config/i386/fbsd64.mh +++ b/gdb/config/i386/fbsd64.mh @@ -4,4 +4,4 @@ XM_FILE= xm-i386.h NAT_FILE= nm-fbsd64.h # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. -NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-regset.o amd64fbsd-nat.o gcore.o fbsd-proc.o +NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-regset.o amd64-nat.o amd64fbsd-nat.o gcore.o fbsd-proc.o