gdb:
[external/binutils.git] / gdb / common / agent.c
1 /* Shared utility routines for GDB to interact with agent.
2
3    Copyright (C) 2009-2012 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #ifdef GDBSERVER
21 #include "server.h"
22 #else
23 #include "defs.h"
24 #include "target.h"
25 #include "inferior.h" /* for non_stop */
26 #endif
27
28 #include <string.h>
29 #include <unistd.h>
30 #include "agent.h"
31
32 int debug_agent = 0;
33
34 #ifdef GDBSERVER
35 #define DEBUG_AGENT(fmt, args...)       \
36   if (debug_agent)                      \
37     fprintf (stderr, fmt, ##args);
38 #else
39 #define DEBUG_AGENT(fmt, args...)       \
40   if (debug_agent)                      \
41     fprintf_unfiltered (gdb_stdlog, fmt, ##args);
42 #endif
43
44 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
45    about.  */
46
47 struct ipa_sym_addresses
48 {
49   CORE_ADDR addr_helper_thread_id;
50   CORE_ADDR addr_cmd_buf;
51 };
52
53 /* Cache of the helper thread id.  FIXME: this global should be made
54    per-process.  */
55 static unsigned int helper_thread_id = 0;
56
57 static struct
58 {
59   const char *name;
60   int offset;
61   int required;
62 } symbol_list[] = {
63   IPA_SYM(helper_thread_id),
64   IPA_SYM(cmd_buf),
65 };
66
67 static struct ipa_sym_addresses ipa_sym_addrs;
68
69 /* Look up all symbols needed by agent.  Return 0 if all the symbols are
70    found, return non-zero otherwise.  */
71
72 int
73 agent_look_up_symbols (void)
74 {
75   int i;
76
77   for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
78     {
79       CORE_ADDR *addrp =
80         (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
81 #ifdef GDBSERVER
82
83       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
84 #else
85       struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
86                                                           NULL, NULL);
87
88       if (sym != NULL)
89         *addrp = SYMBOL_VALUE_ADDRESS (sym);
90       else
91 #endif
92         {
93           DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
94           return -1;
95         }
96     }
97
98   return 0;
99 }
100
101 static unsigned int
102 agent_get_helper_thread_id (void)
103 {
104   if  (helper_thread_id == 0)
105     {
106 #ifdef GDBSERVER
107       if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
108                                 (unsigned char *) &helper_thread_id,
109                                 sizeof helper_thread_id))
110 #else
111       enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
112       gdb_byte buf[4];
113
114       if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
115                               buf, sizeof buf) == 0)
116         helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
117                                                      byte_order);
118       else
119 #endif
120         {
121           warning ("Error reading helper thread's id in lib");
122         }
123     }
124
125   return helper_thread_id;
126 }
127
128 #ifdef HAVE_SYS_UN_H
129 #include <sys/socket.h>
130 #include <sys/un.h>
131 #define SOCK_DIR P_tmpdir
132
133 #ifndef UNIX_PATH_MAX
134 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
135 #endif
136
137 #endif
138
139 /* Connects to synchronization socket.  PID is the pid of inferior, which is
140    used to set up the connection socket.  */
141
142 static int
143 gdb_connect_sync_socket (int pid)
144 {
145 #ifdef HAVE_SYS_UN_H
146   struct sockaddr_un addr;
147   int res, fd;
148   char path[UNIX_PATH_MAX];
149
150   res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
151   if (res >= UNIX_PATH_MAX)
152     return -1;
153
154   res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
155   if (res == -1)
156     {
157       warning ("error opening sync socket: %s\n", strerror (errno));
158       return -1;
159     }
160
161   addr.sun_family = AF_UNIX;
162
163   res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
164   if (res >= UNIX_PATH_MAX)
165     {
166       warning ("string overflow allocating socket name\n");
167       close (fd);
168       return -1;
169     }
170
171   res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
172   if (res == -1)
173     {
174       warning ("error connecting sync socket (%s): %s. "
175                "Make sure the directory exists and that it is writable.",
176                path, strerror (errno));
177       close (fd);
178       return -1;
179     }
180
181   return fd;
182 #else
183   return -1;
184 #endif
185 }
186
187 /* Execute an agent command in the inferior.  PID is the value of pid of the
188    inferior.  CMD is the buffer for command.  GDB or GDBserver will store the
189    command into it and fetch the return result from CMD.  The interaction
190    between GDB/GDBserver and the agent is synchronized by a synchronization
191    socket.  Return zero if success, otherwise return non-zero.  */
192
193 int
194 agent_run_command (int pid, const char *cmd)
195 {
196   int fd;
197   int tid = agent_get_helper_thread_id ();
198   ptid_t ptid = ptid_build (pid, tid, 0);
199   int len = strlen (cmd) + 1;
200
201 #ifdef GDBSERVER
202   int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
203                                    (const unsigned char *) cmd, len);
204 #else
205   int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
206 #endif
207
208   if (ret != 0)
209     {
210       warning ("unable to write");
211       return -1;
212     }
213
214   DEBUG_AGENT ("agent: resumed helper thread\n");
215
216   /* Resume helper thread.  */
217 #ifdef GDBSERVER
218 {
219   struct thread_resume resume_info;
220
221   resume_info.thread = ptid;
222   resume_info.kind = resume_continue;
223   resume_info.sig = TARGET_SIGNAL_0;
224   (*the_target->resume) (&resume_info, 1);
225 }
226 #else
227  target_resume (ptid, 0, TARGET_SIGNAL_0);
228 #endif
229
230   fd = gdb_connect_sync_socket (pid);
231   if (fd >= 0)
232     {
233       char buf[1] = "";
234       int ret;
235
236       DEBUG_AGENT ("agent: signalling helper thread\n");
237
238       do
239         {
240           ret = write (fd, buf, 1);
241         } while (ret == -1 && errno == EINTR);
242
243         DEBUG_AGENT ("agent: waiting for helper thread's response\n");
244
245       do
246         {
247           ret = read (fd, buf, 1);
248         } while (ret == -1 && errno == EINTR);
249
250       close (fd);
251
252       DEBUG_AGENT ("agent: helper thread's response received\n");
253     }
254   else
255     return -1;
256
257   /* Need to read response with the inferior stopped.  */
258   if (!ptid_equal (ptid, null_ptid))
259     {
260       struct target_waitstatus status;
261       int was_non_stop = non_stop;
262       /* Stop thread PTID.  */
263       DEBUG_AGENT ("agent: stop helper thread\n");
264 #ifdef GDBSERVER
265       {
266         struct thread_resume resume_info;
267
268         resume_info.thread = ptid;
269         resume_info.kind = resume_stop;
270         resume_info.sig = TARGET_SIGNAL_0;
271         (*the_target->resume) (&resume_info, 1);
272       }
273
274       non_stop = 1;
275       mywait (ptid, &status, 0, 0);
276 #else
277       non_stop = 1;
278       target_stop (ptid);
279
280       memset (&status, 0, sizeof (status));
281       target_wait (ptid, &status, 0);
282 #endif
283       non_stop = was_non_stop;
284     }
285
286   if (fd >= 0)
287     {
288 #ifdef GDBSERVER
289       if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
290                                 (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
291 #else
292       if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
293                               IPA_CMD_BUF_SIZE))
294 #endif
295         {
296           warning ("Error reading command response");
297           return -1;
298         }
299     }
300
301   return 0;
302 }