2004-05-08 Andrew Cagney <cagney@redhat.com>
[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
81 /* If we can't read the instructions at START_PC, return zero. */
82 buf = alloca (sizeof sigreturn);
83 if (target_read_memory (start_pc + 0x14, buf, sizeof sigreturn))
84 return 0;
85
86 /* Check for sigreturn(2). */
87 if (memcmp (buf, sigreturn, sizeof sigreturn) == 0)
88 return 1;
89
911bc6ee 90 return 0;
5d93ae8c
MK
91}
92\f
93/* Mapping between the general-purpose registers in `struct reg'
94 format and GDB's register cache layout. */
95
67457012
MK
96/* From <machine/reg.h>. */
97static int i386obsd_r_reg_offset[] =
98{
99 0 * 4, /* %eax */
100 1 * 4, /* %ecx */
101 2 * 4, /* %edx */
102 3 * 4, /* %ebx */
103 4 * 4, /* %esp */
104 5 * 4, /* %ebp */
105 6 * 4, /* %esi */
106 7 * 4, /* %edi */
107 8 * 4, /* %eip */
108 9 * 4, /* %eflags */
109 10 * 4, /* %cs */
110 11 * 4, /* %ss */
111 12 * 4, /* %ds */
112 13 * 4, /* %es */
113 14 * 4, /* %fs */
114 15 * 4 /* %gs */
115};
005328e3
MK
116
117static void
67457012
MK
118i386obsd_aout_supply_regset (const struct regset *regset,
119 struct regcache *regcache, int regnum,
120 const void *regs, size_t len)
005328e3 121{
67457012
MK
122 const struct gdbarch_tdep *tdep = regset->descr;
123
124 gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
005328e3 125
67457012
MK
126 i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
127 i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset);
005328e3
MK
128}
129
49cfa46f 130static const struct regset *
67457012
MK
131i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch,
132 const char *sect_name,
133 size_t sect_size)
005328e3 134{
67457012 135 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
005328e3 136
67457012
MK
137 /* OpenBSD a.out core dumps don't use seperate register sets for the
138 general-purpose and floating-point registers. */
005328e3 139
67457012
MK
140 if (strcmp (sect_name, ".reg") == 0
141 && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
005328e3 142 {
67457012
MK
143 if (tdep->gregset == NULL)
144 {
145 tdep->gregset = XMALLOC (struct regset);
146 tdep->gregset->descr = tdep;
147 tdep->gregset->supply_regset = i386obsd_aout_supply_regset;
148 }
149 return tdep->gregset;
005328e3
MK
150 }
151
67457012 152 return NULL;
005328e3 153}
005328e3
MK
154\f
155
5d93ae8c
MK
156/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
157CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
158CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
005328e3
MK
159
160/* From <machine/signal.h>. */
a3386186
MK
161int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
162{
163 10 * 4, /* %eax */
164 9 * 4, /* %ecx */
165 8 * 4, /* %edx */
166 7 * 4, /* %ebx */
167 14 * 4, /* %esp */
168 6 * 4, /* %ebp */
169 5 * 4, /* %esi */
170 4 * 4, /* %edi */
171 11 * 4, /* %eip */
172 13 * 4, /* %eflags */
173 12 * 4, /* %cs */
174 15 * 4, /* %ss */
175 3 * 4, /* %ds */
176 2 * 4, /* %es */
177 1 * 4, /* %fs */
178 0 * 4 /* %gs */
179};
005328e3
MK
180
181static void
182i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
183{
184 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
185
186 /* Obviously OpenBSD is BSD-based. */
187 i386bsd_init_abi (info, gdbarch);
188
67457012
MK
189 /* OpenBSD has a different `struct reg'. */
190 tdep->gregset_reg_offset = i386obsd_r_reg_offset;
191 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
192 tdep->sizeof_gregset = 16 * 4;
193
005328e3
MK
194 /* OpenBSD uses -freg-struct-return by default. */
195 tdep->struct_return = reg_struct_return;
196
197 /* OpenBSD uses a different memory layout. */
5d93ae8c
MK
198 tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
199 tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
911bc6ee 200 tdep->sigtramp_p = i386obsd_sigtramp_p;
005328e3
MK
201
202 /* OpenBSD has a `struct sigcontext' that's different from the
f2e7c15d 203 original 4.3 BSD. */
a3386186 204 tdep->sc_reg_offset = i386obsd_sc_reg_offset;
67457012 205 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
005328e3 206}
60a6eeb6
MK
207
208/* OpenBSD a.out. */
209
210static void
211i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
212{
213 i386obsd_init_abi (info, gdbarch);
214
215 /* OpenBSD a.out has a single register set. */
216 set_gdbarch_regset_from_core_section
217 (gdbarch, i386obsd_aout_regset_from_core_section);
218}
219
220/* OpenBSD ELF. */
221
222static void
223i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
224{
225 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
226
227 /* It's still OpenBSD. */
228 i386obsd_init_abi (info, gdbarch);
229
230 /* But ELF-based. */
231 i386_elf_init_abi (info, gdbarch);
232
233 /* OpenBSD ELF uses SVR4-style shared libraries. */
234 set_gdbarch_in_solib_call_trampoline
235 (gdbarch, generic_in_solib_call_trampoline);
236 set_solib_svr4_fetch_link_map_offsets
237 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
238}
67457012
MK
239\f
240
241/* Provide a prototype to silence -Wmissing-prototypes. */
242void _initialize_i386obsd_tdep (void);
005328e3
MK
243
244void
245_initialize_i386obsd_tdep (void)
246{
005328e3
MK
247 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are
248 indistingushable from NetBSD/i386 a.out binaries, building a GDB
249 that should support both these targets will probably not work as
250 expected. */
251#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
252
05816f70 253 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT,
60a6eeb6
MK
254 i386obsd_aout_init_abi);
255 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF,
256 i386obsd_elf_init_abi);
005328e3 257}
This page took 0.166836 seconds and 4 git commands to generate.