[patch] Overhaul i386nbsd-nat.c, add support for XMM + ELF core files

Jason R Thorpe
2002-01-05T00:08:00Z

[-- Attachment #1: Type: text/plain, Size: 1310 bytes --]

The following patch overhauls i386nbsd-nat.c, using new interfaces to
access the gdb regcache, and adds support for XMM registers and ELF
format NetBSD core files.

[ for gdb/ChangeLog ]
2002-01-04 Jason Thorpe <thorpej@wasabisystems.com>

* i386nbsd-nat.c (supply_regs): New function.
(fetch_inferior_registers): Use supply_regs to
provide integer registers. Use i387_supply_fsave
to supply FP registers. Add support for XMM
registers using PT_GETXMMREGS and i387_supply_fxsave.
(store_inferior_registers): Use regcache_collect
for integer registers. Use i387_fill_fsave for
FP registers. Add support for XMM registers
using i387_fill_fxsave and PT_SETXMMREGS.
(fetch_core_registers): Use supply_regs for
integer registers and i387_supply_fsave for
FP registers.
(fetch_elfcore_registers): New function.
(i386nbsd_elfcore_fns): New.
(_initialize_i386nbsd_nat): Register i386nbsd_elfcore_fns.
* config/i386/nbsd.mh (NATDEPFILES): Add i387-nat.o.
* config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
* config/i386/tm-nbsd.h: Update copyright years.
(HAVE_SSE_REGS): Define.

--
-- Jason R. Thorpe <thorpej@wasabisystems.com>

[-- Attachment #2: patch3 --]
[-- Type: text/plain, Size: 14238 bytes --]

Index: i386nbsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386nbsd-nat.c,v
retrieving revision 1.9
diff -c -r1.9 i386nbsd-nat.c
*** i386nbsd-nat.c 2002/01/04 22:43:31 1.9
--- i386nbsd-nat.c 2002/01/04 23:54:54
***************
*** 25,160 ****
#include <machine/reg.h>
#include <machine/frame.h>
#include "inferior.h"
! #include "gdbcore.h" /* for registers_fetched() */
#include "regcache.h"

/* Defines for XMM0_REGNUM etc. */
#include "i386-tdep.h"

! #define RF(dst, src) \
! memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))

! #define RS(src, dst) \
! memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
!
! struct env387
! {
! unsigned short control;
! unsigned short r0;
! unsigned short status;
! unsigned short r1;
! unsigned short tag;
! unsigned short r2;
! unsigned long eip;
! unsigned short code_seg;
! unsigned short opcode;
! unsigned long operand;
! unsigned short operand_seg;
! unsigned short r3;
! unsigned char regs[8][10];
! };

void
fetch_inferior_registers (int regno)
{
struct reg inferior_registers;
! struct env387 inferior_fpregisters;
!
! ptrace (PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
!
! RF ( 0, inferior_registers.r_eax);
! RF ( 1, inferior_registers.r_ecx);
! RF ( 2, inferior_registers.r_edx);
! RF ( 3, inferior_registers.r_ebx);
! RF ( 4, inferior_registers.r_esp);
! RF ( 5, inferior_registers.r_ebp);
! RF ( 6, inferior_registers.r_esi);
! RF ( 7, inferior_registers.r_edi);
! RF ( 8, inferior_registers.r_eip);
! RF ( 9, inferior_registers.r_eflags);
! RF (10, inferior_registers.r_cs);
! RF (11, inferior_registers.r_ss);
! RF (12, inferior_registers.r_ds);
! RF (13, inferior_registers.r_es);
! RF (14, inferior_registers.r_fs);
! RF (15, inferior_registers.r_gs);
!
! RF (FP0_REGNUM, inferior_fpregisters.regs[0]);
! RF (FP0_REGNUM + 1, inferior_fpregisters.regs[1]);
! RF (FP0_REGNUM + 2, inferior_fpregisters.regs[2]);
! RF (FP0_REGNUM + 3, inferior_fpregisters.regs[3]);
! RF (FP0_REGNUM + 4, inferior_fpregisters.regs[4]);
! RF (FP0_REGNUM + 5, inferior_fpregisters.regs[5]);
! RF (FP0_REGNUM + 6, inferior_fpregisters.regs[6]);
! RF (FP0_REGNUM + 7, inferior_fpregisters.regs[7]);
!
! RF (FCTRL_REGNUM, inferior_fpregisters.control);
! RF (FSTAT_REGNUM, inferior_fpregisters.status);
! RF (FTAG_REGNUM, inferior_fpregisters.tag);
! RF (FCS_REGNUM, inferior_fpregisters.code_seg);
! RF (FCOFF_REGNUM, inferior_fpregisters.eip);
! RF (FDS_REGNUM, inferior_fpregisters.operand_seg);
! RF (FDOFF_REGNUM, inferior_fpregisters.operand);
! RF (FOP_REGNUM, inferior_fpregisters.opcode);
!
! registers_fetched ();
}

void
store_inferior_registers (int regno)
{
struct reg inferior_registers;
! struct env387 inferior_fpregisters;
!
! RS ( 0, inferior_registers.r_eax);
! RS ( 1, inferior_registers.r_ecx);
! RS ( 2, inferior_registers.r_edx);
! RS ( 3, inferior_registers.r_ebx);
! RS ( 4, inferior_registers.r_esp);
! RS ( 5, inferior_registers.r_ebp);
! RS ( 6, inferior_registers.r_esi);
! RS ( 7, inferior_registers.r_edi);
! RS ( 8, inferior_registers.r_eip);
! RS ( 9, inferior_registers.r_eflags);
! RS (10, inferior_registers.r_cs);
! RS (11, inferior_registers.r_ss);
! RS (12, inferior_registers.r_ds);
! RS (13, inferior_registers.r_es);
! RS (14, inferior_registers.r_fs);
! RS (15, inferior_registers.r_gs);
!
!
! RS (FP0_REGNUM, inferior_fpregisters.regs[0]);
! RS (FP0_REGNUM + 1, inferior_fpregisters.regs[1]);
! RS (FP0_REGNUM + 2, inferior_fpregisters.regs[2]);
! RS (FP0_REGNUM + 3, inferior_fpregisters.regs[3]);
! RS (FP0_REGNUM + 4, inferior_fpregisters.regs[4]);
! RS (FP0_REGNUM + 5, inferior_fpregisters.regs[5]);
! RS (FP0_REGNUM + 6, inferior_fpregisters.regs[6]);
! RS (FP0_REGNUM + 7, inferior_fpregisters.regs[7]);
!
! RS (FCTRL_REGNUM, inferior_fpregisters.control);
! RS (FSTAT_REGNUM, inferior_fpregisters.status);
! RS (FTAG_REGNUM, inferior_fpregisters.tag);
! RS (FCS_REGNUM, inferior_fpregisters.code_seg);
! RS (FCOFF_REGNUM, inferior_fpregisters.eip);
! RS (FDS_REGNUM, inferior_fpregisters.operand_seg);
! RS (FDOFF_REGNUM, inferior_fpregisters.operand);
! RS (FOP_REGNUM, inferior_fpregisters.opcode);
!
! ptrace (PT_SETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
! ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
}
\f
struct md_core
{
struct reg intreg;
! struct env387 freg;
};

static void
--- 25,175 ----
#include <machine/reg.h>
#include <machine/frame.h>
#include "inferior.h"
! #include "gdbcore.h"
#include "regcache.h"

+ /* Prototypes for i387_supply_fsave etc. */
+ #include "i387-nat.h"
+
/* Defines for XMM0_REGNUM etc. */
#include "i386-tdep.h"
+
+ #ifdef PT_GETXMMREGS
+ static int have_ptrace_xmmregs = -1;
+ #endif
+
+ /* Offsets of the registers in the "reg" structure, indexed by
+ GDB register array index. */
+ static int regmap[] =
+ {
+ 0x00 /* eax */,
+ 0x04 /* ecx */,
+ 0x08 /* edx */,
+ 0x0c /* ebx */,
+ 0x10 /* esp */,
+ 0x14 /* ebp */,
+ 0x18 /* esi */,
+ 0x1c /* edi */,
+ 0x20 /* eip */,
+ 0x24 /* eflags */,
+ 0x28 /* cs */,
+ 0x2c /* ss */,
+ 0x30 /* ds */,
+ 0x34 /* es */,
+ 0x38 /* fs */,
+ 0x3c /* gs */,
+ };

! /* Macro to determine if a register is fetched with PT_GETREGS. */
! #define GETREGS_SUPPLIES(regno) \
! ((0 <= (regno) && (regno) <= 15))

! static void
! supply_regs (char *regs)
! {
! int regno;

+ for (regno = 0; regno < 16; regno++)
+ supply_register (regno, regs + regmap[regno]);
+ }
+
void
fetch_inferior_registers (int regno)
{
struct reg inferior_registers;
! char inferior_fpregisters[108];
! #ifdef PT_GETXMMREGS
! char inferior_xmmregisters[512];
! #endif
!
! if (regno == -1 || GETREGS_SUPPLIES (regno))
! {
! ptrace (PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
! supply_regs ((char *) &inferior_registers);
! if (regno != -1)
! return;
! }
!
! #ifdef PT_GETXMMREGS
! if (have_ptrace_xmmregs != 0 &&
! ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_xmmregisters, 0) == 0)
! {
! have_ptrace_xmmregs = 1;
! i387_supply_fxsave (inferior_xmmregisters);
! }
! else
! {
! ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_fpregisters, 0);
! have_ptrace_xmmregs = 0;
! i387_supply_fsave ((char *) inferior_fpregisters);
! }
! #else
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_fpregisters, 0);
! i387_supply_fsave ((char *) inferior_fpregisters);
! #endif
}

void
store_inferior_registers (int regno)
{
struct reg inferior_registers;
! char *regs = (char *) &inferior_registers;
! char inferior_fpregisters[108];
! #ifdef PT_GETXMMREGS
! char inferior_xmmregisters[512];
! #endif
! int i;
!
! if (regno == -1 || GETREGS_SUPPLIES (regno))
! {
! ptrace(PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
!
! for (i = 0; i < 16; i++)
! {
! if (regno == -1 || regno == i)
! regcache_collect (i, regs + regmap[i]);
! }
!
! ptrace (PT_SETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
!
! if (regno != -1)
! return;
! }
!
! #ifdef PT_GETXMMREGS
! if (have_ptrace_xmmregs != 0 &&
! ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_xmmregisters, 0) == 0)
! {
! have_ptrace_xmmregs = 1;
! i387_fill_fxsave (inferior_xmmregisters, regno);
! ptrace (PT_SETXMMREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_xmmregisters, 0);
! }
! else
! {
! have_ptrace_xmmregs = 0;
! #endif
! ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_fpregisters, 0);
! i387_fill_fsave (inferior_fpregisters, regno);
! ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) inferior_fpregisters, 0);
! #ifdef PT_GETXMMREGS
! }
! #endif
}
\f
struct md_core
{
struct reg intreg;
! char freg[108];
};

static void
***************
*** 163,192 ****
{
struct md_core *core_reg = (struct md_core *) core_reg_sect;

! /* integer registers */
! memcpy (&registers[REGISTER_BYTE (0)], &core_reg->intreg,
! sizeof (struct reg));
!
! /* floating point registers */
! RF (FP0_REGNUM, core_reg->freg.regs[0]);
! RF (FP0_REGNUM + 1, core_reg->freg.regs[1]);
! RF (FP0_REGNUM + 2, core_reg->freg.regs[2]);
! RF (FP0_REGNUM + 3, core_reg->freg.regs[3]);
! RF (FP0_REGNUM + 4, core_reg->freg.regs[4]);
! RF (FP0_REGNUM + 5, core_reg->freg.regs[5]);
! RF (FP0_REGNUM + 6, core_reg->freg.regs[6]);
! RF (FP0_REGNUM + 7, core_reg->freg.regs[7]);
!
! RF (FCTRL_REGNUM, core_reg->freg.control);
! RF (FSTAT_REGNUM, core_reg->freg.status);
! RF (FTAG_REGNUM, core_reg->freg.tag);
! RF (FCS_REGNUM, core_reg->freg.code_seg);
! RF (FCOFF_REGNUM, core_reg->freg.eip);
! RF (FDS_REGNUM, core_reg->freg.operand_seg);
! RF (FDOFF_REGNUM, core_reg->freg.operand);
! RF (FOP_REGNUM, core_reg->freg.opcode);

! registers_fetched ();
}

/* Register that we are able to handle i386nbsd core file formats.
--- 178,226 ----
{
struct md_core *core_reg = (struct md_core *) core_reg_sect;

! /* We get everything from one section. */
! if (which != 0)
! return;

! /* Integer registers. */
! supply_regs ((char *) &core_reg->intreg);
!
! /* Floating point registers. */
! i387_supply_fsave (core_reg->freg);
! }
!
! static void
! fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
! CORE_ADDR ignore)
! {
! switch (which)
! {
! case 0: /* Integer registers. */
! if (core_reg_size != sizeof (struct reg))
! warning ("Wrong size register set in core file.");
! else
! supply_regs (core_reg_sect);
! break;
!
! case 2: /* Floating point registers. */
! if (core_reg_size != 108)
! warning ("Wrong size FP register set in core file.");
! else
! i387_supply_fsave (core_reg_sect);
! break;
!
! case 3: /* "Extended" floating point registers. This is gdb-speak
! for SSE/SSE2. */
! if (core_reg_size != 512)
! warning ("Wrong size XMM register set in core file.");
! else
! i387_supply_fxsave (core_reg_sect);
! break;
!
! default:
! /* Don't know what kind of register request this is; just ignore it. */
! break;
! }
}

/* Register that we are able to handle i386nbsd core file formats.
***************
*** 201,208 ****
--- 235,252 ----
NULL /* next */
};

+ static struct core_fns i386nbsd_elfcore_fns =
+ {
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+ };
+
void
_initialize_i386nbsd_nat (void)
{
add_core_fns (&i386nbsd_core_fns);
+ add_core_fns (&i386nbsd_elfcore_fns);
}
Index: config/i386/nbsd.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nbsd.mh,v
retrieving revision 1.10
diff -c -r1.10 nbsd.mh
*** nbsd.mh 2001/10/02 23:11:21 1.10
--- nbsd.mh 2002/01/04 23:54:55
***************
*** 7,13 ****
# continuation character (backslash) to extend a commented line. As a
# consequence, BSD make considers subsequent tab-indented lines to be
# "unassociated shell commands".
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386nbsd-nat.o solib.o solib-sunos.o

XM_FILE= xm-nbsd.h
NAT_FILE= nm-nbsd.h
--- 7,13 ----
# continuation character (backslash) to extend a commented line. As a
# consequence, BSD make considers subsequent tab-indented lines to be
# "unassociated shell commands".
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i387-nat.o i386nbsd-nat.o solib.o solib-sunos.o

XM_FILE= xm-nbsd.h
NAT_FILE= nm-nbsd.h
Index: config/i386/nbsdelf.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nbsdelf.mh,v
retrieving revision 1.6
diff -c -r1.6 nbsdelf.mh
*** nbsdelf.mh 2001/03/10 06:17:21 1.6
--- nbsdelf.mh 2002/01/04 23:54:55
***************
*** 1,5 ****
# Host: Intel 386 running NetBSD
XDEPFILES=
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386nbsd-nat.o solib.o solib-svr4.o solib-legacy.o
XM_FILE= xm-nbsd.h
NAT_FILE= nm-nbsdelf.h
--- 1,5 ----
# Host: Intel 386 running NetBSD
XDEPFILES=
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i387-nat.o i386nbsd-nat.o solib.o solib-svr4.o solib-legacy.o
XM_FILE= xm-nbsd.h
NAT_FILE= nm-nbsdelf.h
Index: config/i386/tm-nbsd.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-nbsd.h,v
retrieving revision 1.7
diff -c -r1.7 tm-nbsd.h
*** tm-nbsd.h 2001/03/06 08:21:29 1.7
--- tm-nbsd.h 2002/01/04 23:54:55
***************
*** 1,5 ****
/* Macro definitions for i386 running under NetBSD.
! Copyright 1994, 1996, 2000 Free Software Foundation, Inc.

This file is part of GDB.

--- 1,5 ----
/* Macro definitions for i386 running under NetBSD.
! Copyright 1994, 1996, 2000, 2002 Free Software Foundation, Inc.

This file is part of GDB.

***************
*** 22,27 ****
--- 22,28 ----
#define TM_NBSD_H

#define HAVE_I387_REGS
+ #define HAVE_SSE_REGS

#include "i386/tm-i386.h"
#include "config/tm-nbsd.h"