GDB (API)
/home/stan/gdb/src/gdb/ppc-ravenscar-thread.c
Go to the documentation of this file.
00001 /* Ravenscar PowerPC target support.
00002 
00003    Copyright (C) 2011-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 "gdbcore.h"
00022 #include "regcache.h"
00023 #include "ppc-tdep.h"
00024 #include "inferior.h"
00025 #include "ravenscar-thread.h"
00026 #include "ppc-ravenscar-thread.h"
00027 
00028 #define NO_OFFSET -1
00029 
00030 /* See ppc-tdep.h for register numbers.  */
00031 
00032 static const int powerpc_context_offsets[] =
00033 {
00034   /* R0 - R32 */
00035   NO_OFFSET, 0,         4,         NO_OFFSET,
00036   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00037   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00038   NO_OFFSET, 8,         12,        16,
00039   20,        24,        28,        32,
00040   36,        40,        44,        48,
00041   52,        56,        60,        64,
00042   68,        72,        76,        80,
00043 
00044   /* F0 - F31 */
00045   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00046   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00047   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00048   NO_OFFSET, NO_OFFSET, 96,        104,
00049   112,       120,       128,       136,
00050   144,       152,       160,       168,
00051   176,       184,       192,       200,
00052   208,       216,       224,       232,
00053 
00054   /* PC, MSR, CR, LR */
00055   88,        NO_OFFSET, 84,        NO_OFFSET,
00056 
00057   /* CTR, XER, FPSCR  */
00058   NO_OFFSET, NO_OFFSET, 240
00059 };
00060 
00061 static const int e500_context_offsets[] =
00062 {
00063   /* R0 - R32 */
00064   NO_OFFSET, 4,         12,        NO_OFFSET,
00065   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00066   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00067   NO_OFFSET, 20,        28,        36,
00068   44,        52,        60,        68,
00069   76,        84,        92,        100,
00070   108,       116,       124,       132,
00071   140,       148,       156,       164,
00072 
00073   /* F0 - F31 */
00074   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00075   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00076   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00077   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00078   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00079   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00080   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00081   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00082 
00083   /* PC, MSR, CR, LR */
00084   172,       NO_OFFSET, 168,       NO_OFFSET,
00085 
00086   /* CTR, XER, FPSCR, MQ  */
00087   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00088 
00089   /* Upper R0-R32.  */
00090   NO_OFFSET, 0,         8,        NO_OFFSET,
00091   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00092   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
00093   NO_OFFSET, 16,        24,        32,
00094   40,        48,        56,        64,
00095   72,        80,        88,        96,
00096   104,       112,       120,       128,
00097   136,       144,       152,       160,
00098 
00099   /* ACC, FSCR */
00100   NO_OFFSET, 176
00101 };
00102 
00103 /* The register layout info.  */
00104 
00105 struct ravenscar_reg_info
00106 {
00107   /* A table providing the offset relative to the context structure
00108      where each register is saved.  */
00109   const int *context_offsets;
00110 
00111   /* The number of elements in the context_offsets table above.  */
00112   int context_offsets_size;
00113 };
00114 
00115 /* supply register REGNUM, which has been saved on REGISTER_ADDR, to the
00116    regcache.  */
00117 
00118 static void
00119 supply_register_at_address (struct regcache *regcache, int regnum,
00120                             CORE_ADDR register_addr)
00121 {
00122   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00123   int buf_size = register_size (gdbarch, regnum);
00124   gdb_byte *buf;
00125 
00126   buf = alloca (buf_size);
00127   read_memory (register_addr, buf, buf_size);
00128   regcache_raw_supply (regcache, regnum, buf);
00129 }
00130 
00131 /* Return true if, for a non-running thread, REGNUM has been saved on the
00132    Thread_Descriptor.  */
00133 
00134 static int
00135 register_in_thread_descriptor_p (const struct ravenscar_reg_info *reg_info,
00136                                  int regnum)
00137 {
00138   return (regnum < reg_info->context_offsets_size
00139           && reg_info->context_offsets[regnum] != NO_OFFSET);
00140 }
00141 
00142 /* to_fetch_registers when inferior_ptid is different from the running
00143    thread.  */
00144 
00145 static void
00146 ppc_ravenscar_generic_fetch_registers
00147   (const struct ravenscar_reg_info *reg_info,
00148    struct regcache *regcache, int regnum)
00149 {
00150   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00151   const int sp_regnum = gdbarch_sp_regnum (gdbarch);
00152   const int num_regs = gdbarch_num_regs (gdbarch);
00153   int current_regnum;
00154   CORE_ADDR current_address;
00155   CORE_ADDR thread_descriptor_address;
00156 
00157   /* The tid is the thread_id field, which is a pointer to the thread.  */
00158   thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid);
00159 
00160   /* Read registers.  */
00161   for (current_regnum = 0; current_regnum < num_regs; current_regnum++)
00162     {
00163       if (register_in_thread_descriptor_p (reg_info, current_regnum))
00164         {
00165           current_address = thread_descriptor_address
00166             + reg_info->context_offsets[current_regnum];
00167           supply_register_at_address (regcache, current_regnum,
00168                                       current_address);
00169         }
00170     }
00171 }
00172 
00173 /* to_prepare_to_store when inferior_ptid is different from the running
00174    thread.  */
00175 
00176 static void
00177 ppc_ravenscar_generic_prepare_to_store (struct regcache *regcache)
00178 {
00179   /* Nothing to do.  */
00180 }
00181 
00182 /* to_store_registers when inferior_ptid is different from the running
00183    thread.  */
00184 
00185 static void
00186 ppc_ravenscar_generic_store_registers
00187   (const struct ravenscar_reg_info *reg_info,
00188    struct regcache *regcache, int regnum)
00189 {
00190   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00191   int buf_size = register_size (gdbarch, regnum);
00192   gdb_byte buf[buf_size];
00193   ULONGEST register_address;
00194 
00195   if (register_in_thread_descriptor_p (reg_info, regnum))
00196     register_address
00197       = ptid_get_tid (inferior_ptid) + reg_info->context_offsets [regnum];
00198   else
00199     return;
00200 
00201   regcache_raw_collect (regcache, regnum, buf);
00202   write_memory (register_address,
00203                 buf,
00204                 buf_size);
00205 }
00206 
00207 /* The ravenscar_reg_info for most PowerPC targets.  */
00208 
00209 static const struct ravenscar_reg_info ppc_reg_info =
00210 {
00211   powerpc_context_offsets,
00212   ARRAY_SIZE (powerpc_context_offsets),
00213 };
00214 
00215 /* Implement the to_fetch_registers ravenscar_arch_ops method
00216    for most PowerPC targets.  */
00217 
00218 static void
00219 ppc_ravenscar_powerpc_fetch_registers (struct regcache *regcache, int regnum)
00220 {
00221   ppc_ravenscar_generic_fetch_registers (&ppc_reg_info, regcache, regnum);
00222 }
00223 
00224 /* Implement the to_store_registers ravenscar_arch_ops method
00225    for most PowerPC targets.  */
00226 
00227 static void
00228 ppc_ravenscar_powerpc_store_registers (struct regcache *regcache, int regnum)
00229 {
00230   ppc_ravenscar_generic_store_registers (&ppc_reg_info, regcache, regnum);
00231 }
00232 
00233 /* The ravenscar_arch_ops vector for most PowerPC targets.  */
00234 
00235 static struct ravenscar_arch_ops ppc_ravenscar_powerpc_ops =
00236 {
00237   ppc_ravenscar_powerpc_fetch_registers,
00238   ppc_ravenscar_powerpc_store_registers,
00239   ppc_ravenscar_generic_prepare_to_store
00240 };
00241 
00242 /* Register ppc_ravenscar_powerpc_ops in GDBARCH.  */
00243 
00244 void
00245 register_ppc_ravenscar_ops (struct gdbarch *gdbarch)
00246 {
00247   set_gdbarch_ravenscar_ops (gdbarch, &ppc_ravenscar_powerpc_ops);
00248 }
00249 
00250 /* The ravenscar_reg_info for E500 targets.  */
00251 
00252 static const struct ravenscar_reg_info e500_reg_info =
00253 {
00254   e500_context_offsets,
00255   ARRAY_SIZE (e500_context_offsets),
00256 };
00257 
00258 /* Implement the to_fetch_registers ravenscar_arch_ops method
00259    for E500 targets.  */
00260 
00261 static void
00262 ppc_ravenscar_e500_fetch_registers (struct regcache *regcache, int regnum)
00263 {
00264   ppc_ravenscar_generic_fetch_registers (&e500_reg_info, regcache, regnum);
00265 }
00266 
00267 /* Implement the to_store_registers ravenscar_arch_ops method
00268    for E500 targets.  */
00269 
00270 static void
00271 ppc_ravenscar_e500_store_registers (struct regcache *regcache, int regnum)
00272 {
00273   ppc_ravenscar_generic_store_registers (&e500_reg_info, regcache, regnum);
00274 }
00275 
00276 /* The ravenscar_arch_ops vector for E500 targets.  */
00277 
00278 static struct ravenscar_arch_ops ppc_ravenscar_e500_ops =
00279 {
00280   ppc_ravenscar_e500_fetch_registers,
00281   ppc_ravenscar_e500_store_registers,
00282   ppc_ravenscar_generic_prepare_to_store
00283 };
00284 
00285 /* Register ppc_ravenscar_e500_ops in GDBARCH.  */
00286 
00287 void
00288 register_e500_ravenscar_ops (struct gdbarch *gdbarch)
00289 {
00290   set_gdbarch_ravenscar_ops (gdbarch, &ppc_ravenscar_e500_ops);
00291 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines