GDB (API)
|
00001 /* <proc_service.h> implementation. 00002 00003 Copyright (C) 1999-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 00022 #include "gdbcore.h" 00023 #include "inferior.h" 00024 #include "symtab.h" 00025 #include "target.h" 00026 #include "regcache.h" 00027 00028 #include "gdb_proc_service.h" 00029 00030 #include <sys/procfs.h> 00031 00032 /* Prototypes for supply_gregset etc. */ 00033 #include "gregset.h" 00034 00035 00036 /* Fix-up some broken systems. */ 00037 00038 /* The prototypes in <proc_service.h> are slightly different on older 00039 systems. Compensate for the discrepancies. */ 00040 00041 #ifdef PROC_SERVICE_IS_OLD 00042 typedef const struct ps_prochandle *gdb_ps_prochandle_t; 00043 typedef char *gdb_ps_read_buf_t; 00044 typedef char *gdb_ps_write_buf_t; 00045 typedef int gdb_ps_size_t; 00046 #else 00047 typedef struct ps_prochandle *gdb_ps_prochandle_t; 00048 typedef void *gdb_ps_read_buf_t; 00049 typedef const void *gdb_ps_write_buf_t; 00050 typedef size_t gdb_ps_size_t; 00051 #endif 00052 00053 00054 /* Helper functions. */ 00055 00056 /* Convert a psaddr_t to a CORE_ADDR. */ 00057 00058 static CORE_ADDR 00059 ps_addr_to_core_addr (psaddr_t addr) 00060 { 00061 if (exec_bfd && bfd_get_sign_extend_vma (exec_bfd)) 00062 return (intptr_t) addr; 00063 else 00064 return (uintptr_t) addr; 00065 } 00066 00067 /* Convert a CORE_ADDR to a psaddr_t. */ 00068 00069 static psaddr_t 00070 core_addr_to_ps_addr (CORE_ADDR addr) 00071 { 00072 if (exec_bfd && bfd_get_sign_extend_vma (exec_bfd)) 00073 return (psaddr_t) (intptr_t) addr; 00074 else 00075 return (psaddr_t) (uintptr_t) addr; 00076 } 00077 00078 /* Transfer LEN bytes of memory between BUF and address ADDR in the 00079 process specified by PH. If WRITE, transfer them to the process, 00080 else transfer them from the process. Returns PS_OK for success, 00081 PS_ERR on failure. 00082 00083 This is a helper function for ps_pdread, ps_pdwrite, ps_ptread and 00084 ps_ptwrite. */ 00085 00086 static ps_err_e 00087 ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr, 00088 gdb_byte *buf, size_t len, int write) 00089 { 00090 struct cleanup *old_chain = save_inferior_ptid (); 00091 int ret; 00092 CORE_ADDR core_addr = ps_addr_to_core_addr (addr); 00093 00094 inferior_ptid = ph->ptid; 00095 00096 if (write) 00097 ret = target_write_memory (core_addr, buf, len); 00098 else 00099 ret = target_read_memory (core_addr, buf, len); 00100 00101 do_cleanups (old_chain); 00102 00103 return (ret == 0 ? PS_OK : PS_ERR); 00104 } 00105 00106 00107 /* Stop the target process PH. */ 00108 00109 ps_err_e 00110 ps_pstop (gdb_ps_prochandle_t ph) 00111 { 00112 /* The process is always stopped when under control of GDB. */ 00113 return PS_OK; 00114 } 00115 00116 /* Resume the target process PH. */ 00117 00118 ps_err_e 00119 ps_pcontinue (gdb_ps_prochandle_t ph) 00120 { 00121 /* Pretend we did successfully continue the process. GDB will take 00122 care of it later on. */ 00123 return PS_OK; 00124 } 00125 00126 /* Stop the lightweight process LWPID within the target process PH. */ 00127 00128 ps_err_e 00129 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid) 00130 { 00131 /* All lightweight processes are stopped when under control of GDB. */ 00132 return PS_OK; 00133 } 00134 00135 /* Resume the lightweight process (LWP) LWPID within the target 00136 process PH. */ 00137 00138 ps_err_e 00139 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid) 00140 { 00141 /* Pretend we did successfully continue LWPID. GDB will take care 00142 of it later on. */ 00143 return PS_OK; 00144 } 00145 00146 /* Get the size of the architecture-dependent extra state registers 00147 for LWP LWPID within the target process PH and return it in 00148 *XREGSIZE. */ 00149 00150 ps_err_e 00151 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize) 00152 { 00153 /* FIXME: Not supported yet. */ 00154 return PS_OK; 00155 } 00156 00157 /* Get the extra state registers of LWP LWPID within the target 00158 process PH and store them in XREGSET. */ 00159 00160 ps_err_e 00161 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) 00162 { 00163 /* FIXME: Not supported yet. */ 00164 return PS_OK; 00165 } 00166 00167 /* Set the extra state registers of LWP LWPID within the target 00168 process PH from XREGSET. */ 00169 00170 ps_err_e 00171 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) 00172 { 00173 /* FIXME: Not supported yet. */ 00174 return PS_OK; 00175 } 00176 00177 /* Log (additional) diognostic information. */ 00178 00179 void 00180 ps_plog (const char *fmt, ...) 00181 { 00182 va_list args; 00183 00184 va_start (args, fmt); 00185 vfprintf_filtered (gdb_stderr, fmt, args); 00186 va_end (args); 00187 } 00188 00189 /* Search for the symbol named NAME within the object named OBJ within 00190 the target process PH. If the symbol is found the address of the 00191 symbol is stored in SYM_ADDR. */ 00192 00193 ps_err_e 00194 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, 00195 const char *name, psaddr_t *sym_addr) 00196 { 00197 struct minimal_symbol *ms; 00198 struct cleanup *old_chain = save_current_program_space (); 00199 struct inferior *inf = find_inferior_pid (ptid_get_pid (ph->ptid)); 00200 ps_err_e result; 00201 00202 set_current_program_space (inf->pspace); 00203 00204 /* FIXME: kettenis/2000-09-03: What should we do with OBJ? */ 00205 ms = lookup_minimal_symbol (name, NULL, NULL); 00206 if (ms == NULL) 00207 result = PS_NOSYM; 00208 else 00209 { 00210 *sym_addr = core_addr_to_ps_addr (SYMBOL_VALUE_ADDRESS (ms)); 00211 result = PS_OK; 00212 } 00213 00214 do_cleanups (old_chain); 00215 return result; 00216 } 00217 00218 /* Read SIZE bytes from the target process PH at address ADDR and copy 00219 them into BUF. */ 00220 00221 ps_err_e 00222 ps_pdread (gdb_ps_prochandle_t ph, psaddr_t addr, 00223 gdb_ps_read_buf_t buf, gdb_ps_size_t size) 00224 { 00225 return ps_xfer_memory (ph, addr, buf, size, 0); 00226 } 00227 00228 /* Write SIZE bytes from BUF into the target process PH at address ADDR. */ 00229 00230 ps_err_e 00231 ps_pdwrite (gdb_ps_prochandle_t ph, psaddr_t addr, 00232 gdb_ps_write_buf_t buf, gdb_ps_size_t size) 00233 { 00234 return ps_xfer_memory (ph, addr, (gdb_byte *) buf, size, 1); 00235 } 00236 00237 /* Read SIZE bytes from the target process PH at address ADDR and copy 00238 them into BUF. */ 00239 00240 ps_err_e 00241 ps_ptread (gdb_ps_prochandle_t ph, psaddr_t addr, 00242 gdb_ps_read_buf_t buf, gdb_ps_size_t size) 00243 { 00244 return ps_xfer_memory (ph, addr, (gdb_byte *) buf, size, 0); 00245 } 00246 00247 /* Write SIZE bytes from BUF into the target process PH at address ADDR. */ 00248 00249 ps_err_e 00250 ps_ptwrite (gdb_ps_prochandle_t ph, psaddr_t addr, 00251 gdb_ps_write_buf_t buf, gdb_ps_size_t size) 00252 { 00253 return ps_xfer_memory (ph, addr, (gdb_byte *) buf, size, 1); 00254 } 00255 00256 /* Get the general registers of LWP LWPID within the target process PH 00257 and store them in GREGSET. */ 00258 00259 ps_err_e 00260 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) 00261 { 00262 struct cleanup *old_chain = save_inferior_ptid (); 00263 struct regcache *regcache; 00264 00265 inferior_ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); 00266 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); 00267 00268 target_fetch_registers (regcache, -1); 00269 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1); 00270 00271 do_cleanups (old_chain); 00272 return PS_OK; 00273 } 00274 00275 /* Set the general registers of LWP LWPID within the target process PH 00276 from GREGSET. */ 00277 00278 ps_err_e 00279 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) 00280 { 00281 struct cleanup *old_chain = save_inferior_ptid (); 00282 struct regcache *regcache; 00283 00284 inferior_ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); 00285 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); 00286 00287 supply_gregset (regcache, (const gdb_gregset_t *) gregset); 00288 target_store_registers (regcache, -1); 00289 00290 do_cleanups (old_chain); 00291 return PS_OK; 00292 } 00293 00294 /* Get the floating-point registers of LWP LWPID within the target 00295 process PH and store them in FPREGSET. */ 00296 00297 ps_err_e 00298 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, 00299 gdb_prfpregset_t *fpregset) 00300 { 00301 struct cleanup *old_chain = save_inferior_ptid (); 00302 struct regcache *regcache; 00303 00304 inferior_ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); 00305 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); 00306 00307 target_fetch_registers (regcache, -1); 00308 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); 00309 00310 do_cleanups (old_chain); 00311 return PS_OK; 00312 } 00313 00314 /* Set the floating-point registers of LWP LWPID within the target 00315 process PH from FPREGSET. */ 00316 00317 ps_err_e 00318 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, 00319 const gdb_prfpregset_t *fpregset) 00320 { 00321 struct cleanup *old_chain = save_inferior_ptid (); 00322 struct regcache *regcache; 00323 00324 inferior_ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); 00325 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); 00326 00327 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset); 00328 target_store_registers (regcache, -1); 00329 00330 do_cleanups (old_chain); 00331 return PS_OK; 00332 } 00333 00334 /* Return overall process id of the target PH. Special for GNU/Linux 00335 -- not used on Solaris. */ 00336 00337 pid_t 00338 ps_getpid (gdb_ps_prochandle_t ph) 00339 { 00340 return ptid_get_pid (ph->ptid); 00341 } 00342 00343 /* Provide a prototype to silence -Wmissing-prototypes. */ 00344 extern initialize_file_ftype _initialize_proc_service; 00345 00346 void 00347 _initialize_proc_service (void) 00348 { 00349 /* This function solely exists to make sure this module is linked 00350 into the final binary. */ 00351 }