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 #define MIPS_FBSD_SIGTRAMP_START (0x7ffeffc4)
210 #define MIPS_FBSD_SIGTRAMP_END (0x7ffeffec)
211 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_START (0x7ffeffc8)
212 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_END (0x7ffeffd8)
215 mipsfbsd_sigtramp_offset (CORE_ADDR pc)
217 return pc < MIPS_FBSD_SIGTRAMP_END &&
218 pc >= MIPS_FBSD_SIGTRAMP_START ? 1 : -1;
222 fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
224 return (name && strcmp (name, "__sigtramp") == 0);
228 mipsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
230 return (fbsd_pc_in_sigtramp (pc, func_name)
231 || mipsfbsd_sigtramp_offset (pc) >= 0);
235 is_sigtramp_sp_modified (CORE_ADDR pc)
237 return (pc >= MIPS_FBSD_SIGTRAMP_STACK_MOD_START &&
238 pc <= MIPS_FBSD_SIGTRAMP_STACK_MOD_END);
242 /* Figure out where the longjmp will land. We expect that we have
243 just entered longjmp and haven't yet setup the stack frame, so
244 the args are still in the argument regs. A0_REGNUM points at the
245 jmp_buf structure from which we extract the PC that we will land
246 at. The PC is copied into *pc. This routine returns true on
249 #define FBSD_MIPS_JB_PC (12)
250 #define FBSD_MIPS_JB_ELEMENT_SIZE mips_regsize (current_gdbarch)
251 #define FBSD_MIPS_JB_OFFSET (FBSD_MIPS_JB_PC * \
252 FBSD_MIPS_JB_ELEMENT_SIZE)
255 mipsfbsd_get_longjmp_target (CORE_ADDR *pc)
260 buf = alloca (FBSD_MIPS_JB_ELEMENT_SIZE);
262 jb_addr = read_register (A0_REGNUM);
264 if (target_read_memory (jb_addr + FBSD_MIPS_JB_OFFSET, buf,
265 FBSD_MIPS_JB_ELEMENT_SIZE))
268 *pc = extract_unsigned_integer (buf, FBSD_MIPS_JB_ELEMENT_SIZE);
274 mipsfbsd_cannot_fetch_register (int regno)
276 return (regno == ZERO_REGNUM
277 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision);
278 /* XXX TODO: Are there other registers that we cannot fetch ? */
282 mipsfbsd_cannot_store_register (int regno)
284 return (regno == ZERO_REGNUM
285 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision);
286 /* XXX TODO: Are there other registers that we cannot write ? */
290 * This structure is defined in mips-tdep.c.
292 struct mips_frame_cache
295 struct trad_frame_saved_reg *saved_regs;
299 * Prologue cache for sigtramp frame
300 * When we land in sigtramp, sigcontext is saved on the
301 * stack just below the sigtramp's stack frame. We have
302 * the Registers saved at fixed offsets on the stack.
305 #define MIPS_FBSD_SIGTRAMP_STACK_SIZE (48)
306 #define MIPS_FBSD_SIGCONTEXT_REG_OFFSET (32)
308 static struct mips_frame_cache *
309 mipsfbsd_sigtramp_frame_cache (struct frame_info *next_frame,
312 struct mips_frame_cache *cache;
313 CORE_ADDR gregs_addr, sp, pc;
315 int sigtramp_stack_size;
320 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
323 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
326 * Get sp of next frame which is the adjusted sp of
329 sp = frame_unwind_register_unsigned(next_frame, NUM_REGS + SP_REGNUM);
330 pc = frame_unwind_register_unsigned(next_frame, NUM_REGS + PC_REGNUM);
331 sigtramp_stack_size = is_sigtramp_sp_modified(pc) ?
332 MIPS_FBSD_SIGTRAMP_STACK_SIZE : 0;
333 gregs_addr = sp + sigtramp_stack_size + MIPS_FBSD_SIGCONTEXT_REG_OFFSET;
335 for (regnum = 0; regnum < PC_REGNUM; regnum++) {
336 cache->saved_regs[NUM_REGS + regnum].addr = gregs_addr +
337 regnum * mips_regsize (current_gdbarch);
339 /* Only retrieve PC and SP */
340 cache->saved_regs[NUM_REGS + SP_REGNUM].addr = gregs_addr +
341 SP_REGNUM * ( mips_regsize (current_gdbarch));
343 cache->saved_regs[NUM_REGS + RA_REGNUM].addr = gregs_addr +
344 RA_REGNUM * ( mips_regsize (current_gdbarch));
346 cache->base = get_frame_memory_unsigned (next_frame,
347 cache->saved_regs[NUM_REGS + SP_REGNUM].addr,
348 mips_regsize (current_gdbarch));
350 /* Todo: Floating point registers */
352 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
353 = cache->saved_regs[NUM_REGS + RA_REGNUM];
359 mipsfbsd_sigtramp_frame_this_id (struct frame_info *next_frame,
361 struct frame_id *this_id)
363 struct mips_frame_cache *cache =
364 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
366 (*this_id) = frame_id_build (cache->base,
367 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
371 mipsfbsd_sigtramp_frame_prev_register (struct frame_info *next_frame,
373 int regnum, int *optimizedp,
374 enum lval_type *lvalp,
376 int *realnump, void *valuep)
378 struct mips_frame_cache *cache =
379 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
381 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
382 optimizedp, lvalp, addrp, realnump, valuep);
386 static const struct frame_unwind mipsfbsd_sigtramp_frame_unwind =
389 mipsfbsd_sigtramp_frame_this_id,
390 mipsfbsd_sigtramp_frame_prev_register
393 static const struct frame_unwind *
394 mipsfbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
396 CORE_ADDR pc = frame_pc_unwind (next_frame);
399 find_pc_partial_function (pc, &name, NULL, NULL);
400 if (mipsfbsd_pc_in_sigtramp (pc, name) )
401 return &mipsfbsd_sigtramp_frame_unwind;
407 * Find out if PC has landed into dynamic library stub.
408 * We can find it by seeing if the name of the object
409 * file section where the PC lies is "MIPS.stubs"
413 mipsfbsd_in_stub_section (CORE_ADDR pc, char *name)
415 struct obj_section *s;
418 s = find_pc_section (pc);
421 && s->the_bfd_section->name != NULL
422 && strcmp (s->the_bfd_section->name, ".MIPS.stubs") == 0);
428 * Prologue cache for dynamic library stub frame.
429 * This stub does not modify the SP, so we set the
430 * cache base to calling frame's SP
432 static struct mips_frame_cache *
433 mipsfbsd_stub_frame_cache (struct frame_info *next_frame,
436 struct mips_frame_cache *cache;
441 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
444 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
447 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].realreg =
448 NUM_REGS + RA_REGNUM;
449 cache->base = frame_unwind_register_unsigned (next_frame,
450 NUM_REGS + SP_REGNUM);
452 return (*this_cache);
457 mipsfbsd_stub_frame_this_id (struct frame_info *next_frame,
459 struct frame_id *this_id)
461 struct mips_frame_cache *cache =
462 mipsfbsd_stub_frame_cache (next_frame, this_cache);
464 (*this_id) = frame_id_build (cache->base,
465 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
469 mipsfbsd_stub_frame_prev_register (struct frame_info *next_frame,
471 int regnum, int *optimizedp,
472 enum lval_type *lvalp, CORE_ADDR *addrp,
473 int *realnump, void *valuep)
475 struct mips_frame_cache *cache =
476 mipsfbsd_stub_frame_cache (next_frame, this_cache);
478 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
479 optimizedp, lvalp, addrp, realnump, valuep);
484 static const struct frame_unwind mipsfbsd_stub_frame_unwind = {
486 mipsfbsd_stub_frame_this_id,
487 mipsfbsd_stub_frame_prev_register
490 static const struct frame_unwind *
491 mipsfbsd_stub_frame_sniffer (struct frame_info *next_frame)
493 CORE_ADDR pc = frame_pc_unwind (next_frame);
495 if (mipsfbsd_in_stub_section(pc, NULL))
496 return &mipsfbsd_stub_frame_unwind;
502 * typedef struct link_map {
503 * caddr_t l_addr; /* Base Address of library
505 * caddr_t l_offs; /* Load Offset of library
507 * const char *l_name; /* Absolute Path to Library
508 * const void *l_ld; /* Pointer to .dynamic in memory
509 * struct link_map *l_next, *l_prev; /* linked list of of mapped libs
513 * int r_version; /* not used
514 * struct link_map *r_map; /* list of loaded images
515 * void (*r_brk)(struct r_debug *, struct link_map *);
516 * /* pointer to break point
518 * RT_CONSISTENT, /* things are stable
519 * RT_ADD, /* adding a shared library
520 * RT_DELETE /* removing a shared library
526 static struct link_map_offsets *
527 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
529 static struct link_map_offsets lmo;
530 static struct link_map_offsets *lmp = NULL;
536 lmo.r_debug_size = 16;
538 lmo.r_map_offset = 4;
541 lmo.link_map_size = 24;
543 lmo.l_addr_offset = 0;
546 lmo.l_name_offset = 8;
549 lmo.l_next_offset = 16;
552 lmo.l_prev_offset = 20;
560 mipsfbsd_init_abi (struct gdbarch_info info,
561 struct gdbarch *gdbarch)
563 set_gdbarch_pc_in_sigtramp (gdbarch, mipsfbsd_pc_in_sigtramp);
565 set_gdbarch_get_longjmp_target (gdbarch, mipsfbsd_get_longjmp_target);
567 set_gdbarch_cannot_fetch_register (gdbarch, mipsfbsd_cannot_fetch_register);
568 set_gdbarch_cannot_store_register (gdbarch, mipsfbsd_cannot_store_register);
570 set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
571 set_solib_svr4_fetch_link_map_offsets (gdbarch,
572 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets);
573 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
574 set_gdbarch_in_solib_call_trampoline (gdbarch, mipsfbsd_in_stub_section);
577 frame_unwind_append_sniffer (gdbarch, mipsfbsd_sigtramp_frame_sniffer);
578 frame_unwind_append_sniffer (gdbarch, mipsfbsd_stub_frame_sniffer);
583 _initialize_mipsfbsd_tdep (void)
585 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF,
587 add_core_fns (&mipsfbsd_core_fns);
588 add_core_fns (&mipsfbsd_elfcore_fns);