GDBserver
|
00001 /* libthread_db helper functions for the remote server for GDB. 00002 Copyright (C) 2002-2013 Free Software Foundation, Inc. 00003 00004 Contributed by MontaVista Software. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "server.h" 00022 00023 /* This file is currently tied to GNU/Linux. It should scale well to 00024 another libthread_db implementation, with the approriate gdbserver 00025 hooks, but for now this means we can use GNU/Linux's target data. */ 00026 00027 #include "linux-low.h" 00028 00029 #include "gdb_proc_service.h" 00030 00031 typedef struct ps_prochandle *gdb_ps_prochandle_t; 00032 typedef void *gdb_ps_read_buf_t; 00033 typedef const void *gdb_ps_write_buf_t; 00034 typedef size_t gdb_ps_size_t; 00035 00036 #ifdef HAVE_LINUX_REGSETS 00037 #define HAVE_REGSETS 00038 #endif 00039 00040 #ifdef HAVE_REGSETS 00041 static struct regset_info * 00042 gregset_info (void) 00043 { 00044 int i = 0; 00045 const struct regs_info *regs_info = (*the_low_target.regs_info) (); 00046 struct regsets_info *regsets_info = regs_info->regsets_info; 00047 00048 while (regsets_info->regsets[i].size != -1) 00049 { 00050 if (regsets_info->regsets[i].type == GENERAL_REGS) 00051 break; 00052 i++; 00053 } 00054 00055 return ®sets_info->regsets[i]; 00056 } 00057 #endif 00058 00059 /* Search for the symbol named NAME within the object named OBJ within 00060 the target process PH. If the symbol is found the address of the 00061 symbol is stored in SYM_ADDR. */ 00062 00063 ps_err_e 00064 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, 00065 const char *name, psaddr_t *sym_addr) 00066 { 00067 CORE_ADDR addr; 00068 00069 if (thread_db_look_up_one_symbol (name, &addr) == 0) 00070 return PS_NOSYM; 00071 00072 *sym_addr = (psaddr_t) (unsigned long) addr; 00073 return PS_OK; 00074 } 00075 00076 /* Read SIZE bytes from the target process PH at address ADDR and copy 00077 them into BUF. */ 00078 00079 ps_err_e 00080 ps_pdread (gdb_ps_prochandle_t ph, psaddr_t addr, 00081 gdb_ps_read_buf_t buf, gdb_ps_size_t size) 00082 { 00083 read_inferior_memory ((unsigned long) addr, buf, size); 00084 return PS_OK; 00085 } 00086 00087 /* Write SIZE bytes from BUF into the target process PH at address ADDR. */ 00088 00089 ps_err_e 00090 ps_pdwrite (gdb_ps_prochandle_t ph, psaddr_t addr, 00091 gdb_ps_write_buf_t buf, gdb_ps_size_t size) 00092 { 00093 return write_inferior_memory ((unsigned long) addr, buf, size); 00094 } 00095 00096 /* Get the general registers of LWP LWPID within the target process PH 00097 and store them in GREGSET. */ 00098 00099 ps_err_e 00100 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) 00101 { 00102 #ifdef HAVE_REGSETS 00103 struct lwp_info *lwp; 00104 struct thread_info *reg_inferior, *save_inferior; 00105 struct regcache *regcache; 00106 00107 lwp = find_lwp_pid (pid_to_ptid (lwpid)); 00108 if (lwp == NULL) 00109 return PS_ERR; 00110 00111 reg_inferior = get_lwp_thread (lwp); 00112 save_inferior = current_inferior; 00113 current_inferior = reg_inferior; 00114 regcache = get_thread_regcache (current_inferior, 1); 00115 gregset_info ()->fill_function (regcache, gregset); 00116 00117 current_inferior = save_inferior; 00118 return PS_OK; 00119 #else 00120 return PS_ERR; 00121 #endif 00122 } 00123 00124 /* Set the general registers of LWP LWPID within the target process PH 00125 from GREGSET. */ 00126 00127 ps_err_e 00128 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) 00129 { 00130 /* Unneeded. */ 00131 return PS_ERR; 00132 } 00133 00134 /* Get the floating-point registers of LWP LWPID within the target 00135 process PH and store them in FPREGSET. */ 00136 00137 ps_err_e 00138 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset) 00139 { 00140 /* Unneeded. */ 00141 return PS_ERR; 00142 } 00143 00144 /* Set the floating-point registers of LWP LWPID within the target 00145 process PH from FPREGSET. */ 00146 00147 ps_err_e 00148 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset) 00149 { 00150 /* Unneeded. */ 00151 return PS_ERR; 00152 } 00153 00154 /* Return overall process id of the target PH. Special for GNU/Linux 00155 -- not used on Solaris. */ 00156 00157 pid_t 00158 ps_getpid (gdb_ps_prochandle_t ph) 00159 { 00160 return pid_of (get_thread_lwp (current_inferior)); 00161 }