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