1b725ae77Skettenis /* Target-dependent code for NetBSD/amd64.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 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 "arch-utils.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "gdbcore.h"
26b725ae77Skettenis #include "osabi.h"
27*11efff7fSkettenis #include "symtab.h"
28b725ae77Skettenis
29b725ae77Skettenis #include "gdb_assert.h"
30b725ae77Skettenis
31b725ae77Skettenis #include "amd64-tdep.h"
32b725ae77Skettenis #include "nbsd-tdep.h"
33b725ae77Skettenis #include "solib-svr4.h"
34b725ae77Skettenis
35b725ae77Skettenis /* Support for signal handlers. */
36b725ae77Skettenis
37*11efff7fSkettenis /* Return whether the frame preceding NEXT_FRAME corresponds to a
38*11efff7fSkettenis NetBSD sigtramp routine. */
39*11efff7fSkettenis
40*11efff7fSkettenis static int
amd64nbsd_sigtramp_p(struct frame_info * next_frame)41*11efff7fSkettenis amd64nbsd_sigtramp_p (struct frame_info *next_frame)
42*11efff7fSkettenis {
43*11efff7fSkettenis CORE_ADDR pc = frame_pc_unwind (next_frame);
44*11efff7fSkettenis char *name;
45*11efff7fSkettenis
46*11efff7fSkettenis find_pc_partial_function (pc, &name, NULL, NULL);
47*11efff7fSkettenis return nbsd_pc_in_sigtramp (pc, name);
48*11efff7fSkettenis }
49*11efff7fSkettenis
50*11efff7fSkettenis /* Assuming NEXT_FRAME is preceded by a frame corresponding to a
51*11efff7fSkettenis NetBSD sigtramp routine, return the address of the associated
52*11efff7fSkettenis mcontext structure. */
53b725ae77Skettenis
54b725ae77Skettenis static CORE_ADDR
amd64nbsd_mcontext_addr(struct frame_info * next_frame)55*11efff7fSkettenis amd64nbsd_mcontext_addr (struct frame_info *next_frame)
56b725ae77Skettenis {
57*11efff7fSkettenis CORE_ADDR addr;
58b725ae77Skettenis
59*11efff7fSkettenis /* The register %r15 points at `struct ucontext' upon entry of a
60b725ae77Skettenis signal trampoline. */
61*11efff7fSkettenis addr = frame_unwind_register_unsigned (next_frame, AMD64_R15_REGNUM);
62*11efff7fSkettenis
63*11efff7fSkettenis /* The mcontext structure lives as offset 56 in `struct ucontext'. */
64*11efff7fSkettenis return addr + 56;
65b725ae77Skettenis }
66b725ae77Skettenis
67b725ae77Skettenis /* NetBSD 2.0 or later. */
68b725ae77Skettenis
69b725ae77Skettenis /* Mapping between the general-purpose registers in `struct reg'
70b725ae77Skettenis format and GDB's register cache layout. */
71b725ae77Skettenis
72b725ae77Skettenis /* From <machine/reg.h>. */
73b725ae77Skettenis int amd64nbsd_r_reg_offset[] =
74b725ae77Skettenis {
75b725ae77Skettenis 14 * 8, /* %rax */
76b725ae77Skettenis 13 * 8, /* %rbx */
77b725ae77Skettenis 3 * 8, /* %rcx */
78b725ae77Skettenis 2 * 8, /* %rdx */
79b725ae77Skettenis 1 * 8, /* %rsi */
80b725ae77Skettenis 0 * 8, /* %rdi */
81b725ae77Skettenis 12 * 8, /* %rbp */
82b725ae77Skettenis 24 * 8, /* %rsp */
83b725ae77Skettenis 4 * 8, /* %r8 .. */
84b725ae77Skettenis 5 * 8,
85b725ae77Skettenis 6 * 8,
86b725ae77Skettenis 7 * 8,
87b725ae77Skettenis 8 * 8,
88b725ae77Skettenis 9 * 8,
89b725ae77Skettenis 10 * 8,
90b725ae77Skettenis 11 * 8, /* ... %r15 */
91b725ae77Skettenis 21 * 8, /* %rip */
92b725ae77Skettenis 23 * 8, /* %eflags */
93b725ae77Skettenis 22 * 8, /* %cs */
94b725ae77Skettenis 25 * 8, /* %ss */
95b725ae77Skettenis 18 * 8, /* %ds */
96b725ae77Skettenis 17 * 8, /* %es */
97b725ae77Skettenis 16 * 8, /* %fs */
98b725ae77Skettenis 15 * 8 /* %gs */
99b725ae77Skettenis };
100b725ae77Skettenis
101b725ae77Skettenis static void
amd64nbsd_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)102b725ae77Skettenis amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
103b725ae77Skettenis {
104b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
105b725ae77Skettenis
106b725ae77Skettenis /* Initialize general-purpose register set details first. */
107b725ae77Skettenis tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
108b725ae77Skettenis tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
109b725ae77Skettenis tdep->sizeof_gregset = 26 * 8;
110b725ae77Skettenis
111b725ae77Skettenis amd64_init_abi (info, gdbarch);
112b725ae77Skettenis
113b725ae77Skettenis tdep->jb_pc_offset = 7 * 8;
114b725ae77Skettenis
115b725ae77Skettenis /* NetBSD has its own convention for signal trampolines. */
116*11efff7fSkettenis tdep->sigtramp_p = amd64nbsd_sigtramp_p;
117*11efff7fSkettenis tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
118*11efff7fSkettenis tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
119b725ae77Skettenis tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
120b725ae77Skettenis
121b725ae77Skettenis /* NetBSD uses SVR4-style shared libraries. */
122b725ae77Skettenis set_solib_svr4_fetch_link_map_offsets
123b725ae77Skettenis (gdbarch, svr4_lp64_fetch_link_map_offsets);
124b725ae77Skettenis }
125b725ae77Skettenis
126b725ae77Skettenis
127b725ae77Skettenis /* Provide a prototype to silence -Wmissing-prototypes. */
128b725ae77Skettenis void _initialize_amd64nbsd_tdep (void);
129b725ae77Skettenis
130b725ae77Skettenis void
_initialize_amd64nbsd_ndep(void)131b725ae77Skettenis _initialize_amd64nbsd_ndep (void)
132b725ae77Skettenis {
133b725ae77Skettenis /* The NetBSD/amd64 native dependent code makes this assumption. */
134b725ae77Skettenis gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
135b725ae77Skettenis
136b725ae77Skettenis gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
137b725ae77Skettenis GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi);
138b725ae77Skettenis }
139