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