GDBserver
/home/stan/gdb/src/gdb/gdbserver/proc-service.c
Go to the documentation of this file.
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 &regsets_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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines