GDBserver
|
00001 /* GNU/Linux/Nios II specific low level interface, for the remote server for 00002 GDB. 00003 Copyright (C) 2008-2013 Free Software Foundation, Inc. 00004 00005 Contributed by Mentor Graphics, Inc. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "server.h" 00023 #include "linux-low.h" 00024 #include <sys/ptrace.h> 00025 #include <endian.h> 00026 #include "gdb_proc_service.h" 00027 #include <asm/ptrace.h> 00028 00029 #ifndef PTRACE_GET_THREAD_AREA 00030 #define PTRACE_GET_THREAD_AREA 25 00031 #endif 00032 00033 /* The following definition must agree with the number of registers 00034 defined in "struct user_regs" in GLIBC 00035 (ports/sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with 00036 NIOS2_NUM_REGS in GDB proper. */ 00037 00038 #define nios2_num_regs 49 00039 00040 /* Defined in auto-generated file nios2-linux.c. */ 00041 00042 void init_registers_nios2_linux (void); 00043 extern const struct target_desc *tdesc_nios2_linux; 00044 00045 /* This union is used to convert between int and byte buffer 00046 representations of register contents. */ 00047 00048 union nios2_register 00049 { 00050 unsigned char buf[4]; 00051 int reg32; 00052 }; 00053 00054 /* Return the ptrace ``address'' of register REGNO. */ 00055 00056 static int nios2_regmap[] = { 00057 -1, 1, 2, 3, 4, 5, 6, 7, 00058 8, 9, 10, 11, 12, 13, 14, 15, 00059 16, 17, 18, 19, 20, 21, 22, 23, 00060 24, 25, 26, 27, 28, 29, 30, 31, 00061 32, 33, 34, 35, 36, 37, 38, 39, 00062 40, 41, 42, 43, 44, 45, 46, 47, 00063 48, 00064 0 00065 }; 00066 00067 /* Implement the arch_setup linux_target_ops method. */ 00068 00069 static void 00070 nios2_arch_setup (void) 00071 { 00072 current_process ()->tdesc = tdesc_nios2_linux; 00073 } 00074 00075 /* Implement the cannot_fetch_register linux_target_ops method. */ 00076 00077 static int 00078 nios2_cannot_fetch_register (int regno) 00079 { 00080 if (nios2_regmap[regno] == -1) 00081 return 1; 00082 00083 return 0; 00084 } 00085 00086 /* Implement the cannot_store_register linux_target_ops method. */ 00087 00088 static int 00089 nios2_cannot_store_register (int regno) 00090 { 00091 if (nios2_regmap[regno] == -1) 00092 return 1; 00093 00094 return 0; 00095 } 00096 00097 /* Implement the get_pc linux_target_ops method. */ 00098 00099 static CORE_ADDR 00100 nios2_get_pc (struct regcache *regcache) 00101 { 00102 union nios2_register pc; 00103 00104 collect_register_by_name (regcache, "pc", pc.buf); 00105 return pc.reg32; 00106 } 00107 00108 /* Implement the set_pc linux_target_ops method. */ 00109 00110 static void 00111 nios2_set_pc (struct regcache *regcache, CORE_ADDR pc) 00112 { 00113 union nios2_register newpc; 00114 00115 newpc.reg32 = pc; 00116 supply_register_by_name (regcache, "pc", newpc.buf); 00117 } 00118 00119 /* Breakpoint support. */ 00120 00121 static const unsigned int nios2_breakpoint = 0x003b6ffa; 00122 #define nios2_breakpoint_len 4 00123 00124 /* Implement the breakpoint_reinsert_addr linux_target_ops method. */ 00125 00126 static CORE_ADDR 00127 nios2_reinsert_addr (void) 00128 { 00129 union nios2_register ra; 00130 struct regcache *regcache = get_thread_regcache (current_inferior, 1); 00131 00132 collect_register_by_name (regcache, "ra", ra.buf); 00133 return ra.reg32; 00134 } 00135 00136 /* Implement the breakpoint_at linux_target_ops method. */ 00137 00138 static int 00139 nios2_breakpoint_at (CORE_ADDR where) 00140 { 00141 unsigned int insn; 00142 00143 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); 00144 if (insn == nios2_breakpoint) 00145 return 1; 00146 return 0; 00147 } 00148 00149 /* Fetch the thread-local storage pointer for libthread_db. */ 00150 00151 ps_err_e 00152 ps_get_thread_area (const struct ps_prochandle *ph, 00153 lwpid_t lwpid, int idx, void **base) 00154 { 00155 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) 00156 return PS_ERR; 00157 00158 /* IDX is the bias from the thread pointer to the beginning of the 00159 thread descriptor. It has to be subtracted due to implementation 00160 quirks in libthread_db. */ 00161 *base = (void *) ((char *) *base - idx); 00162 00163 return PS_OK; 00164 } 00165 00166 #ifdef HAVE_PTRACE_GETREGS 00167 00168 /* Helper functions to collect/supply a single register REGNO. */ 00169 00170 static void 00171 nios2_collect_register (struct regcache *regcache, int regno, 00172 union nios2_register *reg) 00173 { 00174 union nios2_register tmp_reg; 00175 00176 collect_register (regcache, regno, &tmp_reg.reg32); 00177 reg->reg32 = tmp_reg.reg32; 00178 } 00179 00180 static void 00181 nios2_supply_register (struct regcache *regcache, int regno, 00182 const union nios2_register *reg) 00183 { 00184 supply_register (regcache, regno, reg->buf); 00185 } 00186 00187 /* We have only a single register set on Nios II. */ 00188 00189 static void 00190 nios2_fill_gregset (struct regcache *regcache, void *buf) 00191 { 00192 union nios2_register *regset = buf; 00193 int i; 00194 00195 for (i = 1; i < nios2_num_regs; i++) 00196 nios2_collect_register (regcache, i, regset + i); 00197 } 00198 00199 static void 00200 nios2_store_gregset (struct regcache *regcache, const void *buf) 00201 { 00202 const union nios2_register *regset = buf; 00203 int i; 00204 00205 for (i = 0; i < nios2_num_regs; i++) 00206 nios2_supply_register (regcache, i, regset + i); 00207 } 00208 #endif /* HAVE_PTRACE_GETREGS */ 00209 00210 static struct regset_info nios2_regsets[] = 00211 { 00212 #ifdef HAVE_PTRACE_GETREGS 00213 { PTRACE_GETREGS, PTRACE_SETREGS, 0, nios2_num_regs * 4, GENERAL_REGS, 00214 nios2_fill_gregset, nios2_store_gregset }, 00215 #endif /* HAVE_PTRACE_GETREGS */ 00216 { 0, 0, 0, -1, -1, NULL, NULL } 00217 }; 00218 00219 static struct regsets_info nios2_regsets_info = 00220 { 00221 nios2_regsets, /* regsets */ 00222 0, /* num_regsets */ 00223 NULL, /* disabled_regsets */ 00224 }; 00225 00226 static struct usrregs_info nios2_usrregs_info = 00227 { 00228 nios2_num_regs, 00229 nios2_regmap, 00230 }; 00231 00232 static struct regs_info regs_info = 00233 { 00234 NULL, /* regset_bitmap */ 00235 &nios2_usrregs_info, 00236 &nios2_regsets_info 00237 }; 00238 00239 static const struct regs_info * 00240 nios2_regs_info (void) 00241 { 00242 return ®s_info; 00243 } 00244 00245 struct linux_target_ops the_low_target = 00246 { 00247 nios2_arch_setup, 00248 nios2_regs_info, 00249 nios2_cannot_fetch_register, 00250 nios2_cannot_store_register, 00251 NULL, 00252 nios2_get_pc, 00253 nios2_set_pc, 00254 (const unsigned char *) &nios2_breakpoint, 00255 nios2_breakpoint_len, 00256 nios2_reinsert_addr, 00257 0, 00258 nios2_breakpoint_at, 00259 }; 00260 00261 void 00262 initialize_low_arch (void) 00263 { 00264 init_registers_nios2_linux (); 00265 00266 initialize_regsets_info (&nios2_regsets_info); 00267 }