Add extra files found in etc/ sub-directory to ETC_SUPPORT in src-release.sh
[binutils-gdb.git] / gdb / mips-sde-tdep.c
blob90988cdfdac0094dffe8f7eb02441823f75ee597
1 /* Target-dependent code for SDE on MIPS processors.
3 Copyright (C) 2014-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "osabi.h"
21 #include "elf-bfd.h"
22 #include "symtab.h"
24 #include "frame.h"
25 #include "frame-unwind.h"
26 #include "frame-base.h"
27 #include "trad-frame.h"
29 #include "mips-tdep.h"
31 /* Fill in the register cache *THIS_CACHE for THIS_FRAME for use
32 in the SDE frame unwinder. */
34 static struct trad_frame_cache *
35 mips_sde_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
37 struct gdbarch *gdbarch = get_frame_arch (this_frame);
38 const struct mips_regnum *regs = mips_regnum (gdbarch);
39 const int sizeof_reg_t = mips_abi_regsize (gdbarch);
40 enum mips_abi abi = mips_abi (gdbarch);
41 struct trad_frame_cache *cache;
42 CORE_ADDR xcpt_frame;
43 CORE_ADDR start_addr;
44 CORE_ADDR stack_addr;
45 CORE_ADDR pc;
46 int i;
48 if (*this_cache != NULL)
49 return (struct trad_frame_cache *) *this_cache;
50 cache = trad_frame_cache_zalloc (this_frame);
51 *this_cache = cache;
53 /* The previous registers are held in struct xcptcontext
54 which is at $sp+offs
56 struct xcptcontext {
57 reg_t sr; CP0 Status
58 reg_t cr; CP0 Cause
59 reg_t epc; CP0 EPC
60 reg_t vaddr; CP0 BadVAddr
61 reg_t regs[32]; General registers
62 reg_t mdlo; LO
63 reg_t mdhi; HI
64 reg_t mdex; ACX
65 ...
69 stack_addr = get_frame_register_signed (this_frame,
70 gdbarch_sp_regnum (gdbarch));
71 switch (abi)
73 case MIPS_ABI_O32:
74 /* 40: XCPTCONTEXT
75 24: xcpt_gen() argspace (16 bytes)
76 16: _xcptcall() saved ra, rounded up ( 8 bytes)
77 00: _xcptcall() argspace (16 bytes) */
78 xcpt_frame = stack_addr + 40;
79 break;
80 case MIPS_ABI_N32:
81 case MIPS_ABI_N64:
82 default: /* Wild guess. */
83 /* 16: XCPTCONTEXT
84 16: xcpt_gen() argspace ( 0 bytes)
85 00: _xcptcall() saved ra, rounded up (16 bytes) */
86 xcpt_frame = stack_addr + 16;
87 break;
90 trad_frame_set_reg_addr (cache,
91 MIPS_PS_REGNUM + gdbarch_num_regs (gdbarch),
92 xcpt_frame + 0 * sizeof_reg_t);
93 trad_frame_set_reg_addr (cache,
94 regs->cause + gdbarch_num_regs (gdbarch),
95 xcpt_frame + 1 * sizeof_reg_t);
96 trad_frame_set_reg_addr (cache,
97 regs->pc + gdbarch_num_regs (gdbarch),
98 xcpt_frame + 2 * sizeof_reg_t);
99 trad_frame_set_reg_addr (cache,
100 regs->badvaddr + gdbarch_num_regs (gdbarch),
101 xcpt_frame + 3 * sizeof_reg_t);
102 for (i = 0; i < MIPS_NUMREGS; i++)
103 trad_frame_set_reg_addr (cache,
104 i + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch),
105 xcpt_frame + (4 + i) * sizeof_reg_t);
106 trad_frame_set_reg_addr (cache,
107 regs->lo + gdbarch_num_regs (gdbarch),
108 xcpt_frame + 36 * sizeof_reg_t);
109 trad_frame_set_reg_addr (cache,
110 regs->hi + gdbarch_num_regs (gdbarch),
111 xcpt_frame + 37 * sizeof_reg_t);
113 pc = get_frame_pc (this_frame);
114 find_pc_partial_function (pc, NULL, &start_addr, NULL);
115 trad_frame_set_id (cache, frame_id_build (start_addr, stack_addr));
117 return cache;
120 /* Implement the this_id function for the SDE frame unwinder. */
122 static void
123 mips_sde_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
124 struct frame_id *this_id)
126 struct trad_frame_cache *this_trad_cache
127 = mips_sde_frame_cache (this_frame, this_cache);
129 trad_frame_get_id (this_trad_cache, this_id);
132 /* Implement the prev_register function for the SDE frame unwinder. */
134 static struct value *
135 mips_sde_frame_prev_register (const frame_info_ptr &this_frame,
136 void **this_cache,
137 int prev_regnum)
139 struct trad_frame_cache *trad_cache
140 = mips_sde_frame_cache (this_frame, this_cache);
142 return trad_frame_get_register (trad_cache, this_frame, prev_regnum);
145 /* Implement the sniffer function for the SDE frame unwinder. */
147 static int
148 mips_sde_frame_sniffer (const struct frame_unwind *self,
149 const frame_info_ptr &this_frame,
150 void **this_cache)
152 CORE_ADDR pc = get_frame_pc (this_frame);
153 const char *name;
155 find_pc_partial_function (pc, &name, NULL, NULL);
156 return (name
157 && (strcmp (name, "_xcptcall") == 0
158 || strcmp (name, "_sigtramp") == 0));
161 /* Data structure for the SDE frame unwinder. */
163 static const struct frame_unwind mips_sde_frame_unwind =
165 "mips sde sigtramp",
166 SIGTRAMP_FRAME,
167 default_frame_unwind_stop_reason,
168 mips_sde_frame_this_id,
169 mips_sde_frame_prev_register,
170 NULL,
171 mips_sde_frame_sniffer
174 /* Implement the this_base, this_locals, and this_args hooks
175 for the normal unwinder. */
177 static CORE_ADDR
178 mips_sde_frame_base_address (const frame_info_ptr &this_frame, void **this_cache)
180 struct trad_frame_cache *this_trad_cache
181 = mips_sde_frame_cache (this_frame, this_cache);
183 return trad_frame_get_this_base (this_trad_cache);
186 static const struct frame_base mips_sde_frame_base =
188 &mips_sde_frame_unwind,
189 mips_sde_frame_base_address,
190 mips_sde_frame_base_address,
191 mips_sde_frame_base_address
194 static const struct frame_base *
195 mips_sde_frame_base_sniffer (const frame_info_ptr &this_frame)
197 if (mips_sde_frame_sniffer (&mips_sde_frame_unwind, this_frame, NULL))
198 return &mips_sde_frame_base;
199 else
200 return NULL;
203 static void
204 mips_sde_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect,
205 void *obj)
207 enum gdb_osabi *os_ident_ptr = (enum gdb_osabi *) obj;
208 const char *name;
210 name = bfd_section_name (sect);
212 /* The presence of a section with a ".sde" prefix is indicative
213 of an SDE binary. */
214 if (startswith (name, ".sde"))
215 *os_ident_ptr = GDB_OSABI_SDE;
218 /* OSABI sniffer for MIPS SDE. */
220 static enum gdb_osabi
221 mips_sde_elf_osabi_sniffer (bfd *abfd)
223 enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
224 unsigned int elfosabi;
226 /* If the generic sniffer gets a hit, return and let other sniffers
227 get a crack at it. */
228 for (asection *sect : gdb_bfd_sections (abfd))
229 generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
230 if (osabi != GDB_OSABI_UNKNOWN)
231 return GDB_OSABI_UNKNOWN;
233 elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
235 if (elfosabi == ELFOSABI_NONE)
237 /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
238 file are conforming to the base specification for that machine
239 (there are no OS-specific extensions). In order to determine the
240 real OS in use we must look for OS notes that have been added.
242 For SDE, we simply look for sections named with .sde as prefixes. */
243 bfd_map_over_sections (abfd,
244 mips_sde_elf_osabi_sniff_abi_tag_sections,
245 &osabi);
247 return osabi;
250 static void
251 mips_sde_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
253 frame_unwind_append_unwinder (gdbarch, &mips_sde_frame_unwind);
254 frame_base_append_sniffer (gdbarch, mips_sde_frame_base_sniffer);
257 void _initialize_mips_sde_tdep ();
258 void
259 _initialize_mips_sde_tdep ()
261 gdbarch_register_osabi_sniffer (bfd_arch_mips,
262 bfd_target_elf_flavour,
263 mips_sde_elf_osabi_sniffer);
265 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_SDE, mips_sde_init_abi);