xref: /openbsd-src/gnu/usr.bin/binutils/gdb/gdbserver/proc-service.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* libthread_db helper functions for the remote server for GDB.
2*11efff7fSkettenis    Copyright 2002, 2004
3b725ae77Skettenis    Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    Contributed by MontaVista Software.
6b725ae77Skettenis 
7b725ae77Skettenis    This file is part of GDB.
8b725ae77Skettenis 
9b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
10b725ae77Skettenis    it under the terms of the GNU General Public License as published by
11b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
12b725ae77Skettenis    (at your option) any later version.
13b725ae77Skettenis 
14b725ae77Skettenis    This program is distributed in the hope that it will be useful,
15b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
16b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17b725ae77Skettenis    GNU General Public License for more details.
18b725ae77Skettenis 
19b725ae77Skettenis    You should have received a copy of the GNU General Public License
20b725ae77Skettenis    along with this program; if not, write to the Free Software
21b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
23b725ae77Skettenis 
24b725ae77Skettenis #include "server.h"
25b725ae77Skettenis 
26b725ae77Skettenis /* This file is currently tied to GNU/Linux.  It should scale well to
27b725ae77Skettenis    another libthread_db implementation, with the approriate gdbserver
28b725ae77Skettenis    hooks, but for now this means we can use GNU/Linux's target data.  */
29b725ae77Skettenis 
30b725ae77Skettenis #include "linux-low.h"
31b725ae77Skettenis 
32b725ae77Skettenis /* Correct for all GNU/Linux targets (for quite some time).  */
33b725ae77Skettenis #define GDB_GREGSET_T elf_gregset_t
34b725ae77Skettenis #define GDB_FPREGSET_T elf_fpregset_t
35b725ae77Skettenis 
36b725ae77Skettenis #ifndef HAVE_ELF_FPREGSET_T
37b725ae77Skettenis /* Make sure we have said types.  Not all platforms bring in <linux/elf.h>
38b725ae77Skettenis    via <sys/procfs.h>.  */
39b725ae77Skettenis #ifdef HAVE_LINUX_ELF_H
40b725ae77Skettenis #include <linux/elf.h>
41b725ae77Skettenis #endif
42b725ae77Skettenis #endif
43b725ae77Skettenis 
44b725ae77Skettenis #include "../gdb_proc_service.h"
45b725ae77Skettenis 
46b725ae77Skettenis typedef struct ps_prochandle *gdb_ps_prochandle_t;
47b725ae77Skettenis typedef void *gdb_ps_read_buf_t;
48b725ae77Skettenis typedef const void *gdb_ps_write_buf_t;
49b725ae77Skettenis typedef size_t gdb_ps_size_t;
50b725ae77Skettenis 
51*11efff7fSkettenis #ifdef HAVE_LINUX_REGSETS
52*11efff7fSkettenis #define HAVE_REGSETS
53*11efff7fSkettenis #endif
54*11efff7fSkettenis 
55*11efff7fSkettenis #ifdef HAVE_REGSETS
56b725ae77Skettenis static struct regset_info *
gregset_info(void)57b725ae77Skettenis gregset_info(void)
58b725ae77Skettenis {
59b725ae77Skettenis   int i = 0;
60b725ae77Skettenis 
61b725ae77Skettenis   while (target_regsets[i].size != -1)
62b725ae77Skettenis     {
63b725ae77Skettenis       if (target_regsets[i].type == GENERAL_REGS)
64b725ae77Skettenis 	break;
65b725ae77Skettenis       i++;
66b725ae77Skettenis     }
67b725ae77Skettenis 
68b725ae77Skettenis   return &target_regsets[i];
69b725ae77Skettenis }
70b725ae77Skettenis #endif
71b725ae77Skettenis 
72b725ae77Skettenis /* Search for the symbol named NAME within the object named OBJ within
73b725ae77Skettenis    the target process PH.  If the symbol is found the address of the
74b725ae77Skettenis    symbol is stored in SYM_ADDR.  */
75b725ae77Skettenis 
76b725ae77Skettenis ps_err_e
ps_pglobal_lookup(gdb_ps_prochandle_t ph,const char * obj,const char * name,paddr_t * sym_addr)77b725ae77Skettenis ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj,
78b725ae77Skettenis 		   const char *name, paddr_t *sym_addr)
79b725ae77Skettenis {
80b725ae77Skettenis   CORE_ADDR addr;
81b725ae77Skettenis 
82b725ae77Skettenis   if (look_up_one_symbol (name, &addr) == 0)
83b725ae77Skettenis     return PS_NOSYM;
84b725ae77Skettenis 
85b725ae77Skettenis   *sym_addr = (paddr_t) (unsigned long) addr;
86b725ae77Skettenis   return PS_OK;
87b725ae77Skettenis }
88b725ae77Skettenis 
89b725ae77Skettenis /* Read SIZE bytes from the target process PH at address ADDR and copy
90b725ae77Skettenis    them into BUF.  */
91b725ae77Skettenis 
92b725ae77Skettenis ps_err_e
ps_pdread(gdb_ps_prochandle_t ph,paddr_t addr,gdb_ps_read_buf_t buf,gdb_ps_size_t size)93b725ae77Skettenis ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
94b725ae77Skettenis 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
95b725ae77Skettenis {
96b725ae77Skettenis   read_inferior_memory (addr, buf, size);
97b725ae77Skettenis   return PS_OK;
98b725ae77Skettenis }
99b725ae77Skettenis 
100b725ae77Skettenis /* Write SIZE bytes from BUF into the target process PH at address ADDR.  */
101b725ae77Skettenis 
102b725ae77Skettenis ps_err_e
ps_pdwrite(gdb_ps_prochandle_t ph,paddr_t addr,gdb_ps_write_buf_t buf,gdb_ps_size_t size)103b725ae77Skettenis ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
104b725ae77Skettenis 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
105b725ae77Skettenis {
106b725ae77Skettenis   return write_inferior_memory (addr, buf, size);
107b725ae77Skettenis }
108b725ae77Skettenis 
109b725ae77Skettenis /* Get the general registers of LWP LWPID within the target process PH
110b725ae77Skettenis    and store them in GREGSET.  */
111b725ae77Skettenis 
112b725ae77Skettenis ps_err_e
ps_lgetregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,prgregset_t gregset)113b725ae77Skettenis ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
114b725ae77Skettenis {
115*11efff7fSkettenis #ifdef HAVE_REGSETS
116b725ae77Skettenis   struct thread_info *reg_inferior, *save_inferior;
117b725ae77Skettenis 
118b725ae77Skettenis   reg_inferior = (struct thread_info *) find_inferior_id (&all_threads,
119b725ae77Skettenis 							  lwpid);
120b725ae77Skettenis   if (reg_inferior == NULL)
121b725ae77Skettenis     return PS_ERR;
122b725ae77Skettenis 
123b725ae77Skettenis   save_inferior = current_inferior;
124b725ae77Skettenis   current_inferior = reg_inferior;
125b725ae77Skettenis 
126*11efff7fSkettenis   the_target->fetch_registers (0);
127*11efff7fSkettenis   gregset_info()->fill_function (gregset);
128b725ae77Skettenis 
129b725ae77Skettenis   current_inferior = save_inferior;
130b725ae77Skettenis   return PS_OK;
131*11efff7fSkettenis #else
132b725ae77Skettenis   return PS_ERR;
133*11efff7fSkettenis #endif
134b725ae77Skettenis }
135b725ae77Skettenis 
136b725ae77Skettenis /* Set the general registers of LWP LWPID within the target process PH
137b725ae77Skettenis    from GREGSET.  */
138b725ae77Skettenis 
139b725ae77Skettenis ps_err_e
ps_lsetregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,const prgregset_t gregset)140b725ae77Skettenis ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset)
141b725ae77Skettenis {
142*11efff7fSkettenis   /* Unneeded.  */
143b725ae77Skettenis   return PS_ERR;
144b725ae77Skettenis }
145b725ae77Skettenis 
146b725ae77Skettenis /* Get the floating-point registers of LWP LWPID within the target
147b725ae77Skettenis    process PH and store them in FPREGSET.  */
148b725ae77Skettenis 
149b725ae77Skettenis ps_err_e
ps_lgetfpregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,gdb_prfpregset_t * fpregset)150b725ae77Skettenis ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
151b725ae77Skettenis 	       gdb_prfpregset_t *fpregset)
152b725ae77Skettenis {
153*11efff7fSkettenis   /* Unneeded.  */
154b725ae77Skettenis   return PS_ERR;
155b725ae77Skettenis }
156b725ae77Skettenis 
157b725ae77Skettenis /* Set the floating-point registers of LWP LWPID within the target
158b725ae77Skettenis    process PH from FPREGSET.  */
159b725ae77Skettenis 
160b725ae77Skettenis ps_err_e
ps_lsetfpregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,const gdb_prfpregset_t * fpregset)161b725ae77Skettenis ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
162b725ae77Skettenis 	       const gdb_prfpregset_t *fpregset)
163b725ae77Skettenis {
164*11efff7fSkettenis   /* Unneeded.  */
165b725ae77Skettenis   return PS_ERR;
166b725ae77Skettenis }
167b725ae77Skettenis 
168b725ae77Skettenis /* Return overall process id of the target PH.  Special for GNU/Linux
169b725ae77Skettenis    -- not used on Solaris.  */
170b725ae77Skettenis 
171b725ae77Skettenis pid_t
ps_getpid(gdb_ps_prochandle_t ph)172b725ae77Skettenis ps_getpid (gdb_ps_prochandle_t ph)
173b725ae77Skettenis {
174b725ae77Skettenis   return ph->pid;
175b725ae77Skettenis }
176b725ae77Skettenis 
177b725ae77Skettenis 
178