15796c8dcSSimon Schubert /* Native-dependent code for modern i386 BSD's.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 2000-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "inferior.h"
225796c8dcSSimon Schubert #include "regcache.h"
235796c8dcSSimon Schubert
245796c8dcSSimon Schubert #include "gdb_assert.h"
255796c8dcSSimon Schubert #include <signal.h>
265796c8dcSSimon Schubert #include <stddef.h>
275796c8dcSSimon Schubert #include <sys/types.h>
285796c8dcSSimon Schubert #include <sys/ptrace.h>
295796c8dcSSimon Schubert #include <machine/reg.h>
305796c8dcSSimon Schubert #include <machine/frame.h>
315796c8dcSSimon Schubert
325796c8dcSSimon Schubert #include "i386-tdep.h"
335796c8dcSSimon Schubert #include "i387-tdep.h"
345796c8dcSSimon Schubert #include "i386bsd-nat.h"
355796c8dcSSimon Schubert #include "inf-ptrace.h"
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert
385796c8dcSSimon Schubert /* In older BSD versions we cannot get at some of the segment
395796c8dcSSimon Schubert registers. FreeBSD for example didn't support the %fs and %gs
405796c8dcSSimon Schubert registers until the 3.0 release. We have autoconf checks for their
415796c8dcSSimon Schubert presence, and deal gracefully with their absence. */
425796c8dcSSimon Schubert
435796c8dcSSimon Schubert /* Offset in `struct reg' where MEMBER is stored. */
445796c8dcSSimon Schubert #define REG_OFFSET(member) offsetof (struct reg, member)
455796c8dcSSimon Schubert
465796c8dcSSimon Schubert /* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct
475796c8dcSSimon Schubert reg' where the GDB register REGNUM is stored. Unsupported
485796c8dcSSimon Schubert registers are marked with `-1'. */
495796c8dcSSimon Schubert static int i386bsd_r_reg_offset[] =
505796c8dcSSimon Schubert {
515796c8dcSSimon Schubert REG_OFFSET (r_eax),
525796c8dcSSimon Schubert REG_OFFSET (r_ecx),
535796c8dcSSimon Schubert REG_OFFSET (r_edx),
545796c8dcSSimon Schubert REG_OFFSET (r_ebx),
555796c8dcSSimon Schubert REG_OFFSET (r_esp),
565796c8dcSSimon Schubert REG_OFFSET (r_ebp),
575796c8dcSSimon Schubert REG_OFFSET (r_esi),
585796c8dcSSimon Schubert REG_OFFSET (r_edi),
595796c8dcSSimon Schubert REG_OFFSET (r_eip),
605796c8dcSSimon Schubert REG_OFFSET (r_eflags),
615796c8dcSSimon Schubert REG_OFFSET (r_cs),
625796c8dcSSimon Schubert REG_OFFSET (r_ss),
635796c8dcSSimon Schubert REG_OFFSET (r_ds),
645796c8dcSSimon Schubert REG_OFFSET (r_es),
655796c8dcSSimon Schubert #ifdef HAVE_STRUCT_REG_R_FS
665796c8dcSSimon Schubert REG_OFFSET (r_fs),
675796c8dcSSimon Schubert #else
685796c8dcSSimon Schubert -1,
695796c8dcSSimon Schubert #endif
705796c8dcSSimon Schubert #ifdef HAVE_STRUCT_REG_R_GS
715796c8dcSSimon Schubert REG_OFFSET (r_gs)
725796c8dcSSimon Schubert #else
735796c8dcSSimon Schubert -1
745796c8dcSSimon Schubert #endif
755796c8dcSSimon Schubert };
765796c8dcSSimon Schubert
775796c8dcSSimon Schubert /* Macro to determine if a register is fetched with PT_GETREGS. */
785796c8dcSSimon Schubert #define GETREGS_SUPPLIES(regnum) \
795796c8dcSSimon Schubert ((0 <= (regnum) && (regnum) <= 15))
805796c8dcSSimon Schubert
815796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS
825796c8dcSSimon Schubert /* Set to 1 if the kernel supports PT_GETXMMREGS. Initialized to -1
835796c8dcSSimon Schubert so that we try PT_GETXMMREGS the first time around. */
845796c8dcSSimon Schubert static int have_ptrace_xmmregs = -1;
855796c8dcSSimon Schubert #endif
865796c8dcSSimon Schubert
875796c8dcSSimon Schubert
885796c8dcSSimon Schubert /* Supply the general-purpose registers in GREGS, to REGCACHE. */
895796c8dcSSimon Schubert
905796c8dcSSimon Schubert static void
i386bsd_supply_gregset(struct regcache * regcache,const void * gregs)915796c8dcSSimon Schubert i386bsd_supply_gregset (struct regcache *regcache, const void *gregs)
925796c8dcSSimon Schubert {
935796c8dcSSimon Schubert const char *regs = gregs;
945796c8dcSSimon Schubert int regnum;
955796c8dcSSimon Schubert
965796c8dcSSimon Schubert for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++)
975796c8dcSSimon Schubert {
985796c8dcSSimon Schubert int offset = i386bsd_r_reg_offset[regnum];
995796c8dcSSimon Schubert
1005796c8dcSSimon Schubert if (offset != -1)
1015796c8dcSSimon Schubert regcache_raw_supply (regcache, regnum, regs + offset);
1025796c8dcSSimon Schubert }
1035796c8dcSSimon Schubert }
1045796c8dcSSimon Schubert
1055796c8dcSSimon Schubert /* Collect register REGNUM from REGCACHE and store its contents in
1065796c8dcSSimon Schubert GREGS. If REGNUM is -1, collect and store all appropriate
1075796c8dcSSimon Schubert registers. */
1085796c8dcSSimon Schubert
1095796c8dcSSimon Schubert static void
i386bsd_collect_gregset(const struct regcache * regcache,void * gregs,int regnum)1105796c8dcSSimon Schubert i386bsd_collect_gregset (const struct regcache *regcache,
1115796c8dcSSimon Schubert void *gregs, int regnum)
1125796c8dcSSimon Schubert {
1135796c8dcSSimon Schubert char *regs = gregs;
1145796c8dcSSimon Schubert int i;
1155796c8dcSSimon Schubert
1165796c8dcSSimon Schubert for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++)
1175796c8dcSSimon Schubert {
1185796c8dcSSimon Schubert if (regnum == -1 || regnum == i)
1195796c8dcSSimon Schubert {
1205796c8dcSSimon Schubert int offset = i386bsd_r_reg_offset[i];
1215796c8dcSSimon Schubert
1225796c8dcSSimon Schubert if (offset != -1)
1235796c8dcSSimon Schubert regcache_raw_collect (regcache, i, regs + offset);
1245796c8dcSSimon Schubert }
1255796c8dcSSimon Schubert }
1265796c8dcSSimon Schubert }
1275796c8dcSSimon Schubert
1285796c8dcSSimon Schubert /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
1295796c8dcSSimon Schubert for all registers (including the floating point registers). */
1305796c8dcSSimon Schubert
1315796c8dcSSimon Schubert static void
i386bsd_fetch_inferior_registers(struct target_ops * ops,struct regcache * regcache,int regnum)1325796c8dcSSimon Schubert i386bsd_fetch_inferior_registers (struct target_ops *ops,
1335796c8dcSSimon Schubert struct regcache *regcache, int regnum)
1345796c8dcSSimon Schubert {
1355796c8dcSSimon Schubert if (regnum == -1 || GETREGS_SUPPLIES (regnum))
1365796c8dcSSimon Schubert {
1375796c8dcSSimon Schubert struct reg regs;
1385796c8dcSSimon Schubert
1395796c8dcSSimon Schubert if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
1405796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1)
1415796c8dcSSimon Schubert perror_with_name (_("Couldn't get registers"));
1425796c8dcSSimon Schubert
1435796c8dcSSimon Schubert i386bsd_supply_gregset (regcache, ®s);
1445796c8dcSSimon Schubert if (regnum != -1)
1455796c8dcSSimon Schubert return;
1465796c8dcSSimon Schubert }
1475796c8dcSSimon Schubert
1485796c8dcSSimon Schubert if (regnum == -1 || regnum >= I386_ST0_REGNUM)
1495796c8dcSSimon Schubert {
1505796c8dcSSimon Schubert struct fpreg fpregs;
1515796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS
1525796c8dcSSimon Schubert char xmmregs[512];
1535796c8dcSSimon Schubert
1545796c8dcSSimon Schubert if (have_ptrace_xmmregs != 0
1555796c8dcSSimon Schubert && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
1565796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
1575796c8dcSSimon Schubert {
1585796c8dcSSimon Schubert have_ptrace_xmmregs = 1;
1595796c8dcSSimon Schubert i387_supply_fxsave (regcache, -1, xmmregs);
1605796c8dcSSimon Schubert }
1615796c8dcSSimon Schubert else
1625796c8dcSSimon Schubert {
1635796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
1645796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
1655796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status"));
1665796c8dcSSimon Schubert
1675796c8dcSSimon Schubert i387_supply_fsave (regcache, -1, &fpregs);
1685796c8dcSSimon Schubert }
1695796c8dcSSimon Schubert #else
1705796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
1715796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
1725796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status"));
1735796c8dcSSimon Schubert
1745796c8dcSSimon Schubert i387_supply_fsave (regcache, -1, &fpregs);
1755796c8dcSSimon Schubert #endif
1765796c8dcSSimon Schubert }
1775796c8dcSSimon Schubert }
1785796c8dcSSimon Schubert
1795796c8dcSSimon Schubert /* Store register REGNUM back into the inferior. If REGNUM is -1, do
1805796c8dcSSimon Schubert this for all registers (including the floating point registers). */
1815796c8dcSSimon Schubert
1825796c8dcSSimon Schubert static void
i386bsd_store_inferior_registers(struct target_ops * ops,struct regcache * regcache,int regnum)1835796c8dcSSimon Schubert i386bsd_store_inferior_registers (struct target_ops *ops,
1845796c8dcSSimon Schubert struct regcache *regcache, int regnum)
1855796c8dcSSimon Schubert {
1865796c8dcSSimon Schubert if (regnum == -1 || GETREGS_SUPPLIES (regnum))
1875796c8dcSSimon Schubert {
1885796c8dcSSimon Schubert struct reg regs;
1895796c8dcSSimon Schubert
1905796c8dcSSimon Schubert if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
1915796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1)
1925796c8dcSSimon Schubert perror_with_name (_("Couldn't get registers"));
1935796c8dcSSimon Schubert
1945796c8dcSSimon Schubert i386bsd_collect_gregset (regcache, ®s, regnum);
1955796c8dcSSimon Schubert
1965796c8dcSSimon Schubert if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
1975796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1)
1985796c8dcSSimon Schubert perror_with_name (_("Couldn't write registers"));
1995796c8dcSSimon Schubert
2005796c8dcSSimon Schubert if (regnum != -1)
2015796c8dcSSimon Schubert return;
2025796c8dcSSimon Schubert }
2035796c8dcSSimon Schubert
2045796c8dcSSimon Schubert if (regnum == -1 || regnum >= I386_ST0_REGNUM)
2055796c8dcSSimon Schubert {
2065796c8dcSSimon Schubert struct fpreg fpregs;
2075796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS
2085796c8dcSSimon Schubert char xmmregs[512];
2095796c8dcSSimon Schubert
2105796c8dcSSimon Schubert if (have_ptrace_xmmregs != 0
2115796c8dcSSimon Schubert && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
2125796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
2135796c8dcSSimon Schubert {
2145796c8dcSSimon Schubert have_ptrace_xmmregs = 1;
2155796c8dcSSimon Schubert
2165796c8dcSSimon Schubert i387_collect_fxsave (regcache, regnum, xmmregs);
2175796c8dcSSimon Schubert
2185796c8dcSSimon Schubert if (ptrace (PT_SETXMMREGS, PIDGET (inferior_ptid),
2195796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
2205796c8dcSSimon Schubert perror_with_name (_("Couldn't write XMM registers"));
2215796c8dcSSimon Schubert }
2225796c8dcSSimon Schubert else
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert have_ptrace_xmmregs = 0;
2255796c8dcSSimon Schubert #endif
2265796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
2275796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
2285796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status"));
2295796c8dcSSimon Schubert
2305796c8dcSSimon Schubert i387_collect_fsave (regcache, regnum, &fpregs);
2315796c8dcSSimon Schubert
2325796c8dcSSimon Schubert if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
2335796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
2345796c8dcSSimon Schubert perror_with_name (_("Couldn't write floating point status"));
2355796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS
2365796c8dcSSimon Schubert }
2375796c8dcSSimon Schubert #endif
2385796c8dcSSimon Schubert }
2395796c8dcSSimon Schubert }
2405796c8dcSSimon Schubert
2415796c8dcSSimon Schubert /* Create a prototype *BSD/i386 target. The client can override it
2425796c8dcSSimon Schubert with local methods. */
2435796c8dcSSimon Schubert
2445796c8dcSSimon Schubert struct target_ops *
i386bsd_target(void)2455796c8dcSSimon Schubert i386bsd_target (void)
2465796c8dcSSimon Schubert {
2475796c8dcSSimon Schubert struct target_ops *t;
2485796c8dcSSimon Schubert
2495796c8dcSSimon Schubert t = inf_ptrace_target ();
2505796c8dcSSimon Schubert t->to_fetch_registers = i386bsd_fetch_inferior_registers;
2515796c8dcSSimon Schubert t->to_store_registers = i386bsd_store_inferior_registers;
2525796c8dcSSimon Schubert return t;
2535796c8dcSSimon Schubert }
2545796c8dcSSimon Schubert
2555796c8dcSSimon Schubert
2565796c8dcSSimon Schubert /* Support for debug registers. */
2575796c8dcSSimon Schubert
2585796c8dcSSimon Schubert #ifdef HAVE_PT_GETDBREGS
2595796c8dcSSimon Schubert
2605796c8dcSSimon Schubert /* Not all versions of FreeBSD/i386 that support the debug registers
2615796c8dcSSimon Schubert have this macro. */
2625796c8dcSSimon Schubert #ifndef DBREG_DRX
2635796c8dcSSimon Schubert #define DBREG_DRX(d, x) ((&d->dr0)[x])
2645796c8dcSSimon Schubert #endif
2655796c8dcSSimon Schubert
266*ef5ccd6cSJohn Marino static unsigned long
i386bsd_dr_get(ptid_t ptid,int regnum)267*ef5ccd6cSJohn Marino i386bsd_dr_get (ptid_t ptid, int regnum)
268*ef5ccd6cSJohn Marino {
269*ef5ccd6cSJohn Marino struct dbreg dbregs;
270*ef5ccd6cSJohn Marino
271*ef5ccd6cSJohn Marino if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
272*ef5ccd6cSJohn Marino (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
273*ef5ccd6cSJohn Marino perror_with_name (_("Couldn't read debug registers"));
274*ef5ccd6cSJohn Marino
275*ef5ccd6cSJohn Marino return DBREG_DRX ((&dbregs), regnum);
276*ef5ccd6cSJohn Marino }
277*ef5ccd6cSJohn Marino
2785796c8dcSSimon Schubert static void
i386bsd_dr_set(int regnum,unsigned int value)2795796c8dcSSimon Schubert i386bsd_dr_set (int regnum, unsigned int value)
2805796c8dcSSimon Schubert {
2815796c8dcSSimon Schubert struct dbreg dbregs;
2825796c8dcSSimon Schubert
2835796c8dcSSimon Schubert if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
2845796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
2855796c8dcSSimon Schubert perror_with_name (_("Couldn't get debug registers"));
2865796c8dcSSimon Schubert
2875796c8dcSSimon Schubert /* For some mysterious reason, some of the reserved bits in the
2885796c8dcSSimon Schubert debug control register get set. Mask these off, otherwise the
2895796c8dcSSimon Schubert ptrace call below will fail. */
2905796c8dcSSimon Schubert DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
2915796c8dcSSimon Schubert
2925796c8dcSSimon Schubert DBREG_DRX ((&dbregs), regnum) = value;
2935796c8dcSSimon Schubert
2945796c8dcSSimon Schubert if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
2955796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
2965796c8dcSSimon Schubert perror_with_name (_("Couldn't write debug registers"));
2975796c8dcSSimon Schubert }
2985796c8dcSSimon Schubert
2995796c8dcSSimon Schubert void
i386bsd_dr_set_control(unsigned long control)3005796c8dcSSimon Schubert i386bsd_dr_set_control (unsigned long control)
3015796c8dcSSimon Schubert {
3025796c8dcSSimon Schubert i386bsd_dr_set (7, control);
3035796c8dcSSimon Schubert }
3045796c8dcSSimon Schubert
3055796c8dcSSimon Schubert void
i386bsd_dr_set_addr(int regnum,CORE_ADDR addr)3065796c8dcSSimon Schubert i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
3075796c8dcSSimon Schubert {
3085796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum <= 4);
3095796c8dcSSimon Schubert
3105796c8dcSSimon Schubert i386bsd_dr_set (regnum, addr);
3115796c8dcSSimon Schubert }
3125796c8dcSSimon Schubert
313*ef5ccd6cSJohn Marino CORE_ADDR
i386bsd_dr_get_addr(int regnum)314*ef5ccd6cSJohn Marino i386bsd_dr_get_addr (int regnum)
3155796c8dcSSimon Schubert {
316*ef5ccd6cSJohn Marino return i386bsd_dr_get (inferior_ptid, regnum);
3175796c8dcSSimon Schubert }
3185796c8dcSSimon Schubert
3195796c8dcSSimon Schubert unsigned long
i386bsd_dr_get_status(void)3205796c8dcSSimon Schubert i386bsd_dr_get_status (void)
3215796c8dcSSimon Schubert {
322*ef5ccd6cSJohn Marino return i386bsd_dr_get (inferior_ptid, 6);
323*ef5ccd6cSJohn Marino }
3245796c8dcSSimon Schubert
325*ef5ccd6cSJohn Marino unsigned long
i386bsd_dr_get_control(void)326*ef5ccd6cSJohn Marino i386bsd_dr_get_control (void)
327*ef5ccd6cSJohn Marino {
328*ef5ccd6cSJohn Marino return i386bsd_dr_get (inferior_ptid, 7);
3295796c8dcSSimon Schubert }
3305796c8dcSSimon Schubert
3315796c8dcSSimon Schubert #endif /* PT_GETDBREGS */
3325796c8dcSSimon Schubert
3335796c8dcSSimon Schubert
334*ef5ccd6cSJohn Marino /* Provide a prototype to silence -Wmissing-prototypes. */
335*ef5ccd6cSJohn Marino void _initialize_i386bsd_nat (void);
336*ef5ccd6cSJohn Marino
3375796c8dcSSimon Schubert void
_initialize_i386bsd_nat(void)3385796c8dcSSimon Schubert _initialize_i386bsd_nat (void)
3395796c8dcSSimon Schubert {
3405796c8dcSSimon Schubert int offset;
3415796c8dcSSimon Schubert
3425796c8dcSSimon Schubert /* To support the recognition of signal handlers, i386bsd-tdep.c
3435796c8dcSSimon Schubert hardcodes some constants. Inclusion of this file means that we
3445796c8dcSSimon Schubert are compiling a native debugger, which means that we can use the
3455796c8dcSSimon Schubert system header files and sysctl(3) to get at the relevant
3465796c8dcSSimon Schubert information. */
3475796c8dcSSimon Schubert
3485796c8dcSSimon Schubert #if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
3495796c8dcSSimon Schubert #define SC_REG_OFFSET i386fbsd4_sc_reg_offset
3505796c8dcSSimon Schubert #elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
3515796c8dcSSimon Schubert #define SC_REG_OFFSET i386fbsd_sc_reg_offset
3525796c8dcSSimon Schubert #elif defined (NetBSD) || defined (__NetBSD_Version__)
3535796c8dcSSimon Schubert #define SC_REG_OFFSET i386nbsd_sc_reg_offset
3545796c8dcSSimon Schubert #elif defined (OpenBSD)
3555796c8dcSSimon Schubert #define SC_REG_OFFSET i386obsd_sc_reg_offset
3565796c8dcSSimon Schubert #elif defined (DragonFly)
3575796c8dcSSimon Schubert #define SC_REG_OFFSET i386dfly_sc_reg_offset
3585796c8dcSSimon Schubert #endif
3595796c8dcSSimon Schubert
3605796c8dcSSimon Schubert #ifdef SC_REG_OFFSET
3615796c8dcSSimon Schubert
3625796c8dcSSimon Schubert /* We only check the program counter, stack pointer and frame
3635796c8dcSSimon Schubert pointer since these members of `struct sigcontext' are essential
3645796c8dcSSimon Schubert for providing backtraces. More checks could be added, but would
3655796c8dcSSimon Schubert involve adding configure checks for the appropriate structure
3665796c8dcSSimon Schubert members, since older BSD's don't provide all of them. */
3675796c8dcSSimon Schubert
3685796c8dcSSimon Schubert #define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
3695796c8dcSSimon Schubert #define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
3705796c8dcSSimon Schubert #define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
3715796c8dcSSimon Schubert
3725796c8dcSSimon Schubert /* Override the default value for the offset of the program counter
3735796c8dcSSimon Schubert in the sigcontext structure. */
3745796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_pc);
3755796c8dcSSimon Schubert
3765796c8dcSSimon Schubert if (SC_PC_OFFSET != offset)
3775796c8dcSSimon Schubert {
3785796c8dcSSimon Schubert warning (_("\
3795796c8dcSSimon Schubert offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
3805796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."),
3815796c8dcSSimon Schubert offset, SC_PC_OFFSET);
3825796c8dcSSimon Schubert }
3835796c8dcSSimon Schubert
3845796c8dcSSimon Schubert SC_PC_OFFSET = offset;
3855796c8dcSSimon Schubert
3865796c8dcSSimon Schubert /* Likewise for the stack pointer. */
3875796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_sp);
3885796c8dcSSimon Schubert
3895796c8dcSSimon Schubert if (SC_SP_OFFSET != offset)
3905796c8dcSSimon Schubert {
3915796c8dcSSimon Schubert warning (_("\
3925796c8dcSSimon Schubert offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
3935796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."),
3945796c8dcSSimon Schubert offset, SC_SP_OFFSET);
3955796c8dcSSimon Schubert }
3965796c8dcSSimon Schubert
3975796c8dcSSimon Schubert SC_SP_OFFSET = offset;
3985796c8dcSSimon Schubert
3995796c8dcSSimon Schubert /* And the frame pointer. */
4005796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_fp);
4015796c8dcSSimon Schubert
4025796c8dcSSimon Schubert if (SC_FP_OFFSET != offset)
4035796c8dcSSimon Schubert {
4045796c8dcSSimon Schubert warning (_("\
4055796c8dcSSimon Schubert offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
4065796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."),
4075796c8dcSSimon Schubert offset, SC_FP_OFFSET);
4085796c8dcSSimon Schubert }
4095796c8dcSSimon Schubert
4105796c8dcSSimon Schubert SC_FP_OFFSET = offset;
4115796c8dcSSimon Schubert
412 #endif /* SC_REG_OFFSET */
413 }
414