GDB (xrefs)
Loading...
Searching...
No Matches
mips-sde-tdep.c
Go to the documentation of this file.
1/* Target-dependent code for SDE on MIPS processors.
2
3 Copyright (C) 2014-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 "osabi.h"
22#include "elf-bfd.h"
23#include "symtab.h"
24
25#include "frame.h"
26#include "frame-unwind.h"
27#include "frame-base.h"
28#include "trad-frame.h"
29
30#include "mips-tdep.h"
31
32/* Fill in the register cache *THIS_CACHE for THIS_FRAME for use
33 in the SDE frame unwinder. */
34
35static struct trad_frame_cache *
37{
38 struct gdbarch *gdbarch = get_frame_arch (this_frame);
39 const struct mips_regnum *regs = mips_regnum (gdbarch);
40 const int sizeof_reg_t = mips_abi_regsize (gdbarch);
41 enum mips_abi abi = mips_abi (gdbarch);
42 struct trad_frame_cache *cache;
43 CORE_ADDR xcpt_frame;
44 CORE_ADDR start_addr;
45 CORE_ADDR stack_addr;
46 CORE_ADDR pc;
47 int i;
48
49 if (*this_cache != NULL)
50 return (struct trad_frame_cache *) *this_cache;
52 *this_cache = cache;
53
54 /* The previous registers are held in struct xcptcontext
55 which is at $sp+offs
56
57 struct xcptcontext {
58 reg_t sr; CP0 Status
59 reg_t cr; CP0 Cause
60 reg_t epc; CP0 EPC
61 reg_t vaddr; CP0 BadVAddr
62 reg_t regs[32]; General registers
63 reg_t mdlo; LO
64 reg_t mdhi; HI
65 reg_t mdex; ACX
66 ...
67 };
68 */
69
72 switch (abi)
73 {
74 case MIPS_ABI_O32:
75 /* 40: XCPTCONTEXT
76 24: xcpt_gen() argspace (16 bytes)
77 16: _xcptcall() saved ra, rounded up ( 8 bytes)
78 00: _xcptcall() argspace (16 bytes) */
79 xcpt_frame = stack_addr + 40;
80 break;
81 case MIPS_ABI_N32:
82 case MIPS_ABI_N64:
83 default: /* Wild guess. */
84 /* 16: XCPTCONTEXT
85 16: xcpt_gen() argspace ( 0 bytes)
86 00: _xcptcall() saved ra, rounded up (16 bytes) */
87 xcpt_frame = stack_addr + 16;
88 break;
89 }
90
93 xcpt_frame + 0 * sizeof_reg_t);
96 xcpt_frame + 1 * sizeof_reg_t);
98 regs->pc + gdbarch_num_regs (gdbarch),
99 xcpt_frame + 2 * sizeof_reg_t);
102 xcpt_frame + 3 * sizeof_reg_t);
103 for (i = 0; i < MIPS_NUMREGS; i++)
106 xcpt_frame + (4 + i) * sizeof_reg_t);
108 regs->lo + gdbarch_num_regs (gdbarch),
109 xcpt_frame + 36 * sizeof_reg_t);
111 regs->hi + gdbarch_num_regs (gdbarch),
112 xcpt_frame + 37 * sizeof_reg_t);
113
115 find_pc_partial_function (pc, NULL, &start_addr, NULL);
116 trad_frame_set_id (cache, frame_id_build (start_addr, stack_addr));
117
118 return cache;
119}
120
121/* Implement the this_id function for the SDE frame unwinder. */
122
123static void
125 struct frame_id *this_id)
126{
127 struct trad_frame_cache *this_trad_cache
128 = mips_sde_frame_cache (this_frame, this_cache);
129
130 trad_frame_get_id (this_trad_cache, this_id);
131}
132
133/* Implement the prev_register function for the SDE frame unwinder. */
134
135static struct value *
137 void **this_cache,
138 int prev_regnum)
139{
140 struct trad_frame_cache *trad_cache
141 = mips_sde_frame_cache (this_frame, this_cache);
142
143 return trad_frame_get_register (trad_cache, this_frame, prev_regnum);
144}
145
146/* Implement the sniffer function for the SDE frame unwinder. */
147
148static int
151 void **this_cache)
152{
153 CORE_ADDR pc = get_frame_pc (this_frame);
154 const char *name;
155
156 find_pc_partial_function (pc, &name, NULL, NULL);
157 return (name
158 && (strcmp (name, "_xcptcall") == 0
159 || strcmp (name, "_sigtramp") == 0));
160}
161
162/* Data structure for the SDE frame unwinder. */
163
174
175/* Implement the this_base, this_locals, and this_args hooks
176 for the normal unwinder. */
177
178static CORE_ADDR
179mips_sde_frame_base_address (frame_info_ptr this_frame, void **this_cache)
180{
181 struct trad_frame_cache *this_trad_cache
182 = mips_sde_frame_cache (this_frame, this_cache);
183
184 return trad_frame_get_this_base (this_trad_cache);
185}
186
194
195static const struct frame_base *
197{
198 if (mips_sde_frame_sniffer (&mips_sde_frame_unwind, this_frame, NULL))
199 return &mips_sde_frame_base;
200 else
201 return NULL;
202}
203
204static void
206 void *obj)
207{
208 enum gdb_osabi *os_ident_ptr = (enum gdb_osabi *) obj;
209 const char *name;
210
211 name = bfd_section_name (sect);
212
213 /* The presence of a section with a ".sde" prefix is indicative
214 of an SDE binary. */
215 if (startswith (name, ".sde"))
216 *os_ident_ptr = GDB_OSABI_SDE;
217}
218
219/* OSABI sniffer for MIPS SDE. */
220
221static enum gdb_osabi
223{
224 enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
225 unsigned int elfosabi;
226
227 /* If the generic sniffer gets a hit, return and let other sniffers
228 get a crack at it. */
229 for (asection *sect : gdb_bfd_sections (abfd))
230 generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
231 if (osabi != GDB_OSABI_UNKNOWN)
232 return GDB_OSABI_UNKNOWN;
233
234 elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
235
236 if (elfosabi == ELFOSABI_NONE)
237 {
238 /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
239 file are conforming to the base specification for that machine
240 (there are no OS-specific extensions). In order to determine the
241 real OS in use we must look for OS notes that have been added.
242
243 For SDE, we simply look for sections named with .sde as prefixes. */
244 bfd_map_over_sections (abfd,
246 &osabi);
247 }
248 return osabi;
249}
250
251static void
257
259void
261{
262 gdbarch_register_osabi_sniffer (bfd_arch_mips,
263 bfd_target_elf_flavour,
265
267}
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 frame_base_append_sniffer(struct gdbarch *gdbarch, frame_base_sniffer_ftype *sniffer)
Definition frame-base.c:81
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)
LONGEST get_frame_register_signed(frame_info_ptr frame, int regnum)
Definition frame.c:1365
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
@ SIGTRAMP_FRAME
Definition frame.h:198
static gdb_bfd_section_range gdb_bfd_sections(bfd *abfd)
Definition gdb_bfd.h:234
int gdbarch_num_regs(struct gdbarch *gdbarch)
Definition gdbarch.c:1930
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition gdbarch.c:2037
static const struct frame_unwind mips_sde_frame_unwind
static struct value * mips_sde_frame_prev_register(frame_info_ptr this_frame, void **this_cache, int prev_regnum)
static enum gdb_osabi mips_sde_elf_osabi_sniffer(bfd *abfd)
static CORE_ADDR mips_sde_frame_base_address(frame_info_ptr this_frame, void **this_cache)
static void mips_sde_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static void mips_sde_frame_this_id(frame_info_ptr this_frame, void **this_cache, struct frame_id *this_id)
static const struct frame_base * mips_sde_frame_base_sniffer(frame_info_ptr this_frame)
static const struct frame_base mips_sde_frame_base
static struct trad_frame_cache * mips_sde_frame_cache(frame_info_ptr this_frame, void **this_cache)
void _initialize_mips_sde_tdep()
static void mips_sde_elf_osabi_sniff_abi_tag_sections(bfd *abfd, asection *sect, void *obj)
static int mips_sde_frame_sniffer(const struct frame_unwind *self, frame_info_ptr this_frame, void **this_cache)
const struct mips_regnum * mips_regnum(struct gdbarch *gdbarch)
Definition mips-tdep.c:228
unsigned int mips_abi_regsize(struct gdbarch *gdbarch)
Definition mips-tdep.c:309
@ MIPS_ZERO_REGNUM
Definition mips-tdep.h:135
@ MIPS_PS_REGNUM
Definition mips-tdep.h:144
@ MIPS_NUMREGS
Definition mips-tdep.h:163
mips_abi
Definition mips-tdep.h:30
@ MIPS_ABI_N32
Definition mips-tdep.h:32
@ MIPS_ABI_O32
Definition mips-tdep.h:33
@ MIPS_ABI_N64
Definition mips-tdep.h:34
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
void generic_elf_osabi_sniff_abi_tag_sections(bfd *abfd, asection *sect, enum gdb_osabi *osabi)
Definition osabi.c:461
void gdbarch_register_osabi_sniffer(enum bfd_architecture arch, enum bfd_flavour flavour, enum gdb_osabi(*sniffer_fn)(bfd *))
Definition osabi.c:220
gdb_osabi
Definition osabi.h:25
@ GDB_OSABI_SDE
Definition osabi.h:47
@ GDB_OSABI_UNKNOWN
Definition osabi.h:26
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
CORE_ADDR trad_frame_get_this_base(struct trad_frame_cache *this_trad_cache)
Definition trad-frame.c:241
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