Constify 'la_name' in struct language_defn
[deliverable/binutils-gdb.git] / gdb / i386obsd-tdep.c
CommitLineData
005328e3 1/* Target-dependent code for OpenBSD/i386.
67457012 2
28e7fd62 3 Copyright (C) 1988-2013 Free Software Foundation, Inc.
005328e3
MK
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
005328e3
MK
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
005328e3
MK
19
20#include "defs.h"
21#include "arch-utils.h"
911bc6ee 22#include "frame.h"
508fbfea 23#include "frame-unwind.h"
005328e3
MK
24#include "gdbcore.h"
25#include "regcache.h"
67457012 26#include "regset.h"
911bc6ee
MK
27#include "symtab.h"
28#include "objfiles.h"
4be87837 29#include "osabi.h"
5d93ae8c 30#include "target.h"
508fbfea 31#include "trad-frame.h"
005328e3 32
67457012
MK
33#include "gdb_assert.h"
34#include "gdb_string.h"
35
005328e3
MK
36#include "i386-tdep.h"
37#include "i387-tdep.h"
60a6eeb6 38#include "solib-svr4.h"
a28109e0 39#include "bsd-uthread.h"
005328e3 40
5d93ae8c
MK
41/* Support for signal handlers. */
42
43/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
44 in virtual memory. The randomness makes it somewhat tricky to
45 detect it, but fortunately we can rely on the fact that the start
3ed85247
MK
46 of the sigtramp routine is page-aligned. We recognize the
47 trampoline by looking for the code that invokes the sigreturn
48 system call. The offset where we can find that code varies from
49 release to release.
50
51 By the way, the mapping mentioned above is read-only, so you cannot
52 place a breakpoint in the signal trampoline. */
5d93ae8c
MK
53
54/* Default page size. */
55static const int i386obsd_page_size = 4096;
56
3ed85247
MK
57/* Offset for sigreturn(2). */
58static const int i386obsd_sigreturn_offset[] = {
59 0x0a, /* OpenBSD 3.2 */
60 0x14, /* OpenBSD 3.6 */
61 0x3a, /* OpenBSD 3.8 */
62 -1
63};
64
10458914
DJ
65/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
66 routine. */
5d93ae8c
MK
67
68static int
10458914 69i386obsd_sigtramp_p (struct frame_info *this_frame)
5d93ae8c 70{
10458914 71 CORE_ADDR pc = get_frame_pc (this_frame);
5d93ae8c 72 CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
3ed85247 73 /* The call sequence invoking sigreturn(2). */
63c0089f 74 const gdb_byte sigreturn[] =
5d93ae8c
MK
75 {
76 0xb8,
77 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */
78 0xcd, 0x80 /* int $0x80 */
79 };
c822af0c 80 size_t buflen = sizeof sigreturn;
3ed85247 81 const int *offset;
63c0089f 82 gdb_byte *buf;
2c02bd72 83 const char *name;
5d93ae8c 84
911bc6ee
MK
85 /* If the function has a valid symbol name, it isn't a
86 trampoline. */
87 find_pc_partial_function (pc, &name, NULL, NULL);
88 if (name != NULL)
89 return 0;
90
91 /* If the function lives in a valid section (even without a starting
92 point) it isn't a trampoline. */
93 if (find_pc_section (pc) != NULL)
5d93ae8c
MK
94 return 0;
95
9c8e3411 96 /* Allocate buffer. */
c822af0c 97 buf = alloca (buflen);
9c8e3411 98
3ed85247
MK
99 /* Loop over all offsets. */
100 for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++)
101 {
102 /* If we can't read the instructions, return zero. */
10458914 103 if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
3ed85247
MK
104 buf, buflen))
105 return 0;
106
107 /* Check for sigreturn(2). */
108 if (memcmp (buf, sigreturn, buflen) == 0)
109 return 1;
110 }
9c8e3411 111
911bc6ee 112 return 0;
5d93ae8c
MK
113}
114\f
115/* Mapping between the general-purpose registers in `struct reg'
116 format and GDB's register cache layout. */
117
67457012
MK
118/* From <machine/reg.h>. */
119static int i386obsd_r_reg_offset[] =
120{
121 0 * 4, /* %eax */
122 1 * 4, /* %ecx */
123 2 * 4, /* %edx */
124 3 * 4, /* %ebx */
125 4 * 4, /* %esp */
126 5 * 4, /* %ebp */
127 6 * 4, /* %esi */
128 7 * 4, /* %edi */
129 8 * 4, /* %eip */
130 9 * 4, /* %eflags */
131 10 * 4, /* %cs */
132 11 * 4, /* %ss */
133 12 * 4, /* %ds */
134 13 * 4, /* %es */
135 14 * 4, /* %fs */
136 15 * 4 /* %gs */
137};
005328e3
MK
138
139static void
67457012
MK
140i386obsd_aout_supply_regset (const struct regset *regset,
141 struct regcache *regcache, int regnum,
142 const void *regs, size_t len)
005328e3 143{
9ea75c57 144 const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
3ed85247 145 const gdb_byte *gregs = regs;
67457012
MK
146
147 gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
005328e3 148
67457012 149 i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
3ed85247 150 i387_supply_fsave (regcache, regnum, gregs + tdep->sizeof_gregset);
005328e3
MK
151}
152
49cfa46f 153static const struct regset *
67457012
MK
154i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch,
155 const char *sect_name,
156 size_t sect_size)
005328e3 157{
67457012 158 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
005328e3 159
67457012
MK
160 /* OpenBSD a.out core dumps don't use seperate register sets for the
161 general-purpose and floating-point registers. */
005328e3 162
67457012
MK
163 if (strcmp (sect_name, ".reg") == 0
164 && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
005328e3 165 {
67457012 166 if (tdep->gregset == NULL)
9ea75c57
MK
167 tdep->gregset =
168 regset_alloc (gdbarch, i386obsd_aout_supply_regset, NULL);
67457012 169 return tdep->gregset;
005328e3
MK
170 }
171
67457012 172 return NULL;
005328e3 173}
005328e3
MK
174\f
175
5d93ae8c
MK
176/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
177CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
178CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
005328e3
MK
179
180/* From <machine/signal.h>. */
a3386186
MK
181int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
182{
183 10 * 4, /* %eax */
184 9 * 4, /* %ecx */
185 8 * 4, /* %edx */
186 7 * 4, /* %ebx */
187 14 * 4, /* %esp */
188 6 * 4, /* %ebp */
189 5 * 4, /* %esi */
190 4 * 4, /* %edi */
191 11 * 4, /* %eip */
192 13 * 4, /* %eflags */
193 12 * 4, /* %cs */
194 15 * 4, /* %ss */
195 3 * 4, /* %ds */
196 2 * 4, /* %es */
197 1 * 4, /* %fs */
198 0 * 4 /* %gs */
199};
005328e3 200
a28109e0
MK
201/* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */
202static int i386obsd_uthread_reg_offset[] =
203{
204 11 * 4, /* %eax */
205 10 * 4, /* %ecx */
206 9 * 4, /* %edx */
207 8 * 4, /* %ebx */
208 -1, /* %esp */
209 6 * 4, /* %ebp */
210 5 * 4, /* %esi */
211 4 * 4, /* %edi */
212 12 * 4, /* %eip */
213 -1, /* %eflags */
214 13 * 4, /* %cs */
215 -1, /* %ss */
216 3 * 4, /* %ds */
217 2 * 4, /* %es */
218 1 * 4, /* %fs */
219 0 * 4 /* %gs */
220};
221
222/* Offset within the thread structure where we can find the saved
223 stack pointer (%esp). */
224#define I386OBSD_UTHREAD_ESP_OFFSET 176
225
226static void
227i386obsd_supply_uthread (struct regcache *regcache,
228 int regnum, CORE_ADDR addr)
229{
e17a4113
UW
230 struct gdbarch *gdbarch = get_regcache_arch (regcache);
231 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
a28109e0
MK
232 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
233 CORE_ADDR sp = 0;
63c0089f 234 gdb_byte buf[4];
a28109e0
MK
235 int i;
236
237 gdb_assert (regnum >= -1);
238
239 if (regnum == -1 || regnum == I386_ESP_REGNUM)
240 {
241 int offset;
242
243 /* Fetch stack pointer from thread structure. */
e17a4113 244 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
a28109e0
MK
245
246 /* Adjust the stack pointer such that it looks as if we just
247 returned from _thread_machdep_switch. */
248 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
e17a4113 249 store_unsigned_integer (buf, 4, byte_order, sp + offset);
a28109e0
MK
250 regcache_raw_supply (regcache, I386_ESP_REGNUM, buf);
251 }
252
253 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
254 {
255 if (i386obsd_uthread_reg_offset[i] != -1
256 && (regnum == -1 || regnum == i))
257 {
258 /* Fetch stack pointer from thread structure (if we didn't
259 do so already). */
260 if (sp == 0)
e17a4113 261 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
a28109e0
MK
262
263 /* Read the saved register from the stack frame. */
264 read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
265 regcache_raw_supply (regcache, i, buf);
266 }
267 }
a28109e0
MK
268}
269
270static void
271i386obsd_collect_uthread (const struct regcache *regcache,
272 int regnum, CORE_ADDR addr)
273{
e17a4113
UW
274 struct gdbarch *gdbarch = get_regcache_arch (regcache);
275 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
a28109e0
MK
276 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
277 CORE_ADDR sp = 0;
63c0089f 278 gdb_byte buf[4];
a28109e0
MK
279 int i;
280
281 gdb_assert (regnum >= -1);
282
283 if (regnum == -1 || regnum == I386_ESP_REGNUM)
284 {
285 int offset;
286
287 /* Calculate the stack pointer (frame pointer) that will be
288 stored into the thread structure. */
289 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
290 regcache_raw_collect (regcache, I386_ESP_REGNUM, buf);
e17a4113 291 sp = extract_unsigned_integer (buf, 4, byte_order) - offset;
a28109e0
MK
292
293 /* Store the stack pointer. */
e17a4113 294 write_memory_unsigned_integer (sp_addr, 4, byte_order, sp);
a28109e0
MK
295
296 /* The stack pointer was (potentially) modified. Make sure we
297 build a proper stack frame. */
298 regnum = -1;
299 }
300
301 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
302 {
303 if (i386obsd_uthread_reg_offset[i] != -1
304 && (regnum == -1 || regnum == i))
305 {
306 /* Fetch stack pointer from thread structure (if we didn't
307 calculate it already). */
308 if (sp == 0)
e17a4113 309 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
a28109e0
MK
310
311 /* Write the register into the stack frame. */
312 regcache_raw_collect (regcache, i, buf);
313 write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
314 }
315 }
316}
508fbfea
MK
317\f
318/* Kernel debugging support. */
319
320/* From <machine/frame.h>. Note that %esp and %ess are only saved in
321 a trap frame when entering the kernel from user space. */
322static int i386obsd_tf_reg_offset[] =
323{
324 10 * 4, /* %eax */
325 9 * 4, /* %ecx */
326 8 * 4, /* %edx */
327 7 * 4, /* %ebx */
328 -1, /* %esp */
329 6 * 4, /* %ebp */
330 5 * 4, /* %esi */
331 4 * 4, /* %edi */
332 13 * 4, /* %eip */
333 15 * 4, /* %eflags */
334 14 * 4, /* %cs */
335 -1, /* %ss */
336 3 * 4, /* %ds */
337 2 * 4, /* %es */
338 0 * 4, /* %fs */
339 1 * 4 /* %gs */
340};
341
342static struct trad_frame_cache *
10458914 343i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
508fbfea 344{
e17a4113
UW
345 struct gdbarch *gdbarch = get_frame_arch (this_frame);
346 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
508fbfea
MK
347 struct trad_frame_cache *cache;
348 CORE_ADDR func, sp, addr;
349 ULONGEST cs;
2c02bd72 350 const char *name;
508fbfea
MK
351 int i;
352
353 if (*this_cache)
354 return *this_cache;
355
10458914 356 cache = trad_frame_cache_zalloc (this_frame);
508fbfea
MK
357 *this_cache = cache;
358
10458914
DJ
359 func = get_frame_func (this_frame);
360 sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
7238f002
MK
361
362 find_pc_partial_function (func, &name, NULL, NULL);
6d566cff 363 if (name && strncmp (name, "Xintr", 5) == 0)
7238f002
MK
364 addr = sp + 8; /* It's an interrupt frame. */
365 else
366 addr = sp;
367
508fbfea
MK
368 for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++)
369 if (i386obsd_tf_reg_offset[i] != -1)
7238f002 370 trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]);
508fbfea
MK
371
372 /* Read %cs from trap frame. */
7238f002 373 addr += i386obsd_tf_reg_offset[I386_CS_REGNUM];
e17a4113 374 cs = read_memory_unsigned_integer (addr, 4, byte_order);
508fbfea
MK
375 if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
376 {
6d566cff 377 /* Trap from user space; terminate backtrace. */
005ca36a 378 trad_frame_set_id (cache, outer_frame_id);
508fbfea
MK
379 }
380 else
381 {
382 /* Construct the frame ID using the function start. */
383 trad_frame_set_id (cache, frame_id_build (sp + 8, func));
384 }
385
386 return cache;
387}
388
389static void
10458914 390i386obsd_trapframe_this_id (struct frame_info *this_frame,
508fbfea
MK
391 void **this_cache, struct frame_id *this_id)
392{
393 struct trad_frame_cache *cache =
10458914 394 i386obsd_trapframe_cache (this_frame, this_cache);
508fbfea
MK
395
396 trad_frame_get_id (cache, this_id);
397}
398
10458914
DJ
399static struct value *
400i386obsd_trapframe_prev_register (struct frame_info *this_frame,
401 void **this_cache, int regnum)
508fbfea
MK
402{
403 struct trad_frame_cache *cache =
10458914 404 i386obsd_trapframe_cache (this_frame, this_cache);
508fbfea 405
10458914 406 return trad_frame_get_register (cache, this_frame, regnum);
508fbfea
MK
407}
408
7238f002
MK
409static int
410i386obsd_trapframe_sniffer (const struct frame_unwind *self,
10458914 411 struct frame_info *this_frame,
7238f002 412 void **this_prologue_cache)
508fbfea
MK
413{
414 ULONGEST cs;
2c02bd72 415 const char *name;
508fbfea 416
e5cc6d11 417 /* Check Current Privilege Level and bail out if we're not executing
6d566cff 418 in kernel space. */
10458914 419 cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM);
508fbfea 420 if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
6d566cff 421 return 0;
508fbfea 422
10458914 423 find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
3597fb82
MK
424 return (name && (strcmp (name, "calltrap") == 0
425 || strcmp (name, "syscall1") == 0
426 || strncmp (name, "Xintr", 5) == 0
427 || strncmp (name, "Xsoft", 5) == 0));
508fbfea 428}
7238f002
MK
429
430static const struct frame_unwind i386obsd_trapframe_unwind = {
431 /* FIXME: kettenis/20051219: This really is more like an interrupt
432 frame, but SIGTRAMP_FRAME would print <signal handler called>,
433 which really is not what we want here. */
434 NORMAL_FRAME,
8fbca658 435 default_frame_unwind_stop_reason,
7238f002
MK
436 i386obsd_trapframe_this_id,
437 i386obsd_trapframe_prev_register,
438 NULL,
439 i386obsd_trapframe_sniffer
440};
508fbfea 441\f
a28109e0 442
005328e3
MK
443static void
444i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
445{
446 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
447
448 /* Obviously OpenBSD is BSD-based. */
449 i386bsd_init_abi (info, gdbarch);
450
67457012
MK
451 /* OpenBSD has a different `struct reg'. */
452 tdep->gregset_reg_offset = i386obsd_r_reg_offset;
453 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
454 tdep->sizeof_gregset = 16 * 4;
455
005328e3
MK
456 /* OpenBSD uses -freg-struct-return by default. */
457 tdep->struct_return = reg_struct_return;
458
459 /* OpenBSD uses a different memory layout. */
5d93ae8c
MK
460 tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
461 tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
911bc6ee 462 tdep->sigtramp_p = i386obsd_sigtramp_p;
005328e3
MK
463
464 /* OpenBSD has a `struct sigcontext' that's different from the
f2e7c15d 465 original 4.3 BSD. */
a3386186 466 tdep->sc_reg_offset = i386obsd_sc_reg_offset;
67457012 467 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
a28109e0
MK
468
469 /* OpenBSD provides a user-level threads implementation. */
470 bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread);
471 bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread);
508fbfea
MK
472
473 /* Unwind kernel trap frames correctly. */
7238f002 474 frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
005328e3 475}
60a6eeb6
MK
476
477/* OpenBSD a.out. */
478
479static void
480i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
481{
482 i386obsd_init_abi (info, gdbarch);
483
484 /* OpenBSD a.out has a single register set. */
485 set_gdbarch_regset_from_core_section
486 (gdbarch, i386obsd_aout_regset_from_core_section);
487}
488
489/* OpenBSD ELF. */
490
491static void
492i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
493{
494 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
495
496 /* It's still OpenBSD. */
497 i386obsd_init_abi (info, gdbarch);
498
499 /* But ELF-based. */
500 i386_elf_init_abi (info, gdbarch);
501
502 /* OpenBSD ELF uses SVR4-style shared libraries. */
60a6eeb6
MK
503 set_solib_svr4_fetch_link_map_offsets
504 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
505}
67457012
MK
506\f
507
508/* Provide a prototype to silence -Wmissing-prototypes. */
509void _initialize_i386obsd_tdep (void);
005328e3
MK
510
511void
512_initialize_i386obsd_tdep (void)
513{
005328e3
MK
514 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are
515 indistingushable from NetBSD/i386 a.out binaries, building a GDB
516 that should support both these targets will probably not work as
517 expected. */
518#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
519
05816f70 520 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT,
60a6eeb6
MK
521 i386obsd_aout_init_abi);
522 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF,
523 i386obsd_elf_init_abi);
005328e3 524}
This page took 0.86754 seconds and 4 git commands to generate.