]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gdb/gdb/gdbserver/proc-service.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gdb / gdb / gdbserver / proc-service.c
1 /* libthread_db helper functions for the remote server for GDB.
2    Copyright 2002
3    Free Software Foundation, Inc.
4
5    Contributed by MontaVista Software.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23
24 #include "server.h"
25
26 /* This file is currently tied to GNU/Linux.  It should scale well to
27    another libthread_db implementation, with the approriate gdbserver
28    hooks, but for now this means we can use GNU/Linux's target data.  */
29
30 #include "linux-low.h"
31
32 /* Correct for all GNU/Linux targets (for quite some time).  */
33 #define GDB_GREGSET_T elf_gregset_t
34 #define GDB_FPREGSET_T elf_fpregset_t
35
36 #ifndef HAVE_ELF_FPREGSET_T
37 /* Make sure we have said types.  Not all platforms bring in <linux/elf.h>
38    via <sys/procfs.h>.  */
39 #ifdef HAVE_LINUX_ELF_H   
40 #include <linux/elf.h>    
41 #endif
42 #endif
43
44 #include "../gdb_proc_service.h"
45
46 typedef struct ps_prochandle *gdb_ps_prochandle_t;
47 typedef void *gdb_ps_read_buf_t;
48 typedef const void *gdb_ps_write_buf_t;
49 typedef size_t gdb_ps_size_t;
50
51 /* FIXME redo this right */
52 #if 0
53 #ifndef HAVE_LINUX_REGSETS
54 #error HAVE_LINUX_REGSETS required!
55 #else
56 static struct regset_info *
57 gregset_info(void)
58 {
59   int i = 0;
60
61   while (target_regsets[i].size != -1)
62     {
63       if (target_regsets[i].type == GENERAL_REGS)
64         break;
65       i++;
66     }
67
68   return &target_regsets[i];
69 }
70
71 static struct regset_info *
72 fpregset_info(void)
73 {
74   int i = 0;
75
76   while (target_regsets[i].size != -1)
77     {
78       if (target_regsets[i].type == FP_REGS)
79         break;
80       i++;
81     }
82
83   return &target_regsets[i];
84 }
85 #endif
86 #endif
87
88 /* Search for the symbol named NAME within the object named OBJ within
89    the target process PH.  If the symbol is found the address of the
90    symbol is stored in SYM_ADDR.  */
91
92 ps_err_e
93 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj,
94                    const char *name, paddr_t *sym_addr)
95 {
96   CORE_ADDR addr;
97
98   if (look_up_one_symbol (name, &addr) == 0)
99     return PS_NOSYM;
100
101   *sym_addr = (paddr_t) (unsigned long) addr;
102   return PS_OK;
103 }
104
105 /* Read SIZE bytes from the target process PH at address ADDR and copy
106    them into BUF.  */
107
108 ps_err_e
109 ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
110            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
111 {
112   read_inferior_memory (addr, buf, size);
113   return PS_OK;
114 }
115
116 /* Write SIZE bytes from BUF into the target process PH at address ADDR.  */
117
118 ps_err_e
119 ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
120             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
121 {
122   return write_inferior_memory (addr, buf, size);
123 }
124
125 /* Get the general registers of LWP LWPID within the target process PH
126    and store them in GREGSET.  */
127
128 ps_err_e
129 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
130 {
131 #if 0
132   struct thread_info *reg_inferior, *save_inferior;
133   void *regcache;
134
135   reg_inferior = (struct thread_info *) find_inferior_id (&all_threads,
136                                                           lwpid);
137   if (reg_inferior == NULL)
138     return PS_ERR;
139
140   save_inferior = current_inferior;
141   current_inferior = reg_inferior;
142
143   regcache = new_register_cache ();
144   the_target->fetch_registers (0, regcache);
145   gregset_info()->fill_function (gregset, regcache);
146   free_register_cache (regcache);
147
148   current_inferior = save_inferior;
149   return PS_OK;
150 #endif
151   /* FIXME */
152   return PS_ERR;
153 }
154
155 /* Set the general registers of LWP LWPID within the target process PH
156    from GREGSET.  */
157
158 ps_err_e
159 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset)
160 {
161 #if 0
162   struct thread_info *reg_inferior, *save_inferior;
163   void *regcache;
164
165   reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
166   if (reg_inferior == NULL)
167     return PS_ERR;
168
169   save_inferior = current_inferior;
170   current_inferior = reg_inferior;
171
172   regcache = new_register_cache ();
173   gregset_info()->store_function (gregset, regcache);
174   the_target->store_registers (0, regcache);
175   free_register_cache (regcache);
176
177   current_inferior = save_inferior;
178
179   return PS_OK;
180 #endif
181   /* FIXME */
182   return PS_ERR;
183 }
184
185 /* Get the floating-point registers of LWP LWPID within the target
186    process PH and store them in FPREGSET.  */
187
188 ps_err_e
189 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
190                gdb_prfpregset_t *fpregset)
191 {
192 #if 0
193   struct thread_info *reg_inferior, *save_inferior;
194   void *regcache;
195
196   reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
197   if (reg_inferior == NULL)
198     return PS_ERR;
199
200   save_inferior = current_inferior;
201   current_inferior = reg_inferior;
202
203   regcache = new_register_cache ();
204   the_target->fetch_registers (0, regcache);
205   fpregset_info()->fill_function (fpregset, regcache);
206   free_register_cache (regcache);
207
208   current_inferior = save_inferior;
209
210   return PS_OK;
211 #endif
212   /* FIXME */
213   return PS_ERR;
214 }
215
216 /* Set the floating-point registers of LWP LWPID within the target
217    process PH from FPREGSET.  */
218
219 ps_err_e
220 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
221                const gdb_prfpregset_t *fpregset)
222 {
223 #if 0
224   struct thread_info *reg_inferior, *save_inferior;
225   void *regcache;
226
227   reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
228   if (reg_inferior == NULL)
229     return PS_ERR;
230
231   save_inferior = current_inferior;
232   current_inferior = reg_inferior;
233
234   regcache = new_register_cache ();
235   fpregset_info()->store_function (fpregset, regcache);
236   the_target->store_registers (0, regcache);
237   free_register_cache (regcache);
238
239   current_inferior = save_inferior;
240
241   return PS_OK;
242 #endif
243   /* FIXME */
244   return PS_ERR;
245 }
246
247 /* Return overall process id of the target PH.  Special for GNU/Linux
248    -- not used on Solaris.  */
249
250 pid_t
251 ps_getpid (gdb_ps_prochandle_t ph)
252 {
253   return ph->pid;
254 }
255
256