GDBserver
/home/stan/gdb/src/gdb/gdbserver/regcache.c
Go to the documentation of this file.
00001 /* Register support routines for the remote server for GDB.
00002    Copyright (C) 2001-2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 #include "server.h"
00020 #include "regdef.h"
00021 #include "gdbthread.h"
00022 #include "tdesc.h"
00023 
00024 #include <stdlib.h>
00025 #include <string.h>
00026 
00027 #ifndef IN_PROCESS_AGENT
00028 
00029 struct regcache *
00030 get_thread_regcache (struct thread_info *thread, int fetch)
00031 {
00032   struct regcache *regcache;
00033 
00034   regcache = (struct regcache *) inferior_regcache_data (thread);
00035 
00036   /* Threads' regcaches are created lazily, because biarch targets add
00037      the main thread/lwp before seeing it stop for the first time, and
00038      it is only after the target sees the thread stop for the first
00039      time that the target has a chance of determining the process's
00040      architecture.  IOW, when we first add the process's main thread
00041      we don't know which architecture/tdesc its regcache should
00042      have.  */
00043   if (regcache == NULL)
00044     {
00045       struct process_info *proc = get_thread_process (thread);
00046 
00047       if (proc->tdesc == NULL)
00048         fatal ("no target description");
00049 
00050       regcache = new_register_cache (proc->tdesc);
00051       set_inferior_regcache_data (thread, regcache);
00052     }
00053 
00054   if (fetch && regcache->registers_valid == 0)
00055     {
00056       struct thread_info *saved_inferior = current_inferior;
00057 
00058       current_inferior = thread;
00059       fetch_inferior_registers (regcache, -1);
00060       current_inferior = saved_inferior;
00061       regcache->registers_valid = 1;
00062     }
00063 
00064   return regcache;
00065 }
00066 
00067 void
00068 regcache_invalidate_thread (struct thread_info *thread)
00069 {
00070   struct regcache *regcache;
00071 
00072   regcache = (struct regcache *) inferior_regcache_data (thread);
00073 
00074   if (regcache == NULL)
00075     return;
00076 
00077   if (regcache->registers_valid)
00078     {
00079       struct thread_info *saved_inferior = current_inferior;
00080 
00081       current_inferior = thread;
00082       store_inferior_registers (regcache, -1);
00083       current_inferior = saved_inferior;
00084     }
00085 
00086   regcache->registers_valid = 0;
00087 }
00088 
00089 static int
00090 regcache_invalidate_one (struct inferior_list_entry *entry,
00091                          void *pid_p)
00092 {
00093   struct thread_info *thread = (struct thread_info *) entry;
00094   int pid = *(int *) pid_p;
00095 
00096   /* Only invalidate the regcaches of threads of this process.  */
00097   if (ptid_get_pid (entry->id) == pid)
00098     regcache_invalidate_thread (thread);
00099 
00100   return 0;
00101 }
00102 
00103 void
00104 regcache_invalidate (void)
00105 {
00106   /* Only update the threads of the current process.  */
00107   int pid = ptid_get_pid (current_inferior->entry.id);
00108 
00109   find_inferior (&all_threads, regcache_invalidate_one, &pid);
00110 }
00111 
00112 #endif
00113 
00114 struct regcache *
00115 init_register_cache (struct regcache *regcache,
00116                      const struct target_desc *tdesc,
00117                      unsigned char *regbuf)
00118 {
00119 #ifndef IN_PROCESS_AGENT
00120   if (regbuf == NULL)
00121     {
00122       /* Make sure to zero-initialize the register cache when it is
00123          created, in case there are registers the target never
00124          fetches.  This way they'll read as zero instead of
00125          garbage.  */
00126       regcache->tdesc = tdesc;
00127       regcache->registers = xcalloc (1, tdesc->registers_size);
00128       regcache->registers_owned = 1;
00129       regcache->register_status = xcalloc (1, tdesc->num_registers);
00130       gdb_assert (REG_UNAVAILABLE == 0);
00131     }
00132   else
00133 #else
00134   if (regbuf == NULL)
00135     fatal ("init_register_cache: can't allocate memory from the heap");
00136   else
00137 #endif
00138     {
00139       regcache->tdesc = tdesc;
00140       regcache->registers = regbuf;
00141       regcache->registers_owned = 0;
00142 #ifndef IN_PROCESS_AGENT
00143       regcache->register_status = NULL;
00144 #endif
00145     }
00146 
00147   regcache->registers_valid = 0;
00148 
00149   return regcache;
00150 }
00151 
00152 #ifndef IN_PROCESS_AGENT
00153 
00154 struct regcache *
00155 new_register_cache (const struct target_desc *tdesc)
00156 {
00157   struct regcache *regcache;
00158 
00159   gdb_assert (tdesc->registers_size != 0);
00160 
00161   regcache = xmalloc (sizeof (*regcache));
00162   return init_register_cache (regcache, tdesc, NULL);
00163 }
00164 
00165 void
00166 free_register_cache (struct regcache *regcache)
00167 {
00168   if (regcache)
00169     {
00170       if (regcache->registers_owned)
00171         free (regcache->registers);
00172       free (regcache->register_status);
00173       free (regcache);
00174     }
00175 }
00176 
00177 #endif
00178 
00179 void
00180 regcache_cpy (struct regcache *dst, struct regcache *src)
00181 {
00182   gdb_assert (src != NULL && dst != NULL);
00183   gdb_assert (src->tdesc == dst->tdesc);
00184   gdb_assert (src != dst);
00185 
00186   memcpy (dst->registers, src->registers, src->tdesc->registers_size);
00187 #ifndef IN_PROCESS_AGENT
00188   if (dst->register_status != NULL && src->register_status != NULL)
00189     memcpy (dst->register_status, src->register_status,
00190             src->tdesc->num_registers);
00191 #endif
00192   dst->registers_valid = src->registers_valid;
00193 }
00194 
00195 
00196 #ifndef IN_PROCESS_AGENT
00197 
00198 void
00199 registers_to_string (struct regcache *regcache, char *buf)
00200 {
00201   unsigned char *registers = regcache->registers;
00202   const struct target_desc *tdesc = regcache->tdesc;
00203   int i;
00204 
00205   for (i = 0; i < tdesc->num_registers; i++)
00206     {
00207       if (regcache->register_status[i] == REG_VALID)
00208         {
00209           convert_int_to_ascii (registers, buf,
00210                                 register_size (tdesc, i));
00211           buf += register_size (tdesc, i) * 2;
00212         }
00213       else
00214         {
00215           memset (buf, 'x', register_size (tdesc, i) * 2);
00216           buf += register_size (tdesc, i) * 2;
00217         }
00218       registers += register_size (tdesc, i);
00219     }
00220   *buf = '\0';
00221 }
00222 
00223 void
00224 registers_from_string (struct regcache *regcache, char *buf)
00225 {
00226   int len = strlen (buf);
00227   unsigned char *registers = regcache->registers;
00228   const struct target_desc *tdesc = regcache->tdesc;
00229 
00230   if (len != tdesc->registers_size * 2)
00231     {
00232       warning ("Wrong sized register packet (expected %d bytes, got %d)",
00233                2 * tdesc->registers_size, len);
00234       if (len > tdesc->registers_size * 2)
00235         len = tdesc->registers_size * 2;
00236     }
00237   convert_ascii_to_int (buf, registers, len / 2);
00238 }
00239 
00240 struct reg *
00241 find_register_by_name (const struct target_desc *tdesc, const char *name)
00242 {
00243   int i;
00244 
00245   for (i = 0; i < tdesc->num_registers; i++)
00246     if (strcmp (name, tdesc->reg_defs[i].name) == 0)
00247       return &tdesc->reg_defs[i];
00248   fatal ("Unknown register %s requested", name);
00249   return 0;
00250 }
00251 
00252 int
00253 find_regno (const struct target_desc *tdesc, const char *name)
00254 {
00255   int i;
00256 
00257   for (i = 0; i < tdesc->num_registers; i++)
00258     if (strcmp (name, tdesc->reg_defs[i].name) == 0)
00259       return i;
00260   fatal ("Unknown register %s requested", name);
00261   return -1;
00262 }
00263 
00264 struct reg *
00265 find_register_by_number (const struct target_desc *tdesc, int n)
00266 {
00267   return &tdesc->reg_defs[n];
00268 }
00269 
00270 #endif
00271 
00272 #ifndef IN_PROCESS_AGENT
00273 static void
00274 free_register_cache_thread (struct thread_info *thread)
00275 {
00276   struct regcache *regcache
00277     = (struct regcache *) inferior_regcache_data (thread);
00278 
00279   if (regcache != NULL)
00280     {
00281       regcache_invalidate_thread (thread);
00282       free_register_cache (regcache);
00283       set_inferior_regcache_data (thread, NULL);
00284     }
00285 }
00286 
00287 static void
00288 free_register_cache_thread_one (struct inferior_list_entry *entry)
00289 {
00290   struct thread_info *thread = (struct thread_info *) entry;
00291 
00292   free_register_cache_thread (thread);
00293 }
00294 
00295 void
00296 regcache_release (void)
00297 {
00298   /* Flush and release all pre-existing register caches.  */
00299   for_each_inferior (&all_threads, free_register_cache_thread_one);
00300 }
00301 #endif
00302 
00303 int
00304 register_cache_size (const struct target_desc *tdesc)
00305 {
00306   return tdesc->registers_size;
00307 }
00308 
00309 int
00310 register_size (const struct target_desc *tdesc, int n)
00311 {
00312   return tdesc->reg_defs[n].size / 8;
00313 }
00314 
00315 static unsigned char *
00316 register_data (struct regcache *regcache, int n, int fetch)
00317 {
00318   return regcache->registers + regcache->tdesc->reg_defs[n].offset / 8;
00319 }
00320 
00321 /* Supply register N, whose contents are stored in BUF, to REGCACHE.
00322    If BUF is NULL, the register's value is recorded as
00323    unavailable.  */
00324 
00325 void
00326 supply_register (struct regcache *regcache, int n, const void *buf)
00327 {
00328   if (buf)
00329     {
00330       memcpy (register_data (regcache, n, 0), buf,
00331               register_size (regcache->tdesc, n));
00332 #ifndef IN_PROCESS_AGENT
00333       if (regcache->register_status != NULL)
00334         regcache->register_status[n] = REG_VALID;
00335 #endif
00336     }
00337   else
00338     {
00339       memset (register_data (regcache, n, 0), 0,
00340               register_size (regcache->tdesc, n));
00341 #ifndef IN_PROCESS_AGENT
00342       if (regcache->register_status != NULL)
00343         regcache->register_status[n] = REG_UNAVAILABLE;
00344 #endif
00345     }
00346 }
00347 
00348 /* Supply register N with value zero to REGCACHE.  */
00349 
00350 void
00351 supply_register_zeroed (struct regcache *regcache, int n)
00352 {
00353   memset (register_data (regcache, n, 0), 0,
00354           register_size (regcache->tdesc, n));
00355 #ifndef IN_PROCESS_AGENT
00356   if (regcache->register_status != NULL)
00357     regcache->register_status[n] = REG_VALID;
00358 #endif
00359 }
00360 
00361 /* Supply the whole register set whose contents are stored in BUF, to
00362    REGCACHE.  If BUF is NULL, all the registers' values are recorded
00363    as unavailable.  */
00364 
00365 void
00366 supply_regblock (struct regcache *regcache, const void *buf)
00367 {
00368   if (buf)
00369     {
00370       const struct target_desc *tdesc = regcache->tdesc;
00371 
00372       memcpy (regcache->registers, buf, tdesc->registers_size);
00373 #ifndef IN_PROCESS_AGENT
00374       {
00375         int i;
00376 
00377         for (i = 0; i < tdesc->num_registers; i++)
00378           regcache->register_status[i] = REG_VALID;
00379       }
00380 #endif
00381     }
00382   else
00383     {
00384       const struct target_desc *tdesc = regcache->tdesc;
00385 
00386       memset (regcache->registers, 0, tdesc->registers_size);
00387 #ifndef IN_PROCESS_AGENT
00388       {
00389         int i;
00390 
00391         for (i = 0; i < tdesc->num_registers; i++)
00392           regcache->register_status[i] = REG_UNAVAILABLE;
00393       }
00394 #endif
00395     }
00396 }
00397 
00398 #ifndef IN_PROCESS_AGENT
00399 
00400 void
00401 supply_register_by_name (struct regcache *regcache,
00402                          const char *name, const void *buf)
00403 {
00404   supply_register (regcache, find_regno (regcache->tdesc, name), buf);
00405 }
00406 
00407 #endif
00408 
00409 void
00410 collect_register (struct regcache *regcache, int n, void *buf)
00411 {
00412   memcpy (buf, register_data (regcache, n, 1),
00413           register_size (regcache->tdesc, n));
00414 }
00415 
00416 #ifndef IN_PROCESS_AGENT
00417 
00418 void
00419 collect_register_as_string (struct regcache *regcache, int n, char *buf)
00420 {
00421   convert_int_to_ascii (register_data (regcache, n, 1), buf,
00422                         register_size (regcache->tdesc, n));
00423 }
00424 
00425 void
00426 collect_register_by_name (struct regcache *regcache,
00427                           const char *name, void *buf)
00428 {
00429   collect_register (regcache, find_regno (regcache->tdesc, name), buf);
00430 }
00431 
00432 /* Special handling for register PC.  */
00433 
00434 CORE_ADDR
00435 regcache_read_pc (struct regcache *regcache)
00436 {
00437   CORE_ADDR pc_val;
00438 
00439   if (the_target->read_pc)
00440     pc_val = the_target->read_pc (regcache);
00441   else
00442     internal_error (__FILE__, __LINE__,
00443                     "regcache_read_pc: Unable to find PC");
00444 
00445   return pc_val;
00446 }
00447 
00448 void
00449 regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
00450 {
00451   if (the_target->write_pc)
00452     the_target->write_pc (regcache, pc);
00453   else
00454     internal_error (__FILE__, __LINE__,
00455                     "regcache_write_pc: Unable to update PC");
00456 }
00457 
00458 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines