GDB (API)
|
00001 /* Target-dependent code for GNU/Linux UltraSPARC. 00002 00003 Copyright (C) 2003-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "frame.h" 00022 #include "frame-unwind.h" 00023 #include "dwarf2-frame.h" 00024 #include "regset.h" 00025 #include "regcache.h" 00026 #include "gdbarch.h" 00027 #include "gdbcore.h" 00028 #include "osabi.h" 00029 #include "solib-svr4.h" 00030 #include "symtab.h" 00031 #include "trad-frame.h" 00032 #include "tramp-frame.h" 00033 #include "xml-syscall.h" 00034 #include "linux-tdep.h" 00035 00036 /* The syscall's XML filename for sparc 64-bit. */ 00037 #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml" 00038 00039 #include "sparc64-tdep.h" 00040 00041 /* Signal trampoline support. */ 00042 00043 static void sparc64_linux_sigframe_init (const struct tramp_frame *self, 00044 struct frame_info *this_frame, 00045 struct trad_frame_cache *this_cache, 00046 CORE_ADDR func); 00047 00048 /* See sparc-linux-tdep.c for details. Note that 64-bit binaries only 00049 use RT signals. */ 00050 00051 static const struct tramp_frame sparc64_linux_rt_sigframe = 00052 { 00053 SIGTRAMP_FRAME, 00054 4, 00055 { 00056 { 0x82102065, -1 }, /* mov __NR_rt_sigreturn, %g1 */ 00057 { 0x91d0206d, -1 }, /* ta 0x6d */ 00058 { TRAMP_SENTINEL_INSN, -1 } 00059 }, 00060 sparc64_linux_sigframe_init 00061 }; 00062 00063 static void 00064 sparc64_linux_sigframe_init (const struct tramp_frame *self, 00065 struct frame_info *this_frame, 00066 struct trad_frame_cache *this_cache, 00067 CORE_ADDR func) 00068 { 00069 CORE_ADDR base, addr, sp_addr; 00070 int regnum; 00071 00072 base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM); 00073 base += 128; 00074 00075 /* Offsets from <bits/sigcontext.h>. */ 00076 00077 /* Since %g0 is always zero, keep the identity encoding. */ 00078 addr = base + 8; 00079 sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8); 00080 for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) 00081 { 00082 trad_frame_set_reg_addr (this_cache, regnum, addr); 00083 addr += 8; 00084 } 00085 00086 trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0); 00087 trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8); 00088 trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16); 00089 trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24); 00090 trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28); 00091 00092 base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM); 00093 if (base & 1) 00094 base += BIAS; 00095 00096 addr = get_frame_memory_unsigned (this_frame, sp_addr, 8); 00097 if (addr & 1) 00098 addr += BIAS; 00099 00100 for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) 00101 { 00102 trad_frame_set_reg_addr (this_cache, regnum, addr); 00103 addr += 8; 00104 } 00105 trad_frame_set_id (this_cache, frame_id_build (base, func)); 00106 } 00107 00108 /* Return the address of a system call's alternative return 00109 address. */ 00110 00111 static CORE_ADDR 00112 sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn) 00113 { 00114 if (insn == 0x91d0206d) 00115 { 00116 struct gdbarch *gdbarch = get_frame_arch (frame); 00117 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00118 00119 ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM); 00120 if (sp & 1) 00121 sp += BIAS; 00122 00123 /* The kernel puts the sigreturn registers on the stack, 00124 and this is where the signal unwinding state is take from 00125 when returning from a signal. 00126 00127 A siginfo_t sits 192 bytes from the base of the stack. This 00128 siginfo_t is 128 bytes, and is followed by the sigreturn 00129 register save area. The saved PC sits at a 136 byte offset 00130 into there. */ 00131 00132 return read_memory_unsigned_integer (sp + 192 + 128 + 136, 00133 8, byte_order); 00134 } 00135 00136 return 0; 00137 } 00138 00139 00140 const struct sparc_gregset sparc64_linux_core_gregset = 00141 { 00142 32 * 8, /* %tstate */ 00143 33 * 8, /* %tpc */ 00144 34 * 8, /* %tnpc */ 00145 35 * 8, /* %y */ 00146 -1, /* %wim */ 00147 -1, /* %tbr */ 00148 1 * 8, /* %g1 */ 00149 16 * 8, /* %l0 */ 00150 8, /* y size */ 00151 }; 00152 00153 00154 static void 00155 sparc64_linux_supply_core_gregset (const struct regset *regset, 00156 struct regcache *regcache, 00157 int regnum, const void *gregs, size_t len) 00158 { 00159 sparc64_supply_gregset (&sparc64_linux_core_gregset, 00160 regcache, regnum, gregs); 00161 } 00162 00163 static void 00164 sparc64_linux_collect_core_gregset (const struct regset *regset, 00165 const struct regcache *regcache, 00166 int regnum, void *gregs, size_t len) 00167 { 00168 sparc64_collect_gregset (&sparc64_linux_core_gregset, 00169 regcache, regnum, gregs); 00170 } 00171 00172 static void 00173 sparc64_linux_supply_core_fpregset (const struct regset *regset, 00174 struct regcache *regcache, 00175 int regnum, const void *fpregs, size_t len) 00176 { 00177 sparc64_supply_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs); 00178 } 00179 00180 static void 00181 sparc64_linux_collect_core_fpregset (const struct regset *regset, 00182 const struct regcache *regcache, 00183 int regnum, void *fpregs, size_t len) 00184 { 00185 sparc64_collect_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs); 00186 } 00187 00188 /* Set the program counter for process PTID to PC. */ 00189 00190 #define TSTATE_SYSCALL 0x0000000000000020ULL 00191 00192 static void 00193 sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) 00194 { 00195 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00196 ULONGEST state; 00197 00198 regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc); 00199 regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4); 00200 00201 /* Clear the "in syscall" bit to prevent the kernel from 00202 messing with the PCs we just installed, if we happen to be 00203 within an interrupted system call that the kernel wants to 00204 restart. 00205 00206 Note that after we return from the dummy call, the TSTATE et al. 00207 registers will be automatically restored, and the kernel 00208 continues to restart the system call at this point. */ 00209 regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state); 00210 state &= ~TSTATE_SYSCALL; 00211 regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state); 00212 } 00213 00214 static LONGEST 00215 sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, 00216 ptid_t ptid) 00217 { 00218 struct regcache *regcache = get_thread_regcache (ptid); 00219 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00220 /* The content of a register. */ 00221 gdb_byte buf[8]; 00222 /* The result. */ 00223 LONGEST ret; 00224 00225 /* Getting the system call number from the register. 00226 When dealing with the sparc architecture, this information 00227 is stored at the %g1 register. */ 00228 regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf); 00229 00230 ret = extract_signed_integer (buf, 8, byte_order); 00231 00232 return ret; 00233 } 00234 00235 00236 00237 static void 00238 sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00239 { 00240 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00241 00242 linux_init_abi (info, gdbarch); 00243 00244 tdep->gregset = regset_alloc (gdbarch, sparc64_linux_supply_core_gregset, 00245 sparc64_linux_collect_core_gregset); 00246 tdep->sizeof_gregset = 288; 00247 00248 tdep->fpregset = regset_alloc (gdbarch, sparc64_linux_supply_core_fpregset, 00249 sparc64_linux_collect_core_fpregset); 00250 tdep->sizeof_fpregset = 280; 00251 00252 tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe); 00253 00254 /* Hook in the DWARF CFI frame unwinder. */ 00255 dwarf2_append_unwinders (gdbarch); 00256 00257 sparc64_init_abi (info, gdbarch); 00258 00259 /* GNU/Linux has SVR4-style shared libraries... */ 00260 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 00261 set_solib_svr4_fetch_link_map_offsets 00262 (gdbarch, svr4_lp64_fetch_link_map_offsets); 00263 00264 /* ...which means that we need some special handling when doing 00265 prologue analysis. */ 00266 tdep->plt_entry_size = 16; 00267 00268 /* Enable TLS support. */ 00269 set_gdbarch_fetch_tls_load_module_address (gdbarch, 00270 svr4_fetch_objfile_link_map); 00271 00272 /* Make sure we can single-step over signal return system calls. */ 00273 tdep->step_trap = sparc64_linux_step_trap; 00274 00275 set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc); 00276 00277 /* Functions for 'catch syscall'. */ 00278 set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC64); 00279 set_gdbarch_get_syscall_number (gdbarch, 00280 sparc64_linux_get_syscall_number); 00281 } 00282 00283 00284 /* Provide a prototype to silence -Wmissing-prototypes. */ 00285 extern void _initialize_sparc64_linux_tdep (void); 00286 00287 void 00288 _initialize_sparc64_linux_tdep (void) 00289 { 00290 gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, 00291 GDB_OSABI_LINUX, sparc64_linux_init_abi); 00292 }