GDBserver
/home/stan/gdb/src/gdb/gdbserver/linux-nios2-low.c
Go to the documentation of this file.
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 &regs_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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines