1/*********************************************************************** 2Copyright 2003-2006 Raza Microelectronics, Inc.(RMI). 3This is a derived work from software originally provided by the external 4entity identified below. The licensing terms and warranties specified in 5the header of the original work apply to this derived work. 6Contribution by RMI: 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. 11 12 This file is part of GDB. 13 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. 18 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. 23 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. */ 28 29#include "defs.h" 30#include "gdbcore.h" 31#include "regcache.h" 32#include "target.h" 33#include "value.h" 34#include "osabi.h" 35 36#include "nbsd-tdep.h" 37#include "mipsfbsd-tdep.h" 38#include "mips-tdep.h" 39 40#include "solib-svr4.h" 41 42#include <sys/procfs.h> 43#include "gregset.h" 44#include "trad-frame.h" 45#include "frame.h" 46#include "frame-unwind.h" 47#include "bfd.h" 48#include "objfiles.h" 49 50/* Conveniently, GDB uses the same register numbering as the 51 ptrace register structure used by NetBSD/mips. */ 52 53void 54mipsfbsd_supply_reg (char *regs, int regno) 55{ 56 int i; 57 58 for (i = 0; i <= PC_REGNUM; i++) 59 { 60 if (regno == i || regno == -1) 61 { 62 if (CANNOT_FETCH_REGISTER (i)) 63 supply_register (i, NULL); 64 else 65 supply_register (i, regs + (i * mips_regsize (current_gdbarch))); 66 } 67 } 68} 69void 70supply_gregset (gdb_gregset_t *gregs) 71{ 72 mipsfbsd_supply_reg((char *)gregs, -1); 73} 74 75void 76mipsfbsd_fill_reg (char *regs, int regno) 77{ 78 int i; 79 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))); 83} 84 85void 86fill_gregset (gdb_gregset_t *gregs, int regno) 87{ 88 mipsfbsd_fill_reg ((char *)gregs, regno); 89} 90 91void 92mipsfbsd_supply_fpreg (char *fpregs, int regno) 93{ 94 int i; 95 96 for (i = FP0_REGNUM; 97 i <= mips_regnum (current_gdbarch)->fp_implementation_revision; 98 i++) 99 { 100 if (regno == i || regno == -1) 101 { 102 if (CANNOT_FETCH_REGISTER (i)) 103 supply_register (i, NULL); 104 else 105 supply_register (i, 106 fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); 107 } 108 } 109} 110 111void 112supply_fpregset (gdb_fpregset_t *fpregs) 113{ 114 mipsfbsd_supply_fpreg((char *)fpregs, -1); 115} 116 117void 118mipsfbsd_fill_fpreg (char *fpregs, int regno) 119{ 120 int i; 121 122 for (i = FP0_REGNUM; i <= mips_regnum (current_gdbarch)->fp_control_status; 123 i++) 124 if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i)) 125 regcache_collect (i, 126 fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); 127} 128 129void 130fill_fpregset (gdb_fpregset_t *fpregs, int regno) 131{ 132 mipsfbsd_fill_fpreg ((char *)fpregs, regno); 133} 134 135static void 136fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, 137 CORE_ADDR ignore) 138{ 139 char *regs, *fpregs; 140 141 /* We get everything from one section. */ 142 if (which != 0) 143 return; 144 145 regs = core_reg_sect; 146 fpregs = core_reg_sect + SIZEOF_STRUCT_REG; 147 148 /* Integer registers. */ 149 mipsfbsd_supply_reg (regs, -1); 150 151 /* Floating point registers. */ 152 mipsfbsd_supply_fpreg (fpregs, -1); 153} 154 155static void 156fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, 157 CORE_ADDR ignore) 158{ 159 switch (which) 160 { 161 case 0: /* Integer registers. */ 162 if (core_reg_size != SIZEOF_STRUCT_REG) 163 warning ("Wrong size register set in core file."); 164 else 165 mipsfbsd_supply_reg (core_reg_sect, -1); 166 break; 167 168 case 2: /* Floating point registers. */ 169 if (core_reg_size != SIZEOF_STRUCT_FPREG) 170 warning ("Wrong size register set in core file."); 171 else 172 mipsfbsd_supply_fpreg (core_reg_sect, -1); 173 break; 174 175 default: 176 /* Don't know what kind of register request this is; just ignore it. */ 177 break; 178 } 179} 180 181static struct core_fns mipsfbsd_core_fns = 182{ 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 */ 187 NULL /* next */ 188}; 189 190static struct core_fns mipsfbsd_elfcore_fns = 191{ 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 */ 196 NULL /* next */ 197}; 198 199/* 200 * MIPSFBSD Offsets 201 * 0x7fff0000 User high mem -> USRSTACK [64K] 202 * 203 * 0x7ffefff0 ps_strings -> 16 bytes 204 * 205 * 0x7ffeffec sigcode -> 44 bytes 206 * 207 * 0x7ffeffc4 sigcode end env strings etc start 208 * 209 * XXX This is out-of-date and varies by ABI. 210 */ 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) 215 216static LONGEST 217mipsfbsd_sigtramp_offset (CORE_ADDR pc) 218{ 219 return pc < MIPS_FBSD_SIGTRAMP_END && 220 pc >= MIPS_FBSD_SIGTRAMP_START ? 1 : -1; 221} 222 223static int 224fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) 225{ 226 return (name && strcmp (name, "__sigtramp") == 0); 227} 228 229static int 230mipsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) 231{ 232 return (fbsd_pc_in_sigtramp (pc, func_name) 233 || mipsfbsd_sigtramp_offset (pc) >= 0); 234} 235 236static int 237is_sigtramp_sp_modified (CORE_ADDR pc) 238{ 239 return (pc >= MIPS_FBSD_SIGTRAMP_STACK_MOD_START && 240 pc <= MIPS_FBSD_SIGTRAMP_STACK_MOD_END); 241} 242 243 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 249 success. */ 250 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) 255 256static int 257mipsfbsd_get_longjmp_target (CORE_ADDR *pc) 258{ 259 CORE_ADDR jb_addr; 260 char *buf; 261 262 buf = alloca (FBSD_MIPS_JB_ELEMENT_SIZE); 263 264 jb_addr = read_register (A0_REGNUM); 265 266 if (target_read_memory (jb_addr + FBSD_MIPS_JB_OFFSET, buf, 267 FBSD_MIPS_JB_ELEMENT_SIZE)) 268 return 0; 269 270 *pc = extract_unsigned_integer (buf, FBSD_MIPS_JB_ELEMENT_SIZE); 271 272 return 1; 273} 274 275static int 276mipsfbsd_cannot_fetch_register (int regno) 277{ 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 ? */ 281} 282 283static int 284mipsfbsd_cannot_store_register (int regno) 285{ 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 ? */ 289} 290 291/* 292 * This structure is defined in mips-tdep.c. 293 */ 294struct mips_frame_cache 295{ 296 CORE_ADDR base; 297 struct trad_frame_saved_reg *saved_regs; 298}; 299 300/* 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. 305 */ 306 307#define MIPS_FBSD_SIGTRAMP_STACK_SIZE (48) 308#define MIPS_FBSD_SIGCONTEXT_REG_OFFSET (32) 309 310static struct mips_frame_cache * 311mipsfbsd_sigtramp_frame_cache (struct frame_info *next_frame, 312 void **this_cache) 313{ 314 struct mips_frame_cache *cache; 315 CORE_ADDR gregs_addr, sp, pc; 316 int regnum; 317 int sigtramp_stack_size; 318 319 if (*this_cache) 320 return *this_cache; 321 322 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); 323 *this_cache = cache; 324 325 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 326 327 /* 328 * Get sp of next frame which is the adjusted sp of 329 * tramp code. 330 */ 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; 336 337 for (regnum = 0; regnum < PC_REGNUM; regnum++) { 338 cache->saved_regs[NUM_REGS + regnum].addr = gregs_addr + 339 regnum * mips_regsize (current_gdbarch); 340 } 341 /* Only retrieve PC and SP */ 342 cache->saved_regs[NUM_REGS + SP_REGNUM].addr = gregs_addr + 343 SP_REGNUM * ( mips_regsize (current_gdbarch)); 344 345 cache->saved_regs[NUM_REGS + RA_REGNUM].addr = gregs_addr + 346 RA_REGNUM * ( mips_regsize (current_gdbarch)); 347 348 cache->base = get_frame_memory_unsigned (next_frame, 349 cache->saved_regs[NUM_REGS + SP_REGNUM].addr, 350 mips_regsize (current_gdbarch)); 351 352 /* Todo: Floating point registers */ 353 354 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc] 355 = cache->saved_regs[NUM_REGS + RA_REGNUM]; 356 357 return *this_cache; 358} 359 360static void 361mipsfbsd_sigtramp_frame_this_id (struct frame_info *next_frame, 362 void **this_cache, 363 struct frame_id *this_id) 364{ 365 struct mips_frame_cache *cache = 366 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache); 367 368 (*this_id) = frame_id_build (cache->base, 369 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr); 370} 371 372static void 373mipsfbsd_sigtramp_frame_prev_register (struct frame_info *next_frame, 374 void **this_cache, 375 int regnum, int *optimizedp, 376 enum lval_type *lvalp, 377 CORE_ADDR *addrp, 378 int *realnump, void *valuep) 379{ 380 struct mips_frame_cache *cache = 381 mipsfbsd_sigtramp_frame_cache (next_frame, this_cache); 382 383 trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 384 optimizedp, lvalp, addrp, realnump, valuep); 385} 386 387 388static const struct frame_unwind mipsfbsd_sigtramp_frame_unwind = 389{ 390 SIGTRAMP_FRAME, 391 mipsfbsd_sigtramp_frame_this_id, 392 mipsfbsd_sigtramp_frame_prev_register 393}; 394 395static const struct frame_unwind * 396mipsfbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) 397{ 398 CORE_ADDR pc = frame_pc_unwind (next_frame); 399 char *name; 400 401 find_pc_partial_function (pc, &name, NULL, NULL); 402 if (mipsfbsd_pc_in_sigtramp (pc, name) ) 403 return &mipsfbsd_sigtramp_frame_unwind; 404 405 return NULL; 406} 407 408/* 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" 412 */ 413 414int 415mipsfbsd_in_stub_section (CORE_ADDR pc, char *name) 416{ 417 struct obj_section *s; 418 int retval = 0; 419 420 s = find_pc_section (pc); 421 422 retval = (s != NULL 423 && s->the_bfd_section->name != NULL 424 && strcmp (s->the_bfd_section->name, ".MIPS.stubs") == 0); 425 return (retval); 426} 427 428 429/* 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 433 */ 434static struct mips_frame_cache * 435mipsfbsd_stub_frame_cache (struct frame_info *next_frame, 436 void **this_cache) 437{ 438 struct mips_frame_cache *cache; 439 440 if (*this_cache) 441 return *this_cache; 442 443 cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); 444 *this_cache = cache; 445 446 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 447 448 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); 453 454 return (*this_cache); 455} 456 457 458static void 459mipsfbsd_stub_frame_this_id (struct frame_info *next_frame, 460 void **this_cache, 461 struct frame_id *this_id) 462{ 463 struct mips_frame_cache *cache = 464 mipsfbsd_stub_frame_cache (next_frame, this_cache); 465 466 (*this_id) = frame_id_build (cache->base, 467 cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr); 468} 469 470static void 471mipsfbsd_stub_frame_prev_register (struct frame_info *next_frame, 472 void **this_cache, 473 int regnum, int *optimizedp, 474 enum lval_type *lvalp, CORE_ADDR *addrp, 475 int *realnump, void *valuep) 476{ 477 struct mips_frame_cache *cache = 478 mipsfbsd_stub_frame_cache (next_frame, this_cache); 479 480 trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 481 optimizedp, lvalp, addrp, realnump, valuep); 482} 483 484 485 486static const struct frame_unwind mipsfbsd_stub_frame_unwind = { 487 NORMAL_FRAME, 488 mipsfbsd_stub_frame_this_id, 489 mipsfbsd_stub_frame_prev_register 490}; 491 492static const struct frame_unwind * 493mipsfbsd_stub_frame_sniffer (struct frame_info *next_frame) 494{ 495 CORE_ADDR pc = frame_pc_unwind (next_frame); 496 497 if (mipsfbsd_in_stub_section(pc, NULL)) 498 return &mipsfbsd_stub_frame_unwind; 499 500 return NULL; 501} 502 503/* 504 * typedef struct link_map { 505 * caddr_t l_addr; /* Base Address of library 506 * #ifdef __mips__ 507 * caddr_t l_offs; /* Load Offset of library 508 * #endif 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 512 * } Link_map; 513 * 514 * struct r_debug { 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 519 * enum { 520 * RT_CONSISTENT, /* things are stable 521 * RT_ADD, /* adding a shared library 522 * RT_DELETE /* removing a shared library 523 * } r_state; 524 * }; 525 * 526 */ 527 528static struct link_map_offsets * 529mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets (void) 530{ 531 static struct link_map_offsets lmo; 532 static struct link_map_offsets *lmp = NULL; 533 534 if (lmp == NULL) 535 { 536 lmp = &lmo; 537 538 lmo.r_debug_size = 16; 539 540 lmo.r_map_offset = 4; 541 lmo.r_map_size = 4; 542 543 lmo.link_map_size = 24; 544 545 lmo.l_addr_offset = 0; 546 lmo.l_addr_size = 4; 547 548 lmo.l_name_offset = 8; 549 lmo.l_name_size = 4; 550 551 lmo.l_next_offset = 16; 552 lmo.l_next_size = 4; 553 554 lmo.l_prev_offset = 20; 555 lmo.l_prev_size = 4; 556 } 557 558 return lmp; 559} 560 561static void 562mipsfbsd_init_abi (struct gdbarch_info info, 563 struct gdbarch *gdbarch) 564{ 565 set_gdbarch_pc_in_sigtramp (gdbarch, mipsfbsd_pc_in_sigtramp); 566 567 set_gdbarch_get_longjmp_target (gdbarch, mipsfbsd_get_longjmp_target); 568 569 set_gdbarch_cannot_fetch_register (gdbarch, mipsfbsd_cannot_fetch_register); 570 set_gdbarch_cannot_store_register (gdbarch, mipsfbsd_cannot_store_register); 571 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); 577 578 /* frame sniffers */ 579 frame_unwind_append_sniffer (gdbarch, mipsfbsd_sigtramp_frame_sniffer); 580 frame_unwind_append_sniffer (gdbarch, mipsfbsd_stub_frame_sniffer); 581 582} 583 584void 585_initialize_mipsfbsd_tdep (void) 586{ 587 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF, 588 mipsfbsd_init_abi); 589 add_core_fns (&mipsfbsd_core_fns); 590 add_core_fns (&mipsfbsd_elfcore_fns); 591} 592