1204174Srrs/*********************************************************************** 2204174SrrsCopyright 2003-2006 Raza Microelectronics, Inc.(RMI). 3204174SrrsThis is a derived work from software originally provided by the external 4204174Srrsentity identified below. The licensing terms and warranties specified in 5204174Srrsthe header of the original work apply to this derived work. 6204174SrrsContribution by RMI: 7204174Srrs*****************************#RMI_1#**********************************/ 8204174Srrs/* Target-dependent code for MIPS systems running NetBSD. 9204174Srrs Copyright 2002, 2003 Free Software Foundation, Inc. 10204174Srrs Contributed by Wasabi Systems, Inc. 11204174Srrs 12204174Srrs This file is part of GDB. 13204174Srrs 14204174Srrs This program is free software; you can redistribute it and/or modify 15204174Srrs it under the terms of the GNU General Public License as published by 16204174Srrs the Free Software Foundation; either version 2 of the License, or 17204174Srrs (at your option) any later version. 18204174Srrs 19204174Srrs This program is distributed in the hope that it will be useful, 20204174Srrs but WITHOUT ANY WARRANTY; without even the implied warranty of 21204174Srrs MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22204174Srrs GNU General Public License for more details. 23204174Srrs 24204174Srrs You should have received a copy of the GNU General Public License 25204174Srrs along with this program; if not, write to the Free Software 26204174Srrs Foundation, Inc., 59 Temple Place - Suite 330, 27204174Srrs Boston, MA 02111-1307, USA. */ 28204174Srrs 29204174Srrs#include "defs.h" 30204174Srrs#include "gdbcore.h" 31204174Srrs#include "regcache.h" 32204174Srrs#include "target.h" 33204174Srrs#include "value.h" 34204174Srrs#include "osabi.h" 35204174Srrs 36204174Srrs#include "nbsd-tdep.h" 37204174Srrs#include "mipsfbsd-tdep.h" 38204174Srrs#include "mips-tdep.h" 39204174Srrs 40204174Srrs#include "solib-svr4.h" 41204174Srrs 42204174Srrs#include <sys/procfs.h> 43204174Srrs#include "gregset.h" 44204174Srrs#include "trad-frame.h" 45204174Srrs#include "frame.h" 46204174Srrs#include "frame-unwind.h" 47204174Srrs#include "bfd.h" 48204174Srrs#include "objfiles.h" 49204174Srrs 50204174Srrs/* Conveniently, GDB uses the same register numbering as the 51204174Srrs ptrace register structure used by NetBSD/mips. */ 52204174Srrs 53204174Srrsvoid 54204174Srrsmipsfbsd_supply_reg (char *regs, int regno) 55204174Srrs{ 56204174Srrs int i; 57204174Srrs 58204174Srrs for (i = 0; i <= PC_REGNUM; i++) 59204174Srrs { 60204174Srrs if (regno == i || regno == -1) 61204174Srrs { 62204174Srrs if (CANNOT_FETCH_REGISTER (i)) 63204174Srrs supply_register (i, NULL); 64204174Srrs else 65204174Srrs supply_register (i, regs + (i * mips_regsize (current_gdbarch))); 66204174Srrs } 67204174Srrs } 68204174Srrs} 69204174Srrsvoid 70204174Srrssupply_gregset (gdb_gregset_t *gregs) 71204174Srrs{ 72204174Srrs mipsfbsd_supply_reg((char *)gregs, -1); 73204174Srrs} 74204174Srrs 75204174Srrsvoid 76204174Srrsmipsfbsd_fill_reg (char *regs, int regno) 77204174Srrs{ 78204174Srrs int i; 79204174Srrs 80204174Srrs for (i = 0; i <= PC_REGNUM; i++) 81204174Srrs if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i)) 82204174Srrs regcache_collect (i, regs + (i * mips_regsize (current_gdbarch))); 83204174Srrs} 84204174Srrs 85204174Srrsvoid 86204174Srrsfill_gregset (gdb_gregset_t *gregs, int regno) 87204174Srrs{ 88204174Srrs mipsfbsd_fill_reg ((char *)gregs, regno); 89204174Srrs} 90204174Srrs 91204174Srrsvoid 92204174Srrsmipsfbsd_supply_fpreg (char *fpregs, int regno) 93204174Srrs{ 94204174Srrs int i; 95204174Srrs 96204174Srrs for (i = FP0_REGNUM; 97204174Srrs i <= mips_regnum (current_gdbarch)->fp_implementation_revision; 98204174Srrs i++) 99204174Srrs { 100204174Srrs if (regno == i || regno == -1) 101204174Srrs { 102204174Srrs if (CANNOT_FETCH_REGISTER (i)) 103204174Srrs supply_register (i, NULL); 104204174Srrs else 105204174Srrs supply_register (i, 106204174Srrs fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); 107204174Srrs } 108204174Srrs } 109204174Srrs} 110204174Srrs 111204174Srrsvoid 112204174Srrssupply_fpregset (gdb_fpregset_t *fpregs) 113204174Srrs{ 114204174Srrs mipsfbsd_supply_fpreg((char *)fpregs, -1); 115204174Srrs} 116204174Srrs 117204174Srrsvoid 118204174Srrsmipsfbsd_fill_fpreg (char *fpregs, int regno) 119204174Srrs{ 120204174Srrs int i; 121204174Srrs 122204174Srrs for (i = FP0_REGNUM; i <= mips_regnum (current_gdbarch)->fp_control_status; 123204174Srrs i++) 124204174Srrs if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i)) 125204174Srrs regcache_collect (i, 126204174Srrs fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); 127204174Srrs} 128204174Srrs 129204174Srrsvoid 130204174Srrsfill_fpregset (gdb_fpregset_t *fpregs, int regno) 131204174Srrs{ 132204174Srrs mipsfbsd_fill_fpreg ((char *)fpregs, regno); 133204174Srrs} 134204174Srrs 135204174Srrsstatic void 136204174Srrsfetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, 137204174Srrs CORE_ADDR ignore) 138204174Srrs{ 139204174Srrs char *regs, *fpregs; 140204174Srrs 141204174Srrs /* We get everything from one section. */ 142204174Srrs if (which != 0) 143204174Srrs return; 144204174Srrs 145204174Srrs regs = core_reg_sect; 146204174Srrs fpregs = core_reg_sect + SIZEOF_STRUCT_REG; 147204174Srrs 148204174Srrs /* Integer registers. */ 149204174Srrs mipsfbsd_supply_reg (regs, -1); 150204174Srrs 151204174Srrs /* Floating point registers. */ 152204174Srrs mipsfbsd_supply_fpreg (fpregs, -1); 153204174Srrs} 154204174Srrs 155204174Srrsstatic void 156204174Srrsfetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, 157204174Srrs CORE_ADDR ignore) 158204174Srrs{ 159204174Srrs switch (which) 160204174Srrs { 161204174Srrs case 0: /* Integer registers. */ 162204174Srrs if (core_reg_size != SIZEOF_STRUCT_REG) 163204174Srrs warning ("Wrong size register set in core file."); 164204174Srrs else 165204174Srrs mipsfbsd_supply_reg (core_reg_sect, -1); 166204174Srrs break; 167204174Srrs 168204174Srrs case 2: /* Floating point registers. */ 169204174Srrs if (core_reg_size != SIZEOF_STRUCT_FPREG) 170204174Srrs warning ("Wrong size register set in core file."); 171204174Srrs else 172204174Srrs mipsfbsd_supply_fpreg (core_reg_sect, -1); 173204174Srrs break; 174204174Srrs 175204174Srrs default: 176204174Srrs /* Don't know what kind of register request this is; just ignore it. */ 177204174Srrs break; 178204174Srrs } 179204174Srrs} 180204174Srrs 181204174Srrsstatic struct core_fns mipsfbsd_core_fns = 182204174Srrs{ 183204174Srrs bfd_target_unknown_flavour, /* core_flavour */ 184204174Srrs default_check_format, /* check_format */ 185204174Srrs default_core_sniffer, /* core_sniffer */ 186204174Srrs fetch_core_registers, /* core_read_registers */ 187204174Srrs NULL /* next */ 188204174Srrs}; 189204174Srrs 190214652Sgonzostatic struct core_fns mipsfbsd_elfcore_fns = 191214652Sgonzo{ 192214652Sgonzo bfd_target_elf_flavour, /* core_flavour */ 193214652Sgonzo default_check_format, /* check_format */ 194214652Sgonzo default_core_sniffer, /* core_sniffer */ 195214652Sgonzo fetch_elfcore_registers, /* core_read_registers */ 196214652Sgonzo NULL /* next */ 197214652Sgonzo}; 198204174Srrs 199204174Srrs/* 200204174Srrs * MIPSFBSD Offsets 201204174Srrs * 0x7fff0000 User high mem -> USRSTACK [64K] 202204174Srrs * 203204174Srrs * 0x7ffefff0 ps_strings -> 16 bytes 204204174Srrs * 205204174Srrs * 0x7ffeffec sigcode -> 44 bytes 206204174Srrs * 207204174Srrs * 0x7ffeffc4 sigcode end env strings etc start 208232910Sjmallett * 209232910Sjmallett * XXX This is out-of-date and varies by ABI. 210204174Srrs */ 211204174Srrs#define MIPS_FBSD_SIGTRAMP_START (0x7ffeffc4) 212204174Srrs#define MIPS_FBSD_SIGTRAMP_END (0x7ffeffec) 213204174Srrs#define MIPS_FBSD_SIGTRAMP_STACK_MOD_START (0x7ffeffc8) 214204174Srrs#define MIPS_FBSD_SIGTRAMP_STACK_MOD_END (0x7ffeffd8) 215204174Srrs 216204174Srrsstatic LONGEST 217204174Srrsmipsfbsd_sigtramp_offset (CORE_ADDR pc) 218204174Srrs{ 219204174Srrs return pc < MIPS_FBSD_SIGTRAMP_END && 220204174Srrs pc >= MIPS_FBSD_SIGTRAMP_START ? 1 : -1; 221204174Srrs} 222204174Srrs 223204174Srrsstatic int 224204174Srrsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) 225204174Srrs{ 226204174Srrs return (name && strcmp (name, "__sigtramp") == 0); 227204174Srrs} 228204174Srrs 229204174Srrsstatic int 230204174Srrsmipsfbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) 231204174Srrs{ 232204174Srrs return (fbsd_pc_in_sigtramp (pc, func_name) 233204174Srrs || mipsfbsd_sigtramp_offset (pc) >= 0); 234204174Srrs} 235204174Srrs 236204174Srrsstatic int 237204174Srrsis_sigtramp_sp_modified (CORE_ADDR pc) 238204174Srrs{ 239204174Srrs return (pc >= MIPS_FBSD_SIGTRAMP_STACK_MOD_START && 240204174Srrs pc <= MIPS_FBSD_SIGTRAMP_STACK_MOD_END); 241204174Srrs} 242204174Srrs 243204174Srrs 244204174Srrs/* Figure out where the longjmp will land. We expect that we have 245204174Srrs just entered longjmp and haven't yet setup the stack frame, so 246204174Srrs the args are still in the argument regs. A0_REGNUM points at the 247204174Srrs jmp_buf structure from which we extract the PC that we will land 248204174Srrs at. The PC is copied into *pc. This routine returns true on 249204174Srrs success. */ 250204174Srrs 251204174Srrs#define FBSD_MIPS_JB_PC (12) 252204174Srrs#define FBSD_MIPS_JB_ELEMENT_SIZE mips_regsize (current_gdbarch) 253204174Srrs#define FBSD_MIPS_JB_OFFSET (FBSD_MIPS_JB_PC * \ 254204174Srrs FBSD_MIPS_JB_ELEMENT_SIZE) 255204174Srrs 256204174Srrsstatic int 257204174Srrsmipsfbsd_get_longjmp_target (CORE_ADDR *pc) 258204174Srrs{ 259204174Srrs CORE_ADDR jb_addr; 260204174Srrs char *buf; 261204174Srrs 262204174Srrs buf = alloca (FBSD_MIPS_JB_ELEMENT_SIZE); 263204174Srrs 264204174Srrs jb_addr = read_register (A0_REGNUM); 265204174Srrs 266204174Srrs if (target_read_memory (jb_addr + FBSD_MIPS_JB_OFFSET, buf, 267204174Srrs FBSD_MIPS_JB_ELEMENT_SIZE)) 268204174Srrs return 0; 269204174Srrs 270204174Srrs *pc = extract_unsigned_integer (buf, FBSD_MIPS_JB_ELEMENT_SIZE); 271204174Srrs 272204174Srrs return 1; 273204174Srrs} 274204174Srrs 275204174Srrsstatic int 276204174Srrsmipsfbsd_cannot_fetch_register (int regno) 277204174Srrs{ 278204174Srrs return (regno == ZERO_REGNUM 279204174Srrs || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); 280204174Srrs /* XXX TODO: Are there other registers that we cannot fetch ? */ 281204174Srrs} 282204174Srrs 283204174Srrsstatic int 284204174Srrsmipsfbsd_cannot_store_register (int regno) 285204174Srrs{ 286204174Srrs return (regno == ZERO_REGNUM 287204174Srrs || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); 288204174Srrs /* XXX TODO: Are there other registers that we cannot write ? */ 289204174Srrs} 290204174Srrs 291204174Srrs/* 292204174Srrs * This structure is defined in mips-tdep.c. 293204174Srrs */ 294204174Srrsstruct mips_frame_cache 295204174Srrs{ 296204174Srrs CORE_ADDR base; 297204174Srrs struct trad_frame_saved_reg *saved_regs; 298204174Srrs}; 299204174Srrs 300204174Srrs/* 301204174Srrs * Prologue cache for sigtramp frame 302204174Srrs * When we land in sigtramp, sigcontext is saved on the 303204174Srrs * stack just below the sigtramp's stack frame. We have 304204174Srrs * the Registers saved at fixed offsets on the stack. 305204174Srrs */ 306204174Srrs 307204174Srrs#define MIPS_FBSD_SIGTRAMP_STACK_SIZE (48) 308204174Srrs#define MIPS_FBSD_SIGCONTEXT_REG_OFFSET (32) 309204174Srrs 310204174Srrsstatic struct mips_frame_cache * 311204174Srrsmipsfbsd_sigtramp_frame_cache (struct frame_info *next_frame, 312204174Srrs void **this_cache) 313204174Srrs{ 314204174Srrs struct mips_frame_cache *cache; 315204174Srrs CORE_ADDR gregs_addr, sp, pc; 316204174Srrs int regnum; 317204174Srrs int sigtramp_stack_size; 318204174Srrs 319204174Srrs if (*this_cache) 320204174Srrs return *this_cache; 321204174Srrs 322204174Srrs cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); 323204174Srrs *this_cache = cache; 324204174Srrs 325204174Srrs cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 326204174Srrs 327204174Srrs /* 328204174Srrs * Get sp of next frame which is the adjusted sp of 329204174Srrs * tramp code. 330204174Srrs */ 331204174Srrs sp = frame_unwind_register_unsigned(next_frame, NUM_REGS + SP_REGNUM); 332204174Srrs pc = frame_unwind_register_unsigned(next_frame, NUM_REGS + PC_REGNUM); 333204174Srrs sigtramp_stack_size = is_sigtramp_sp_modified(pc) ? 334204174Srrs MIPS_FBSD_SIGTRAMP_STACK_SIZE : 0; 335204174Srrs gregs_addr = sp + sigtramp_stack_size + MIPS_FBSD_SIGCONTEXT_REG_OFFSET; 336204174Srrs 337204174Srrs for (regnum = 0; regnum < PC_REGNUM; regnum++) { 338204174Srrs cache->saved_regs[NUM_REGS + regnum].addr = gregs_addr + 339204174Srrs regnum * mips_regsize (current_gdbarch); 340204174Srrs } 341204174Srrs /* Only retrieve PC and SP */ 342204174Srrs cache->saved_regs[NUM_REGS + SP_REGNUM].addr = gregs_addr + 343204174Srrs SP_REGNUM * ( mips_regsize (current_gdbarch)); 344204174Srrs 345204174Srrs cache->saved_regs[NUM_REGS + RA_REGNUM].addr = gregs_addr + 346204174Srrs RA_REGNUM * ( mips_regsize (current_gdbarch)); 347204174Srrs 348204174Srrs cache->base = get_frame_memory_unsigned (next_frame, 349204174Srrs cache->saved_regs[NUM_REGS + SP_REGNUM].addr, 350204174Srrs mips_regsize (current_gdbarch)); 351204174Srrs 352204174Srrs /* Todo: Floating point registers */ 353204174Srrs 354204174Srrs cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc] 355204174Srrs = cache->saved_regs[NUM_REGS + RA_REGNUM]; 356204174Srrs 357204174Srrs return *this_cache; 358204174Srrs} 359204174Srrs 360204174Srrsstatic void 361204174Srrsmipsfbsd_sigtramp_frame_this_id (struct frame_info *next_frame, 362204174Srrs void **this_cache, 363204174Srrs struct frame_id *this_id) 364204174Srrs{ 365204174Srrs struct mips_frame_cache *cache = 366204174Srrs mipsfbsd_sigtramp_frame_cache (next_frame, this_cache); 367204174Srrs 368204174Srrs (*this_id) = frame_id_build (cache->base, 369204174Srrs cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr); 370204174Srrs} 371204174Srrs 372204174Srrsstatic void 373204174Srrsmipsfbsd_sigtramp_frame_prev_register (struct frame_info *next_frame, 374204174Srrs void **this_cache, 375204174Srrs int regnum, int *optimizedp, 376204174Srrs enum lval_type *lvalp, 377204174Srrs CORE_ADDR *addrp, 378204174Srrs int *realnump, void *valuep) 379204174Srrs{ 380204174Srrs struct mips_frame_cache *cache = 381204174Srrs mipsfbsd_sigtramp_frame_cache (next_frame, this_cache); 382204174Srrs 383204174Srrs trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 384204174Srrs optimizedp, lvalp, addrp, realnump, valuep); 385204174Srrs} 386204174Srrs 387204174Srrs 388204174Srrsstatic const struct frame_unwind mipsfbsd_sigtramp_frame_unwind = 389204174Srrs{ 390204174Srrs SIGTRAMP_FRAME, 391204174Srrs mipsfbsd_sigtramp_frame_this_id, 392204174Srrs mipsfbsd_sigtramp_frame_prev_register 393204174Srrs}; 394204174Srrs 395204174Srrsstatic const struct frame_unwind * 396204174Srrsmipsfbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) 397204174Srrs{ 398204174Srrs CORE_ADDR pc = frame_pc_unwind (next_frame); 399204174Srrs char *name; 400204174Srrs 401204174Srrs find_pc_partial_function (pc, &name, NULL, NULL); 402204174Srrs if (mipsfbsd_pc_in_sigtramp (pc, name) ) 403204174Srrs return &mipsfbsd_sigtramp_frame_unwind; 404204174Srrs 405204174Srrs return NULL; 406204174Srrs} 407204174Srrs 408204174Srrs/* 409204174Srrs * Find out if PC has landed into dynamic library stub. 410204174Srrs * We can find it by seeing if the name of the object 411204174Srrs * file section where the PC lies is "MIPS.stubs" 412204174Srrs */ 413204174Srrs 414204174Srrsint 415204174Srrsmipsfbsd_in_stub_section (CORE_ADDR pc, char *name) 416204174Srrs{ 417204174Srrs struct obj_section *s; 418204174Srrs int retval = 0; 419204174Srrs 420204174Srrs s = find_pc_section (pc); 421204174Srrs 422204174Srrs retval = (s != NULL 423204174Srrs && s->the_bfd_section->name != NULL 424204174Srrs && strcmp (s->the_bfd_section->name, ".MIPS.stubs") == 0); 425204174Srrs return (retval); 426204174Srrs} 427204174Srrs 428204174Srrs 429204174Srrs/* 430204174Srrs * Prologue cache for dynamic library stub frame. 431204174Srrs * This stub does not modify the SP, so we set the 432204174Srrs * cache base to calling frame's SP 433204174Srrs */ 434204174Srrsstatic struct mips_frame_cache * 435204174Srrsmipsfbsd_stub_frame_cache (struct frame_info *next_frame, 436204174Srrs void **this_cache) 437204174Srrs{ 438204174Srrs struct mips_frame_cache *cache; 439204174Srrs 440204174Srrs if (*this_cache) 441204174Srrs return *this_cache; 442204174Srrs 443204174Srrs cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); 444204174Srrs *this_cache = cache; 445204174Srrs 446204174Srrs cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 447204174Srrs 448204174Srrs 449204174Srrs cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].realreg = 450204174Srrs NUM_REGS + RA_REGNUM; 451204174Srrs cache->base = frame_unwind_register_unsigned (next_frame, 452204174Srrs NUM_REGS + SP_REGNUM); 453204174Srrs 454204174Srrs return (*this_cache); 455204174Srrs} 456204174Srrs 457204174Srrs 458204174Srrsstatic void 459204174Srrsmipsfbsd_stub_frame_this_id (struct frame_info *next_frame, 460204174Srrs void **this_cache, 461204174Srrs struct frame_id *this_id) 462204174Srrs{ 463204174Srrs struct mips_frame_cache *cache = 464204174Srrs mipsfbsd_stub_frame_cache (next_frame, this_cache); 465204174Srrs 466204174Srrs (*this_id) = frame_id_build (cache->base, 467204174Srrs cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc].addr); 468204174Srrs} 469204174Srrs 470204174Srrsstatic void 471204174Srrsmipsfbsd_stub_frame_prev_register (struct frame_info *next_frame, 472204174Srrs void **this_cache, 473204174Srrs int regnum, int *optimizedp, 474204174Srrs enum lval_type *lvalp, CORE_ADDR *addrp, 475204174Srrs int *realnump, void *valuep) 476204174Srrs{ 477204174Srrs struct mips_frame_cache *cache = 478204174Srrs mipsfbsd_stub_frame_cache (next_frame, this_cache); 479204174Srrs 480204174Srrs trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 481204174Srrs optimizedp, lvalp, addrp, realnump, valuep); 482204174Srrs} 483204174Srrs 484204174Srrs 485204174Srrs 486204174Srrsstatic const struct frame_unwind mipsfbsd_stub_frame_unwind = { 487204174Srrs NORMAL_FRAME, 488204174Srrs mipsfbsd_stub_frame_this_id, 489204174Srrs mipsfbsd_stub_frame_prev_register 490204174Srrs}; 491204174Srrs 492204174Srrsstatic const struct frame_unwind * 493204174Srrsmipsfbsd_stub_frame_sniffer (struct frame_info *next_frame) 494204174Srrs{ 495204174Srrs CORE_ADDR pc = frame_pc_unwind (next_frame); 496204174Srrs 497204174Srrs if (mipsfbsd_in_stub_section(pc, NULL)) 498204174Srrs return &mipsfbsd_stub_frame_unwind; 499204174Srrs 500204174Srrs return NULL; 501204174Srrs} 502204174Srrs 503204174Srrs/* 504204174Srrs * typedef struct link_map { 505204174Srrs * caddr_t l_addr; /* Base Address of library 506204174Srrs * #ifdef __mips__ 507204174Srrs * caddr_t l_offs; /* Load Offset of library 508204174Srrs * #endif 509204174Srrs * const char *l_name; /* Absolute Path to Library 510204174Srrs * const void *l_ld; /* Pointer to .dynamic in memory 511204174Srrs * struct link_map *l_next, *l_prev; /* linked list of of mapped libs 512204174Srrs * } Link_map; 513204174Srrs * 514204174Srrs * struct r_debug { 515204174Srrs * int r_version; /* not used 516204174Srrs * struct link_map *r_map; /* list of loaded images 517204174Srrs * void (*r_brk)(struct r_debug *, struct link_map *); 518204174Srrs * /* pointer to break point 519204174Srrs * enum { 520204174Srrs * RT_CONSISTENT, /* things are stable 521204174Srrs * RT_ADD, /* adding a shared library 522204174Srrs * RT_DELETE /* removing a shared library 523204174Srrs * } r_state; 524204174Srrs * }; 525204174Srrs * 526204174Srrs */ 527204174Srrs 528204174Srrsstatic struct link_map_offsets * 529204174Srrsmipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets (void) 530204174Srrs{ 531204174Srrs static struct link_map_offsets lmo; 532204174Srrs static struct link_map_offsets *lmp = NULL; 533204174Srrs 534204174Srrs if (lmp == NULL) 535204174Srrs { 536204174Srrs lmp = &lmo; 537204174Srrs 538204174Srrs lmo.r_debug_size = 16; 539204174Srrs 540204174Srrs lmo.r_map_offset = 4; 541204174Srrs lmo.r_map_size = 4; 542204174Srrs 543204174Srrs lmo.link_map_size = 24; 544204174Srrs 545204174Srrs lmo.l_addr_offset = 0; 546204174Srrs lmo.l_addr_size = 4; 547204174Srrs 548204174Srrs lmo.l_name_offset = 8; 549204174Srrs lmo.l_name_size = 4; 550204174Srrs 551204174Srrs lmo.l_next_offset = 16; 552204174Srrs lmo.l_next_size = 4; 553204174Srrs 554204174Srrs lmo.l_prev_offset = 20; 555204174Srrs lmo.l_prev_size = 4; 556204174Srrs } 557204174Srrs 558204174Srrs return lmp; 559204174Srrs} 560204174Srrs 561204174Srrsstatic void 562204174Srrsmipsfbsd_init_abi (struct gdbarch_info info, 563204174Srrs struct gdbarch *gdbarch) 564204174Srrs{ 565204174Srrs set_gdbarch_pc_in_sigtramp (gdbarch, mipsfbsd_pc_in_sigtramp); 566204174Srrs 567204174Srrs set_gdbarch_get_longjmp_target (gdbarch, mipsfbsd_get_longjmp_target); 568204174Srrs 569204174Srrs set_gdbarch_cannot_fetch_register (gdbarch, mipsfbsd_cannot_fetch_register); 570204174Srrs set_gdbarch_cannot_store_register (gdbarch, mipsfbsd_cannot_store_register); 571204174Srrs 572204174Srrs set_gdbarch_software_single_step (gdbarch, mips_software_single_step); 573204174Srrs set_solib_svr4_fetch_link_map_offsets (gdbarch, 574204174Srrs mipsfbsd_ilp32_solib_svr4_fetch_link_map_offsets); 575204174Srrs set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 576204174Srrs set_gdbarch_in_solib_call_trampoline (gdbarch, mipsfbsd_in_stub_section); 577204174Srrs 578204174Srrs /* frame sniffers */ 579204174Srrs frame_unwind_append_sniffer (gdbarch, mipsfbsd_sigtramp_frame_sniffer); 580204174Srrs frame_unwind_append_sniffer (gdbarch, mipsfbsd_stub_frame_sniffer); 581204174Srrs 582204174Srrs} 583204174Srrs 584204174Srrsvoid 585204174Srrs_initialize_mipsfbsd_tdep (void) 586204174Srrs{ 587204174Srrs gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF, 588204174Srrs mipsfbsd_init_abi); 589214652Sgonzo add_core_fns (&mipsfbsd_core_fns); 590214652Sgonzo add_core_fns (&mipsfbsd_elfcore_fns); 591204174Srrs} 592