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 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
47 struct ipa_sym_addresses
49 CORE_ADDR addr_helper_thread_id
;
50 CORE_ADDR addr_cmd_buf
;
53 /* Cache of the helper thread id. FIXME: this global should be made
55 static unsigned int helper_thread_id
= 0;
63 IPA_SYM(helper_thread_id
),
67 static struct ipa_sym_addresses ipa_sym_addrs
;
69 /* Look up all symbols needed by agent. Return 0 if all the symbols are
70 found, return non-zero otherwise. */
73 agent_look_up_symbols (void)
77 for (i
= 0; i
< sizeof (symbol_list
) / sizeof (symbol_list
[0]); i
++)
80 (CORE_ADDR
*) ((char *) &ipa_sym_addrs
+ symbol_list
[i
].offset
);
83 if (look_up_one_symbol (symbol_list
[i
].name
, addrp
, 1) == 0)
85 struct minimal_symbol
*sym
= lookup_minimal_symbol (symbol_list
[i
].name
,
89 *addrp
= SYMBOL_VALUE_ADDRESS (sym
);
93 DEBUG_AGENT ("symbol `%s' not found\n", symbol_list
[i
].name
);
102 agent_get_helper_thread_id (void)
104 if (helper_thread_id
== 0)
107 if (read_inferior_memory (ipa_sym_addrs
.addr_helper_thread_id
,
108 (unsigned char *) &helper_thread_id
,
109 sizeof helper_thread_id
))
111 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch
);
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
,
121 warning ("Error reading helper thread's id in lib");
125 return helper_thread_id
;
129 #include <sys/socket.h>
131 #define SOCK_DIR P_tmpdir
133 #ifndef UNIX_PATH_MAX
134 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
139 /* Connects to synchronization socket. PID is the pid of inferior, which is
140 used to set up the connection socket. */
143 gdb_connect_sync_socket (int pid
)
146 struct sockaddr_un addr
;
148 char path
[UNIX_PATH_MAX
];
150 res
= xsnprintf (path
, UNIX_PATH_MAX
, "%s/gdb_ust%d", P_tmpdir
, pid
);
151 if (res
>= UNIX_PATH_MAX
)
154 res
= fd
= socket (PF_UNIX
, SOCK_STREAM
, 0);
157 warning ("error opening sync socket: %s\n", strerror (errno
));
161 addr
.sun_family
= AF_UNIX
;
163 res
= xsnprintf (addr
.sun_path
, UNIX_PATH_MAX
, "%s", path
);
164 if (res
>= UNIX_PATH_MAX
)
166 warning ("string overflow allocating socket name\n");
171 res
= connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
));
174 warning ("error connecting sync socket (%s): %s. "
175 "Make sure the directory exists and that it is writable.",
176 path
, strerror (errno
));
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. */
194 agent_run_command (int pid
, const char *cmd
)
197 int tid
= agent_get_helper_thread_id ();
198 ptid_t ptid
= ptid_build (pid
, tid
, 0);
199 int len
= strlen (cmd
) + 1;
202 int ret
= write_inferior_memory (ipa_sym_addrs
.addr_cmd_buf
,
203 (const unsigned char *) cmd
, len
);
205 int ret
= target_write_memory (ipa_sym_addrs
.addr_cmd_buf
, cmd
, len
);
210 warning ("unable to write");
214 DEBUG_AGENT ("agent: resumed helper thread\n");
216 /* Resume helper thread. */
219 struct thread_resume resume_info
;
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);
227 target_resume (ptid
, 0, TARGET_SIGNAL_0
);
230 fd
= gdb_connect_sync_socket (pid
);
236 DEBUG_AGENT ("agent: signalling helper thread\n");
240 ret
= write (fd
, buf
, 1);
241 } while (ret
== -1 && errno
== EINTR
);
243 DEBUG_AGENT ("agent: waiting for helper thread's response\n");
247 ret
= read (fd
, buf
, 1);
248 } while (ret
== -1 && errno
== EINTR
);
252 DEBUG_AGENT ("agent: helper thread's response received\n");
257 /* Need to read response with the inferior stopped. */
258 if (!ptid_equal (ptid
, null_ptid
))
260 struct target_waitstatus status
;
261 int was_non_stop
= non_stop
;
262 /* Stop thread PTID. */
263 DEBUG_AGENT ("agent: stop helper thread\n");
266 struct thread_resume resume_info
;
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);
275 mywait (ptid
, &status
, 0, 0);
280 memset (&status
, 0, sizeof (status
));
281 target_wait (ptid
, &status
, 0);
283 non_stop
= was_non_stop
;
289 if (read_inferior_memory (ipa_sym_addrs
.addr_cmd_buf
,
290 (unsigned char *) cmd
, IPA_CMD_BUF_SIZE
))
292 if (target_read_memory (ipa_sym_addrs
.addr_cmd_buf
, (gdb_byte
*) cmd
,
296 warning ("Error reading command response");