* 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.
This commit is contained in:
Mark Kettenis 2003-08-29 13:58:26 +00:00
parent a16d75cc48
commit 2a6d284d76
5 changed files with 278 additions and 49 deletions

View File

@ -1,5 +1,31 @@
2003-08-29 Mark Kettenis <kettenis@gnu.org>
* 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.

144
gdb/amd64-nat.c Normal file
View File

@ -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);
}
}
}

51
gdb/amd64-nat.h Normal file
View File

@ -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 */

View File

@ -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
};
#define REG_ADDR(regset, regno) ((char *) (regset) + reg_offset[regno])
/* Mapping between the general-purpose registers in FreeBSD/amd64
`struct reg' format and GDB's register cache layout for
FreeBSD/i386.
/* Macro to determine if a register is fetched with PT_GETREGS. */
#define GETREGS_SUPPLIES(regno) \
((0 <= (regno) && (regno) < X86_64_NUM_GREGS))
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. */
/* From <machine/reg.h>. */
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) &regs, 0) == -1)
perror_with_name ("Couldn't get registers");
supply_gregset (&gregs);
if (regno != -1)
amd64_supply_native_gregset (current_regcache, &regs, -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) &regs, 0) == -1)
perror_with_name ("Couldn't get registers");
fill_gregset (&gregs, regno);
amd64_collect_native_gregset (current_regcache, &regs, regnum);
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &gregs, 0) == -1)
(PTRACE_ARG3_TYPE) &regs, 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

View File

@ -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