GDB (API)
/home/stan/gdb/src/gdb/armnbsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
00002 
00003    Copyright (C) 1988-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 "gdbcore.h"
00022 #include "inferior.h"
00023 #include "regcache.h"
00024 #include "target.h"
00025 
00026 #include "gdb_string.h"
00027 #include <sys/types.h>
00028 #include <sys/ptrace.h>
00029 #include <machine/reg.h>
00030 #include <machine/frame.h>
00031 
00032 #include "arm-tdep.h"
00033 #include "inf-ptrace.h"
00034 
00035 extern int arm_apcs_32;
00036 
00037 static void
00038 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
00039 {
00040   int regno;
00041   CORE_ADDR r_pc;
00042 
00043   /* Integer registers.  */
00044   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
00045     regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
00046 
00047   regcache_raw_supply (regcache, ARM_SP_REGNUM,
00048                        (char *) &gregset->r_sp);
00049   regcache_raw_supply (regcache, ARM_LR_REGNUM,
00050                        (char *) &gregset->r_lr);
00051   /* This is ok: we're running native...  */
00052   r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
00053   regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
00054 
00055   if (arm_apcs_32)
00056     regcache_raw_supply (regcache, ARM_PS_REGNUM,
00057                          (char *) &gregset->r_cpsr);
00058   else
00059     regcache_raw_supply (regcache, ARM_PS_REGNUM,
00060                          (char *) &gregset->r_pc);
00061 }
00062 
00063 static void
00064 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
00065 {
00066   int regno;
00067 
00068   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
00069     regcache_raw_supply (regcache, regno,
00070                          (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
00071 
00072   regcache_raw_supply (regcache, ARM_FPS_REGNUM,
00073                        (char *) &fparegset->fpr_fpsr);
00074 }
00075 
00076 static void
00077 fetch_register (struct regcache *regcache, int regno)
00078 {
00079   struct reg inferior_registers;
00080   int ret;
00081 
00082   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00083                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
00084 
00085   if (ret < 0)
00086     {
00087       warning (_("unable to fetch general register"));
00088       return;
00089     }
00090 
00091   switch (regno)
00092     {
00093     case ARM_SP_REGNUM:
00094       regcache_raw_supply (regcache, ARM_SP_REGNUM,
00095                            (char *) &inferior_registers.r_sp);
00096       break;
00097 
00098     case ARM_LR_REGNUM:
00099       regcache_raw_supply (regcache, ARM_LR_REGNUM,
00100                            (char *) &inferior_registers.r_lr);
00101       break;
00102 
00103     case ARM_PC_REGNUM:
00104       /* This is ok: we're running native...  */
00105       inferior_registers.r_pc = gdbarch_addr_bits_remove
00106                                   (get_regcache_arch (regcache),
00107                                    inferior_registers.r_pc);
00108       regcache_raw_supply (regcache, ARM_PC_REGNUM,
00109                            (char *) &inferior_registers.r_pc);
00110       break;
00111 
00112     case ARM_PS_REGNUM:
00113       if (arm_apcs_32)
00114         regcache_raw_supply (regcache, ARM_PS_REGNUM,
00115                              (char *) &inferior_registers.r_cpsr);
00116       else
00117         regcache_raw_supply (regcache, ARM_PS_REGNUM,
00118                              (char *) &inferior_registers.r_pc);
00119       break;
00120 
00121     default:
00122       regcache_raw_supply (regcache, regno,
00123                            (char *) &inferior_registers.r[regno]);
00124       break;
00125     }
00126 }
00127 
00128 static void
00129 fetch_regs (struct regcache *regcache)
00130 {
00131   struct reg inferior_registers;
00132   int ret;
00133   int regno;
00134 
00135   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00136                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
00137 
00138   if (ret < 0)
00139     {
00140       warning (_("unable to fetch general registers"));
00141       return;
00142     }
00143 
00144   arm_supply_gregset (regcache, &inferior_registers);
00145 }
00146 
00147 static void
00148 fetch_fp_register (struct regcache *regcache, int regno)
00149 {
00150   struct fpreg inferior_fp_registers;
00151   int ret;
00152 
00153   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00154                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
00155 
00156   if (ret < 0)
00157     {
00158       warning (_("unable to fetch floating-point register"));
00159       return;
00160     }
00161 
00162   switch (regno)
00163     {
00164     case ARM_FPS_REGNUM:
00165       regcache_raw_supply (regcache, ARM_FPS_REGNUM,
00166                            (char *) &inferior_fp_registers.fpr_fpsr);
00167       break;
00168 
00169     default:
00170       regcache_raw_supply (regcache, regno,
00171                            (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
00172       break;
00173     }
00174 }
00175 
00176 static void
00177 fetch_fp_regs (struct regcache *regcache)
00178 {
00179   struct fpreg inferior_fp_registers;
00180   int ret;
00181   int regno;
00182 
00183   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00184                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
00185 
00186   if (ret < 0)
00187     {
00188       warning (_("unable to fetch general registers"));
00189       return;
00190     }
00191 
00192   arm_supply_fparegset (regcache, &inferior_fp_registers);
00193 }
00194 
00195 static void
00196 armnbsd_fetch_registers (struct target_ops *ops,
00197                          struct regcache *regcache, int regno)
00198 {
00199   if (regno >= 0)
00200     {
00201       if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
00202         fetch_register (regcache, regno);
00203       else
00204         fetch_fp_register (regcache, regno);
00205     }
00206   else
00207     {
00208       fetch_regs (regcache);
00209       fetch_fp_regs (regcache);
00210     }
00211 }
00212 
00213 
00214 static void
00215 store_register (const struct regcache *regcache, int regno)
00216 {
00217   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00218   struct reg inferior_registers;
00219   int ret;
00220 
00221   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00222                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
00223 
00224   if (ret < 0)
00225     {
00226       warning (_("unable to fetch general registers"));
00227       return;
00228     }
00229 
00230   switch (regno)
00231     {
00232     case ARM_SP_REGNUM:
00233       regcache_raw_collect (regcache, ARM_SP_REGNUM,
00234                             (char *) &inferior_registers.r_sp);
00235       break;
00236 
00237     case ARM_LR_REGNUM:
00238       regcache_raw_collect (regcache, ARM_LR_REGNUM,
00239                             (char *) &inferior_registers.r_lr);
00240       break;
00241 
00242     case ARM_PC_REGNUM:
00243       if (arm_apcs_32)
00244         regcache_raw_collect (regcache, ARM_PC_REGNUM,
00245                               (char *) &inferior_registers.r_pc);
00246       else
00247         {
00248           unsigned pc_val;
00249 
00250           regcache_raw_collect (regcache, ARM_PC_REGNUM,
00251                                 (char *) &pc_val);
00252           
00253           pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
00254           inferior_registers.r_pc ^= gdbarch_addr_bits_remove
00255                                        (gdbarch, inferior_registers.r_pc);
00256           inferior_registers.r_pc |= pc_val;
00257         }
00258       break;
00259 
00260     case ARM_PS_REGNUM:
00261       if (arm_apcs_32)
00262         regcache_raw_collect (regcache, ARM_PS_REGNUM,
00263                               (char *) &inferior_registers.r_cpsr);
00264       else
00265         {
00266           unsigned psr_val;
00267 
00268           regcache_raw_collect (regcache, ARM_PS_REGNUM,
00269                                 (char *) &psr_val);
00270 
00271           psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
00272           inferior_registers.r_pc = gdbarch_addr_bits_remove
00273                                       (gdbarch, inferior_registers.r_pc);
00274           inferior_registers.r_pc |= psr_val;
00275         }
00276       break;
00277 
00278     default:
00279       regcache_raw_collect (regcache, regno,
00280                             (char *) &inferior_registers.r[regno]);
00281       break;
00282     }
00283 
00284   ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
00285                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
00286 
00287   if (ret < 0)
00288     warning (_("unable to write register %d to inferior"), regno);
00289 }
00290 
00291 static void
00292 store_regs (const struct regcache *regcache)
00293 {
00294   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00295   struct reg inferior_registers;
00296   int ret;
00297   int regno;
00298 
00299 
00300   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
00301     regcache_raw_collect (regcache, regno,
00302                           (char *) &inferior_registers.r[regno]);
00303 
00304   regcache_raw_collect (regcache, ARM_SP_REGNUM,
00305                         (char *) &inferior_registers.r_sp);
00306   regcache_raw_collect (regcache, ARM_LR_REGNUM,
00307                         (char *) &inferior_registers.r_lr);
00308 
00309   if (arm_apcs_32)
00310     {
00311       regcache_raw_collect (regcache, ARM_PC_REGNUM,
00312                             (char *) &inferior_registers.r_pc);
00313       regcache_raw_collect (regcache, ARM_PS_REGNUM,
00314                             (char *) &inferior_registers.r_cpsr);
00315     }
00316   else
00317     {
00318       unsigned pc_val;
00319       unsigned psr_val;
00320 
00321       regcache_raw_collect (regcache, ARM_PC_REGNUM,
00322                             (char *) &pc_val);
00323       regcache_raw_collect (regcache, ARM_PS_REGNUM,
00324                             (char *) &psr_val);
00325           
00326       pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
00327       psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
00328 
00329       inferior_registers.r_pc = pc_val | psr_val;
00330     }
00331 
00332   ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
00333                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
00334 
00335   if (ret < 0)
00336     warning (_("unable to store general registers"));
00337 }
00338 
00339 static void
00340 store_fp_register (const struct regcache *regcache, int regno)
00341 {
00342   struct fpreg inferior_fp_registers;
00343   int ret;
00344 
00345   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00346                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
00347 
00348   if (ret < 0)
00349     {
00350       warning (_("unable to fetch floating-point registers"));
00351       return;
00352     }
00353 
00354   switch (regno)
00355     {
00356     case ARM_FPS_REGNUM:
00357       regcache_raw_collect (regcache, ARM_FPS_REGNUM,
00358                             (char *) &inferior_fp_registers.fpr_fpsr);
00359       break;
00360 
00361     default:
00362       regcache_raw_collect (regcache, regno,
00363                             (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
00364       break;
00365     }
00366 
00367   ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
00368                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
00369 
00370   if (ret < 0)
00371     warning (_("unable to write register %d to inferior"), regno);
00372 }
00373 
00374 static void
00375 store_fp_regs (const struct regcache *regcache)
00376 {
00377   struct fpreg inferior_fp_registers;
00378   int ret;
00379   int regno;
00380 
00381 
00382   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
00383     regcache_raw_collect (regcache, regno,
00384                           (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
00385 
00386   regcache_raw_collect (regcache, ARM_FPS_REGNUM,
00387                         (char *) &inferior_fp_registers.fpr_fpsr);
00388 
00389   ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
00390                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
00391 
00392   if (ret < 0)
00393     warning (_("unable to store floating-point registers"));
00394 }
00395 
00396 static void
00397 armnbsd_store_registers (struct target_ops *ops,
00398                          struct regcache *regcache, int regno)
00399 {
00400   if (regno >= 0)
00401     {
00402       if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
00403         store_register (regcache, regno);
00404       else
00405         store_fp_register (regcache, regno);
00406     }
00407   else
00408     {
00409       store_regs (regcache);
00410       store_fp_regs (regcache);
00411     }
00412 }
00413 
00414 struct md_core
00415 {
00416   struct reg intreg;
00417   struct fpreg freg;
00418 };
00419 
00420 static void
00421 fetch_core_registers (struct regcache *regcache,
00422                       char *core_reg_sect, unsigned core_reg_size,
00423                       int which, CORE_ADDR ignore)
00424 {
00425   struct md_core *core_reg = (struct md_core *) core_reg_sect;
00426   int regno;
00427   CORE_ADDR r_pc;
00428 
00429   arm_supply_gregset (regcache, &core_reg->intreg);
00430   arm_supply_fparegset (regcache, &core_reg->freg);
00431 }
00432 
00433 static void
00434 fetch_elfcore_registers (struct regcache *regcache,
00435                          char *core_reg_sect, unsigned core_reg_size,
00436                          int which, CORE_ADDR ignore)
00437 {
00438   struct reg gregset;
00439   struct fpreg fparegset;
00440 
00441   switch (which)
00442     {
00443     case 0:     /* Integer registers.  */
00444       if (core_reg_size != sizeof (struct reg))
00445         warning (_("wrong size of register set in core file"));
00446       else
00447         {
00448           /* The memcpy may be unnecessary, but we can't really be sure
00449              of the alignment of the data in the core file.  */
00450           memcpy (&gregset, core_reg_sect, sizeof (gregset));
00451           arm_supply_gregset (regcache, &gregset);
00452         }
00453       break;
00454 
00455     case 2:
00456       if (core_reg_size != sizeof (struct fpreg))
00457         warning (_("wrong size of FPA register set in core file"));
00458       else
00459         {
00460           /* The memcpy may be unnecessary, but we can't really be sure
00461              of the alignment of the data in the core file.  */
00462           memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
00463           arm_supply_fparegset (regcache, &fparegset);
00464         }
00465       break;
00466 
00467     default:
00468       /* Don't know what kind of register request this is; just ignore it.  */
00469       break;
00470     }
00471 }
00472 
00473 static struct core_fns arm_netbsd_core_fns =
00474 {
00475   bfd_target_unknown_flavour,           /* core_flovour.  */
00476   default_check_format,                 /* check_format.  */
00477   default_core_sniffer,                 /* core_sniffer.  */
00478   fetch_core_registers,                 /* core_read_registers.  */
00479   NULL
00480 };
00481 
00482 static struct core_fns arm_netbsd_elfcore_fns =
00483 {
00484   bfd_target_elf_flavour,               /* core_flovour.  */
00485   default_check_format,                 /* check_format.  */
00486   default_core_sniffer,                 /* core_sniffer.  */
00487   fetch_elfcore_registers,              /* core_read_registers.  */
00488   NULL
00489 };
00490 
00491 void
00492 _initialize_arm_netbsd_nat (void)
00493 {
00494   struct target_ops *t;
00495 
00496   t = inf_ptrace_target ();
00497   t->to_fetch_registers = armnbsd_fetch_registers;
00498   t->to_store_registers = armnbsd_store_registers;
00499   add_target (t);
00500 
00501   deprecated_add_core_fns (&arm_netbsd_core_fns);
00502   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
00503 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines