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