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