xref: /openbsd-src/gnu/usr.bin/binutils/gdb/i386bsd-nat.c (revision c9d97425b53eb2c95333e2ccd62cc009fe5c85e4)
1b725ae77Skettenis /* Native-dependent code for modern i386 BSD's.
211efff7fSkettenis 
311efff7fSkettenis    Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "inferior.h"
24b725ae77Skettenis #include "regcache.h"
25b725ae77Skettenis 
26b725ae77Skettenis #include "gdb_assert.h"
27b725ae77Skettenis #include <signal.h>
28b725ae77Skettenis #include <stddef.h>
29b725ae77Skettenis #include <sys/types.h>
30b725ae77Skettenis #include <sys/ptrace.h>
31b725ae77Skettenis #include <machine/reg.h>
32b725ae77Skettenis #include <machine/frame.h>
33b725ae77Skettenis 
34b725ae77Skettenis #include "i386-tdep.h"
3511efff7fSkettenis #include "i387-tdep.h"
3611efff7fSkettenis #include "i386bsd-nat.h"
3711efff7fSkettenis #include "inf-ptrace.h"
38b725ae77Skettenis 
39b725ae77Skettenis 
40b725ae77Skettenis /* In older BSD versions we cannot get at some of the segment
41b725ae77Skettenis    registers.  FreeBSD for example didn't support the %fs and %gs
42b725ae77Skettenis    registers until the 3.0 release.  We have autoconf checks for their
43b725ae77Skettenis    presence, and deal gracefully with their absence.  */
44b725ae77Skettenis 
4511efff7fSkettenis /* Offset in `struct reg' where MEMBER is stored.  */
4611efff7fSkettenis #define REG_OFFSET(member) offsetof (struct reg, member)
47b725ae77Skettenis 
4811efff7fSkettenis /* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct
4911efff7fSkettenis    reg' where the GDB register REGNUM is stored.  Unsupported
50b725ae77Skettenis    registers are marked with `-1'.  */
5111efff7fSkettenis static int i386bsd_r_reg_offset[] =
52b725ae77Skettenis {
53b725ae77Skettenis   REG_OFFSET (r_eax),
54b725ae77Skettenis   REG_OFFSET (r_ecx),
55b725ae77Skettenis   REG_OFFSET (r_edx),
56b725ae77Skettenis   REG_OFFSET (r_ebx),
57b725ae77Skettenis   REG_OFFSET (r_esp),
58b725ae77Skettenis   REG_OFFSET (r_ebp),
59b725ae77Skettenis   REG_OFFSET (r_esi),
60b725ae77Skettenis   REG_OFFSET (r_edi),
61b725ae77Skettenis   REG_OFFSET (r_eip),
62b725ae77Skettenis   REG_OFFSET (r_eflags),
63b725ae77Skettenis   REG_OFFSET (r_cs),
64b725ae77Skettenis   REG_OFFSET (r_ss),
65b725ae77Skettenis   REG_OFFSET (r_ds),
66b725ae77Skettenis   REG_OFFSET (r_es),
67b725ae77Skettenis #ifdef HAVE_STRUCT_REG_R_FS
68b725ae77Skettenis   REG_OFFSET (r_fs),
69b725ae77Skettenis #else
70b725ae77Skettenis   -1,
71b725ae77Skettenis #endif
72b725ae77Skettenis #ifdef HAVE_STRUCT_REG_R_GS
73b725ae77Skettenis   REG_OFFSET (r_gs)
74b725ae77Skettenis #else
75b725ae77Skettenis   -1
76b725ae77Skettenis #endif
77b725ae77Skettenis };
78b725ae77Skettenis 
79b725ae77Skettenis /* Macro to determine if a register is fetched with PT_GETREGS.  */
8011efff7fSkettenis #define GETREGS_SUPPLIES(regnum) \
8111efff7fSkettenis   ((0 <= (regnum) && (regnum) <= 15))
82b725ae77Skettenis 
83b725ae77Skettenis #ifdef HAVE_PT_GETXMMREGS
84b725ae77Skettenis /* Set to 1 if the kernel supports PT_GETXMMREGS.  Initialized to -1
85b725ae77Skettenis    so that we try PT_GETXMMREGS the first time around.  */
86b725ae77Skettenis static int have_ptrace_xmmregs = -1;
87b725ae77Skettenis #endif
88b725ae77Skettenis 
89b725ae77Skettenis 
9011efff7fSkettenis /* Supply the general-purpose registers in GREGS, to REGCACHE.  */
91b725ae77Skettenis 
9211efff7fSkettenis static void
i386bsd_supply_gregset(struct regcache * regcache,const void * gregs)9311efff7fSkettenis i386bsd_supply_gregset (struct regcache *regcache, const void *gregs)
94b725ae77Skettenis {
9511efff7fSkettenis   const char *regs = gregs;
9611efff7fSkettenis   int regnum;
9711efff7fSkettenis 
9811efff7fSkettenis   for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++)
9911efff7fSkettenis     {
10011efff7fSkettenis       int offset = i386bsd_r_reg_offset[regnum];
10111efff7fSkettenis 
10211efff7fSkettenis       if (offset != -1)
10311efff7fSkettenis 	regcache_raw_supply (regcache, regnum, regs + offset);
10411efff7fSkettenis     }
10511efff7fSkettenis }
10611efff7fSkettenis 
10711efff7fSkettenis /* Collect register REGNUM from REGCACHE and store its contents in
10811efff7fSkettenis    GREGS.  If REGNUM is -1, collect and store all appropriate
10911efff7fSkettenis    registers.  */
11011efff7fSkettenis 
11111efff7fSkettenis static void
i386bsd_collect_gregset(const struct regcache * regcache,void * gregs,int regnum)11211efff7fSkettenis i386bsd_collect_gregset (const struct regcache *regcache,
11311efff7fSkettenis 			 void *gregs, int regnum)
11411efff7fSkettenis {
11511efff7fSkettenis   char *regs = gregs;
116b725ae77Skettenis   int i;
117b725ae77Skettenis 
11811efff7fSkettenis   for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++)
119b725ae77Skettenis     {
12011efff7fSkettenis       if (regnum == -1 || regnum == i)
121b725ae77Skettenis 	{
12211efff7fSkettenis 	  int offset = i386bsd_r_reg_offset[i];
123b725ae77Skettenis 
12411efff7fSkettenis 	  if (offset != -1)
12511efff7fSkettenis 	    regcache_raw_collect (regcache, i, regs + offset);
12611efff7fSkettenis 	}
12711efff7fSkettenis     }
128b725ae77Skettenis }
129b725ae77Skettenis 
13011efff7fSkettenis /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
131b725ae77Skettenis    for all registers (including the floating point registers).  */
132b725ae77Skettenis 
13311efff7fSkettenis static void
i386bsd_fetch_inferior_registers(int regnum)13411efff7fSkettenis i386bsd_fetch_inferior_registers (int regnum)
135b725ae77Skettenis {
136*c9d97425Skettenis   int pid;
137*c9d97425Skettenis 
138*c9d97425Skettenis   /* Cater for systems like OpenBSD, that implement threads as
139*c9d97425Skettenis      separate processes.  */
140*c9d97425Skettenis   pid = ptid_get_lwp (inferior_ptid);
141*c9d97425Skettenis   if (pid == 0)
142*c9d97425Skettenis     pid = ptid_get_pid (inferior_ptid);
143*c9d97425Skettenis 
14411efff7fSkettenis   if (regnum == -1 || GETREGS_SUPPLIES (regnum))
145b725ae77Skettenis     {
14611efff7fSkettenis       struct reg regs;
147b725ae77Skettenis 
148*c9d97425Skettenis       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
149b725ae77Skettenis 	perror_with_name ("Couldn't get registers");
150b725ae77Skettenis 
15111efff7fSkettenis       i386bsd_supply_gregset (current_regcache, &regs);
15211efff7fSkettenis       if (regnum != -1)
153b725ae77Skettenis 	return;
154b725ae77Skettenis     }
155b725ae77Skettenis 
15611efff7fSkettenis   if (regnum == -1 || regnum >= I386_ST0_REGNUM)
157b725ae77Skettenis     {
15811efff7fSkettenis       struct fpreg fpregs;
159b725ae77Skettenis #ifdef HAVE_PT_GETXMMREGS
160b725ae77Skettenis       char xmmregs[512];
161b725ae77Skettenis 
162b725ae77Skettenis       if (have_ptrace_xmmregs != 0
163*c9d97425Skettenis 	  && ptrace(PT_GETXMMREGS, pid, (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
164b725ae77Skettenis 	{
165b725ae77Skettenis 	  have_ptrace_xmmregs = 1;
166b725ae77Skettenis 	  i387_supply_fxsave (current_regcache, -1, xmmregs);
167b725ae77Skettenis 	}
168b725ae77Skettenis       else
169b725ae77Skettenis 	{
170*c9d97425Skettenis           if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
171b725ae77Skettenis 	    perror_with_name ("Couldn't get floating point status");
172b725ae77Skettenis 
173b725ae77Skettenis 	  i387_supply_fsave (current_regcache, -1, &fpregs);
174b725ae77Skettenis 	}
175b725ae77Skettenis #else
176*c9d97425Skettenis       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
177b725ae77Skettenis 	perror_with_name ("Couldn't get floating point status");
178b725ae77Skettenis 
179b725ae77Skettenis       i387_supply_fsave (current_regcache, -1, &fpregs);
180b725ae77Skettenis #endif
181b725ae77Skettenis     }
182b725ae77Skettenis }
183b725ae77Skettenis 
18411efff7fSkettenis /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
185b725ae77Skettenis    this for all registers (including the floating point registers).  */
186b725ae77Skettenis 
18711efff7fSkettenis static void
i386bsd_store_inferior_registers(int regnum)18811efff7fSkettenis i386bsd_store_inferior_registers (int regnum)
189b725ae77Skettenis {
190*c9d97425Skettenis   int pid;
191*c9d97425Skettenis 
192*c9d97425Skettenis   /* Cater for systems like OpenBSD, that implement threads as
193*c9d97425Skettenis      separate processes.  */
194*c9d97425Skettenis   pid = ptid_get_lwp (inferior_ptid);
195*c9d97425Skettenis   if (pid == 0)
196*c9d97425Skettenis     pid = ptid_get_pid (inferior_ptid);
197*c9d97425Skettenis 
19811efff7fSkettenis   if (regnum == -1 || GETREGS_SUPPLIES (regnum))
199b725ae77Skettenis     {
20011efff7fSkettenis       struct reg regs;
201b725ae77Skettenis 
202*c9d97425Skettenis       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
203b725ae77Skettenis         perror_with_name ("Couldn't get registers");
204b725ae77Skettenis 
20511efff7fSkettenis       i386bsd_collect_gregset (current_regcache, &regs, regnum);
206b725ae77Skettenis 
207*c9d97425Skettenis       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
208b725ae77Skettenis         perror_with_name ("Couldn't write registers");
209b725ae77Skettenis 
21011efff7fSkettenis       if (regnum != -1)
211b725ae77Skettenis 	return;
212b725ae77Skettenis     }
213b725ae77Skettenis 
21411efff7fSkettenis   if (regnum == -1 || regnum >= I386_ST0_REGNUM)
215b725ae77Skettenis     {
21611efff7fSkettenis       struct fpreg fpregs;
217b725ae77Skettenis #ifdef HAVE_PT_GETXMMREGS
218b725ae77Skettenis       char xmmregs[512];
219b725ae77Skettenis 
220b725ae77Skettenis       if (have_ptrace_xmmregs != 0
221*c9d97425Skettenis 	  && ptrace(PT_GETXMMREGS, pid, (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
222b725ae77Skettenis 	{
223b725ae77Skettenis 	  have_ptrace_xmmregs = 1;
224b725ae77Skettenis 
22511efff7fSkettenis 	  i387_collect_fxsave (current_regcache, regnum, xmmregs);
226b725ae77Skettenis 
227*c9d97425Skettenis 	  if (ptrace (PT_SETXMMREGS, pid, (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
228b725ae77Skettenis             perror_with_name ("Couldn't write XMM registers");
229b725ae77Skettenis 	}
230b725ae77Skettenis       else
231b725ae77Skettenis 	{
232b725ae77Skettenis 	  have_ptrace_xmmregs = 0;
233b725ae77Skettenis #endif
234*c9d97425Skettenis           if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
235b725ae77Skettenis 	    perror_with_name ("Couldn't get floating point status");
236b725ae77Skettenis 
23711efff7fSkettenis           i387_collect_fsave (current_regcache, regnum, &fpregs);
238b725ae77Skettenis 
239*c9d97425Skettenis           if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
240b725ae77Skettenis 	    perror_with_name ("Couldn't write floating point status");
241b725ae77Skettenis #ifdef HAVE_PT_GETXMMREGS
242b725ae77Skettenis         }
243b725ae77Skettenis #endif
244b725ae77Skettenis     }
245b725ae77Skettenis }
24611efff7fSkettenis 
24711efff7fSkettenis /* Create a prototype *BSD/i386 target.  The client can override it
24811efff7fSkettenis    with local methods.  */
24911efff7fSkettenis 
25011efff7fSkettenis struct target_ops *
i386bsd_target(void)25111efff7fSkettenis i386bsd_target (void)
25211efff7fSkettenis {
25311efff7fSkettenis   struct target_ops *t;
25411efff7fSkettenis 
25511efff7fSkettenis   t = inf_ptrace_target ();
25611efff7fSkettenis   t->to_fetch_registers = i386bsd_fetch_inferior_registers;
25711efff7fSkettenis   t->to_store_registers = i386bsd_store_inferior_registers;
25811efff7fSkettenis   return t;
25911efff7fSkettenis }
260b725ae77Skettenis 
261b725ae77Skettenis 
262b725ae77Skettenis /* Support for debug registers.  */
263b725ae77Skettenis 
264b725ae77Skettenis #ifdef HAVE_PT_GETDBREGS
265b725ae77Skettenis 
266b725ae77Skettenis /* Not all versions of FreeBSD/i386 that support the debug registers
267b725ae77Skettenis    have this macro.  */
268b725ae77Skettenis #ifndef DBREG_DRX
269b725ae77Skettenis #define DBREG_DRX(d, x) ((&d->dr0)[x])
270b725ae77Skettenis #endif
271b725ae77Skettenis 
272b725ae77Skettenis static void
i386bsd_dr_set(int regnum,unsigned int value)273b725ae77Skettenis i386bsd_dr_set (int regnum, unsigned int value)
274b725ae77Skettenis {
275b725ae77Skettenis   struct dbreg dbregs;
276b725ae77Skettenis 
277b725ae77Skettenis   if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
27811efff7fSkettenis               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
279b725ae77Skettenis     perror_with_name ("Couldn't get debug registers");
280b725ae77Skettenis 
281b725ae77Skettenis   /* For some mysterious reason, some of the reserved bits in the
282b725ae77Skettenis      debug control register get set.  Mask these off, otherwise the
283b725ae77Skettenis      ptrace call below will fail.  */
284b725ae77Skettenis   DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
285b725ae77Skettenis 
286b725ae77Skettenis   DBREG_DRX ((&dbregs), regnum) = value;
287b725ae77Skettenis 
288b725ae77Skettenis   if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
28911efff7fSkettenis               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
290b725ae77Skettenis     perror_with_name ("Couldn't write debug registers");
291b725ae77Skettenis }
292b725ae77Skettenis 
293b725ae77Skettenis void
i386bsd_dr_set_control(unsigned long control)294b725ae77Skettenis i386bsd_dr_set_control (unsigned long control)
295b725ae77Skettenis {
296b725ae77Skettenis   i386bsd_dr_set (7, control);
297b725ae77Skettenis }
298b725ae77Skettenis 
299b725ae77Skettenis void
i386bsd_dr_set_addr(int regnum,CORE_ADDR addr)300b725ae77Skettenis i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
301b725ae77Skettenis {
302b725ae77Skettenis   gdb_assert (regnum >= 0 && regnum <= 4);
303b725ae77Skettenis 
304b725ae77Skettenis   i386bsd_dr_set (regnum, addr);
305b725ae77Skettenis }
306b725ae77Skettenis 
307b725ae77Skettenis void
i386bsd_dr_reset_addr(int regnum)308b725ae77Skettenis i386bsd_dr_reset_addr (int regnum)
309b725ae77Skettenis {
310b725ae77Skettenis   gdb_assert (regnum >= 0 && regnum <= 4);
311b725ae77Skettenis 
312b725ae77Skettenis   i386bsd_dr_set (regnum, 0);
313b725ae77Skettenis }
314b725ae77Skettenis 
315b725ae77Skettenis unsigned long
i386bsd_dr_get_status(void)316b725ae77Skettenis i386bsd_dr_get_status (void)
317b725ae77Skettenis {
318b725ae77Skettenis   struct dbreg dbregs;
319b725ae77Skettenis 
320b725ae77Skettenis   /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
321b725ae77Skettenis      ptrace call fails breaks debugging remote targets.  The correct
322b725ae77Skettenis      way to fix this is to add the hardware breakpoint and watchpoint
323b725ae77Skettenis      stuff to the target vector.  For now, just return zero if the
324b725ae77Skettenis      ptrace call fails.  */
325b725ae77Skettenis   if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
32611efff7fSkettenis 	      (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
327b725ae77Skettenis #if 0
328b725ae77Skettenis     perror_with_name ("Couldn't read debug registers");
329b725ae77Skettenis #else
330b725ae77Skettenis     return 0;
331b725ae77Skettenis #endif
332b725ae77Skettenis 
333b725ae77Skettenis   return DBREG_DRX ((&dbregs), 6);
334b725ae77Skettenis }
335b725ae77Skettenis 
336b725ae77Skettenis #endif /* PT_GETDBREGS */
337b725ae77Skettenis 
338b725ae77Skettenis 
339b725ae77Skettenis /* Support for the user struct.  */
340b725ae77Skettenis 
34111efff7fSkettenis /* Return the address register REGNUM.  BLOCKEND is the value of
342b725ae77Skettenis    u.u_ar0, which should point to the registers.  */
343b725ae77Skettenis 
344b725ae77Skettenis CORE_ADDR
register_u_addr(CORE_ADDR blockend,int regnum)34511efff7fSkettenis register_u_addr (CORE_ADDR blockend, int regnum)
346b725ae77Skettenis {
34711efff7fSkettenis   gdb_assert (regnum >= 0 && regnum < ARRAY_SIZE (i386bsd_r_reg_offset));
34811efff7fSkettenis 
34911efff7fSkettenis   return blockend + i386bsd_r_reg_offset[regnum];
350b725ae77Skettenis }
351b725ae77Skettenis 
352b725ae77Skettenis #include <sys/param.h>
353b725ae77Skettenis #include <sys/user.h>
354b725ae77Skettenis 
355b725ae77Skettenis /* Return the size of the user struct.  */
356b725ae77Skettenis 
357b725ae77Skettenis int
kernel_u_size(void)358b725ae77Skettenis kernel_u_size (void)
359b725ae77Skettenis {
360b725ae77Skettenis   return (sizeof (struct user));
361b725ae77Skettenis }
362b725ae77Skettenis 
363b725ae77Skettenis void
_initialize_i386bsd_nat(void)364b725ae77Skettenis _initialize_i386bsd_nat (void)
365b725ae77Skettenis {
366b725ae77Skettenis   int offset;
367b725ae77Skettenis 
368b725ae77Skettenis   /* To support the recognition of signal handlers, i386bsd-tdep.c
369b725ae77Skettenis      hardcodes some constants.  Inclusion of this file means that we
370b725ae77Skettenis      are compiling a native debugger, which means that we can use the
371b725ae77Skettenis      system header files and sysctl(3) to get at the relevant
372b725ae77Skettenis      information.  */
373b725ae77Skettenis 
374b725ae77Skettenis #if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
375b725ae77Skettenis #define SC_REG_OFFSET i386fbsd4_sc_reg_offset
376b725ae77Skettenis #elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
377b725ae77Skettenis #define SC_REG_OFFSET i386fbsd_sc_reg_offset
378b725ae77Skettenis #elif defined (NetBSD) || defined (__NetBSD_Version__)
379b725ae77Skettenis #define SC_REG_OFFSET i386nbsd_sc_reg_offset
380b725ae77Skettenis #elif defined (OpenBSD)
381b725ae77Skettenis #define SC_REG_OFFSET i386obsd_sc_reg_offset
382b725ae77Skettenis #endif
383b725ae77Skettenis 
38411efff7fSkettenis #ifdef SC_REG_OFFSET
38511efff7fSkettenis 
386b725ae77Skettenis   /* We only check the program counter, stack pointer and frame
387b725ae77Skettenis      pointer since these members of `struct sigcontext' are essential
388b725ae77Skettenis      for providing backtraces.  More checks could be added, but would
389b725ae77Skettenis      involve adding configure checks for the appropriate structure
390b725ae77Skettenis      members, since older BSD's don't provide all of them.  */
391b725ae77Skettenis 
392b725ae77Skettenis #define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
393b725ae77Skettenis #define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
394b725ae77Skettenis #define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
395b725ae77Skettenis 
396b725ae77Skettenis   /* Override the default value for the offset of the program counter
397b725ae77Skettenis      in the sigcontext structure.  */
398b725ae77Skettenis   offset = offsetof (struct sigcontext, sc_pc);
399b725ae77Skettenis 
400b725ae77Skettenis   if (SC_PC_OFFSET != offset)
401b725ae77Skettenis     {
402b725ae77Skettenis       warning ("\
403b725ae77Skettenis offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
404b725ae77Skettenis Please report this to <bug-gdb@gnu.org>.",
405b725ae77Skettenis 	       offset, SC_PC_OFFSET);
406b725ae77Skettenis     }
407b725ae77Skettenis 
408b725ae77Skettenis   SC_PC_OFFSET = offset;
409b725ae77Skettenis 
410b725ae77Skettenis   /* Likewise for the stack pointer.  */
411b725ae77Skettenis   offset = offsetof (struct sigcontext, sc_sp);
412b725ae77Skettenis 
413b725ae77Skettenis   if (SC_SP_OFFSET != offset)
414b725ae77Skettenis     {
415b725ae77Skettenis       warning ("\
416b725ae77Skettenis offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
417b725ae77Skettenis Please report this to <bug-gdb@gnu.org>.",
418b725ae77Skettenis 	       offset, SC_SP_OFFSET);
419b725ae77Skettenis     }
420b725ae77Skettenis 
421b725ae77Skettenis   SC_SP_OFFSET = offset;
422b725ae77Skettenis 
423b725ae77Skettenis   /* And the frame pointer.  */
424b725ae77Skettenis   offset = offsetof (struct sigcontext, sc_fp);
425b725ae77Skettenis 
426b725ae77Skettenis   if (SC_FP_OFFSET != offset)
427b725ae77Skettenis     {
428b725ae77Skettenis       warning ("\
429b725ae77Skettenis offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
430b725ae77Skettenis Please report this to <bug-gdb@gnu.org>.",
431b725ae77Skettenis 	       offset, SC_FP_OFFSET);
432b725ae77Skettenis     }
433b725ae77Skettenis 
434b725ae77Skettenis   SC_FP_OFFSET = offset;
43511efff7fSkettenis 
43611efff7fSkettenis #endif /* SC_REG_OFFSET */
437b725ae77Skettenis }
438