* i386obsd-tdep.c (i386obsd_sigtramp_p): Adjust for changed signal
[deliverable/binutils-gdb.git] / gdb / i386obsd-tdep.c
CommitLineData
005328e3 1/* Target-dependent code for OpenBSD/i386.
67457012 2
60a6eeb6
MK
3 Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002,
4 2003, 2004
005328e3
MK
5 Free Software Foundation, Inc.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
24#include "defs.h"
25#include "arch-utils.h"
911bc6ee 26#include "frame.h"
005328e3
MK
27#include "gdbcore.h"
28#include "regcache.h"
67457012 29#include "regset.h"
911bc6ee
MK
30#include "symtab.h"
31#include "objfiles.h"
4be87837 32#include "osabi.h"
5d93ae8c 33#include "target.h"
005328e3 34
67457012
MK
35#include "gdb_assert.h"
36#include "gdb_string.h"
37
005328e3
MK
38#include "i386-tdep.h"
39#include "i387-tdep.h"
60a6eeb6 40#include "solib-svr4.h"
005328e3 41
5d93ae8c
MK
42/* Support for signal handlers. */
43
44/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
45 in virtual memory. The randomness makes it somewhat tricky to
46 detect it, but fortunately we can rely on the fact that the start
47 of the sigtramp routine is page-aligned. By the way, the mapping
48 is read-only, so you cannot place a breakpoint in the signal
49 trampoline. */
50
51/* Default page size. */
52static const int i386obsd_page_size = 4096;
53
377d9ebd 54/* Return whether the frame preceding NEXT_FRAME corresponds to an
911bc6ee 55 OpenBSD sigtramp routine. */
5d93ae8c
MK
56
57static int
911bc6ee 58i386obsd_sigtramp_p (struct frame_info *next_frame)
5d93ae8c 59{
911bc6ee 60 CORE_ADDR pc = frame_pc_unwind (next_frame);
5d93ae8c
MK
61 CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
62 const char sigreturn[] =
63 {
64 0xb8,
65 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */
66 0xcd, 0x80 /* int $0x80 */
67 };
911bc6ee 68 char *name, *buf;
5d93ae8c 69
911bc6ee
MK
70 /* If the function has a valid symbol name, it isn't a
71 trampoline. */
72 find_pc_partial_function (pc, &name, NULL, NULL);
73 if (name != NULL)
74 return 0;
75
76 /* If the function lives in a valid section (even without a starting
77 point) it isn't a trampoline. */
78 if (find_pc_section (pc) != NULL)
5d93ae8c
MK
79 return 0;
80
9c8e3411 81 /* Allocate buffer. */
5d93ae8c 82 buf = alloca (sizeof sigreturn);
9c8e3411
MK
83
84 /* If we can't read the instructions at START_PC, return zero. */
85 if (target_read_memory (start_pc + 0x0a, buf, sizeof sigreturn))
5d93ae8c
MK
86 return 0;
87
88 /* Check for sigreturn(2). */
89 if (memcmp (buf, sigreturn, sizeof sigreturn) == 0)
90 return 1;
91
9c8e3411
MK
92 /* If we can't read the instructions at START_PC, return zero. */
93 if (target_read_memory (start_pc + 0x14, buf, sizeof sigreturn))
94 return 0;
95
96 /* Check for sigreturn(2) (again). */
97 if (memcmp (buf, sigreturn, sizeof sigreturn) == 0)
98 return 1;
99
911bc6ee 100 return 0;
5d93ae8c
MK
101}
102\f
103/* Mapping between the general-purpose registers in `struct reg'
104 format and GDB's register cache layout. */
105
67457012
MK
106/* From <machine/reg.h>. */
107static int i386obsd_r_reg_offset[] =
108{
109 0 * 4, /* %eax */
110 1 * 4, /* %ecx */
111 2 * 4, /* %edx */
112 3 * 4, /* %ebx */
113 4 * 4, /* %esp */
114 5 * 4, /* %ebp */
115 6 * 4, /* %esi */
116 7 * 4, /* %edi */
117 8 * 4, /* %eip */
118 9 * 4, /* %eflags */
119 10 * 4, /* %cs */
120 11 * 4, /* %ss */
121 12 * 4, /* %ds */
122 13 * 4, /* %es */
123 14 * 4, /* %fs */
124 15 * 4 /* %gs */
125};
005328e3
MK
126
127static void
67457012
MK
128i386obsd_aout_supply_regset (const struct regset *regset,
129 struct regcache *regcache, int regnum,
130 const void *regs, size_t len)
005328e3 131{
9ea75c57 132 const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
67457012
MK
133
134 gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
005328e3 135
67457012
MK
136 i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
137 i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset);
005328e3
MK
138}
139
49cfa46f 140static const struct regset *
67457012
MK
141i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch,
142 const char *sect_name,
143 size_t sect_size)
005328e3 144{
67457012 145 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
005328e3 146
67457012
MK
147 /* OpenBSD a.out core dumps don't use seperate register sets for the
148 general-purpose and floating-point registers. */
005328e3 149
67457012
MK
150 if (strcmp (sect_name, ".reg") == 0
151 && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
005328e3 152 {
67457012 153 if (tdep->gregset == NULL)
9ea75c57
MK
154 tdep->gregset =
155 regset_alloc (gdbarch, i386obsd_aout_supply_regset, NULL);
67457012 156 return tdep->gregset;
005328e3
MK
157 }
158
67457012 159 return NULL;
005328e3 160}
005328e3
MK
161\f
162
5d93ae8c
MK
163/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
164CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
165CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
005328e3
MK
166
167/* From <machine/signal.h>. */
a3386186
MK
168int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
169{
170 10 * 4, /* %eax */
171 9 * 4, /* %ecx */
172 8 * 4, /* %edx */
173 7 * 4, /* %ebx */
174 14 * 4, /* %esp */
175 6 * 4, /* %ebp */
176 5 * 4, /* %esi */
177 4 * 4, /* %edi */
178 11 * 4, /* %eip */
179 13 * 4, /* %eflags */
180 12 * 4, /* %cs */
181 15 * 4, /* %ss */
182 3 * 4, /* %ds */
183 2 * 4, /* %es */
184 1 * 4, /* %fs */
185 0 * 4 /* %gs */
186};
005328e3
MK
187
188static void
189i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
190{
191 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
192
193 /* Obviously OpenBSD is BSD-based. */
194 i386bsd_init_abi (info, gdbarch);
195
67457012
MK
196 /* OpenBSD has a different `struct reg'. */
197 tdep->gregset_reg_offset = i386obsd_r_reg_offset;
198 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
199 tdep->sizeof_gregset = 16 * 4;
200
005328e3
MK
201 /* OpenBSD uses -freg-struct-return by default. */
202 tdep->struct_return = reg_struct_return;
203
204 /* OpenBSD uses a different memory layout. */
5d93ae8c
MK
205 tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
206 tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
911bc6ee 207 tdep->sigtramp_p = i386obsd_sigtramp_p;
005328e3
MK
208
209 /* OpenBSD has a `struct sigcontext' that's different from the
f2e7c15d 210 original 4.3 BSD. */
a3386186 211 tdep->sc_reg_offset = i386obsd_sc_reg_offset;
67457012 212 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
005328e3 213}
60a6eeb6
MK
214
215/* OpenBSD a.out. */
216
217static void
218i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
219{
220 i386obsd_init_abi (info, gdbarch);
221
222 /* OpenBSD a.out has a single register set. */
223 set_gdbarch_regset_from_core_section
224 (gdbarch, i386obsd_aout_regset_from_core_section);
225}
226
227/* OpenBSD ELF. */
228
229static void
230i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
231{
232 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
233
234 /* It's still OpenBSD. */
235 i386obsd_init_abi (info, gdbarch);
236
237 /* But ELF-based. */
238 i386_elf_init_abi (info, gdbarch);
239
240 /* OpenBSD ELF uses SVR4-style shared libraries. */
241 set_gdbarch_in_solib_call_trampoline
242 (gdbarch, generic_in_solib_call_trampoline);
243 set_solib_svr4_fetch_link_map_offsets
244 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
245}
67457012
MK
246\f
247
248/* Provide a prototype to silence -Wmissing-prototypes. */
249void _initialize_i386obsd_tdep (void);
005328e3
MK
250
251void
252_initialize_i386obsd_tdep (void)
253{
005328e3
MK
254 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are
255 indistingushable from NetBSD/i386 a.out binaries, building a GDB
256 that should support both these targets will probably not work as
257 expected. */
258#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
259
05816f70 260 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT,
60a6eeb6
MK
261 i386obsd_aout_init_abi);
262 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF,
263 i386obsd_elf_init_abi);
005328e3 264}
This page took 0.206052 seconds and 4 git commands to generate.