GDB (API)
/home/stan/gdb/src/gdb/tilegx-linux-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for GNU/Linux TILE-Gx.
00002 
00003    Copyright (C) 2012-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 "gdbcore.h"
00023 #include "regcache.h"
00024 #include "linux-nat.h"
00025 
00026 #include <sys/ptrace.h>
00027 
00028 #include "gdb_assert.h"
00029 #include "gdb_string.h"
00030 
00031 #include <sys/procfs.h>
00032 
00033 #include "gdb_proc_service.h"
00034 #include <sys/ptrace.h>
00035 
00036 /* Prototypes for supply_gregset etc.  */
00037 #include "gregset.h"
00038 
00039 /* Defines ps_err_e, struct ps_prochandle.  */
00040 #include "gdb_proc_service.h"
00041 
00042 /* The register sets used in GNU/Linux ELF core-dumps are identical to
00043    the register sets in `struct user' that is used for a.out
00044    core-dumps, and is also used by `ptrace'.  The corresponding types
00045    are `elf_gregset_t' for the general-purpose registers (with
00046    `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
00047    for the floating-point registers.
00048 
00049    Those types used to be available under the names `gregset_t' and
00050    `fpregset_t' too, and this file used those names in the past.  But
00051    those names are now used for the register sets used in the
00052    `mcontext_t' type, and have a different size and layout.  */
00053 
00054 /* Mapping between the general-purpose registers in `struct user'
00055    format and GDB's register array layout.  Note that we map the
00056    first 56 registers (0 thru 55) one-to-one.  GDB maps the pc to
00057    slot 64, but ptrace returns it in slot 56.  */
00058 static const int regmap[] =
00059 {
00060    0,  1,  2,  3,  4,  5,  6,  7,
00061    8,  9, 10, 11, 12, 13, 14, 15,
00062   16, 17, 18, 19, 20, 21, 22, 23,
00063   24, 25, 26, 27, 28, 29, 30, 31,
00064   32, 33, 34, 35, 36, 37, 38, 39,
00065   40, 41, 42, 43, 44, 45, 46, 47,
00066   48, 49, 50, 51, 52, 53, 54, 55,
00067   -1, -1, -1, -1, -1, -1, -1, -1,
00068   56, 58
00069 };
00070 
00071 /* Transfering the general-purpose registers between GDB, inferiors
00072    and core files.  */
00073 
00074 /* Fill GDB's register array with the general-purpose register values
00075    in *GREGSETP.  */
00076 
00077 void
00078 supply_gregset (struct regcache* regcache,
00079                 const elf_gregset_t *gregsetp)
00080 {
00081   elf_greg_t *regp = (elf_greg_t *) gregsetp;
00082   int i;
00083 
00084   for (i = 0; i < sizeof (regmap) / sizeof (regmap[0]); i++)
00085     if (regmap[i] >= 0)
00086       regcache_raw_supply (regcache, i, regp + regmap[i]);
00087 }
00088 
00089 /* Fill registers in *GREGSETPS with the values in GDB's
00090    register array.  */
00091 
00092 void
00093 fill_gregset (const struct regcache* regcache,
00094               elf_gregset_t *gregsetp, int regno)
00095 {
00096   elf_greg_t *regp = (elf_greg_t *) gregsetp;
00097   int i;
00098 
00099   for (i = 0; i < sizeof (regmap) / sizeof (regmap[0]); i++)
00100     if (regmap[i] >= 0)
00101       regcache_raw_collect (regcache, i, regp + regmap[i]);
00102 }
00103 
00104 /* Transfering floating-point registers between GDB, inferiors and cores.  */
00105 
00106 /* Fill GDB's register array with the floating-point register values in
00107    *FPREGSETP.  */
00108 
00109 void
00110 supply_fpregset (struct regcache *regcache,
00111                  const elf_fpregset_t *fpregsetp)
00112 {
00113   /* NOTE: There are no floating-point registers for TILE-Gx.  */
00114 }
00115 
00116 /* Fill register REGNO (if it is a floating-point register) in
00117    *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
00118    do this for all registers.  */
00119 
00120 void
00121 fill_fpregset (const struct regcache *regcache,
00122                elf_fpregset_t *fpregsetp, int regno)
00123 {
00124   /* NOTE: There are no floating-point registers for TILE-Gx.  */
00125 }
00126 
00127 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
00128    for all registers.  */
00129 
00130 static void
00131 fetch_inferior_registers (struct target_ops *ops,
00132                           struct regcache *regcache, int regnum)
00133 {
00134   elf_gregset_t regs;
00135   int tid;
00136 
00137   tid = ptid_get_lwp (inferior_ptid);
00138   if (tid == 0)
00139     tid = ptid_get_pid (inferior_ptid);
00140 
00141   if (ptrace (PTRACE_GETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
00142     perror_with_name (_("Couldn't get registers"));
00143 
00144   supply_gregset (regcache, (const elf_gregset_t *)&regs);
00145 }
00146 
00147 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
00148    this for all registers.  */
00149 
00150 static void
00151 store_inferior_registers (struct target_ops *ops,
00152                           struct regcache *regcache, int regnum)
00153 {
00154   elf_gregset_t regs;
00155   int tid;
00156 
00157   tid = ptid_get_lwp (inferior_ptid);
00158   if (tid == 0)
00159     tid = ptid_get_pid (inferior_ptid);
00160 
00161   if (ptrace (PTRACE_GETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
00162     perror_with_name (_("Couldn't get registers"));
00163 
00164   fill_gregset (regcache, &regs, regnum);
00165 
00166   if (ptrace (PTRACE_SETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
00167     perror_with_name (_("Couldn't write registers"));
00168 }
00169 
00170 
00171 extern initialize_file_ftype _initialize_tile_linux_nat;
00172 
00173 void
00174 _initialize_tile_linux_nat (void)
00175 {
00176   struct target_ops *t;
00177 
00178   /* Fill in the generic GNU/Linux methods.  */
00179   t = linux_target ();
00180 
00181   /* Add our register access methods.  */
00182   t->to_fetch_registers = fetch_inferior_registers;
00183   t->to_store_registers = store_inferior_registers;
00184 
00185   /* Register the target.  */
00186   linux_nat_add_target (t);
00187 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines