GDB (xrefs)
Loading...
Searching...
No Matches
ppc-obsd-tdep.c
Go to the documentation of this file.
1/* Target-dependent code for OpenBSD/powerpc.
2
3 Copyright (C) 2004-2023 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 "frame-unwind.h"
24#include "gdbtypes.h"
25#include "osabi.h"
26#include "regcache.h"
27#include "regset.h"
28#include "symtab.h"
29#include "trad-frame.h"
30
31#include "ppc-tdep.h"
32#include "ppc-obsd-tdep.h"
33#include "solib-svr4.h"
34
35/* Register offsets from <machine/reg.h>. */
38
39
40/* Core file support. */
41
42/* Supply register REGNUM in the general-purpose register set REGSET
43 from the buffer specified by GREGS and LEN to register cache
44 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
45
46void
48 struct regcache *regcache, int regnum,
49 const void *gregs, size_t len)
50{
53}
54
55/* Collect register REGNUM in the general-purpose register set
56 REGSET, from register cache REGCACHE into the buffer specified by
57 GREGS and LEN. If REGNUM is -1, do this for all registers in
58 REGSET. */
59
60void
62 const struct regcache *regcache, int regnum,
63 void *gregs, size_t len)
64{
67}
68
69/* OpenBSD/powerpc register set. */
70
76
82
83/* Iterate over core file register note sections. */
84
85static void
88 void *cb_data,
89 const struct regcache *regcache)
90{
91 cb (".reg", 412, 412, &ppcobsd_gregset, NULL, cb_data);
92}
93
94
95/* Signal trampolines. */
96
97/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
98 in virtual memory. The randomness makes it somewhat tricky to
99 detect it, but fortunately we can rely on the fact that the start
100 of the sigtramp routine is page-aligned. We recognize the
101 trampoline by looking for the code that invokes the sigreturn
102 system call. The offset where we can find that code varies from
103 release to release.
104
105 By the way, the mapping mentioned above is read-only, so you cannot
106 place a breakpoint in the signal trampoline. */
107
108/* Default page size. */
109static const int ppcobsd_page_size = 4096;
110
111/* Offset for sigreturn(2). */
112static const int ppcobsd_sigreturn_offset[] = {
113 0x98, /* OpenBSD 3.8 */
114 0x0c, /* OpenBSD 3.2 */
115 -1
116};
117
118static int
120 frame_info_ptr this_frame,
121 void **this_cache)
122{
123 struct gdbarch *gdbarch = get_frame_arch (this_frame);
124 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
125 CORE_ADDR pc = get_frame_pc (this_frame);
126 CORE_ADDR start_pc = (pc & ~(ppcobsd_page_size - 1));
127 const int *offset;
128 const char *name;
129
130 find_pc_partial_function (pc, &name, NULL, NULL);
131 if (name)
132 return 0;
133
134 for (offset = ppcobsd_sigreturn_offset; *offset != -1; offset++)
135 {
136 gdb_byte buf[2 * PPC_INSN_SIZE];
137 unsigned long insn;
138
139 if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
140 {buf, sizeof buf}))
141 continue;
142
143 /* Check for "li r0,SYS_sigreturn". */
144 insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
145 if (insn != 0x38000067)
146 continue;
147
148 /* Check for "sc". */
150 PPC_INSN_SIZE, byte_order);
151 if (insn != 0x44000002)
152 continue;
153
154 return 1;
155 }
156
157 return 0;
158}
159
160static struct trad_frame_cache *
162{
163 struct gdbarch *gdbarch = get_frame_arch (this_frame);
164 ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
165 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
166 struct trad_frame_cache *cache;
167 CORE_ADDR addr, base, func;
168 gdb_byte buf[PPC_INSN_SIZE];
169 unsigned long insn, sigcontext_offset;
170 int i;
171
172 if (*this_cache)
173 return (struct trad_frame_cache *) *this_cache;
174
176 *this_cache = cache;
177
179 func &= ~(ppcobsd_page_size - 1);
180 if (!safe_frame_unwind_memory (this_frame, func, {buf, sizeof buf}))
181 return cache;
182
183 /* Calculate the offset where we can find `struct sigcontext'. We
184 base our calculation on the amount of stack space reserved by the
185 first instruction of the signal trampoline. */
186 insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
187 sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8;
188
190 addr = base + sigcontext_offset + 2 * tdep->wordsize;
191 for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
192 {
193 int regnum = i + tdep->ppc_gp0_regnum;
194 trad_frame_set_reg_addr (cache, regnum, addr);
195 }
196 trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
197 addr += tdep->wordsize;
198 trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
199 addr += tdep->wordsize;
200 trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
201 addr += tdep->wordsize;
202 trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
203 addr += tdep->wordsize;
205 /* SRR0? */
206 addr += tdep->wordsize;
207
208 /* Construct the frame ID using the function start. */
209 trad_frame_set_id (cache, frame_id_build (base, func));
210
211 return cache;
212}
213
214static void
216 void **this_cache, struct frame_id *this_id)
217{
218 struct trad_frame_cache *cache =
220
221 trad_frame_get_id (cache, this_id);
222}
223
224static struct value *
226 void **this_cache, int regnum)
227{
228 struct trad_frame_cache *cache =
230
232}
233
243
244
245static void
247{
248 /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */
251
252 /* OpenBSD currently uses a broken GCC. */
254
255 /* OpenBSD uses SVR4-style shared libraries. */
258
261
263}
264
266void
268{
269 gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD,
271 gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD,
273
274 /* Avoid initializing the register offsets again if they were
275 already initialized by ppcobsd-nat.c. */
277 {
278 /* General-purpose registers. */
289
290 /* Floating-point registers. */
293
294 }
295
297 {
298 /* Floating-point registers. */
302 }
303}
int regnum
const char *const name
bool find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr, const struct block **block)
Definition blockframe.c:373
static ULONGEST extract_unsigned_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
Definition defs.h:480
enum unwind_stop_reason default_frame_unwind_stop_reason(frame_info_ptr this_frame, void **this_cache)
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
ULONGEST get_frame_register_unsigned(frame_info_ptr frame, int regnum)
Definition frame.c:1399
CORE_ADDR get_frame_pc(frame_info_ptr frame)
Definition frame.c:2712
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition frame.c:736
struct gdbarch * get_frame_arch(frame_info_ptr this_frame)
Definition frame.c:3027
bool safe_frame_unwind_memory(frame_info_ptr this_frame, CORE_ADDR addr, gdb::array_view< gdb_byte > buffer)
Definition frame.c:3017
@ SIGTRAMP_FRAME
Definition frame.h:198
int gdbarch_pc_regnum(struct gdbarch *gdbarch)
Definition gdbarch.c:2054
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition gdbarch.c:1396
void set_gdbarch_return_value(struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value)
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition gdbarch.c:2037
void set_gdbarch_long_double_format(struct gdbarch *gdbarch, const struct floatformat **long_double_format)
Definition gdbarch.c:1663
void set_gdbarch_long_double_bit(struct gdbarch *gdbarch, int long_double_bit)
Definition gdbarch.c:1646
void set_gdbarch_iterate_over_regset_sections(struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype *iterate_over_regset_sections)
void iterate_over_regset_sections_cb(const char *sect_name, int supply_size, int collect_size, const struct regset *regset, const char *human_name, void *cb_data)
Definition gdbarch.h:104
const struct floatformat * floatformats_ieee_double[BFD_ENDIAN_UNKNOWN]
Definition gdbtypes.c:89
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition osabi.c:146
@ GDB_OSABI_OPENBSD
Definition osabi.h:35
const struct regset ppcobsd_fpregset
static const int ppcobsd_page_size
static void ppcobsd_iterate_over_regset_sections(struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
static const int ppcobsd_sigreturn_offset[]
static void ppcobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
struct ppc_reg_offsets ppcobsd_fpreg_offsets
static struct trad_frame_cache * ppcobsd_sigtramp_frame_cache(frame_info_ptr this_frame, void **this_cache)
const struct regset ppcobsd_gregset
static void ppcobsd_sigtramp_frame_this_id(frame_info_ptr this_frame, void **this_cache, struct frame_id *this_id)
void ppcobsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
static int ppcobsd_sigtramp_frame_sniffer(const struct frame_unwind *self, frame_info_ptr this_frame, void **this_cache)
void ppcobsd_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
void _initialize_ppcobsd_tdep()
struct ppc_reg_offsets ppcobsd_reg_offsets
static struct value * ppcobsd_sigtramp_frame_prev_register(frame_info_ptr this_frame, void **this_cache, int regnum)
static const struct frame_unwind ppcobsd_sigtramp_frame_unwind
enum return_value_convention ppc_sysv_abi_broken_return_value(struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf)
void ppc_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
void ppc_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
void ppc_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
@ ppc_num_gprs
Definition ppc-tdep.h:318
void ppc_collect_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
#define PPC_INSN_SIZE
Definition ppc-tdep.h:440
void(* func)(remote_target *remote, char *)
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
struct frame_id this_id
Definition trad-frame.c:35
frame_info_ptr this_frame
Definition trad-frame.c:32
Definition value.h:130
struct trad_frame_cache * trad_frame_cache_zalloc(frame_info_ptr this_frame)
Definition trad-frame.c:39
void trad_frame_set_reg_addr(struct trad_frame_cache *this_trad_cache, int regnum, CORE_ADDR addr)
Definition trad-frame.c:110
void trad_frame_get_id(struct trad_frame_cache *this_trad_cache, struct frame_id *this_id)
Definition trad-frame.c:227
void trad_frame_set_id(struct trad_frame_cache *this_trad_cache, struct frame_id this_id)
Definition trad-frame.c:220
struct value * trad_frame_get_register(struct trad_frame_cache *this_trad_cache, frame_info_ptr this_frame, int regnum)
Definition trad-frame.c:211