GDB (API)
/home/stan/gdb/src/gdb/proc-service.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines