alpha-obsd-tdep.c revision 1.1 1 1.1 christos /* Target-dependent code for OpenBSD/alpha.
2 1.1 christos
3 1.1 christos Copyright (C) 2006-2017 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "defs.h"
21 1.1 christos #include "frame.h"
22 1.1 christos #include "gdbcore.h"
23 1.1 christos #include "osabi.h"
24 1.1 christos
25 1.1 christos #include "obsd-tdep.h"
26 1.1 christos #include "alpha-tdep.h"
27 1.1 christos #include "alpha-bsd-tdep.h"
28 1.1 christos #include "solib-svr4.h"
29 1.1 christos
30 1.1 christos /* Signal trampolines. */
31 1.1 christos
32 1.1 christos /* The OpenBSD kernel maps the signal trampoline at some random
33 1.1 christos location in user space, which means that the traditional BSD way of
34 1.1 christos detecting it won't work.
35 1.1 christos
36 1.1 christos The signal trampoline will be mapped at an address that is page
37 1.1 christos aligned. We recognize the signal trampoline by looking for the
38 1.1 christos sigreturn system call. */
39 1.1 christos
40 1.1 christos static const int alphaobsd_page_size = 8192;
41 1.1 christos
42 1.1 christos static LONGEST
43 1.1 christos alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
44 1.1 christos {
45 1.1 christos return (pc & (alphaobsd_page_size - 1));
46 1.1 christos }
47 1.1 christos
48 1.1 christos static int
49 1.1 christos alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
50 1.1 christos CORE_ADDR pc, const char *name)
51 1.1 christos {
52 1.1 christos CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1));
53 1.1 christos unsigned insn;
54 1.1 christos
55 1.1 christos if (name)
56 1.1 christos return 0;
57 1.1 christos
58 1.1 christos /* Check for "". */
59 1.1 christos insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE);
60 1.1 christos if (insn != 0x201f0067)
61 1.1 christos return 0;
62 1.1 christos
63 1.1 christos /* Check for "". */
64 1.1 christos insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE);
65 1.1 christos if (insn != 0x00000083)
66 1.1 christos return 0;
67 1.1 christos
68 1.1 christos return 1;
69 1.1 christos }
70 1.1 christos
71 1.1 christos static CORE_ADDR
72 1.1 christos alphaobsd_sigcontext_addr (struct frame_info *this_frame)
73 1.1 christos {
74 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame);
75 1.1 christos CORE_ADDR pc = get_frame_pc (this_frame);
76 1.1 christos
77 1.1 christos if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
78 1.1 christos {
79 1.1 christos /* On entry, a pointer the `struct sigcontext' is passed in %a2. */
80 1.1 christos return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
81 1.1 christos }
82 1.1 christos else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
83 1.1 christos {
84 1.1 christos /* It is stored on the stack Before calling the signal handler. */
85 1.1 christos CORE_ADDR sp;
86 1.1 christos sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
87 1.1 christos return get_frame_memory_unsigned (this_frame, sp, 8);
88 1.1 christos }
89 1.1 christos else
90 1.1 christos {
91 1.1 christos /* It is reloaded into %a0 for the sigreturn(2) call. */
92 1.1 christos return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
93 1.1 christos }
94 1.1 christos }
95 1.1 christos
96 1.1 christos
98 1.1 christos static void
99 1.1 christos alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
100 1.1 christos {
101 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
102 1.1 christos
103 1.1 christos /* Hook into the DWARF CFI frame unwinder. */
104 1.1 christos alpha_dwarf2_init_abi (info, gdbarch);
105 1.1 christos
106 1.1 christos /* Hook into the MDEBUG frame unwinder. */
107 1.1 christos alpha_mdebug_init_abi (info, gdbarch);
108 1.1 christos
109 1.1 christos /* OpenBSD/alpha 3.0 and earlier does not provide single step
110 1.1 christos support via ptrace(2); use software single-stepping for now. */
111 1.1 christos set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
112 1.1 christos
113 1.1 christos /* OpenBSD/alpha has SVR4-style shared libraries. */
114 1.1 christos set_solib_svr4_fetch_link_map_offsets
115 1.1 christos (gdbarch, svr4_lp64_fetch_link_map_offsets);
116 1.1 christos set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
117 1.1 christos
118 1.1 christos tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
119 1.1 christos tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp;
120 1.1 christos tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
121 1.1 christos
122 1.1 christos tdep->jb_pc = 2;
123 1.1 christos tdep->jb_elt_size = 8;
124 1.1 christos
125 1.1 christos set_gdbarch_iterate_over_regset_sections
126 1.1 christos (gdbarch, alphanbsd_iterate_over_regset_sections);
127 1.1 christos }
128 1.1 christos
129 1.1 christos
131 1.1 christos /* Provide a prototype to silence -Wmissing-prototypes. */
132 1.1 christos void _initialize_alphaobsd_tdep (void);
133 1.1 christos
134 1.1 christos void
135 1.1 christos _initialize_alphaobsd_tdep (void)
136 1.1 christos {
137 1.1 christos gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD,
138 alphaobsd_init_abi);
139 }
140