PR gdb/7912:
[deliverable/binutils-gdb.git] / gdb / common / agent.c
CommitLineData
2fa291ac
YQ
1/* Shared utility routines for GDB to interact with agent.
2
28e7fd62 3 Copyright (C) 2009-2013 Free Software Foundation, Inc.
2fa291ac
YQ
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"
614c279d 31#include "filestuff.h"
2fa291ac
YQ
32
33int debug_agent = 0;
34
35#ifdef GDBSERVER
36#define DEBUG_AGENT(fmt, args...) \
37 if (debug_agent) \
38 fprintf (stderr, fmt, ##args);
39#else
40#define DEBUG_AGENT(fmt, args...) \
41 if (debug_agent) \
42 fprintf_unfiltered (gdb_stdlog, fmt, ##args);
43#endif
44
d1feda86
YQ
45/* Global flag to determine using agent or not. */
46int use_agent = 0;
47
2fa291ac
YQ
48/* Addresses of in-process agent's symbols both GDB and GDBserver cares
49 about. */
50
51struct ipa_sym_addresses
52{
53 CORE_ADDR addr_helper_thread_id;
54 CORE_ADDR addr_cmd_buf;
8ffcbaaf 55 CORE_ADDR addr_capability;
2fa291ac
YQ
56};
57
58/* Cache of the helper thread id. FIXME: this global should be made
59 per-process. */
60static unsigned int helper_thread_id = 0;
61
62static struct
63{
64 const char *name;
65 int offset;
66 int required;
67} symbol_list[] = {
68 IPA_SYM(helper_thread_id),
69 IPA_SYM(cmd_buf),
8ffcbaaf 70 IPA_SYM(capability),
2fa291ac
YQ
71};
72
73static struct ipa_sym_addresses ipa_sym_addrs;
74
58b4daa5
YQ
75static int all_agent_symbols_looked_up = 0;
76
77int
78agent_loaded_p (void)
79{
80 return all_agent_symbols_looked_up;
81}
82
2fa291ac
YQ
83/* Look up all symbols needed by agent. Return 0 if all the symbols are
84 found, return non-zero otherwise. */
85
86int
5808517f 87agent_look_up_symbols (void *arg)
2fa291ac
YQ
88{
89 int i;
90
58b4daa5
YQ
91 all_agent_symbols_looked_up = 0;
92
2fa291ac
YQ
93 for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
94 {
95 CORE_ADDR *addrp =
96 (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
97#ifdef GDBSERVER
98
99 if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
100#else
5808517f
YQ
101 struct minimal_symbol *sym =
102 lookup_minimal_symbol (symbol_list[i].name, NULL,
103 (struct objfile *) arg);
2fa291ac
YQ
104
105 if (sym != NULL)
106 *addrp = SYMBOL_VALUE_ADDRESS (sym);
107 else
108#endif
109 {
110 DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
111 return -1;
112 }
113 }
114
58b4daa5 115 all_agent_symbols_looked_up = 1;
2fa291ac
YQ
116 return 0;
117}
118
119static unsigned int
120agent_get_helper_thread_id (void)
121{
122 if (helper_thread_id == 0)
123 {
124#ifdef GDBSERVER
125 if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
126 (unsigned char *) &helper_thread_id,
127 sizeof helper_thread_id))
128#else
f5656ead 129 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
2fa291ac
YQ
130 gdb_byte buf[4];
131
132 if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
133 buf, sizeof buf) == 0)
134 helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
135 byte_order);
136 else
137#endif
138 {
87399aa1 139 warning (_("Error reading helper thread's id in lib"));
2fa291ac
YQ
140 }
141 }
142
143 return helper_thread_id;
144}
145
146#ifdef HAVE_SYS_UN_H
147#include <sys/socket.h>
148#include <sys/un.h>
149#define SOCK_DIR P_tmpdir
150
151#ifndef UNIX_PATH_MAX
152#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
153#endif
154
155#endif
156
157/* Connects to synchronization socket. PID is the pid of inferior, which is
158 used to set up the connection socket. */
159
160static int
161gdb_connect_sync_socket (int pid)
162{
163#ifdef HAVE_SYS_UN_H
164 struct sockaddr_un addr;
165 int res, fd;
166 char path[UNIX_PATH_MAX];
167
168 res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
169 if (res >= UNIX_PATH_MAX)
170 return -1;
171
614c279d 172 res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0);
2fa291ac
YQ
173 if (res == -1)
174 {
87399aa1 175 warning (_("error opening sync socket: %s"), strerror (errno));
2fa291ac
YQ
176 return -1;
177 }
178
179 addr.sun_family = AF_UNIX;
180
181 res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
182 if (res >= UNIX_PATH_MAX)
183 {
87399aa1 184 warning (_("string overflow allocating socket name"));
2fa291ac
YQ
185 close (fd);
186 return -1;
187 }
188
189 res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
190 if (res == -1)
191 {
87399aa1
YQ
192 warning (_("error connecting sync socket (%s): %s. "
193 "Make sure the directory exists and that it is writable."),
194 path, strerror (errno));
2fa291ac
YQ
195 close (fd);
196 return -1;
197 }
198
199 return fd;
200#else
201 return -1;
202#endif
203}
204
205/* Execute an agent command in the inferior. PID is the value of pid of the
206 inferior. CMD is the buffer for command. GDB or GDBserver will store the
207 command into it and fetch the return result from CMD. The interaction
208 between GDB/GDBserver and the agent is synchronized by a synchronization
209 socket. Return zero if success, otherwise return non-zero. */
210
211int
42476b70 212agent_run_command (int pid, const char *cmd, int len)
2fa291ac
YQ
213{
214 int fd;
215 int tid = agent_get_helper_thread_id ();
216 ptid_t ptid = ptid_build (pid, tid, 0);
2fa291ac
YQ
217
218#ifdef GDBSERVER
219 int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
220 (const unsigned char *) cmd, len);
221#else
fda0389f
PA
222 int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf,
223 (gdb_byte *) cmd, len);
2fa291ac
YQ
224#endif
225
226 if (ret != 0)
227 {
87399aa1 228 warning (_("unable to write"));
2fa291ac
YQ
229 return -1;
230 }
231
232 DEBUG_AGENT ("agent: resumed helper thread\n");
233
234 /* Resume helper thread. */
235#ifdef GDBSERVER
236{
237 struct thread_resume resume_info;
238
239 resume_info.thread = ptid;
240 resume_info.kind = resume_continue;
a493e3e2 241 resume_info.sig = GDB_SIGNAL_0;
2fa291ac
YQ
242 (*the_target->resume) (&resume_info, 1);
243}
244#else
a493e3e2 245 target_resume (ptid, 0, GDB_SIGNAL_0);
2fa291ac
YQ
246#endif
247
248 fd = gdb_connect_sync_socket (pid);
249 if (fd >= 0)
250 {
251 char buf[1] = "";
252 int ret;
253
254 DEBUG_AGENT ("agent: signalling helper thread\n");
255
256 do
257 {
258 ret = write (fd, buf, 1);
259 } while (ret == -1 && errno == EINTR);
260
261 DEBUG_AGENT ("agent: waiting for helper thread's response\n");
262
263 do
264 {
265 ret = read (fd, buf, 1);
266 } while (ret == -1 && errno == EINTR);
267
268 close (fd);
269
270 DEBUG_AGENT ("agent: helper thread's response received\n");
271 }
272 else
273 return -1;
274
275 /* Need to read response with the inferior stopped. */
276 if (!ptid_equal (ptid, null_ptid))
277 {
278 struct target_waitstatus status;
279 int was_non_stop = non_stop;
280 /* Stop thread PTID. */
281 DEBUG_AGENT ("agent: stop helper thread\n");
282#ifdef GDBSERVER
283 {
284 struct thread_resume resume_info;
285
286 resume_info.thread = ptid;
287 resume_info.kind = resume_stop;
a493e3e2 288 resume_info.sig = GDB_SIGNAL_0;
2fa291ac
YQ
289 (*the_target->resume) (&resume_info, 1);
290 }
291
292 non_stop = 1;
293 mywait (ptid, &status, 0, 0);
294#else
295 non_stop = 1;
296 target_stop (ptid);
297
298 memset (&status, 0, sizeof (status));
299 target_wait (ptid, &status, 0);
300#endif
301 non_stop = was_non_stop;
302 }
303
304 if (fd >= 0)
305 {
306#ifdef GDBSERVER
307 if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
308 (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
309#else
310 if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
311 IPA_CMD_BUF_SIZE))
312#endif
313 {
87399aa1 314 warning (_("Error reading command response"));
2fa291ac
YQ
315 return -1;
316 }
317 }
318
319 return 0;
320}
8ffcbaaf
YQ
321
322/* Each bit of it stands for a capability of agent. */
323static unsigned int agent_capability = 0;
324
325/* Return true if agent has capability AGENT_CAP, otherwise return false. */
326
327int
328agent_capability_check (enum agent_capa agent_capa)
329{
330 if (agent_capability == 0)
331 {
332#ifdef GDBSERVER
333 if (read_inferior_memory (ipa_sym_addrs.addr_capability,
334 (unsigned char *) &agent_capability,
335 sizeof agent_capability))
336#else
f5656ead 337 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
8ffcbaaf
YQ
338 gdb_byte buf[4];
339
340 if (target_read_memory (ipa_sym_addrs.addr_capability,
341 buf, sizeof buf) == 0)
342 agent_capability = extract_unsigned_integer (buf, sizeof buf,
343 byte_order);
344 else
345#endif
87399aa1 346 warning (_("Error reading capability of agent"));
8ffcbaaf
YQ
347 }
348 return agent_capability & agent_capa;
349}
350
351/* Invalidate the cache of agent capability, so we'll read it from inferior
352 again. Call it when launches a new program or reconnect to remote stub. */
353
354void
355agent_capability_invalidate (void)
356{
357 agent_capability = 0;
358}
This page took 0.123444 seconds and 4 git commands to generate.