GDB (xrefs)

/tmp/gdb-8.1/gdb/ppc-obsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for OpenBSD/powerpc.
2
3 Copyright (C) 2004-2018 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>. */
36 struct ppc_reg_offsets ppcobsd_reg_offsets;
37 struct ppc_reg_offsets ppcobsd_fpreg_offsets;
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
46 void
47 ppcobsd_supply_gregset (const struct regset *regset,
48 struct regcache *regcache, int regnum,
49 const void *gregs, size_t len)
50 {
51 ppc_supply_gregset (regset, regcache, regnum, gregs, len);
52 ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
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
60 void
61 ppcobsd_collect_gregset (const struct regset *regset,
62 const struct regcache *regcache, int regnum,
63 void *gregs, size_t len)
64 {
65 ppc_collect_gregset (regset, regcache, regnum, gregs, len);
66 ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
67 }
68
69 /* OpenBSD/powerpc register set. */
70
71 const struct regset ppcobsd_gregset =
72 {
73 &ppcobsd_reg_offsets,
74 ppcobsd_supply_gregset
75 };
76
77 const struct regset ppcobsd_fpregset =
78 {
79 &ppcobsd_fpreg_offsets,
80 ppc_supply_fpregset
81 };
82
83 /* Iterate over core file register note sections. */
84
85 static void
86 ppcobsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
87 iterate_over_regset_sections_cb *cb,
88 void *cb_data,
89 const struct regcache *regcache)
90 {
91 cb (".reg", 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. */
109 static const int ppcobsd_page_size = 4096;
110
111 /* Offset for sigreturn(2). */
112 static const int ppcobsd_sigreturn_offset[] = {
113 0x98, /* OpenBSD 3.8 */
114 0x0c, /* OpenBSD 3.2 */
115 -1
116 };
117
118 static int
119 ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
120 struct frame_info *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". */
149 insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
150 PPC_INSN_SIZE, byte_order);
151 if (insn != 0x44000002)
152 continue;
153
154 return 1;
155 }
156
157 return 0;
158 }
159
160 static struct trad_frame_cache *
161 ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
162 {
163 struct gdbarch *gdbarch = get_frame_arch (this_frame);
164 struct gdbarch_tdep *tdep = 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
175 cache = trad_frame_cache_zalloc (this_frame);
176 *this_cache = cache;
177
178 func = get_frame_pc (this_frame);
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
189 base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
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;
204 trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
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
214 static void
215 ppcobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
216 void **this_cache, struct frame_id *this_id)
217 {
218 struct trad_frame_cache *cache =
219 ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
220
221 trad_frame_get_id (cache, this_id);
222 }
223
224 static struct value *
225 ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
226 void **this_cache, int regnum)
227 {
228 struct trad_frame_cache *cache =
229 ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
230
231 return trad_frame_get_register (cache, this_frame, regnum);
232 }
233
234 static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
235 SIGTRAMP_FRAME,
236 default_frame_unwind_stop_reason,
237 ppcobsd_sigtramp_frame_this_id,
238 ppcobsd_sigtramp_frame_prev_register,
239 NULL,
240 ppcobsd_sigtramp_frame_sniffer
241 };
242
243
244 static void
245 ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
246 {
247 /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */
248 set_gdbarch_long_double_bit (gdbarch, 64);
249 set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
250
251 /* OpenBSD currently uses a broken GCC. */
252 set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
253
254 /* OpenBSD uses SVR4-style shared libraries. */
255 set_solib_svr4_fetch_link_map_offsets
256 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
257
258 set_gdbarch_iterate_over_regset_sections
259 (gdbarch, ppcobsd_iterate_over_regset_sections);
260
261 frame_unwind_append_unwinder (gdbarch, &ppcobsd_sigtramp_frame_unwind);
262 }
263
264 void
265 _initialize_ppcobsd_tdep (void)
266 {
267 gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD,
268 ppcobsd_init_abi);
269 gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD,
270 ppcobsd_init_abi);
271
272 /* Avoid initializing the register offsets again if they were
273 already initialized by ppcobsd-nat.c. */
274 if (ppcobsd_reg_offsets.pc_offset == 0)
275 {
276 /* General-purpose registers. */
277 ppcobsd_reg_offsets.r0_offset = 0;
278 ppcobsd_reg_offsets.gpr_size = 4;
279 ppcobsd_reg_offsets.xr_size = 4;
280 ppcobsd_reg_offsets.pc_offset = 384;
281 ppcobsd_reg_offsets.ps_offset = 388;
282 ppcobsd_reg_offsets.cr_offset = 392;
283 ppcobsd_reg_offsets.lr_offset = 396;
284 ppcobsd_reg_offsets.ctr_offset = 400;
285 ppcobsd_reg_offsets.xer_offset = 404;
286 ppcobsd_reg_offsets.mq_offset = 408;
287
288 /* Floating-point registers. */
289 ppcobsd_reg_offsets.f0_offset = 128;
290 ppcobsd_reg_offsets.fpscr_offset = -1;
291
292 /* AltiVec registers. */
293 ppcobsd_reg_offsets.vr0_offset = 0;
294 ppcobsd_reg_offsets.vscr_offset = 512;
295 ppcobsd_reg_offsets.vrsave_offset = 520;
296 }
297
298 if (ppcobsd_fpreg_offsets.fpscr_offset == 0)
299 {
300 /* Floating-point registers. */
301 ppcobsd_reg_offsets.f0_offset = 0;
302 ppcobsd_reg_offsets.fpscr_offset = 256;
303 ppcobsd_reg_offsets.fpscr_size = 4;
304 }
305 }
ppc_reg_offsets::gpr_size
int gpr_size
Definition: ppc-tdep.h:89
gdbarch
Definition: gdbarch.c:127
trad_frame_set_reg_addr
void trad_frame_set_reg_addr(struct trad_frame_cache *this_trad_cache, int regnum, CORE_ADDR addr)
Definition: trad-frame.c:126
ppcobsd_sigtramp_frame_prev_register
static struct value * ppcobsd_sigtramp_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
Definition: ppc-obsd-tdep.c:225
frame_id_build
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:624
ppc_sysv_abi_broken_return_value
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)
Definition: ppc-sysv-tdep.c:1052
ppcobsd_fpreg_offsets
struct ppc_reg_offsets ppcobsd_fpreg_offsets
Definition: ppc-obsd-tdep.c:37
get_frame_pc
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2376
CORE_ADDR
bfd_vma CORE_ADDR
Definition: common-types.h:41
floatformats_ieee_double
const struct floatformat * floatformats_ieee_double[BFD_ENDIAN_UNKNOWN]
Definition: gdbtypes.c:76
ppc_reg_offsets::vscr_offset
int vscr_offset
Definition: ppc-tdep.h:106
gdbarch_tdep::ppc_lr_regnum
int ppc_lr_regnum
Definition: ppc-tdep.h:231
ppc_reg_offsets::vrsave_offset
int vrsave_offset
Definition: ppc-tdep.h:107
func
void(* func)(char *)
Definition: remote-fileio.c:1104
iterate_over_regset_sections_cb
void() iterate_over_regset_sections_cb(const char *sect_name, int size, const struct regset *regset, const char *human_name, void *cb_data)
Definition: gdbarch.h:99
ppc_reg_offsets::xer_offset
int xer_offset
Definition: ppc-tdep.h:96
ppc_supply_fpregset
void ppc_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
Definition: rs6000-tdep.c:561
ppcobsd_gregset
const struct regset ppcobsd_gregset
Definition: ppc-obsd-tdep.c:71
trad_frame_set_id
void trad_frame_set_id(struct trad_frame_cache *this_trad_cache, struct frame_id this_id)
Definition: trad-frame.c:171
ppc-tdep.h
ppcobsd_sigtramp_frame_this_id
static void ppcobsd_sigtramp_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
Definition: ppc-obsd-tdep.c:215
gdbarch_tdep
Definition: aarch64-tdep.h:55
SIGTRAMP_FRAME
Definition: frame.h:255
frame_info
Definition: frame.c:85
svr4_ilp32_fetch_link_map_offsets
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3183
ppcobsd_supply_gregset
void ppcobsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
Definition: ppc-obsd-tdep.c:47
defs.h
gdbarch_tdep::ppc_cr_regnum
int ppc_cr_regnum
Definition: ppc-tdep.h:230
gdbarch_tdep
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1491
ppcobsd_fpregset
const struct regset ppcobsd_fpregset
Definition: ppc-obsd-tdep.c:77
frame_unwind_append_unwinder
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:79
ppc_reg_offsets::fpscr_offset
int fpscr_offset
Definition: ppc-tdep.h:101
arch-utils.h
regset
Definition: regset.h:34
symtab.h
trad_frame_get_id
void trad_frame_get_id(struct trad_frame_cache *this_trad_cache, struct frame_id *this_id)
Definition: trad-frame.c:178
name
const char *const name
Definition: aarch64-tdep.c:76
ppcobsd_init_abi
static void ppcobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: ppc-obsd-tdep.c:245
ppc_collect_gregset
void ppc_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
Definition: rs6000-tdep.c:675
gdbarch_sp_regnum
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2146
trad-frame.h
ppc_reg_offsets::vr0_offset
int vr0_offset
Definition: ppc-tdep.h:105
ppc_reg_offsets::f0_offset
int f0_offset
Definition: ppc-tdep.h:100
solib-svr4.h
extract_unsigned_integer
static ULONGEST extract_unsigned_integer(const gdb_byte *addr, int len, enum bfd_endian byte_order)
Definition: defs.h:577
safe_frame_unwind_memory
int safe_frame_unwind_memory(struct frame_info *this_frame, CORE_ADDR addr, gdb_byte *buf, int len)
Definition: frame.c:2681
osabi.h
trad_frame_cache
Definition: trad-frame.c:27
regcache.h
PPC_INSN_SIZE
#define PPC_INSN_SIZE
Definition: ppc-tdep.h:343
gdbarch_tdep::ppc_gp0_regnum
int ppc_gp0_regnum
Definition: ppc-tdep.h:227
frame.h
gdbarch_byte_order
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1509
set_solib_svr4_fetch_link_map_offsets
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3137
find_pc_partial_function
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:320
frame-unwind.h
ppc_collect_fpregset
void ppc_collect_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
Definition: rs6000-tdep.c:726
ppc_reg_offsets
Definition: ppc-tdep.h:85
trad_frame_cache_zalloc
struct trad_frame_cache * trad_frame_cache_zalloc(struct frame_info *this_frame)
Definition: trad-frame.c:36
ppcobsd_reg_offsets
struct ppc_reg_offsets ppcobsd_reg_offsets
Definition: ppc-obsd-tdep.c:36
ppcobsd_sigtramp_frame_unwind
static const struct frame_unwind ppcobsd_sigtramp_frame_unwind
Definition: ppc-obsd-tdep.c:234
ppc_reg_offsets::fpscr_size
int fpscr_size
Definition: ppc-tdep.h:102
regnum
int regnum
Definition: aarch64-tdep.c:77
ppcobsd_sigtramp_frame_sniffer
static int ppcobsd_sigtramp_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
Definition: ppc-obsd-tdep.c:119
get_frame_register_unsigned
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1308
gdbarch_register_osabi
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:143
trad_frame_cache::this_frame
struct frame_info * this_frame
Definition: trad-frame.c:29
value
Definition: value.c:169
ppc_reg_offsets::mq_offset
int mq_offset
Definition: ppc-tdep.h:97
trad_frame_cache::this_id
struct frame_id this_id
Definition: trad-frame.c:32
gdb_byte
bfd_byte gdb_byte
Definition: common-types.h:38
gdbarch_tdep::ppc_ctr_regnum
int ppc_ctr_regnum
Definition: ppc-tdep.h:232
ppc_reg_offsets::xr_size
int xr_size
Definition: ppc-tdep.h:90
ppcobsd_collect_gregset
void ppcobsd_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
Definition: ppc-obsd-tdep.c:61
ppc-obsd-tdep.h
ppcobsd_page_size
static const int ppcobsd_page_size
Definition: ppc-obsd-tdep.c:109
gdbarch_tdep::wordsize
int wordsize
Definition: ppc-tdep.h:216
offset
int offset
Definition: agent.c:65
gdbarch_tdep::ppc_xer_regnum
int ppc_xer_regnum
Definition: ppc-tdep.h:233
ppc_reg_offsets::r0_offset
int r0_offset
Definition: ppc-tdep.h:88
ppc_reg_offsets::pc_offset
int pc_offset
Definition: ppc-tdep.h:91
frame_unwind
Definition: frame-unwind.h:144
_initialize_ppcobsd_tdep
void _initialize_ppcobsd_tdep(void)
Definition: ppc-obsd-tdep.c:265
ppc_reg_offsets::ctr_offset
int ctr_offset
Definition: ppc-tdep.h:95
ppc_reg_offsets::cr_offset
int cr_offset
Definition: ppc-tdep.h:93
ppcobsd_sigreturn_offset
static const int ppcobsd_sigreturn_offset[]
Definition: ppc-obsd-tdep.c:112
ppc_reg_offsets::lr_offset
int lr_offset
Definition: ppc-tdep.h:94
gdbtypes.h
default_frame_unwind_stop_reason
enum unwind_stop_reason default_frame_unwind_stop_reason(struct frame_info *this_frame, void **this_cache)
Definition: frame-unwind.c:184
ppc_reg_offsets::ps_offset
int ps_offset
Definition: ppc-tdep.h:92
regcache
Definition: regcache.h:232
gdbarch_info
Definition: gdbarch.h:1626
set_gdbarch_long_double_bit
void set_gdbarch_long_double_bit(struct gdbarch *gdbarch, int long_double_bit)
Definition: gdbarch.c:1756
set_gdbarch_return_value
void set_gdbarch_return_value(struct gdbarch *gdbarch, gdbarch_return_value_ftype return_value)
Definition: gdbarch.c:2738
gdbarch_pc_regnum
int gdbarch_pc_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2163
regset.h
set_gdbarch_long_double_format
void set_gdbarch_long_double_format(struct gdbarch *gdbarch, const struct floatformat **long_double_format)
Definition: gdbarch.c:1772
set_gdbarch_iterate_over_regset_sections
void set_gdbarch_iterate_over_regset_sections(struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype iterate_over_regset_sections)
Definition: gdbarch.c:3647
GDB_OSABI_OPENBSD
Definition: defs.h:520
trad_frame_get_register
struct value * trad_frame_get_register(struct trad_frame_cache *this_trad_cache, struct frame_info *this_frame, int regnum)
Definition: trad-frame.c:162
gdbarch::byte_order
enum bfd_endian byte_order
Definition: gdbarch.c:137
ppcobsd_sigtramp_frame_cache
static struct trad_frame_cache * ppcobsd_sigtramp_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: ppc-obsd-tdep.c:161
ppc_supply_gregset
void ppc_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
Definition: rs6000-tdep.c:511
ppc_num_gprs
Definition: ppc-tdep.h:283
ppcobsd_iterate_over_regset_sections
static void ppcobsd_iterate_over_regset_sections(struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
Definition: ppc-obsd-tdep.c:86
frame_id
Definition: frame.h:111
get_frame_arch
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2691