1 /* Target-dependent code for Solaris UltraSPARC. 2 3 Copyright 2003, 2004 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #include "defs.h" 23 #include "frame.h" 24 #include "frame-unwind.h" 25 #include "gdbarch.h" 26 #include "symtab.h" 27 #include "objfiles.h" 28 #include "osabi.h" 29 #include "trad-frame.h" 30 31 #include "gdb_assert.h" 32 33 #include "sparc64-tdep.h" 34 #include "solib-svr4.h" 35 36 /* From <sys/regset.h>. */ 37 const struct sparc_gregset sparc64_sol2_gregset = 38 { 39 32 * 8, /* "tstate" */ 40 33 * 8, /* %pc */ 41 34 * 8, /* %npc */ 42 35 * 8, /* %y */ 43 -1, /* %wim */ 44 -1, /* %tbr */ 45 1 * 8, /* %g1 */ 46 16 * 8, /* %l0 */ 47 8 /* sizeof (%y) */ 48 }; 49 50 51 static struct sparc_frame_cache * 52 sparc64_sol2_sigtramp_frame_cache (struct frame_info *next_frame, 53 void **this_cache) 54 { 55 struct sparc_frame_cache *cache; 56 CORE_ADDR mcontext_addr, addr; 57 int regnum; 58 59 if (*this_cache) 60 return *this_cache; 61 62 cache = sparc_frame_cache (next_frame, this_cache); 63 gdb_assert (cache == *this_cache); 64 65 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 66 67 /* The third argument is a pointer to an instance of `ucontext_t', 68 which has a member `uc_mcontext' that contains the saved 69 registers. */ 70 regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); 71 mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 64; 72 73 cache->saved_regs[SPARC64_CCR_REGNUM].addr = mcontext_addr + 0 * 8; 74 cache->saved_regs[SPARC64_PC_REGNUM].addr = mcontext_addr + 1 * 8; 75 cache->saved_regs[SPARC64_NPC_REGNUM].addr = mcontext_addr + 2 * 8; 76 cache->saved_regs[SPARC64_Y_REGNUM].addr = mcontext_addr + 3 * 8; 77 cache->saved_regs[SPARC64_ASI_REGNUM].addr = mcontext_addr + 19 * 8; 78 cache->saved_regs[SPARC64_FPRS_REGNUM].addr = mcontext_addr + 20 * 8; 79 80 /* Since %g0 is always zero, keep the identity encoding. */ 81 for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 8; 82 regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) 83 cache->saved_regs[regnum].addr = addr; 84 85 if (get_frame_memory_unsigned (next_frame, mcontext_addr + 21 * 8, 8)) 86 { 87 /* The register windows haven't been flushed. */ 88 for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) 89 trad_frame_set_unknown (cache->saved_regs, regnum); 90 } 91 else 92 { 93 CORE_ADDR sp; 94 95 addr = cache->saved_regs[SPARC_SP_REGNUM].addr; 96 sp = get_frame_memory_unsigned (next_frame, addr, 8); 97 for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; 98 regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) 99 cache->saved_regs[regnum].addr = addr; 100 } 101 102 return cache; 103 } 104 105 static void 106 sparc64_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, 107 void **this_cache, 108 struct frame_id *this_id) 109 { 110 struct sparc_frame_cache *cache = 111 sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); 112 113 (*this_id) = frame_id_build (cache->base, cache->pc); 114 } 115 116 static void 117 sparc64_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, 118 void **this_cache, 119 int regnum, int *optimizedp, 120 enum lval_type *lvalp, 121 CORE_ADDR *addrp, 122 int *realnump, void *valuep) 123 { 124 struct sparc_frame_cache *cache = 125 sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); 126 127 trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum, 128 optimizedp, lvalp, addrp, realnump, valuep); 129 } 130 131 static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = 132 { 133 SIGTRAMP_FRAME, 134 sparc64_sol2_sigtramp_frame_this_id, 135 sparc64_sol2_sigtramp_frame_prev_register 136 }; 137 138 static const struct frame_unwind * 139 sparc64_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) 140 { 141 CORE_ADDR pc = frame_pc_unwind (next_frame); 142 char *name; 143 144 find_pc_partial_function (pc, &name, NULL, NULL); 145 if (sparc_sol2_pc_in_sigtramp (pc, name)) 146 return &sparc64_sol2_sigtramp_frame_unwind; 147 148 return NULL; 149 } 150 151 152 void 153 sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 154 { 155 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 156 157 frame_unwind_append_sniffer (gdbarch, sparc64_sol2_sigtramp_frame_sniffer); 158 159 sparc64_init_abi (info, gdbarch); 160 161 /* Solaris has SVR4-style shared libraries... */ 162 set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); 163 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 164 set_solib_svr4_fetch_link_map_offsets 165 (gdbarch, svr4_lp64_fetch_link_map_offsets); 166 167 /* ...which means that we need some special handling when doing 168 prologue analysis. */ 169 tdep->plt_entry_size = 16; 170 171 /* Solaris has kernel-assisted single-stepping support. */ 172 set_gdbarch_software_single_step (gdbarch, NULL); 173 } 174 175 176 /* Provide a prototype to silence -Wmissing-prototypes. */ 177 void _initialize_sparc64_sol2_tdep (void); 178 179 void 180 _initialize_sparc64_sol2_tdep (void) 181 { 182 gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, 183 GDB_OSABI_SOLARIS, sparc64_sol2_init_abi); 184 } 185