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