GDBserver
|
00001 /* GNU/Linux/TILE-Gx specific low level interface, GDBserver. 00002 00003 Copyright (C) 2012-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 "server.h" 00021 #include "linux-low.h" 00022 00023 #include <arch/abi.h> 00024 #include <sys/ptrace.h> 00025 00026 /* Defined in auto-generated file reg-tilegx.c. */ 00027 void init_registers_tilegx (void); 00028 extern const struct target_desc *tdesc_tilegx; 00029 00030 /* Defined in auto-generated file reg-tilegx32.c. */ 00031 void init_registers_tilegx32 (void); 00032 extern const struct target_desc *tdesc_tilegx32; 00033 00034 #define tile_num_regs 65 00035 00036 static int tile_regmap[] = 00037 { 00038 0, 1, 2, 3, 4, 5, 6, 7, 00039 8, 9, 10, 11, 12, 13, 14, 15, 00040 16, 17, 18, 19, 20, 21, 22, 23, 00041 24, 25, 26, 27, 28, 29, 30, 31, 00042 32, 33, 34, 35, 36, 37, 38, 39, 00043 40, 41, 42, 43, 44, 45, 46, 47, 00044 48, 49, 50, 51, 52, 53, 54, 55, 00045 -1, -1, -1, -1, -1, -1, -1, -1, 00046 56 00047 }; 00048 00049 static int 00050 tile_cannot_fetch_register (int regno) 00051 { 00052 if (regno >= 0 && regno < 56) 00053 return 0; 00054 else if (regno == 64) 00055 return 0; 00056 else 00057 return 1; 00058 } 00059 00060 static int 00061 tile_cannot_store_register (int regno) 00062 { 00063 if (regno >= 0 && regno < 56) 00064 return 0; 00065 else if (regno == 64) 00066 return 0; 00067 else 00068 return 1; 00069 } 00070 00071 static CORE_ADDR 00072 tile_get_pc (struct regcache *regcache) 00073 { 00074 unsigned long pc; 00075 00076 collect_register_by_name (regcache, "pc", &pc); 00077 return pc; 00078 } 00079 00080 static void 00081 tile_set_pc (struct regcache *regcache, CORE_ADDR pc) 00082 { 00083 unsigned long newpc = pc; 00084 00085 supply_register_by_name (regcache, "pc", &newpc); 00086 } 00087 00088 static uint64_t tile_breakpoint = 0x400b3cae70166000ULL; 00089 #define tile_breakpoint_len 8 00090 00091 static int 00092 tile_breakpoint_at (CORE_ADDR where) 00093 { 00094 uint64_t insn; 00095 00096 (*the_target->read_memory) (where, (unsigned char *) &insn, 8); 00097 if (insn == tile_breakpoint) 00098 return 1; 00099 00100 /* If necessary, recognize more trap instructions here. GDB only uses the 00101 one. */ 00102 return 0; 00103 } 00104 00105 static void 00106 tile_fill_gregset (struct regcache *regcache, void *buf) 00107 { 00108 int i; 00109 00110 for (i = 0; i < tile_num_regs; i++) 00111 if (tile_regmap[i] != -1) 00112 collect_register (regcache, i, ((uint_reg_t *) buf) + tile_regmap[i]); 00113 } 00114 00115 static void 00116 tile_store_gregset (struct regcache *regcache, const void *buf) 00117 { 00118 int i; 00119 00120 for (i = 0; i < tile_num_regs; i++) 00121 if (tile_regmap[i] != -1) 00122 supply_register (regcache, i, ((uint_reg_t *) buf) + tile_regmap[i]); 00123 } 00124 00125 static struct regset_info tile_regsets[] = 00126 { 00127 { PTRACE_GETREGS, PTRACE_SETREGS, 0, tile_num_regs * 8, 00128 GENERAL_REGS, tile_fill_gregset, tile_store_gregset }, 00129 { 0, 0, 0, -1, -1, NULL, NULL } 00130 }; 00131 00132 static struct regsets_info tile_regsets_info = 00133 { 00134 tile_regsets, /* regsets */ 00135 0, /* num_regsets */ 00136 NULL, /* disabled_regsets */ 00137 }; 00138 00139 static struct usrregs_info tile_usrregs_info = 00140 { 00141 tile_num_regs, 00142 tile_regmap, 00143 }; 00144 00145 static struct regs_info regs_info = 00146 { 00147 NULL, /* regset_bitmap */ 00148 &tile_usrregs_info, 00149 &tile_regsets_info, 00150 }; 00151 00152 static const struct regs_info * 00153 tile_regs_info (void) 00154 { 00155 return ®s_info; 00156 } 00157 00158 static void 00159 tile_arch_setup (void) 00160 { 00161 int pid = pid_of (get_thread_lwp (current_inferior)); 00162 unsigned int machine; 00163 int is_elf64 = linux_pid_exe_is_elf_64_file (pid, &machine); 00164 00165 if (sizeof (void *) == 4) 00166 if (is_elf64 > 0) 00167 error (_("Can't debug 64-bit process with 32-bit GDBserver")); 00168 00169 if (!is_elf64) 00170 current_process ()->tdesc = tdesc_tilegx32; 00171 else 00172 current_process ()->tdesc = tdesc_tilegx; 00173 } 00174 00175 00176 struct linux_target_ops the_low_target = 00177 { 00178 tile_arch_setup, 00179 tile_regs_info, 00180 tile_cannot_fetch_register, 00181 tile_cannot_store_register, 00182 NULL, 00183 tile_get_pc, 00184 tile_set_pc, 00185 (const unsigned char *) &tile_breakpoint, 00186 tile_breakpoint_len, 00187 NULL, 00188 0, 00189 tile_breakpoint_at, 00190 }; 00191 00192 void 00193 initialize_low_arch (void) 00194 { 00195 init_registers_tilegx32(); 00196 init_registers_tilegx(); 00197 00198 initialize_regsets_info (&tile_regsets_info); 00199 }