GDB (xrefs)
Loading...
Searching...
No Matches
/tmp/gdb-13.1/gdb/sparc-obsd-tdep.c
Go to the documentation of this file.
1/* Target-dependent code for OpenBSD/sparc.
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 "frame.h"
22#include "frame-unwind.h"
23#include "gdbcore.h"
24#include "osabi.h"
25#include "regcache.h"
26#include "symtab.h"
27#include "trad-frame.h"
28#include "inferior.h"
29
30#include "obsd-tdep.h"
31#include "sparc-tdep.h"
32#include "solib-svr4.h"
33#include "bsd-uthread.h"
34#include "gdbarch.h"
35
36/* Signal trampolines. */
37
38/* The OpenBSD kernel maps the signal trampoline at some random
39 location in user space, which means that the traditional BSD way of
40 detecting it won't work.
41
42 The signal trampoline will be mapped at an address that is page
43 aligned. We recognize the signal trampoline by looking for the
44 sigreturn system call. */
45
46static const int sparc32obsd_page_size = 4096;
47
48static int
49sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
50{
51 CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
52 unsigned long insn;
53
54 if (name)
55 return 0;
56
57 /* Check for "restore %g0, SYS_sigreturn, %g1". */
58 insn = sparc_fetch_instruction (start_pc + 0xec);
59 if (insn != 0x83e82067)
60 return 0;
61
62 /* Check for "t ST_SYSCALL". */
63 insn = sparc_fetch_instruction (start_pc + 0xf4);
64 if (insn != 0x91d02000)
65 return 0;
66
67 return 1;
68}
69
70static struct sparc_frame_cache *
72 void **this_cache)
73{
74 struct sparc_frame_cache *cache;
75 CORE_ADDR addr;
76
77 if (*this_cache)
78 return (struct sparc_frame_cache *) *this_cache;
79
80 cache = sparc_frame_cache (this_frame, this_cache);
81 gdb_assert (cache == *this_cache);
82
83 /* If we couldn't find the frame's function, we're probably dealing
84 with an on-stack signal trampoline. */
85 if (cache->pc == 0)
86 {
87 cache->pc = get_frame_pc (this_frame);
88 cache->pc &= ~(sparc32obsd_page_size - 1);
89
90 /* Since we couldn't find the frame's function, the cache was
91 initialized under the assumption that we're frameless. */
94 cache->base = addr;
95 }
96
98
99 return cache;
100}
101
102static void
104 void **this_cache,
105 struct frame_id *this_id)
106{
107 struct sparc_frame_cache *cache =
108 sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
109
110 (*this_id) = frame_id_build (cache->base, cache->pc);
111}
112
113static struct value *
115 void **this_cache, int regnum)
116{
117 struct sparc_frame_cache *cache =
118 sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
119
120 return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
121}
122
123static int
125 frame_info_ptr this_frame,
126 void **this_cache)
127{
128 CORE_ADDR pc = get_frame_pc (this_frame);
129 const char *name;
130
131 find_pc_partial_function (pc, &name, NULL, NULL);
133 return 1;
134
135 return 0;
136}
138{
139 "sparc32 openbsd sigtramp",
144 NULL,
146};
147
148
149
150/* Offset wthin the thread structure where we can find %fp and %i7. */
151#define SPARC32OBSD_UTHREAD_FP_OFFSET 128
152#define SPARC32OBSD_UTHREAD_PC_OFFSET 132
153
154static void
156 int regnum, CORE_ADDR addr)
157{
158 struct gdbarch *gdbarch = regcache->arch ();
159 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
160 CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
161 gdb_byte buf[4];
162
163 /* This function calls functions that depend on the global current thread. */
164 gdb_assert (regcache->ptid () == inferior_ptid);
165
166 gdb_assert (regnum >= -1);
167
168 fp = read_memory_unsigned_integer (fp_addr, 4, byte_order);
169 if (regnum == SPARC_SP_REGNUM || regnum == -1)
170 {
171 store_unsigned_integer (buf, 4, byte_order, fp);
173
174 if (regnum == SPARC_SP_REGNUM)
175 return;
176 }
177
179 || regnum == -1)
180 {
181 CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
182
183 i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order);
184 if (regnum == SPARC32_PC_REGNUM || regnum == -1)
185 {
186 store_unsigned_integer (buf, 4, byte_order, i7 + 8);
188 }
189 if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
190 {
191 store_unsigned_integer (buf, 4, byte_order, i7 + 12);
193 }
194
196 return;
197 }
198
200}
201
202static void
204 int regnum, CORE_ADDR addr)
205{
206 struct gdbarch *gdbarch = regcache->arch ();
207 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
208 CORE_ADDR sp;
209 gdb_byte buf[4];
210
211 /* This function calls functions that depend on the global current thread. */
212 gdb_assert (regcache->ptid () == inferior_ptid);
213
214 gdb_assert (regnum >= -1);
215
216 if (regnum == SPARC_SP_REGNUM || regnum == -1)
217 {
218 CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
219
221 write_memory (fp_addr,buf, 4);
222 }
223
224 if (regnum == SPARC32_PC_REGNUM || regnum == -1)
225 {
226 CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
227
229 i7 = extract_unsigned_integer (buf, 4, byte_order) - 8;
230 write_memory_unsigned_integer (i7_addr, 4, byte_order, i7);
231
233 return;
234 }
235
237 sp = extract_unsigned_integer (buf, 4, byte_order);
239}
240
241
242static void
244{
245 /* OpenBSD/sparc is very similar to NetBSD/sparc ELF. */
247
249
251
252 /* OpenBSD provides a user-level threads implementation. */
255}
256
258void
260{
261 gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD,
263}
int regnum
Definition: aarch64-tdep.c:68
const char *const name
Definition: aarch64-tdep.c:67
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
void bsd_uthread_set_collect_uthread(struct gdbarch *gdbarch, void(*collect_uthread)(const struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:111
void bsd_uthread_set_supply_uthread(struct gdbarch *gdbarch, void(*supply_uthread)(struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:98
gdbarch * arch() const
Definition: regcache.c:230
void raw_collect(int regnum, void *buf) const override
Definition: regcache.c:1118
void raw_supply(int regnum, const void *buf) override
Definition: regcache.c:1053
ptid_t ptid() const
Definition: regcache.h:407
void write_memory(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
Definition: corefile.c:346
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
Definition: corefile.c:305
void write_memory_unsigned_integer(CORE_ADDR addr, int len, enum bfd_endian byte_order, ULONGEST value)
Definition: corefile.c:369
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition: defs.h:561
static ULONGEST extract_unsigned_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
Definition: defs.h:526
enum unwind_stop_reason default_frame_unwind_stop_reason(frame_info_ptr this_frame, void **this_cache)
Definition: frame-unwind.c:227
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:107
ULONGEST get_frame_register_unsigned(frame_info_ptr frame, int regnum)
Definition: frame.c:1351
CORE_ADDR get_frame_pc(frame_info_ptr frame)
Definition: frame.c:2592
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:713
@ SIGTRAMP_FRAME
Definition: frame.h:190
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1370
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype *skip_solib_resolver)
ptid_t inferior_ptid
Definition: infcmd.c:91
def info(c)
Definition: gdbarch.py:184
CORE_ADDR obsd_skip_solib_resolver(struct gdbarch *gdbarch, CORE_ADDR pc)
Definition: obsd-tdep.c:29
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
trad_frame_saved_reg * sparc32nbsd_sigcontext_saved_regs(frame_info_ptr this_frame)
void sparc32nbsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static struct value * sparc32obsd_sigtramp_frame_prev_register(frame_info_ptr this_frame, void **this_cache, int regnum)
void _initialize_sparc32obsd_tdep()
static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind
#define SPARC32OBSD_UTHREAD_FP_OFFSET
static void sparc32obsd_sigtramp_frame_this_id(frame_info_ptr this_frame, void **this_cache, struct frame_id *this_id)
static void sparc32obsd_supply_uthread(struct regcache *regcache, int regnum, CORE_ADDR addr)
static int sparc32obsd_pc_in_sigtramp(CORE_ADDR pc, const char *name)
static void sparc32obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static const int sparc32obsd_page_size
static struct sparc_frame_cache * sparc32obsd_sigtramp_frame_cache(frame_info_ptr this_frame, void **this_cache)
static void sparc32obsd_collect_uthread(const struct regcache *regcache, int regnum, CORE_ADDR addr)
#define SPARC32OBSD_UTHREAD_PC_OFFSET
static int sparc32obsd_sigtramp_frame_sniffer(const struct frame_unwind *self, frame_info_ptr this_frame, void **this_cache)
void sparc_supply_rwindow(struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1935
void sparc_record_save_insn(struct sparc_frame_cache *cache)
Definition: sparc-tdep.c:960
void sparc_collect_rwindow(const struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:2011
unsigned long sparc_fetch_instruction(CORE_ADDR pc)
Definition: sparc-tdep.c:94
@ SPARC32_NPC_REGNUM
Definition: sparc-tdep.h:156
@ SPARC32_PC_REGNUM
Definition: sparc-tdep.h:155
@ SPARC_FP_REGNUM
Definition: sparc-tdep.h:134
@ SPARC_SP_REGNUM
Definition: sparc-tdep.h:118
struct trad_frame_saved_reg * saved_regs
Definition: sparc-tdep.h:192
CORE_ADDR base
Definition: sparc-tdep.h:173
Definition: value.c:181
struct value * trad_frame_get_prev_register(frame_info_ptr this_frame, trad_frame_saved_reg this_saved_regs[], int regnum)
Definition: trad-frame.c:187