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) ®s, 0) == -1)
149b725ae77Skettenis perror_with_name ("Couldn't get registers");
150b725ae77Skettenis
15111efff7fSkettenis i386bsd_supply_gregset (current_regcache, ®s);
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) ®s, 0) == -1)
203b725ae77Skettenis perror_with_name ("Couldn't get registers");
204b725ae77Skettenis
20511efff7fSkettenis i386bsd_collect_gregset (current_regcache, ®s, regnum);
206b725ae77Skettenis
207*c9d97425Skettenis if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 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