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 */
193 * 0x7fff0000 User high mem -> USRSTACK [64K]
195 * 0x7ffefff0 ps_strings -> 16 bytes
197 * 0x7ffeffec sigcode -> 44 bytes
199 * 0x7ffeffc4 sigcode end env strings etc start
201 #define MIPS_FBSD_SIGTRAMP_START (0x7ffeffc4)
202 #define MIPS_FBSD_SIGTRAMP_END (0x7ffeffec)
203 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_START (0x7ffeffc8)
204 #define MIPS_FBSD_SIGTRAMP_STACK_MOD_END (0x7ffeffd8)
207 mipsfbsd_sigtramp_offset (CORE_ADDR pc)
209 return pc < MIPS_FBSD_SIGTRAMP_END &&
210 pc >= MIPS_FBSD_SIGTRAMP_START ? 1 : -1;
214 fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
216 return (name && strcmp (name, "__sigtramp") == 0);
220 mipsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
222 return (fbsd_pc_in_sigtramp (pc, func_name)
223 || mipsfbsd_sigtramp_offset (pc) >= 0);
227 is_sigtramp_sp_modified (CORE_ADDR pc)
229 return (pc >= MIPS_FBSD_SIGTRAMP_STACK_MOD_START &&
230 pc <= MIPS_FBSD_SIGTRAMP_STACK_MOD_END);
234 /* Figure out where the longjmp will land. We expect that we have
235 just entered longjmp and haven't yet setup the stack frame, so
236 the args are still in the argument regs. A0_REGNUM points at the
237 jmp_buf structure from which we extract the PC that we will land
238 at. The PC is copied into *pc. This routine returns true on
241 #define FBSD_MIPS_JB_PC (12)
242 #define FBSD_MIPS_JB_ELEMENT_SIZE mips_regsize (current_gdbarch)
243 #define FBSD_MIPS_JB_OFFSET (FBSD_MIPS_JB_PC * \
244 FBSD_MIPS_JB_ELEMENT_SIZE)
247 mipsfbsd_get_longjmp_target (CORE_ADDR *pc)
252 buf = alloca (FBSD_MIPS_JB_ELEMENT_SIZE);
254 jb_addr = read_register (A0_REGNUM);
256 if (target_read_memory (jb_addr + FBSD_MIPS_JB_OFFSET, buf,
257 FBSD_MIPS_JB_ELEMENT_SIZE))
260 *pc = extract_unsigned_integer (buf, FBSD_MIPS_JB_ELEMENT_SIZE);
266 mipsfbsd_cannot_fetch_register (int regno)
268 return (regno == ZERO_REGNUM
269 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision);
270 /* XXX TODO: Are there other registers that we cannot fetch ? */
274 mipsfbsd_cannot_store_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 write ? */
282 * This structure is defined in mips-tdep.c.
284 struct mips_frame_cache
287 struct trad_frame_saved_reg *saved_regs;
291 * Prologue cache for sigtramp frame
292 * When we land in sigtramp, sigcontext is saved on the
293 * stack just below the sigtramp's stack frame. We have
294 * the Registers saved at fixed offsets on the stack.
297 #define MIPS_FBSD_SIGTRAMP_STACK_SIZE (48)
298 #define MIPS_FBSD_SIGCONTEXT_REG_OFFSET (32)
300 static struct mips_frame_cache *
301 mipsfbsd_sigtramp_frame_cache (struct frame_info *next_frame,
304 struct mips_frame_cache *cache;
305 CORE_ADDR gregs_addr, sp, pc;
307 int sigtramp_stack_size;
312 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
315 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
318 * Get sp of next frame which is the adjusted sp of
321 sp = frame_unwind_register_unsigned(next_frame, NUM_REGS + SP_REGNUM);
322 pc = frame_unwind_register_unsigned(next_frame, NUM_REGS + PC_REGNUM);
323 sigtramp_stack_size = is_sigtramp_sp_modified(pc) ?
324 MIPS_FBSD_SIGTRAMP_STACK_SIZE : 0;
325 gregs_addr = sp + sigtramp_stack_size + MIPS_FBSD_SIGCONTEXT_REG_OFFSET;
327 for (regnum = 0; regnum < PC_REGNUM; regnum++) {
328 cache->saved_regs[NUM_REGS + regnum].addr = gregs_addr +
329 regnum * mips_regsize (current_gdbarch);
331 /* Only retrieve PC and SP */
332 cache->saved_regs[NUM_REGS + SP_REGNUM].addr = gregs_addr +
333 SP_REGNUM * ( mips_regsize (current_gdbarch));
335 cache->saved_regs[NUM_REGS + RA_REGNUM].addr = gregs_addr +
336 RA_REGNUM * ( mips_regsize (current_gdbarch));
338 cache->base = get_frame_memory_unsigned (next_frame,
339 cache->saved_regs[NUM_REGS + SP_REGNUM].addr,
340 mips_regsize (current_gdbarch));
342 /* Todo: Floating point registers */
344 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
345 = cache->saved_regs[NUM_REGS + RA_REGNUM];
351 mipsfbsd_sigtramp_frame_this_id (struct frame_info *next_frame,
353 struct frame_id *this_id)
355 struct mips_frame_cache *cache =
356 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
358 (*this_id) = frame_id_build (cache->base,
359 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
363 mipsfbsd_sigtramp_frame_prev_register (struct frame_info *next_frame,
365 int regnum, int *optimizedp,
366 enum lval_type *lvalp,
368 int *realnump, void *valuep)
370 struct mips_frame_cache *cache =
371 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache);
373 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
374 optimizedp, lvalp, addrp, realnump, valuep);
378 static const struct frame_unwind mipsfbsd_sigtramp_frame_unwind =
381 mipsfbsd_sigtramp_frame_this_id,
382 mipsfbsd_sigtramp_frame_prev_register
385 static const struct frame_unwind *
386 mipsfbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
388 CORE_ADDR pc = frame_pc_unwind (next_frame);
391 find_pc_partial_function (pc, &name, NULL, NULL);
392 if (mipsfbsd_pc_in_sigtramp (pc, name) )
393 return &mipsfbsd_sigtramp_frame_unwind;
399 * Find out if PC has landed into dynamic library stub.
400 * We can find it by seeing if the name of the object
401 * file section where the PC lies is "MIPS.stubs"
405 mipsfbsd_in_stub_section (CORE_ADDR pc, char *name)
407 struct obj_section *s;
410 s = find_pc_section (pc);
413 && s->the_bfd_section->name != NULL
414 && strcmp (s->the_bfd_section->name, ".MIPS.stubs") == 0);
420 * Prologue cache for dynamic library stub frame.
421 * This stub does not modify the SP, so we set the
422 * cache base to calling frame's SP
424 static struct mips_frame_cache *
425 mipsfbsd_stub_frame_cache (struct frame_info *next_frame,
428 struct mips_frame_cache *cache;
433 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
436 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
439 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].realreg =
440 NUM_REGS + RA_REGNUM;
441 cache->base = frame_unwind_register_unsigned (next_frame,
442 NUM_REGS + SP_REGNUM);
444 return (*this_cache);
449 mipsfbsd_stub_frame_this_id (struct frame_info *next_frame,
451 struct frame_id *this_id)
453 struct mips_frame_cache *cache =
454 mipsfbsd_stub_frame_cache (next_frame, this_cache);
456 (*this_id) = frame_id_build (cache->base,
457 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr);
461 mipsfbsd_stub_frame_prev_register (struct frame_info *next_frame,
463 int regnum, int *optimizedp,
464 enum lval_type *lvalp, CORE_ADDR *addrp,
465 int *realnump, void *valuep)
467 struct mips_frame_cache *cache =
468 mipsfbsd_stub_frame_cache (next_frame, this_cache);
470 trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
471 optimizedp, lvalp, addrp, realnump, valuep);
476 static const struct frame_unwind mipsfbsd_stub_frame_unwind = {
478 mipsfbsd_stub_frame_this_id,
479 mipsfbsd_stub_frame_prev_register
482 static const struct frame_unwind *
483 mipsfbsd_stub_frame_sniffer (struct frame_info *next_frame)
485 CORE_ADDR pc = frame_pc_unwind (next_frame);
487 if (mipsfbsd_in_stub_section(pc, NULL))
488 return &mipsfbsd_stub_frame_unwind;
494 * typedef struct link_map {
495 * caddr_t l_addr; /* Base Address of library
497 * caddr_t l_offs; /* Load Offset of library
499 * const char *l_name; /* Absolute Path to Library
500 * const void *l_ld; /* Pointer to .dynamic in memory
501 * struct link_map *l_next, *l_prev; /* linked list of of mapped libs
505 * int r_version; /* not used
506 * struct link_map *r_map; /* list of loaded images
507 * void (*r_brk)(struct r_debug *, struct link_map *);
508 * /* pointer to break point
510 * RT_CONSISTENT, /* things are stable
511 * RT_ADD, /* adding a shared library
512 * RT_DELETE /* removing a shared library
518 static struct link_map_offsets *
519 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
521 static struct link_map_offsets lmo;
522 static struct link_map_offsets *lmp = NULL;
528 lmo.r_debug_size = 16;
530 lmo.r_map_offset = 4;
533 lmo.link_map_size = 24;
535 lmo.l_addr_offset = 0;
538 lmo.l_name_offset = 8;
541 lmo.l_next_offset = 16;
544 lmo.l_prev_offset = 20;
552 mipsfbsd_init_abi (struct gdbarch_info info,
553 struct gdbarch *gdbarch)
555 set_gdbarch_pc_in_sigtramp (gdbarch, mipsfbsd_pc_in_sigtramp);
557 set_gdbarch_get_longjmp_target (gdbarch, mipsfbsd_get_longjmp_target);
559 set_gdbarch_cannot_fetch_register (gdbarch, mipsfbsd_cannot_fetch_register);
560 set_gdbarch_cannot_store_register (gdbarch, mipsfbsd_cannot_store_register);
562 set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
563 set_solib_svr4_fetch_link_map_offsets (gdbarch,
564 mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets);
565 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
566 set_gdbarch_in_solib_call_trampoline (gdbarch, mipsfbsd_in_stub_section);
569 frame_unwind_append_sniffer (gdbarch, mipsfbsd_sigtramp_frame_sniffer);
570 frame_unwind_append_sniffer (gdbarch, mipsfbsd_stub_frame_sniffer);
575 _initialize_mipsfbsd_tdep (void)
577 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF,