GDB (API)
/home/stan/gdb/src/gdb/sparc-ravenscar-thread.c
Go to the documentation of this file.
00001 /* Ravenscar SPARC target support.
00002 
00003    Copyright (C) 2004-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 "sparc-tdep.h"
00024 #include "inferior.h"
00025 #include "ravenscar-thread.h"
00026 #include "sparc-ravenscar-thread.h"
00027 
00028 static void sparc_ravenscar_fetch_registers (struct regcache *regcache,
00029                                              int regnum);
00030 static void sparc_ravenscar_store_registers (struct regcache *regcache,
00031                                              int regnum);
00032 static void sparc_ravenscar_prepare_to_store (struct regcache *regcache);
00033 
00034 /* Register offsets from a referenced address (exempli gratia the
00035    Thread_Descriptor).  The referenced address depends on the register
00036    number.  The Thread_Descriptor layout and the stack layout are documented
00037    in the GNAT sources, in sparc-bb.h.  */
00038 
00039 static const int sparc_register_offsets[] =
00040 {
00041   /* G0 - G7 */
00042   -1,   0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
00043   /* O0 - O7 */
00044   0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
00045   /* L0 - L7 */
00046   0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
00047   /* I0 - I7 */
00048   0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
00049   /* F0 - F31 */
00050   0x50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C,
00051   0x70, 0x74, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C,
00052   0x90, 0x94, 0x99, 0x9C, 0xA0, 0xA4, 0xA8, 0xAC,
00053   0xB0, 0xB4, 0xBB, 0xBC, 0xC0, 0xC4, 0xC8, 0xCC,
00054   /* Y  PSR   WIM   TBR   PC    NPC   FPSR  CPSR */
00055   0x40, 0x20, 0x44, -1,   0x1C, -1,   0x4C, -1
00056 };
00057 
00058 /* supply register REGNUM, which has been saved on REGISTER_ADDR, to the
00059    regcache.  */
00060 
00061 static void
00062 supply_register_at_address (struct regcache *regcache, int regnum,
00063                             CORE_ADDR register_addr)
00064 {
00065   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00066   int buf_size = register_size (gdbarch, regnum);
00067   gdb_byte *buf;
00068 
00069   buf = alloca (buf_size);
00070   read_memory (register_addr, buf, buf_size);
00071   regcache_raw_supply (regcache, regnum, buf);
00072 }
00073 
00074 /* Return true if, for a non-running thread, REGNUM has been saved on the
00075    stack.  */
00076 
00077 static int
00078 register_on_stack_p (int regnum)
00079 {
00080   return (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
00081     || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM);
00082 }
00083 
00084 /* Return true if, for a non-running thread, REGNUM has been saved on the
00085    Thread_Descriptor.  */
00086 
00087 static int
00088 register_in_thread_descriptor_p (int regnum)
00089 {
00090   return (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
00091     || (regnum == SPARC32_PSR_REGNUM)
00092     || (regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
00093     || (regnum == SPARC32_Y_REGNUM)
00094     || (regnum == SPARC32_WIM_REGNUM)
00095     || (regnum == SPARC32_FSR_REGNUM)
00096     || (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F0_REGNUM + 31)
00097     || (regnum == SPARC32_PC_REGNUM);
00098 }
00099 
00100 /* to_fetch_registers when inferior_ptid is different from the running
00101    thread.  */
00102 
00103 static void
00104 sparc_ravenscar_fetch_registers (struct regcache *regcache, int regnum)
00105 {
00106   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00107   const int sp_regnum = gdbarch_sp_regnum (gdbarch);
00108   const int num_regs = gdbarch_num_regs (gdbarch);
00109   int current_regnum;
00110   CORE_ADDR current_address;
00111   CORE_ADDR thread_descriptor_address;
00112   ULONGEST stack_address;
00113 
00114   /* The tid is the thread_id field, which is a pointer to the thread.  */
00115   thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid);
00116 
00117   /* Read the saved SP in the context buffer.  */
00118   current_address = thread_descriptor_address
00119     + sparc_register_offsets [sp_regnum];
00120   supply_register_at_address (regcache, sp_regnum, current_address);
00121   regcache_cooked_read_unsigned (regcache, sp_regnum, &stack_address);
00122 
00123   /* Read registers.  */
00124   for (current_regnum = 0; current_regnum < num_regs; current_regnum ++)
00125     {
00126       if (register_in_thread_descriptor_p (current_regnum))
00127         {
00128           current_address = thread_descriptor_address
00129             + sparc_register_offsets [current_regnum];
00130           supply_register_at_address (regcache, current_regnum,
00131                                       current_address);
00132         }
00133       else if (register_on_stack_p (current_regnum))
00134         {
00135           current_address = stack_address
00136             + sparc_register_offsets [current_regnum];
00137           supply_register_at_address (regcache, current_regnum,
00138                                       current_address);
00139         }
00140     }
00141 }
00142 
00143 /* to_prepare_to_store when inferior_ptid is different from the running
00144    thread.  */
00145 
00146 static void
00147 sparc_ravenscar_prepare_to_store (struct regcache *regcache)
00148 {
00149   /* Nothing to do.  */
00150 }
00151 
00152 /* to_store_registers when inferior_ptid is different from the running
00153    thread.  */
00154 
00155 static void
00156 sparc_ravenscar_store_registers (struct regcache *regcache, int regnum)
00157 {
00158   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00159   int buf_size = register_size (gdbarch, regnum);
00160   gdb_byte buf[buf_size];
00161   ULONGEST register_address;
00162 
00163   if (register_in_thread_descriptor_p (regnum))
00164     register_address =
00165       ptid_get_tid (inferior_ptid) + sparc_register_offsets [regnum];
00166   else if (register_on_stack_p (regnum))
00167     {
00168       regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM,
00169                                      &register_address);
00170       register_address += sparc_register_offsets [regnum];
00171     }
00172   else
00173     return;
00174 
00175   regcache_raw_collect (regcache, regnum, buf);
00176   write_memory (register_address,
00177                 buf,
00178                 buf_size);
00179 }
00180 
00181 static struct ravenscar_arch_ops sparc_ravenscar_ops =
00182 {
00183   sparc_ravenscar_fetch_registers,
00184   sparc_ravenscar_store_registers,
00185   sparc_ravenscar_prepare_to_store
00186 };
00187 
00188 /* Register ravenscar_arch_ops in GDBARCH.  */
00189 
00190 void
00191 register_sparc_ravenscar_ops (struct gdbarch *gdbarch)
00192 {
00193   set_gdbarch_ravenscar_ops (gdbarch, &sparc_ravenscar_ops);
00194 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines