GDB (API)
/home/stan/gdb/src/gdb/hppabsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for HP PA-RISC BSD's.
00002 
00003    Copyright (C) 2004-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 <sys/types.h>
00026 #include <sys/ptrace.h>
00027 #include <machine/reg.h>
00028 
00029 #include "hppa-tdep.h"
00030 #include "inf-ptrace.h"
00031 
00032 static int
00033 hppabsd_gregset_supplies_p (int regnum)
00034 {
00035   return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
00036 }
00037 
00038 static int
00039 hppabsd_fpregset_supplies_p (int regnum)
00040 {
00041   return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
00042 }
00043 
00044 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
00045 
00046 static void
00047 hppabsd_supply_gregset (struct regcache *regcache, const void *gregs)
00048 {
00049   gdb_byte zero[4] = { 0 };
00050   const char *regs = gregs;
00051   int regnum;
00052 
00053   regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
00054   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
00055     regcache_raw_supply (regcache, regnum, regs + regnum * 4);
00056 
00057   if (sizeof(struct reg) >= 46 * 4)
00058     {
00059       regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
00060       regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
00061       regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
00062       regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
00063       regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
00064       regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
00065       regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
00066       regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
00067       regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
00068       regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
00069       regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
00070       regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
00071       regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
00072       regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
00073       regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
00074       regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
00075     } 
00076   else
00077     {
00078       regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
00079       regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
00080       regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
00081     }
00082 }
00083 
00084 /* Supply the floating-point registers stored in FPREGS to REGCACHE.  */
00085 
00086 static void
00087 hppabsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
00088 {
00089   const char *regs = fpregs;
00090   int regnum;
00091 
00092   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
00093        regnum += 2, regs += 8)
00094     {
00095       regcache_raw_supply (regcache, regnum, regs);
00096       regcache_raw_supply (regcache, regnum + 1, regs + 4);
00097     }
00098 }
00099 
00100 /* Collect the general-purpose registers from REGCACHE and store them
00101    in GREGS.  */
00102 
00103 static void
00104 hppabsd_collect_gregset (const struct regcache *regcache,
00105                           void *gregs, int regnum)
00106 {
00107   char *regs = gregs;
00108   int i;
00109 
00110   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
00111     {
00112       if (regnum == -1 || regnum == i)
00113         regcache_raw_collect (regcache, i, regs + i * 4);
00114     }
00115 
00116   if (sizeof(struct reg) >= 46 * 4)
00117     {
00118       if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
00119         regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
00120       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
00121         regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
00122       if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
00123         regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
00124       if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
00125         regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
00126       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
00127         regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
00128       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
00129         regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
00130       if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
00131         regcache_raw_collect (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
00132       if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
00133         regcache_raw_collect (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
00134       if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
00135         regcache_raw_collect (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
00136       if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
00137         regcache_raw_collect (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
00138       if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
00139         regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
00140       if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
00141         regcache_raw_collect (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
00142       if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
00143         regcache_raw_collect (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
00144       if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
00145         regcache_raw_collect (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
00146       if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
00147         regcache_raw_collect (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
00148       if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
00149         regcache_raw_collect (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
00150     }
00151   else
00152     {
00153       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
00154         regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
00155       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
00156         regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
00157       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
00158         regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
00159     }
00160 }
00161 
00162 /* Collect the floating-point registers from REGCACHE and store them
00163    in FPREGS.  */
00164 
00165 static void
00166 hppabsd_collect_fpregset (struct regcache *regcache,
00167                           void *fpregs, int regnum)
00168 {
00169   char *regs = fpregs;
00170   int i;
00171 
00172   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
00173     {
00174       if (regnum == -1 || regnum == i || regnum == i + 1)
00175         {
00176           regcache_raw_collect (regcache, i, regs);
00177           regcache_raw_collect (regcache, i + 1, regs + 4);
00178         }
00179     }
00180 }
00181 
00182 
00183 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
00184    for all registers (including the floating-point registers).  */
00185 
00186 static void
00187 hppabsd_fetch_registers (struct target_ops *ops,
00188                          struct regcache *regcache, int regnum)
00189 {
00190   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
00191     {
00192       struct reg regs;
00193 
00194       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00195                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00196         perror_with_name (_("Couldn't get registers"));
00197 
00198       hppabsd_supply_gregset (regcache, &regs);
00199     }
00200 
00201   if (regnum == -1 || hppabsd_fpregset_supplies_p (regnum))
00202     {
00203       struct fpreg fpregs;
00204 
00205       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00206                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00207         perror_with_name (_("Couldn't get floating point status"));
00208 
00209       hppabsd_supply_fpregset (regcache, &fpregs);
00210     }
00211 }
00212 
00213 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
00214    this for all registers (including the floating-point registers).  */
00215 
00216 static void
00217 hppabsd_store_registers (struct target_ops *ops,
00218                          struct regcache *regcache, int regnum)
00219 {
00220   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
00221     {
00222       struct reg regs;
00223 
00224       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00225                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00226         perror_with_name (_("Couldn't get registers"));
00227 
00228       hppabsd_collect_gregset (regcache, &regs, regnum);
00229 
00230       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
00231                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00232         perror_with_name (_("Couldn't write registers"));
00233     }
00234 
00235   if (regnum == -1 || hppabsd_fpregset_supplies_p (regnum))
00236     {
00237       struct fpreg fpregs;
00238 
00239       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00240                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00241         perror_with_name (_("Couldn't get floating point status"));
00242 
00243       hppabsd_collect_fpregset (regcache, &fpregs, regnum);
00244 
00245       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
00246                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00247         perror_with_name (_("Couldn't write floating point status"));
00248     }
00249 }
00250 
00251 /* Provide a prototype to silence -Wmissing-prototypes.  */
00252 void _initialize_hppabsd_nat (void);
00253 
00254 void
00255 _initialize_hppabsd_nat (void)
00256 {
00257   struct target_ops *t;
00258 
00259   /* Add in local overrides.  */
00260   t = inf_ptrace_target ();
00261   t->to_fetch_registers = hppabsd_fetch_registers;
00262   t->to_store_registers = hppabsd_store_registers;
00263   add_target (t);
00264 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines