1 /* Shared utility routines for GDB to interact with agent.
3 Copyright (C) 2009-2012 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
25 #include "inferior.h" /* for non_stop */
35 #define DEBUG_AGENT(fmt, args...) \
37 fprintf (stderr, fmt, ##args);
39 #define DEBUG_AGENT(fmt, args...) \
41 fprintf_unfiltered (gdb_stdlog, fmt, ##args);
44 /* Global flag to determine using agent or not. */
47 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
50 struct ipa_sym_addresses
52 CORE_ADDR addr_helper_thread_id
;
53 CORE_ADDR addr_cmd_buf
;
54 CORE_ADDR addr_capability
;
57 /* Cache of the helper thread id. FIXME: this global should be made
59 static unsigned int helper_thread_id
= 0;
67 IPA_SYM(helper_thread_id
),
72 static struct ipa_sym_addresses ipa_sym_addrs
;
74 /* Look up all symbols needed by agent. Return 0 if all the symbols are
75 found, return non-zero otherwise. */
78 agent_look_up_symbols (void)
82 for (i
= 0; i
< sizeof (symbol_list
) / sizeof (symbol_list
[0]); i
++)
85 (CORE_ADDR
*) ((char *) &ipa_sym_addrs
+ symbol_list
[i
].offset
);
88 if (look_up_one_symbol (symbol_list
[i
].name
, addrp
, 1) == 0)
90 struct minimal_symbol
*sym
= lookup_minimal_symbol (symbol_list
[i
].name
,
94 *addrp
= SYMBOL_VALUE_ADDRESS (sym
);
98 DEBUG_AGENT ("symbol `%s' not found\n", symbol_list
[i
].name
);
107 agent_get_helper_thread_id (void)
109 if (helper_thread_id
== 0)
112 if (read_inferior_memory (ipa_sym_addrs
.addr_helper_thread_id
,
113 (unsigned char *) &helper_thread_id
,
114 sizeof helper_thread_id
))
116 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch
);
119 if (target_read_memory (ipa_sym_addrs
.addr_helper_thread_id
,
120 buf
, sizeof buf
) == 0)
121 helper_thread_id
= extract_unsigned_integer (buf
, sizeof buf
,
126 warning ("Error reading helper thread's id in lib");
130 return helper_thread_id
;
134 #include <sys/socket.h>
136 #define SOCK_DIR P_tmpdir
138 #ifndef UNIX_PATH_MAX
139 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
144 /* Connects to synchronization socket. PID is the pid of inferior, which is
145 used to set up the connection socket. */
148 gdb_connect_sync_socket (int pid
)
151 struct sockaddr_un addr
;
153 char path
[UNIX_PATH_MAX
];
155 res
= xsnprintf (path
, UNIX_PATH_MAX
, "%s/gdb_ust%d", P_tmpdir
, pid
);
156 if (res
>= UNIX_PATH_MAX
)
159 res
= fd
= socket (PF_UNIX
, SOCK_STREAM
, 0);
162 warning ("error opening sync socket: %s\n", strerror (errno
));
166 addr
.sun_family
= AF_UNIX
;
168 res
= xsnprintf (addr
.sun_path
, UNIX_PATH_MAX
, "%s", path
);
169 if (res
>= UNIX_PATH_MAX
)
171 warning ("string overflow allocating socket name\n");
176 res
= connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
));
179 warning ("error connecting sync socket (%s): %s. "
180 "Make sure the directory exists and that it is writable.",
181 path
, strerror (errno
));
192 /* Execute an agent command in the inferior. PID is the value of pid of the
193 inferior. CMD is the buffer for command. GDB or GDBserver will store the
194 command into it and fetch the return result from CMD. The interaction
195 between GDB/GDBserver and the agent is synchronized by a synchronization
196 socket. Return zero if success, otherwise return non-zero. */
199 agent_run_command (int pid
, const char *cmd
)
202 int tid
= agent_get_helper_thread_id ();
203 ptid_t ptid
= ptid_build (pid
, tid
, 0);
204 int len
= strlen (cmd
) + 1;
207 int ret
= write_inferior_memory (ipa_sym_addrs
.addr_cmd_buf
,
208 (const unsigned char *) cmd
, len
);
210 int ret
= target_write_memory (ipa_sym_addrs
.addr_cmd_buf
, cmd
, len
);
215 warning ("unable to write");
219 DEBUG_AGENT ("agent: resumed helper thread\n");
221 /* Resume helper thread. */
224 struct thread_resume resume_info
;
226 resume_info
.thread
= ptid
;
227 resume_info
.kind
= resume_continue
;
228 resume_info
.sig
= TARGET_SIGNAL_0
;
229 (*the_target
->resume
) (&resume_info
, 1);
232 target_resume (ptid
, 0, TARGET_SIGNAL_0
);
235 fd
= gdb_connect_sync_socket (pid
);
241 DEBUG_AGENT ("agent: signalling helper thread\n");
245 ret
= write (fd
, buf
, 1);
246 } while (ret
== -1 && errno
== EINTR
);
248 DEBUG_AGENT ("agent: waiting for helper thread's response\n");
252 ret
= read (fd
, buf
, 1);
253 } while (ret
== -1 && errno
== EINTR
);
257 DEBUG_AGENT ("agent: helper thread's response received\n");
262 /* Need to read response with the inferior stopped. */
263 if (!ptid_equal (ptid
, null_ptid
))
265 struct target_waitstatus status
;
266 int was_non_stop
= non_stop
;
267 /* Stop thread PTID. */
268 DEBUG_AGENT ("agent: stop helper thread\n");
271 struct thread_resume resume_info
;
273 resume_info
.thread
= ptid
;
274 resume_info
.kind
= resume_stop
;
275 resume_info
.sig
= TARGET_SIGNAL_0
;
276 (*the_target
->resume
) (&resume_info
, 1);
280 mywait (ptid
, &status
, 0, 0);
285 memset (&status
, 0, sizeof (status
));
286 target_wait (ptid
, &status
, 0);
288 non_stop
= was_non_stop
;
294 if (read_inferior_memory (ipa_sym_addrs
.addr_cmd_buf
,
295 (unsigned char *) cmd
, IPA_CMD_BUF_SIZE
))
297 if (target_read_memory (ipa_sym_addrs
.addr_cmd_buf
, (gdb_byte
*) cmd
,
301 warning ("Error reading command response");
309 /* Each bit of it stands for a capability of agent. */
310 static unsigned int agent_capability
= 0;
312 /* Return true if agent has capability AGENT_CAP, otherwise return false. */
315 agent_capability_check (enum agent_capa agent_capa
)
317 if (agent_capability
== 0)
320 if (read_inferior_memory (ipa_sym_addrs
.addr_capability
,
321 (unsigned char *) &agent_capability
,
322 sizeof agent_capability
))
324 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch
);
327 if (target_read_memory (ipa_sym_addrs
.addr_capability
,
328 buf
, sizeof buf
) == 0)
329 agent_capability
= extract_unsigned_integer (buf
, sizeof buf
,
333 warning ("Error reading capability of agent");
335 return agent_capability
& agent_capa
;
338 /* Invalidate the cache of agent capability, so we'll read it from inferior
339 again. Call it when launches a new program or reconnect to remote stub. */
342 agent_capability_invalidate (void)
344 agent_capability
= 0;