GDB (xrefs)
Loading...
Searching...
No Matches
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}
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
256
258void
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
void bsd_uthread_set_collect_uthread(struct gdbarch *gdbarch, void(*collect_uthread)(const struct regcache *, int, CORE_ADDR))
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:231
void raw_collect(int regnum, void *buf) const override
Definition regcache.c:1127
void raw_supply(int regnum, const void *buf) override
Definition regcache.c:1062
ptid_t ptid() const
Definition regcache.h:408
void write_memory(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
Definition corefile.c:347
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
Definition corefile.c:306
void write_memory_unsigned_integer(CORE_ADDR addr, int len, enum bfd_endian byte_order, ULONGEST value)
Definition corefile.c:380
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition defs.h:515
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
@ SIGTRAMP_FRAME
Definition frame.h:198
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition gdbarch.c:1396
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype *skip_solib_resolver)
ptid_t inferior_ptid
Definition infcmd.c:74
info(Component c)
Definition gdbarch.py:41
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)
struct sparc_frame_cache * sparc_frame_cache(frame_info_ptr this_frame, void **this_cache)
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)
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
Definition value.h:130
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