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