GDB (API)
|
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) ®s) < 0) 00142 perror_with_name (_("Couldn't get registers")); 00143 00144 supply_gregset (regcache, (const elf_gregset_t *)®s); 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) ®s) < 0) 00162 perror_with_name (_("Couldn't get registers")); 00163 00164 fill_gregset (regcache, ®s, regnum); 00165 00166 if (ptrace (PTRACE_SETREGS, tid, 0, (PTRACE_TYPE_ARG3) ®s) < 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 }