GDB (API)
|
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 ®ister_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 }