GDB (API)
/home/stan/gdb/src/gdb/sparc64-linux-tdep.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines