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 /* Global flag to determine using agent or not.  */
45 int use_agent = 0;
46
47 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
48    about.  */
49
50 struct ipa_sym_addresses
51 {
52   CORE_ADDR addr_helper_thread_id;
53   CORE_ADDR addr_cmd_buf;
54 };
55
56 /* Cache of the helper thread id.  FIXME: this global should be made
57    per-process.  */
58 static unsigned int helper_thread_id = 0;
59
60 static struct
61 {
62   const char *name;
63   int offset;
64   int required;
65 } symbol_list[] = {
66   IPA_SYM(helper_thread_id),
67   IPA_SYM(cmd_buf),
68 };
69
70 static struct ipa_sym_addresses ipa_sym_addrs;
71
72 /* Look up all symbols needed by agent.  Return 0 if all the symbols are
73    found, return non-zero otherwise.  */
74
75 int
76 agent_look_up_symbols (void)
77 {
78   int i;
79
80   for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
81     {
82       CORE_ADDR *addrp =
83         (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
84 #ifdef GDBSERVER
85
86       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
87 #else
88       struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
89                                                           NULL, NULL);
90
91       if (sym != NULL)
92         *addrp = SYMBOL_VALUE_ADDRESS (sym);
93       else
94 #endif
95         {
96           DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
97           return -1;
98         }
99     }
100
101   return 0;
102 }
103
104 static unsigned int
105 agent_get_helper_thread_id (void)
106 {
107   if  (helper_thread_id == 0)
108     {
109 #ifdef GDBSERVER
110       if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
111                                 (unsigned char *) &helper_thread_id,
112                                 sizeof helper_thread_id))
113 #else
114       enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
115       gdb_byte buf[4];
116
117       if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
118                               buf, sizeof buf) == 0)
119         helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
120                                                      byte_order);
121       else
122 #endif
123         {
124           warning ("Error reading helper thread's id in lib");
125         }
126     }
127
128   return helper_thread_id;
129 }
130
131 #ifdef HAVE_SYS_UN_H
132 #include <sys/socket.h>
133 #include <sys/un.h>
134 #define SOCK_DIR P_tmpdir
135
136 #ifndef UNIX_PATH_MAX
137 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
138 #endif
139
140 #endif
141
142 /* Connects to synchronization socket.  PID is the pid of inferior, which is
143    used to set up the connection socket.  */
144
145 static int
146 gdb_connect_sync_socket (int pid)
147 {
148 #ifdef HAVE_SYS_UN_H
149   struct sockaddr_un addr;
150   int res, fd;
151   char path[UNIX_PATH_MAX];
152
153   res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
154   if (res >= UNIX_PATH_MAX)
155     return -1;
156
157   res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
158   if (res == -1)
159     {
160       warning ("error opening sync socket: %s\n", strerror (errno));
161       return -1;
162     }
163
164   addr.sun_family = AF_UNIX;
165
166   res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
167   if (res >= UNIX_PATH_MAX)
168     {
169       warning ("string overflow allocating socket name\n");
170       close (fd);
171       return -1;
172     }
173
174   res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
175   if (res == -1)
176     {
177       warning ("error connecting sync socket (%s): %s. "
178                "Make sure the directory exists and that it is writable.",
179                path, strerror (errno));
180       close (fd);
181       return -1;
182     }
183
184   return fd;
185 #else
186   return -1;
187 #endif
188 }
189
190 /* Execute an agent command in the inferior.  PID is the value of pid of the
191    inferior.  CMD is the buffer for command.  GDB or GDBserver will store the
192    command into it and fetch the return result from CMD.  The interaction
193    between GDB/GDBserver and the agent is synchronized by a synchronization
194    socket.  Return zero if success, otherwise return non-zero.  */
195
196 int
197 agent_run_command (int pid, const char *cmd)
198 {
199   int fd;
200   int tid = agent_get_helper_thread_id ();
201   ptid_t ptid = ptid_build (pid, tid, 0);
202   int len = strlen (cmd) + 1;
203
204 #ifdef GDBSERVER
205   int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
206                                    (const unsigned char *) cmd, len);
207 #else
208   int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
209 #endif
210
211   if (ret != 0)
212     {
213       warning ("unable to write");
214       return -1;
215     }
216
217   DEBUG_AGENT ("agent: resumed helper thread\n");
218
219   /* Resume helper thread.  */
220 #ifdef GDBSERVER
221 {
222   struct thread_resume resume_info;
223
224   resume_info.thread = ptid;
225   resume_info.kind = resume_continue;
226   resume_info.sig = TARGET_SIGNAL_0;
227   (*the_target->resume) (&resume_info, 1);
228 }
229 #else
230  target_resume (ptid, 0, TARGET_SIGNAL_0);
231 #endif
232
233   fd = gdb_connect_sync_socket (pid);
234   if (fd >= 0)
235     {
236       char buf[1] = "";
237       int ret;
238
239       DEBUG_AGENT ("agent: signalling helper thread\n");
240
241       do
242         {
243           ret = write (fd, buf, 1);
244         } while (ret == -1 && errno == EINTR);
245
246         DEBUG_AGENT ("agent: waiting for helper thread's response\n");
247
248       do
249         {
250           ret = read (fd, buf, 1);
251         } while (ret == -1 && errno == EINTR);
252
253       close (fd);
254
255       DEBUG_AGENT ("agent: helper thread's response received\n");
256     }
257   else
258     return -1;
259
260   /* Need to read response with the inferior stopped.  */
261   if (!ptid_equal (ptid, null_ptid))
262     {
263       struct target_waitstatus status;
264       int was_non_stop = non_stop;
265       /* Stop thread PTID.  */
266       DEBUG_AGENT ("agent: stop helper thread\n");
267 #ifdef GDBSERVER
268       {
269         struct thread_resume resume_info;
270
271         resume_info.thread = ptid;
272         resume_info.kind = resume_stop;
273         resume_info.sig = TARGET_SIGNAL_0;
274         (*the_target->resume) (&resume_info, 1);
275       }
276
277       non_stop = 1;
278       mywait (ptid, &status, 0, 0);
279 #else
280       non_stop = 1;
281       target_stop (ptid);
282
283       memset (&status, 0, sizeof (status));
284       target_wait (ptid, &status, 0);
285 #endif
286       non_stop = was_non_stop;
287     }
288
289   if (fd >= 0)
290     {
291 #ifdef GDBSERVER
292       if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
293                                 (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
294 #else
295       if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
296                               IPA_CMD_BUF_SIZE))
297 #endif
298         {
299           warning ("Error reading command response");
300           return -1;
301         }
302     }
303
304   return 0;
305 }