GDB (API)
/home/stan/gdb/src/gdb/sparc-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for SPARC.
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 "inferior.h"
00022 #include "regcache.h"
00023 #include "target.h"
00024 
00025 #include "gdb_assert.h"
00026 #include <signal.h>
00027 #include "gdb_string.h"
00028 #include <sys/ptrace.h>
00029 #include "gdb_wait.h"
00030 #ifdef HAVE_MACHINE_REG_H
00031 #include <machine/reg.h>
00032 #endif
00033 
00034 #include "sparc-tdep.h"
00035 #include "sparc-nat.h"
00036 #include "inf-ptrace.h"
00037 
00038 /* With some trickery we can use the code in this file for most (if
00039    not all) ptrace(2) based SPARC systems, which includes SunOS 4,
00040    GNU/Linux and the various SPARC BSD's.
00041 
00042    First, we need a data structure for use with ptrace(2).  SunOS has
00043    `struct regs' and `struct fp_status' in <machine/reg.h>.  BSD's
00044    have `struct reg' and `struct fpreg' in <machine/reg.h>.  GNU/Linux
00045    has the same structures as SunOS 4, but they're in <asm/reg.h>,
00046    which is a kernel header.  As a general rule we avoid including
00047    GNU/Linux kernel headers.  Fortunately GNU/Linux has a `gregset_t'
00048    and a `fpregset_t' that are equivalent to `struct regs' and `struct
00049    fp_status' in <sys/ucontext.h>, which is automatically included by
00050    <signal.h>.  Settling on using the `gregset_t' and `fpregset_t'
00051    typedefs, providing them for the other systems, therefore solves
00052    the puzzle.  */
00053 
00054 #ifdef HAVE_MACHINE_REG_H
00055 #ifdef HAVE_STRUCT_REG
00056 typedef struct reg gregset_t;
00057 typedef struct fpreg fpregset_t;
00058 #else 
00059 typedef struct regs gregset_t;
00060 typedef struct fp_status fpregset_t;
00061 #endif
00062 #endif
00063 
00064 /* Second, we need to remap the BSD ptrace(2) requests to their SunOS
00065    equivalents.  GNU/Linux already follows SunOS here.  */
00066 
00067 #ifndef PTRACE_GETREGS
00068 #define PTRACE_GETREGS PT_GETREGS
00069 #endif
00070 
00071 #ifndef PTRACE_SETREGS
00072 #define PTRACE_SETREGS PT_SETREGS
00073 #endif
00074 
00075 #ifndef PTRACE_GETFPREGS
00076 #define PTRACE_GETFPREGS PT_GETFPREGS
00077 #endif
00078 
00079 #ifndef PTRACE_SETFPREGS
00080 #define PTRACE_SETFPREGS PT_SETFPREGS
00081 #endif
00082 
00083 /* Register set description.  */
00084 const struct sparc_gregset *sparc_gregset;
00085 const struct sparc_fpregset *sparc_fpregset;
00086 void (*sparc_supply_gregset) (const struct sparc_gregset *,
00087                               struct regcache *, int , const void *);
00088 void (*sparc_collect_gregset) (const struct sparc_gregset *,
00089                                const struct regcache *, int, void *);
00090 void (*sparc_supply_fpregset) (const struct sparc_fpregset *,
00091                                struct regcache *, int , const void *);
00092 void (*sparc_collect_fpregset) (const struct sparc_fpregset *,
00093                                 const struct regcache *, int , void *);
00094 int (*sparc_gregset_supplies_p) (struct gdbarch *, int);
00095 int (*sparc_fpregset_supplies_p) (struct gdbarch *, int);
00096 
00097 /* Determine whether `gregset_t' contains register REGNUM.  */
00098 
00099 int
00100 sparc32_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
00101 {
00102   /* Integer registers.  */
00103   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
00104       || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
00105       || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
00106       || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
00107     return 1;
00108 
00109   /* Control registers.  */
00110   if (regnum == SPARC32_PC_REGNUM
00111       || regnum == SPARC32_NPC_REGNUM
00112       || regnum == SPARC32_PSR_REGNUM
00113       || regnum == SPARC32_Y_REGNUM)
00114     return 1;
00115 
00116   return 0;
00117 }
00118 
00119 /* Determine whether `fpregset_t' contains register REGNUM.  */
00120 
00121 int
00122 sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
00123 {
00124   /* Floating-point registers.  */
00125   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
00126     return 1;
00127 
00128   /* Control registers.  */
00129   if (regnum == SPARC32_FSR_REGNUM)
00130     return 1;
00131 
00132   return 0;
00133 }
00134 
00135 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
00136    for all registers (including the floating-point registers).  */
00137 
00138 void
00139 sparc_fetch_inferior_registers (struct target_ops *ops,
00140                                 struct regcache *regcache, int regnum)
00141 {
00142   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00143   int pid;
00144 
00145   /* NOTE: cagney/2002-12-03: This code assumes that the currently
00146      selected light weight processes' registers can be written
00147      directly into the selected thread's register cache.  This works
00148      fine when given an 1:1 LWP:thread model (such as found on
00149      GNU/Linux) but will, likely, have problems when used on an N:1
00150      (userland threads) or N:M (userland multiple LWP) model.  In the
00151      case of the latter two, the LWP's registers do not necessarily
00152      belong to the selected thread (the LWP could be in the middle of
00153      executing the thread switch code).
00154 
00155      These functions should instead be paramaterized with an explicit
00156      object (struct regcache, struct thread_info?) into which the LWPs
00157      registers can be written.  */
00158   pid = ptid_get_lwp (inferior_ptid);
00159   if (pid == 0)
00160     pid = ptid_get_pid (inferior_ptid);
00161 
00162   if (regnum == SPARC_G0_REGNUM)
00163     {
00164       gdb_byte zero[8] = { 0 };
00165 
00166       regcache_raw_supply (regcache, SPARC_G0_REGNUM, &zero);
00167       return;
00168     }
00169 
00170   if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
00171     {
00172       gregset_t regs;
00173 
00174       if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00175         perror_with_name (_("Couldn't get registers"));
00176 
00177       sparc_supply_gregset (sparc_gregset, regcache, -1, &regs);
00178       if (regnum != -1)
00179         return;
00180     }
00181 
00182   if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
00183     {
00184       fpregset_t fpregs;
00185 
00186       if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00187         perror_with_name (_("Couldn't get floating point status"));
00188 
00189       sparc_supply_fpregset (sparc_fpregset, regcache, -1, &fpregs);
00190     }
00191 }
00192 
00193 void
00194 sparc_store_inferior_registers (struct target_ops *ops,
00195                                 struct regcache *regcache, int regnum)
00196 {
00197   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00198   int pid;
00199 
00200   /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
00201      about threaded assumptions.  */
00202   pid = ptid_get_lwp (inferior_ptid);
00203   if (pid == 0)
00204     pid = ptid_get_pid (inferior_ptid);
00205 
00206   if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
00207     {
00208       gregset_t regs;
00209 
00210       if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00211         perror_with_name (_("Couldn't get registers"));
00212 
00213       sparc_collect_gregset (sparc_gregset, regcache, regnum, &regs);
00214 
00215       if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00216         perror_with_name (_("Couldn't write registers"));
00217 
00218       /* Deal with the stack regs.  */
00219       if (regnum == -1 || regnum == SPARC_SP_REGNUM
00220           || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM))
00221         {
00222           ULONGEST sp;
00223 
00224           regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
00225           sparc_collect_rwindow (regcache, sp, regnum);
00226         }
00227 
00228       if (regnum != -1)
00229         return;
00230     }
00231 
00232   if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
00233     {
00234       fpregset_t fpregs, saved_fpregs;
00235 
00236       if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00237         perror_with_name (_("Couldn't get floating-point registers"));
00238 
00239       memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
00240       sparc_collect_fpregset (sparc_fpregset, regcache, regnum, &fpregs);
00241 
00242       /* Writing the floating-point registers will fail on NetBSD with
00243          EINVAL if the inferior process doesn't have an FPU state
00244          (i.e. if it didn't use the FPU yet).  Therefore we don't try
00245          to write the registers if nothing changed.  */
00246       if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
00247         {
00248           if (ptrace (PTRACE_SETFPREGS, pid,
00249                       (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00250             perror_with_name (_("Couldn't write floating-point registers"));
00251         }
00252 
00253       if (regnum != -1)
00254         return;
00255     }
00256 }
00257 
00258 
00259 /* Fetch StackGhost Per-Process XOR cookie.  */
00260 
00261 static LONGEST
00262 sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
00263                     const char *annex, gdb_byte *readbuf,
00264                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
00265 {
00266   unsigned long wcookie = 0;
00267   char *buf = (char *)&wcookie;
00268 
00269   gdb_assert (object == TARGET_OBJECT_WCOOKIE);
00270   gdb_assert (readbuf && writebuf == NULL);
00271 
00272   if (offset == sizeof (unsigned long))
00273     return 0;                   /* Signal EOF.  */
00274   if (offset > sizeof (unsigned long))
00275     return -1;
00276 
00277 #ifdef PT_WCOOKIE
00278   /* If PT_WCOOKIE is defined (by <sys/ptrace.h>), assume we're
00279      running on an OpenBSD release that uses StackGhost (3.1 or
00280      later).  Since release 3.6, OpenBSD uses a fully randomized
00281      cookie.  */
00282   {
00283     int pid;
00284 
00285     pid = ptid_get_lwp (inferior_ptid);
00286     if (pid == 0)
00287       pid = ptid_get_pid (inferior_ptid);
00288 
00289     /* Sanity check.  The proper type for a cookie is register_t, but
00290        we can't assume that this type exists on all systems supported
00291        by the code in this file.  */
00292     gdb_assert (sizeof (wcookie) == sizeof (register_t));
00293 
00294     /* Fetch the cookie.  */
00295     if (ptrace (PT_WCOOKIE, pid, (PTRACE_TYPE_ARG3) &wcookie, 0) == -1)
00296       {
00297         if (errno != EINVAL)
00298           perror_with_name (_("Couldn't get StackGhost cookie"));
00299 
00300         /* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later,
00301            the request wasn't implemented until after OpenBSD 3.4.  If
00302            the kernel doesn't support the PT_WCOOKIE request, assume
00303            we're running on a kernel that uses non-randomized cookies.  */
00304         wcookie = 0x3;
00305       }
00306   }
00307 #endif /* PT_WCOOKIE */
00308 
00309   if (len > sizeof (unsigned long) - offset)
00310     len = sizeof (unsigned long) - offset;
00311 
00312   memcpy (readbuf, buf + offset, len);
00313   return len;
00314 }
00315 
00316 LONGEST (*inf_ptrace_xfer_partial) (struct target_ops *, enum target_object,
00317                                     const char *, gdb_byte *, const gdb_byte *,
00318                                     ULONGEST, LONGEST);
00319 
00320 static LONGEST
00321 sparc_xfer_partial (struct target_ops *ops, enum target_object object,
00322                     const char *annex, gdb_byte *readbuf,
00323                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
00324 {
00325   if (object == TARGET_OBJECT_WCOOKIE)
00326     return sparc_xfer_wcookie (ops, object, annex, readbuf, writebuf, 
00327                                offset, len);
00328 
00329   return inf_ptrace_xfer_partial (ops, object, annex, readbuf, writebuf,
00330                                   offset, len);
00331 }
00332 
00333 /* Create a prototype generic SPARC target.  The client can override
00334    it with local methods.  */
00335 
00336 struct target_ops *
00337 sparc_target (void)
00338 {
00339   struct target_ops *t;
00340 
00341   t = inf_ptrace_target ();
00342   t->to_fetch_registers = sparc_fetch_inferior_registers;
00343   t->to_store_registers = sparc_store_inferior_registers;
00344   inf_ptrace_xfer_partial = t->to_xfer_partial;
00345   t->to_xfer_partial = sparc_xfer_partial;
00346   return t;
00347 }
00348 
00349 
00350 /* Provide a prototype to silence -Wmissing-prototypes.  */
00351 void _initialize_sparc_nat (void);
00352 
00353 void
00354 _initialize_sparc_nat (void)
00355 {
00356   /* Deafult to using SunOS 4 register sets.  */
00357   if (sparc_gregset == NULL)
00358     sparc_gregset = &sparc32_sunos4_gregset;
00359   if (sparc_fpregset == NULL)
00360     sparc_fpregset = &sparc32_sunos4_fpregset;
00361   if (sparc_supply_gregset == NULL)
00362     sparc_supply_gregset = sparc32_supply_gregset;
00363   if (sparc_collect_gregset == NULL)
00364     sparc_collect_gregset = sparc32_collect_gregset;
00365   if (sparc_supply_fpregset == NULL)
00366     sparc_supply_fpregset = sparc32_supply_fpregset;
00367   if (sparc_collect_fpregset == NULL)
00368     sparc_collect_fpregset = sparc32_collect_fpregset;
00369   if (sparc_gregset_supplies_p == NULL)
00370     sparc_gregset_supplies_p = sparc32_gregset_supplies_p;
00371   if (sparc_fpregset_supplies_p == NULL)
00372     sparc_fpregset_supplies_p = sparc32_fpregset_supplies_p;
00373 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines