1 /***********************************************************************
2 Copyright 2003-2006 Raza Microelectronics, Inc.(RMI).
3 This is a derived work from software originally provided by the external
4 entity identified below. The licensing terms and warranties specified in
5 the header of the original work apply to this derived work.
7 *****************************#RMI_1#**********************************/
8 /* Target-dependent code for MIPS systems running NetBSD.
9 Copyright 2002, 2003 Free Software Foundation, Inc.
10 Contributed by Wasabi Systems, Inc.
12 This file is part of GDB.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. */
36 #include "nbsd-tdep.h"
37 #include "mipsfbsd-tdep.h"
38 #include "mips-tdep.h"
40 #include "solib-svr4.h"
42 #include <sys/procfs.h>
44 #include "trad-frame.h"
46 #include "frame-unwind.h"
50 /* Conveniently, GDB uses the same register numbering as the
51 ptrace register structure used by NetBSD/mips. */
54 mipsfbsd_supply_reg (char *regs, int regno)
58 for (i = 0; i <= PC_REGNUM; i++)
60 if (regno == i || regno == -1)
62 if (CANNOT_FETCH_REGISTER (i))
63 supply_register (i, NULL);
65 supply_register (i, regs + (i * mips_regsize (current_gdbarch)));
70 supply_gregset (gdb_gregset_t *gregs)
72 mipsfbsd_supply_reg((char *)gregs, -1);
76 mipsfbsd_fill_reg (char *regs, int regno)
80 for (i = 0; i <= PC_REGNUM; i++)
81 if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
82 regcache_collect (i, regs + (i * mips_regsize (current_gdbarch)));
86 fill_gregset (gdb_gregset_t *gregs, int regno)
88 mipsfbsd_fill_reg ((char *)gregs, regno);
92 mipsfbsd_supply_fpreg (char *fpregs, int regno)
97 i <= mips_regnum (current_gdbarch)->fp_implementation_revision;
100 if (regno == i || regno == -1)
102 if (CANNOT_FETCH_REGISTER (i))
103 supply_register (i, NULL);
106 fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch)));
112 supply_fpregset (gdb_fpregset_t *fpregs)
114 mipsfbsd_supply_fpreg((char *)fpregs, -1);
118 mipsfbsd_fill_fpreg (char *fpregs, int regno)
122 for (i = FP0_REGNUM; i <= mips_regnum (current_gdbarch)->fp_control_status;
124 if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
126 fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch)));
130 fill_fpregset (gdb_fpregset_t *fpregs, int regno)
132 mipsfbsd_fill_fpreg ((char *)fpregs, regno);
136 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
141 /* We get everything from one section. */
145 regs = core_reg_sect;
146 fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
148 /* Integer registers. */
149 mipsfbsd_supply_reg (regs, -1);
151 /* Floating point registers. */
152 mipsfbsd_supply_fpreg (fpregs, -1);
156 fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
161 case 0: /* Integer registers. */
162 if (core_reg_size != SIZEOF_STRUCT_REG)
163 warning ("Wrong size register set in core file.");
165 mipsfbsd_supply_reg (core_reg_sect, -1);
168 case 2: /* Floating point registers. */
169 if (core_reg_size != SIZEOF_STRUCT_FPREG)
170 warning ("Wrong size register set in core file.");
172 mipsfbsd_supply_fpreg (core_reg_sect, -1);
176 /* Don't know what kind of register request this is; just ignore it. */
181 static struct core_fns mipsfbsd_core_fns =
183 bfd_target_unknown_flavour, /* core_flavour */
184 default_check_format, /* check_format */
185 default_core_sniffer, /* core_sniffer */
186 fetch_core_registers, /* core_read_registers */
190 static struct core_fns mipsfbsd_elfcore_fns =
192 bfd_target_elf_flavour, /* core_flavour */
193 default_check_format, /* check_format */
194 default_core_sniffer, /* core_sniffer */
195 fetch_elfcore_registers, /* core_read_registers */
201 * 0x7fff0000 User high mem -> USRSTACK [64K]
203 * 0x7ffefff0 ps_strings -> 16 bytes
205 * 0x7ffeffec sigcode -> 44 bytes
207 * 0x7ffeffc4 sigcode end env strings etc start
209 * XXX This is out-of-date and varies by ABI.
211 #define MIPS_FBSD_SIGTRAMP_START (0x7ffeffc4)
212 #define MIPS_FBSD_SIGTRAMP_END (0x7ffeffec)
213 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_START (0x7ffeffc8)
214 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_END (0x7ffeffd8)
217 mipsfbsd_sigtramp_offset (CORE_ADDR pc)
219 return pc < MIPS_FBSD_SIGTRAMP_END &&
220 pc >= MIPS_FBSD_SIGTRAMP_START ? 1 : -1;
224 fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
226 return (name && strcmp (name, "__sigtramp") == 0);
230 mipsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
232 return (fbsd_pc_in_sigtramp (pc, func_name)
233 || mipsfbsd_sigtramp_offset (pc) >= 0);
237 is_sigtramp_sp_modified (CORE_ADDR pc)
239 return (pc >= MIPS_FBSD_SIGTRAMP_STACK_MOD_START &&
240 pc <= MIPS_FBSD_SIGTRAMP_STACK_MOD_END);
244 /* Figure out where the longjmp will land. We expect that we have
245 just entered longjmp and haven't yet setup the stack frame, so
246 the args are still in the argument regs. A0_REGNUM points at the
247 jmp_buf structure from which we extract the PC that we will land
248 at. The PC is copied into *pc. This routine returns true on
251 #define FBSD_MIPS_JB_PC (12)
252 #define FBSD_MIPS_JB_ELEMENT_SIZE mips_regsize (current_gdbarch)
253 #define FBSD_MIPS_JB_OFFSET (FBSD_MIPS_JB_PC * \
254 FBSD_MIPS_JB_ELEMENT_SIZE)
257 mipsfbsd_get_longjmp_target (CORE_ADDR *pc)
262 buf = alloca (FBSD_MIPS_JB_ELEMENT_SIZE);
264 jb_addr = read_register (A0_REGNUM);
266 if (target_read_memory (jb_addr + FBSD_MIPS_JB_OFFSET, buf,
267 FBSD_MIPS_JB_ELEMENT_SIZE))
270 *pc = extract_unsigned_integer (buf, FBSD_MIPS_JB_ELEMENT_SIZE);
276 mipsfbsd_cannot_fetch_register (int regno)
278 return (regno == ZERO_REGNUM
279 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision);
280 /* XXX TODO: Are there other registers that we cannot fetch ? */
284 mipsfbsd_cannot_store_register (int regno)
286 return (regno == ZERO_REGNUM
287 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision);
288 /* XXX TODO: Are there other registers that we cannot write ? */
292 * This structure is defined in mips-tdep.c.
294 struct mips_frame_cache
297 struct trad_frame_saved_reg *saved_regs;
301 * Prologue cache for sigtramp frame
302 * When we land in sigtramp, sigcontext is saved on the
303 * stack just below the sigtramp's stack frame. We have
304 * the Registers saved at fixed offsets on the stack.
307 #define MIPS_FBSD_SIGTRAMP_STACK_SIZE (48)
308 #define MIPS_FBSD_SIGCONTEXT_REG_OFFSET (32)
310 static struct mips_frame_cache *
311 mipsfbsd_sigtramp_frame_cache (struct frame_info *next_frame,
314 struct mips_frame_cache *cache;
315 CORE_ADDR gregs_addr, sp, pc;
317 int sigtramp_stack_size;
322 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
325 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
328 * Get sp of next frame which is the adjusted sp of
331 sp = frame_unwind_register_unsigned(next_frame, NUM_REGS + SP_REGNUM);
332 pc = frame_unwind_register_unsigned(next_frame, NUM_REGS + PC_REGNUM);
333 sigtramp_stack_size = is_sigtramp_sp_modified(pc) ?
334 MIPS_FBSD_SIGTRAMP_STACK_SIZE : 0;
335 gregs_addr = sp + sigtramp_stack_size + MIPS_FBSD_SIGCONTEXT_REG_OFFSET;
337 for (regnum = 0; regnum < PC_REGNUM; regnum++) {
338 cache->saved_regs[NUM_REGS + regnum].addr = gregs_addr +
339 regnum * mips_regsize (current_gdbarch);
341 /* Only retrieve PC and SP */
342 cache->saved_regs[NUM_REGS + SP_REGNUM].addr = gregs_addr +
343 SP_REGNUM * ( mips_regsize (current_gdbarch));
345 cache->saved_regs[NUM_REGS + RA_REGNUM].addr = gregs_addr +
346 RA_REGNUM * ( mips_regsize (current_gdbarch));
348 cache->base = get_frame_memory_unsigned (next_frame,
349 cache->saved_regs[NUM_REGS + SP_REGNUM].addr,
350 mips_regsize (current_gdbarch));
352 /* Todo: Floating point registers */
354 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
355 = cache->saved_regs[NUM_REGS + RA_REGNUM];
361 mipsfbsd_sigtramp_frame_this_id (struct frame_info *next_frame,
363 struct frame_id *this_id)
365 struct mips_frame_cache *cache =
366 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
368 (*this_id) = frame_id_build (cache->base,
369 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
373 mipsfbsd_sigtramp_frame_prev_register (struct frame_info *next_frame,
375 int regnum, int *optimizedp,
376 enum lval_type *lvalp,
378 int *realnump, void *valuep)
380 struct mips_frame_cache *cache =
381 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
383 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
384 optimizedp, lvalp, addrp, realnump, valuep);
388 static const struct frame_unwind mipsfbsd_sigtramp_frame_unwind =
391 mipsfbsd_sigtramp_frame_this_id,
392 mipsfbsd_sigtramp_frame_prev_register
395 static const struct frame_unwind *
396 mipsfbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
398 CORE_ADDR pc = frame_pc_unwind (next_frame);
401 find_pc_partial_function (pc, &name, NULL, NULL);
402 if (mipsfbsd_pc_in_sigtramp (pc, name) )
403 return &mipsfbsd_sigtramp_frame_unwind;
409 * Find out if PC has landed into dynamic library stub.
410 * We can find it by seeing if the name of the object
411 * file section where the PC lies is "MIPS.stubs"
415 mipsfbsd_in_stub_section (CORE_ADDR pc, char *name)
417 struct obj_section *s;
420 s = find_pc_section (pc);
423 && s->the_bfd_section->name != NULL
424 && strcmp (s->the_bfd_section->name, ".MIPS.stubs") == 0);
430 * Prologue cache for dynamic library stub frame.
431 * This stub does not modify the SP, so we set the
432 * cache base to calling frame's SP
434 static struct mips_frame_cache *
435 mipsfbsd_stub_frame_cache (struct frame_info *next_frame,
438 struct mips_frame_cache *cache;
443 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
446 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
449 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].realreg =
450 NUM_REGS + RA_REGNUM;
451 cache->base = frame_unwind_register_unsigned (next_frame,
452 NUM_REGS + SP_REGNUM);
454 return (*this_cache);
459 mipsfbsd_stub_frame_this_id (struct frame_info *next_frame,
461 struct frame_id *this_id)
463 struct mips_frame_cache *cache =
464 mipsfbsd_stub_frame_cache (next_frame, this_cache);
466 (*this_id) = frame_id_build (cache->base,
467 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
471 mipsfbsd_stub_frame_prev_register (struct frame_info *next_frame,
473 int regnum, int *optimizedp,
474 enum lval_type *lvalp, CORE_ADDR *addrp,
475 int *realnump, void *valuep)
477 struct mips_frame_cache *cache =
478 mipsfbsd_stub_frame_cache (next_frame, this_cache);
480 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
481 optimizedp, lvalp, addrp, realnump, valuep);
486 static const struct frame_unwind mipsfbsd_stub_frame_unwind = {
488 mipsfbsd_stub_frame_this_id,
489 mipsfbsd_stub_frame_prev_register
492 static const struct frame_unwind *
493 mipsfbsd_stub_frame_sniffer (struct frame_info *next_frame)
495 CORE_ADDR pc = frame_pc_unwind (next_frame);
497 if (mipsfbsd_in_stub_section(pc, NULL))
498 return &mipsfbsd_stub_frame_unwind;
504 * typedef struct link_map {
505 * caddr_t l_addr; /* Base Address of library
507 * caddr_t l_offs; /* Load Offset of library
509 * const char *l_name; /* Absolute Path to Library
510 * const void *l_ld; /* Pointer to .dynamic in memory
511 * struct link_map *l_next, *l_prev; /* linked list of of mapped libs
515 * int r_version; /* not used
516 * struct link_map *r_map; /* list of loaded images
517 * void (*r_brk)(struct r_debug *, struct link_map *);
518 * /* pointer to break point
520 * RT_CONSISTENT, /* things are stable
521 * RT_ADD, /* adding a shared library
522 * RT_DELETE /* removing a shared library
528 static struct link_map_offsets *
529 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
531 static struct link_map_offsets lmo;
532 static struct link_map_offsets *lmp = NULL;
538 lmo.r_debug_size = 16;
540 lmo.r_map_offset = 4;
543 lmo.link_map_size = 24;
545 lmo.l_addr_offset = 0;
548 lmo.l_name_offset = 8;
551 lmo.l_next_offset = 16;
554 lmo.l_prev_offset = 20;
562 mipsfbsd_init_abi (struct gdbarch_info info,
563 struct gdbarch *gdbarch)
565 set_gdbarch_pc_in_sigtramp (gdbarch, mipsfbsd_pc_in_sigtramp);
567 set_gdbarch_get_longjmp_target (gdbarch, mipsfbsd_get_longjmp_target);
569 set_gdbarch_cannot_fetch_register (gdbarch, mipsfbsd_cannot_fetch_register);
570 set_gdbarch_cannot_store_register (gdbarch, mipsfbsd_cannot_store_register);
572 set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
573 set_solib_svr4_fetch_link_map_offsets (gdbarch,
574 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets);
575 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
576 set_gdbarch_in_solib_call_trampoline (gdbarch, mipsfbsd_in_stub_section);
579 frame_unwind_append_sniffer (gdbarch, mipsfbsd_sigtramp_frame_sniffer);
580 frame_unwind_append_sniffer (gdbarch, mipsfbsd_stub_frame_sniffer);
585 _initialize_mipsfbsd_tdep (void)
587 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF,
589 add_core_fns (&mipsfbsd_core_fns);
590 add_core_fns (&mipsfbsd_elfcore_fns);