xref: /dragonfly/contrib/gdb-7/gdb/probe.c (revision ef5ccd6c)
1*ef5ccd6cSJohn Marino /* Generic static probe support for GDB.
2*ef5ccd6cSJohn Marino 
3*ef5ccd6cSJohn Marino    Copyright (C) 2012-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 #include "defs.h"
21*ef5ccd6cSJohn Marino #include "probe.h"
22*ef5ccd6cSJohn Marino #include "command.h"
23*ef5ccd6cSJohn Marino #include "cli/cli-cmds.h"
24*ef5ccd6cSJohn Marino #include "cli/cli-utils.h"
25*ef5ccd6cSJohn Marino #include "objfiles.h"
26*ef5ccd6cSJohn Marino #include "symtab.h"
27*ef5ccd6cSJohn Marino #include "progspace.h"
28*ef5ccd6cSJohn Marino #include "filenames.h"
29*ef5ccd6cSJohn Marino #include "exceptions.h"
30*ef5ccd6cSJohn Marino #include "linespec.h"
31*ef5ccd6cSJohn Marino #include "gdb_regex.h"
32*ef5ccd6cSJohn Marino #include "frame.h"
33*ef5ccd6cSJohn Marino #include "arch-utils.h"
34*ef5ccd6cSJohn Marino #include <ctype.h>
35*ef5ccd6cSJohn Marino 
36*ef5ccd6cSJohn Marino 
37*ef5ccd6cSJohn Marino 
38*ef5ccd6cSJohn Marino /* See definition in probe.h.  */
39*ef5ccd6cSJohn Marino 
40*ef5ccd6cSJohn Marino struct symtabs_and_lines
parse_probes(char ** argptr,struct linespec_result * canonical)41*ef5ccd6cSJohn Marino parse_probes (char **argptr, struct linespec_result *canonical)
42*ef5ccd6cSJohn Marino {
43*ef5ccd6cSJohn Marino   char *arg_start, *arg_end, *arg;
44*ef5ccd6cSJohn Marino   char *objfile_name = NULL, *provider = NULL, *name, *p;
45*ef5ccd6cSJohn Marino   struct cleanup *cleanup;
46*ef5ccd6cSJohn Marino   struct symtabs_and_lines result;
47*ef5ccd6cSJohn Marino   struct objfile *objfile;
48*ef5ccd6cSJohn Marino   struct program_space *pspace;
49*ef5ccd6cSJohn Marino   const struct probe_ops *probe_ops;
50*ef5ccd6cSJohn Marino   const char *cs;
51*ef5ccd6cSJohn Marino 
52*ef5ccd6cSJohn Marino   result.sals = NULL;
53*ef5ccd6cSJohn Marino   result.nelts = 0;
54*ef5ccd6cSJohn Marino 
55*ef5ccd6cSJohn Marino   arg_start = *argptr;
56*ef5ccd6cSJohn Marino 
57*ef5ccd6cSJohn Marino   cs = *argptr;
58*ef5ccd6cSJohn Marino   probe_ops = probe_linespec_to_ops (&cs);
59*ef5ccd6cSJohn Marino   gdb_assert (probe_ops != NULL);
60*ef5ccd6cSJohn Marino 
61*ef5ccd6cSJohn Marino   arg = (char *) cs;
62*ef5ccd6cSJohn Marino   arg = skip_spaces (arg);
63*ef5ccd6cSJohn Marino   if (!*arg)
64*ef5ccd6cSJohn Marino     error (_("argument to `%s' missing"), arg_start);
65*ef5ccd6cSJohn Marino 
66*ef5ccd6cSJohn Marino   arg_end = skip_to_space (arg);
67*ef5ccd6cSJohn Marino 
68*ef5ccd6cSJohn Marino   /* We make a copy here so we can write over parts with impunity.  */
69*ef5ccd6cSJohn Marino   arg = savestring (arg, arg_end - arg);
70*ef5ccd6cSJohn Marino   cleanup = make_cleanup (xfree, arg);
71*ef5ccd6cSJohn Marino 
72*ef5ccd6cSJohn Marino   /* Extract each word from the argument, separated by ":"s.  */
73*ef5ccd6cSJohn Marino   p = strchr (arg, ':');
74*ef5ccd6cSJohn Marino   if (p == NULL)
75*ef5ccd6cSJohn Marino     {
76*ef5ccd6cSJohn Marino       /* This is `-p name'.  */
77*ef5ccd6cSJohn Marino       name = arg;
78*ef5ccd6cSJohn Marino     }
79*ef5ccd6cSJohn Marino   else
80*ef5ccd6cSJohn Marino     {
81*ef5ccd6cSJohn Marino       char *hold = p + 1;
82*ef5ccd6cSJohn Marino 
83*ef5ccd6cSJohn Marino       *p = '\0';
84*ef5ccd6cSJohn Marino       p = strchr (hold, ':');
85*ef5ccd6cSJohn Marino       if (p == NULL)
86*ef5ccd6cSJohn Marino 	{
87*ef5ccd6cSJohn Marino 	  /* This is `-p provider:name'.  */
88*ef5ccd6cSJohn Marino 	  provider = arg;
89*ef5ccd6cSJohn Marino 	  name = hold;
90*ef5ccd6cSJohn Marino 	}
91*ef5ccd6cSJohn Marino       else
92*ef5ccd6cSJohn Marino 	{
93*ef5ccd6cSJohn Marino 	  /* This is `-p objfile:provider:name'.  */
94*ef5ccd6cSJohn Marino 	  *p = '\0';
95*ef5ccd6cSJohn Marino 	  objfile_name = arg;
96*ef5ccd6cSJohn Marino 	  provider = hold;
97*ef5ccd6cSJohn Marino 	  name = p + 1;
98*ef5ccd6cSJohn Marino 	}
99*ef5ccd6cSJohn Marino     }
100*ef5ccd6cSJohn Marino 
101*ef5ccd6cSJohn Marino   if (*name == '\0')
102*ef5ccd6cSJohn Marino     error (_("no probe name specified"));
103*ef5ccd6cSJohn Marino   if (provider && *provider == '\0')
104*ef5ccd6cSJohn Marino     error (_("invalid provider name"));
105*ef5ccd6cSJohn Marino   if (objfile_name && *objfile_name == '\0')
106*ef5ccd6cSJohn Marino     error (_("invalid objfile name"));
107*ef5ccd6cSJohn Marino 
108*ef5ccd6cSJohn Marino   ALL_PSPACES (pspace)
109*ef5ccd6cSJohn Marino     ALL_PSPACE_OBJFILES (pspace, objfile)
110*ef5ccd6cSJohn Marino       {
111*ef5ccd6cSJohn Marino 	VEC (probe_p) *probes;
112*ef5ccd6cSJohn Marino 	struct probe *probe;
113*ef5ccd6cSJohn Marino 	int ix;
114*ef5ccd6cSJohn Marino 
115*ef5ccd6cSJohn Marino 	if (!objfile->sf || !objfile->sf->sym_probe_fns)
116*ef5ccd6cSJohn Marino 	  continue;
117*ef5ccd6cSJohn Marino 
118*ef5ccd6cSJohn Marino 	if (objfile_name
119*ef5ccd6cSJohn Marino 	    && FILENAME_CMP (objfile->name, objfile_name) != 0
120*ef5ccd6cSJohn Marino 	    && FILENAME_CMP (lbasename (objfile->name), objfile_name) != 0)
121*ef5ccd6cSJohn Marino 	  continue;
122*ef5ccd6cSJohn Marino 
123*ef5ccd6cSJohn Marino 	probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
124*ef5ccd6cSJohn Marino 
125*ef5ccd6cSJohn Marino 	for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
126*ef5ccd6cSJohn Marino 	  {
127*ef5ccd6cSJohn Marino 	    struct symtab_and_line *sal;
128*ef5ccd6cSJohn Marino 
129*ef5ccd6cSJohn Marino 	    if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
130*ef5ccd6cSJohn Marino 	      continue;
131*ef5ccd6cSJohn Marino 
132*ef5ccd6cSJohn Marino 	    if (provider && strcmp (probe->provider, provider) != 0)
133*ef5ccd6cSJohn Marino 	      continue;
134*ef5ccd6cSJohn Marino 
135*ef5ccd6cSJohn Marino 	    if (strcmp (probe->name, name) != 0)
136*ef5ccd6cSJohn Marino 	      continue;
137*ef5ccd6cSJohn Marino 
138*ef5ccd6cSJohn Marino 	    ++result.nelts;
139*ef5ccd6cSJohn Marino 	    result.sals = xrealloc (result.sals,
140*ef5ccd6cSJohn Marino 				    result.nelts
141*ef5ccd6cSJohn Marino 				    * sizeof (struct symtab_and_line));
142*ef5ccd6cSJohn Marino 	    sal = &result.sals[result.nelts - 1];
143*ef5ccd6cSJohn Marino 
144*ef5ccd6cSJohn Marino 	    init_sal (sal);
145*ef5ccd6cSJohn Marino 
146*ef5ccd6cSJohn Marino 	    sal->pc = probe->address;
147*ef5ccd6cSJohn Marino 	    sal->explicit_pc = 1;
148*ef5ccd6cSJohn Marino 	    sal->section = find_pc_overlay (sal->pc);
149*ef5ccd6cSJohn Marino 	    sal->pspace = pspace;
150*ef5ccd6cSJohn Marino 	    sal->probe = probe;
151*ef5ccd6cSJohn Marino 	  }
152*ef5ccd6cSJohn Marino       }
153*ef5ccd6cSJohn Marino 
154*ef5ccd6cSJohn Marino   if (result.nelts == 0)
155*ef5ccd6cSJohn Marino     {
156*ef5ccd6cSJohn Marino       throw_error (NOT_FOUND_ERROR,
157*ef5ccd6cSJohn Marino 		   _("No probe matching objfile=`%s', provider=`%s', name=`%s'"),
158*ef5ccd6cSJohn Marino 		   objfile_name ? objfile_name : _("<any>"),
159*ef5ccd6cSJohn Marino 		   provider ? provider : _("<any>"),
160*ef5ccd6cSJohn Marino 		   name);
161*ef5ccd6cSJohn Marino     }
162*ef5ccd6cSJohn Marino 
163*ef5ccd6cSJohn Marino   if (canonical)
164*ef5ccd6cSJohn Marino     {
165*ef5ccd6cSJohn Marino       canonical->special_display = 1;
166*ef5ccd6cSJohn Marino       canonical->pre_expanded = 1;
167*ef5ccd6cSJohn Marino       canonical->addr_string = savestring (*argptr, arg_end - *argptr);
168*ef5ccd6cSJohn Marino     }
169*ef5ccd6cSJohn Marino 
170*ef5ccd6cSJohn Marino   *argptr = arg_end;
171*ef5ccd6cSJohn Marino   do_cleanups (cleanup);
172*ef5ccd6cSJohn Marino 
173*ef5ccd6cSJohn Marino   return result;
174*ef5ccd6cSJohn Marino }
175*ef5ccd6cSJohn Marino 
176*ef5ccd6cSJohn Marino /* See definition in probe.h.  */
177*ef5ccd6cSJohn Marino 
VEC(probe_p)178*ef5ccd6cSJohn Marino VEC (probe_p) *
179*ef5ccd6cSJohn Marino find_probes_in_objfile (struct objfile *objfile, const char *provider,
180*ef5ccd6cSJohn Marino 			const char *name)
181*ef5ccd6cSJohn Marino {
182*ef5ccd6cSJohn Marino   VEC (probe_p) *probes, *result = NULL;
183*ef5ccd6cSJohn Marino   int ix;
184*ef5ccd6cSJohn Marino   struct probe *probe;
185*ef5ccd6cSJohn Marino 
186*ef5ccd6cSJohn Marino   if (!objfile->sf || !objfile->sf->sym_probe_fns)
187*ef5ccd6cSJohn Marino     return NULL;
188*ef5ccd6cSJohn Marino 
189*ef5ccd6cSJohn Marino   probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
190*ef5ccd6cSJohn Marino   for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
191*ef5ccd6cSJohn Marino     {
192*ef5ccd6cSJohn Marino       if (strcmp (probe->provider, provider) != 0)
193*ef5ccd6cSJohn Marino 	continue;
194*ef5ccd6cSJohn Marino 
195*ef5ccd6cSJohn Marino       if (strcmp (probe->name, name) != 0)
196*ef5ccd6cSJohn Marino 	continue;
197*ef5ccd6cSJohn Marino 
198*ef5ccd6cSJohn Marino       VEC_safe_push (probe_p, result, probe);
199*ef5ccd6cSJohn Marino     }
200*ef5ccd6cSJohn Marino 
201*ef5ccd6cSJohn Marino   return result;
202*ef5ccd6cSJohn Marino }
203*ef5ccd6cSJohn Marino 
204*ef5ccd6cSJohn Marino /* See definition in probe.h.  */
205*ef5ccd6cSJohn Marino 
206*ef5ccd6cSJohn Marino struct probe *
find_probe_by_pc(CORE_ADDR pc)207*ef5ccd6cSJohn Marino find_probe_by_pc (CORE_ADDR pc)
208*ef5ccd6cSJohn Marino {
209*ef5ccd6cSJohn Marino   struct objfile *objfile;
210*ef5ccd6cSJohn Marino 
211*ef5ccd6cSJohn Marino   ALL_OBJFILES (objfile)
212*ef5ccd6cSJohn Marino   {
213*ef5ccd6cSJohn Marino     VEC (probe_p) *probes;
214*ef5ccd6cSJohn Marino     int ix;
215*ef5ccd6cSJohn Marino     struct probe *probe;
216*ef5ccd6cSJohn Marino 
217*ef5ccd6cSJohn Marino     if (!objfile->sf || !objfile->sf->sym_probe_fns)
218*ef5ccd6cSJohn Marino       continue;
219*ef5ccd6cSJohn Marino 
220*ef5ccd6cSJohn Marino     /* If this proves too inefficient, we can replace with a hash.  */
221*ef5ccd6cSJohn Marino     probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
222*ef5ccd6cSJohn Marino     for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
223*ef5ccd6cSJohn Marino       if (probe->address == pc)
224*ef5ccd6cSJohn Marino 	return probe;
225*ef5ccd6cSJohn Marino   }
226*ef5ccd6cSJohn Marino 
227*ef5ccd6cSJohn Marino   return NULL;
228*ef5ccd6cSJohn Marino }
229*ef5ccd6cSJohn Marino 
230*ef5ccd6cSJohn Marino 
231*ef5ccd6cSJohn Marino 
232*ef5ccd6cSJohn Marino /* A helper function for collect_probes that compiles a regexp and
233*ef5ccd6cSJohn Marino    throws an exception on error.  This installs a cleanup to free the
234*ef5ccd6cSJohn Marino    resulting pattern on success.  If RX is NULL, this does nothing.  */
235*ef5ccd6cSJohn Marino 
236*ef5ccd6cSJohn Marino static void
compile_rx_or_error(regex_t * pattern,const char * rx,const char * message)237*ef5ccd6cSJohn Marino compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
238*ef5ccd6cSJohn Marino {
239*ef5ccd6cSJohn Marino   int code;
240*ef5ccd6cSJohn Marino 
241*ef5ccd6cSJohn Marino   if (!rx)
242*ef5ccd6cSJohn Marino     return;
243*ef5ccd6cSJohn Marino 
244*ef5ccd6cSJohn Marino   code = regcomp (pattern, rx, REG_NOSUB);
245*ef5ccd6cSJohn Marino   if (code == 0)
246*ef5ccd6cSJohn Marino     make_regfree_cleanup (pattern);
247*ef5ccd6cSJohn Marino   else
248*ef5ccd6cSJohn Marino     {
249*ef5ccd6cSJohn Marino       char *err = get_regcomp_error (code, pattern);
250*ef5ccd6cSJohn Marino 
251*ef5ccd6cSJohn Marino       make_cleanup (xfree, err);
252*ef5ccd6cSJohn Marino       error (("%s: %s"), message, err);
253*ef5ccd6cSJohn Marino     }
254*ef5ccd6cSJohn Marino }
255*ef5ccd6cSJohn Marino 
256*ef5ccd6cSJohn Marino /* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE_NAME.
257*ef5ccd6cSJohn Marino    If POPS is not NULL, only probes of this certain probe_ops will match.
258*ef5ccd6cSJohn Marino    Each argument is a regexp, or NULL, which matches anything.  */
259*ef5ccd6cSJohn Marino 
VEC(probe_p)260*ef5ccd6cSJohn Marino static VEC (probe_p) *
261*ef5ccd6cSJohn Marino collect_probes (char *objname, char *provider, char *probe_name,
262*ef5ccd6cSJohn Marino 		const struct probe_ops *pops)
263*ef5ccd6cSJohn Marino {
264*ef5ccd6cSJohn Marino   struct objfile *objfile;
265*ef5ccd6cSJohn Marino   VEC (probe_p) *result = NULL;
266*ef5ccd6cSJohn Marino   struct cleanup *cleanup, *cleanup_temps;
267*ef5ccd6cSJohn Marino   regex_t obj_pat, prov_pat, probe_pat;
268*ef5ccd6cSJohn Marino 
269*ef5ccd6cSJohn Marino   cleanup = make_cleanup (VEC_cleanup (probe_p), &result);
270*ef5ccd6cSJohn Marino 
271*ef5ccd6cSJohn Marino   cleanup_temps = make_cleanup (null_cleanup, NULL);
272*ef5ccd6cSJohn Marino   compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp"));
273*ef5ccd6cSJohn Marino   compile_rx_or_error (&probe_pat, probe_name, _("Invalid probe regexp"));
274*ef5ccd6cSJohn Marino   compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp"));
275*ef5ccd6cSJohn Marino 
276*ef5ccd6cSJohn Marino   ALL_OBJFILES (objfile)
277*ef5ccd6cSJohn Marino     {
278*ef5ccd6cSJohn Marino       VEC (probe_p) *probes;
279*ef5ccd6cSJohn Marino       struct probe *probe;
280*ef5ccd6cSJohn Marino       int ix;
281*ef5ccd6cSJohn Marino 
282*ef5ccd6cSJohn Marino       if (! objfile->sf || ! objfile->sf->sym_probe_fns)
283*ef5ccd6cSJohn Marino 	continue;
284*ef5ccd6cSJohn Marino 
285*ef5ccd6cSJohn Marino       if (objname)
286*ef5ccd6cSJohn Marino 	{
287*ef5ccd6cSJohn Marino 	  if (regexec (&obj_pat, objfile->name, 0, NULL, 0) != 0)
288*ef5ccd6cSJohn Marino 	    continue;
289*ef5ccd6cSJohn Marino 	}
290*ef5ccd6cSJohn Marino 
291*ef5ccd6cSJohn Marino       probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
292*ef5ccd6cSJohn Marino 
293*ef5ccd6cSJohn Marino       for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
294*ef5ccd6cSJohn Marino 	{
295*ef5ccd6cSJohn Marino 	  if (pops != NULL && probe->pops != pops)
296*ef5ccd6cSJohn Marino 	    continue;
297*ef5ccd6cSJohn Marino 
298*ef5ccd6cSJohn Marino 	  if (provider
299*ef5ccd6cSJohn Marino 	      && regexec (&prov_pat, probe->provider, 0, NULL, 0) != 0)
300*ef5ccd6cSJohn Marino 	    continue;
301*ef5ccd6cSJohn Marino 
302*ef5ccd6cSJohn Marino 	  if (probe_name
303*ef5ccd6cSJohn Marino 	      && regexec (&probe_pat, probe->name, 0, NULL, 0) != 0)
304*ef5ccd6cSJohn Marino 	    continue;
305*ef5ccd6cSJohn Marino 
306*ef5ccd6cSJohn Marino 	  VEC_safe_push (probe_p, result, probe);
307*ef5ccd6cSJohn Marino 	}
308*ef5ccd6cSJohn Marino     }
309*ef5ccd6cSJohn Marino 
310*ef5ccd6cSJohn Marino   do_cleanups (cleanup_temps);
311*ef5ccd6cSJohn Marino   discard_cleanups (cleanup);
312*ef5ccd6cSJohn Marino   return result;
313*ef5ccd6cSJohn Marino }
314*ef5ccd6cSJohn Marino 
315*ef5ccd6cSJohn Marino /* A qsort comparison function for probe_p objects.  */
316*ef5ccd6cSJohn Marino 
317*ef5ccd6cSJohn Marino static int
compare_probes(const void * a,const void * b)318*ef5ccd6cSJohn Marino compare_probes (const void *a, const void *b)
319*ef5ccd6cSJohn Marino {
320*ef5ccd6cSJohn Marino   const struct probe *pa = *((const struct probe **) a);
321*ef5ccd6cSJohn Marino   const struct probe *pb = *((const struct probe **) b);
322*ef5ccd6cSJohn Marino   int v;
323*ef5ccd6cSJohn Marino 
324*ef5ccd6cSJohn Marino   v = strcmp (pa->provider, pb->provider);
325*ef5ccd6cSJohn Marino   if (v)
326*ef5ccd6cSJohn Marino     return v;
327*ef5ccd6cSJohn Marino 
328*ef5ccd6cSJohn Marino   v = strcmp (pa->name, pb->name);
329*ef5ccd6cSJohn Marino   if (v)
330*ef5ccd6cSJohn Marino     return v;
331*ef5ccd6cSJohn Marino 
332*ef5ccd6cSJohn Marino   if (pa->address < pb->address)
333*ef5ccd6cSJohn Marino     return -1;
334*ef5ccd6cSJohn Marino   if (pa->address > pb->address)
335*ef5ccd6cSJohn Marino     return 1;
336*ef5ccd6cSJohn Marino 
337*ef5ccd6cSJohn Marino   return strcmp (pa->objfile->name, pb->objfile->name);
338*ef5ccd6cSJohn Marino }
339*ef5ccd6cSJohn Marino 
340*ef5ccd6cSJohn Marino /* Helper function that generate entries in the ui_out table being
341*ef5ccd6cSJohn Marino    crafted by `info_probes_for_ops'.  */
342*ef5ccd6cSJohn Marino 
343*ef5ccd6cSJohn Marino static void
gen_ui_out_table_header_info(VEC (probe_p)* probes,const struct probe_ops * p)344*ef5ccd6cSJohn Marino gen_ui_out_table_header_info (VEC (probe_p) *probes,
345*ef5ccd6cSJohn Marino 			      const struct probe_ops *p)
346*ef5ccd6cSJohn Marino {
347*ef5ccd6cSJohn Marino   /* `headings' refers to the names of the columns when printing `info
348*ef5ccd6cSJohn Marino      probes'.  */
349*ef5ccd6cSJohn Marino   VEC (info_probe_column_s) *headings = NULL;
350*ef5ccd6cSJohn Marino   struct cleanup *c;
351*ef5ccd6cSJohn Marino   info_probe_column_s *column;
352*ef5ccd6cSJohn Marino   size_t headings_size;
353*ef5ccd6cSJohn Marino   int ix;
354*ef5ccd6cSJohn Marino 
355*ef5ccd6cSJohn Marino   gdb_assert (p != NULL);
356*ef5ccd6cSJohn Marino 
357*ef5ccd6cSJohn Marino   if (p->gen_info_probes_table_header == NULL
358*ef5ccd6cSJohn Marino       && p->gen_info_probes_table_values == NULL)
359*ef5ccd6cSJohn Marino     return;
360*ef5ccd6cSJohn Marino 
361*ef5ccd6cSJohn Marino   gdb_assert (p->gen_info_probes_table_header != NULL
362*ef5ccd6cSJohn Marino 	      && p->gen_info_probes_table_values != NULL);
363*ef5ccd6cSJohn Marino 
364*ef5ccd6cSJohn Marino   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
365*ef5ccd6cSJohn Marino   p->gen_info_probes_table_header (&headings);
366*ef5ccd6cSJohn Marino 
367*ef5ccd6cSJohn Marino   headings_size = VEC_length (info_probe_column_s, headings);
368*ef5ccd6cSJohn Marino 
369*ef5ccd6cSJohn Marino   for (ix = 0;
370*ef5ccd6cSJohn Marino        VEC_iterate (info_probe_column_s, headings, ix, column);
371*ef5ccd6cSJohn Marino        ++ix)
372*ef5ccd6cSJohn Marino     {
373*ef5ccd6cSJohn Marino       struct probe *probe;
374*ef5ccd6cSJohn Marino       int jx;
375*ef5ccd6cSJohn Marino       size_t size_max = strlen (column->print_name);
376*ef5ccd6cSJohn Marino 
377*ef5ccd6cSJohn Marino       for (jx = 0; VEC_iterate (probe_p, probes, jx, probe); ++jx)
378*ef5ccd6cSJohn Marino 	{
379*ef5ccd6cSJohn Marino 	  /* `probe_fields' refers to the values of each new field that this
380*ef5ccd6cSJohn Marino 	     probe will display.  */
381*ef5ccd6cSJohn Marino 	  VEC (const_char_ptr) *probe_fields = NULL;
382*ef5ccd6cSJohn Marino 	  struct cleanup *c2;
383*ef5ccd6cSJohn Marino 	  const char *val;
384*ef5ccd6cSJohn Marino 	  int kx;
385*ef5ccd6cSJohn Marino 
386*ef5ccd6cSJohn Marino 	  if (probe->pops != p)
387*ef5ccd6cSJohn Marino 	    continue;
388*ef5ccd6cSJohn Marino 
389*ef5ccd6cSJohn Marino 	  c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields);
390*ef5ccd6cSJohn Marino 	  p->gen_info_probes_table_values (probe, &probe_fields);
391*ef5ccd6cSJohn Marino 
392*ef5ccd6cSJohn Marino 	  gdb_assert (VEC_length (const_char_ptr, probe_fields)
393*ef5ccd6cSJohn Marino 		      == headings_size);
394*ef5ccd6cSJohn Marino 
395*ef5ccd6cSJohn Marino 	  for (kx = 0; VEC_iterate (const_char_ptr, probe_fields, kx, val);
396*ef5ccd6cSJohn Marino 	       ++kx)
397*ef5ccd6cSJohn Marino 	    {
398*ef5ccd6cSJohn Marino 	      /* It is valid to have a NULL value here, which means that the
399*ef5ccd6cSJohn Marino 		 backend does not have something to write and this particular
400*ef5ccd6cSJohn Marino 		 field should be skipped.  */
401*ef5ccd6cSJohn Marino 	      if (val == NULL)
402*ef5ccd6cSJohn Marino 		continue;
403*ef5ccd6cSJohn Marino 
404*ef5ccd6cSJohn Marino 	      size_max = max (strlen (val), size_max);
405*ef5ccd6cSJohn Marino 	    }
406*ef5ccd6cSJohn Marino 	  do_cleanups (c2);
407*ef5ccd6cSJohn Marino 	}
408*ef5ccd6cSJohn Marino 
409*ef5ccd6cSJohn Marino       ui_out_table_header (current_uiout, size_max, ui_left,
410*ef5ccd6cSJohn Marino 			   column->field_name, column->print_name);
411*ef5ccd6cSJohn Marino     }
412*ef5ccd6cSJohn Marino 
413*ef5ccd6cSJohn Marino   do_cleanups (c);
414*ef5ccd6cSJohn Marino }
415*ef5ccd6cSJohn Marino 
416*ef5ccd6cSJohn Marino /* Helper function to print extra information about a probe and an objfile
417*ef5ccd6cSJohn Marino    represented by PROBE.  */
418*ef5ccd6cSJohn Marino 
419*ef5ccd6cSJohn Marino static void
print_ui_out_info(struct probe * probe)420*ef5ccd6cSJohn Marino print_ui_out_info (struct probe *probe)
421*ef5ccd6cSJohn Marino {
422*ef5ccd6cSJohn Marino   int ix;
423*ef5ccd6cSJohn Marino   int j = 0;
424*ef5ccd6cSJohn Marino   /* `values' refers to the actual values of each new field in the output
425*ef5ccd6cSJohn Marino      of `info probe'.  `headings' refers to the names of each new field.  */
426*ef5ccd6cSJohn Marino   VEC (const_char_ptr) *values = NULL;
427*ef5ccd6cSJohn Marino   VEC (info_probe_column_s) *headings = NULL;
428*ef5ccd6cSJohn Marino   info_probe_column_s *column;
429*ef5ccd6cSJohn Marino   struct cleanup *c;
430*ef5ccd6cSJohn Marino 
431*ef5ccd6cSJohn Marino   gdb_assert (probe != NULL);
432*ef5ccd6cSJohn Marino   gdb_assert (probe->pops != NULL);
433*ef5ccd6cSJohn Marino 
434*ef5ccd6cSJohn Marino   if (probe->pops->gen_info_probes_table_header == NULL
435*ef5ccd6cSJohn Marino       && probe->pops->gen_info_probes_table_values == NULL)
436*ef5ccd6cSJohn Marino     return;
437*ef5ccd6cSJohn Marino 
438*ef5ccd6cSJohn Marino   gdb_assert (probe->pops->gen_info_probes_table_header != NULL
439*ef5ccd6cSJohn Marino 	      && probe->pops->gen_info_probes_table_values != NULL);
440*ef5ccd6cSJohn Marino 
441*ef5ccd6cSJohn Marino   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
442*ef5ccd6cSJohn Marino   make_cleanup (VEC_cleanup (const_char_ptr), &values);
443*ef5ccd6cSJohn Marino 
444*ef5ccd6cSJohn Marino   probe->pops->gen_info_probes_table_header (&headings);
445*ef5ccd6cSJohn Marino   probe->pops->gen_info_probes_table_values (probe, &values);
446*ef5ccd6cSJohn Marino 
447*ef5ccd6cSJohn Marino   gdb_assert (VEC_length (info_probe_column_s, headings)
448*ef5ccd6cSJohn Marino 	      == VEC_length (const_char_ptr, values));
449*ef5ccd6cSJohn Marino 
450*ef5ccd6cSJohn Marino   for (ix = 0;
451*ef5ccd6cSJohn Marino        VEC_iterate (info_probe_column_s, headings, ix, column);
452*ef5ccd6cSJohn Marino        ++ix)
453*ef5ccd6cSJohn Marino     {
454*ef5ccd6cSJohn Marino       const char *val = VEC_index (const_char_ptr, values, j++);
455*ef5ccd6cSJohn Marino 
456*ef5ccd6cSJohn Marino       if (val == NULL)
457*ef5ccd6cSJohn Marino 	ui_out_field_skip (current_uiout, column->field_name);
458*ef5ccd6cSJohn Marino       else
459*ef5ccd6cSJohn Marino 	ui_out_field_string (current_uiout, column->field_name, val);
460*ef5ccd6cSJohn Marino     }
461*ef5ccd6cSJohn Marino 
462*ef5ccd6cSJohn Marino   do_cleanups (c);
463*ef5ccd6cSJohn Marino }
464*ef5ccd6cSJohn Marino 
465*ef5ccd6cSJohn Marino /* Helper function that returns the number of extra fields which POPS will
466*ef5ccd6cSJohn Marino    need.  */
467*ef5ccd6cSJohn Marino 
468*ef5ccd6cSJohn Marino static int
get_number_extra_fields(const struct probe_ops * pops)469*ef5ccd6cSJohn Marino get_number_extra_fields (const struct probe_ops *pops)
470*ef5ccd6cSJohn Marino {
471*ef5ccd6cSJohn Marino   VEC (info_probe_column_s) *headings = NULL;
472*ef5ccd6cSJohn Marino   struct cleanup *c;
473*ef5ccd6cSJohn Marino   int n;
474*ef5ccd6cSJohn Marino 
475*ef5ccd6cSJohn Marino   if (pops->gen_info_probes_table_header == NULL)
476*ef5ccd6cSJohn Marino     return 0;
477*ef5ccd6cSJohn Marino 
478*ef5ccd6cSJohn Marino   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
479*ef5ccd6cSJohn Marino   pops->gen_info_probes_table_header (&headings);
480*ef5ccd6cSJohn Marino 
481*ef5ccd6cSJohn Marino   n = VEC_length (info_probe_column_s, headings);
482*ef5ccd6cSJohn Marino 
483*ef5ccd6cSJohn Marino   do_cleanups (c);
484*ef5ccd6cSJohn Marino 
485*ef5ccd6cSJohn Marino   return n;
486*ef5ccd6cSJohn Marino }
487*ef5ccd6cSJohn Marino 
488*ef5ccd6cSJohn Marino /* See comment in probe.h.  */
489*ef5ccd6cSJohn Marino 
490*ef5ccd6cSJohn Marino void
info_probes_for_ops(char * arg,int from_tty,const struct probe_ops * pops)491*ef5ccd6cSJohn Marino info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
492*ef5ccd6cSJohn Marino {
493*ef5ccd6cSJohn Marino   char *provider, *probe_name = NULL, *objname = NULL;
494*ef5ccd6cSJohn Marino   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
495*ef5ccd6cSJohn Marino   VEC (probe_p) *probes;
496*ef5ccd6cSJohn Marino   int i, any_found;
497*ef5ccd6cSJohn Marino   int ui_out_extra_fields = 0;
498*ef5ccd6cSJohn Marino   size_t size_addr;
499*ef5ccd6cSJohn Marino   size_t size_name = strlen ("Name");
500*ef5ccd6cSJohn Marino   size_t size_objname = strlen ("Object");
501*ef5ccd6cSJohn Marino   size_t size_provider = strlen ("Provider");
502*ef5ccd6cSJohn Marino   struct probe *probe;
503*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = get_current_arch ();
504*ef5ccd6cSJohn Marino 
505*ef5ccd6cSJohn Marino   /* Do we have a `provider:probe:objfile' style of linespec?  */
506*ef5ccd6cSJohn Marino   provider = extract_arg (&arg);
507*ef5ccd6cSJohn Marino   if (provider)
508*ef5ccd6cSJohn Marino     {
509*ef5ccd6cSJohn Marino       make_cleanup (xfree, provider);
510*ef5ccd6cSJohn Marino 
511*ef5ccd6cSJohn Marino       probe_name = extract_arg (&arg);
512*ef5ccd6cSJohn Marino       if (probe_name)
513*ef5ccd6cSJohn Marino 	{
514*ef5ccd6cSJohn Marino 	  make_cleanup (xfree, probe_name);
515*ef5ccd6cSJohn Marino 
516*ef5ccd6cSJohn Marino 	  objname = extract_arg (&arg);
517*ef5ccd6cSJohn Marino 	  if (objname)
518*ef5ccd6cSJohn Marino 	    make_cleanup (xfree, objname);
519*ef5ccd6cSJohn Marino 	}
520*ef5ccd6cSJohn Marino     }
521*ef5ccd6cSJohn Marino 
522*ef5ccd6cSJohn Marino   if (pops == NULL)
523*ef5ccd6cSJohn Marino     {
524*ef5ccd6cSJohn Marino       const struct probe_ops *po;
525*ef5ccd6cSJohn Marino       int ix;
526*ef5ccd6cSJohn Marino 
527*ef5ccd6cSJohn Marino       /* If the probe_ops is NULL, it means the user has requested a "simple"
528*ef5ccd6cSJohn Marino 	 `info probes', i.e., she wants to print all information about all
529*ef5ccd6cSJohn Marino 	 probes.  For that, we have to identify how many extra fields we will
530*ef5ccd6cSJohn Marino 	 need to add in the ui_out table.
531*ef5ccd6cSJohn Marino 
532*ef5ccd6cSJohn Marino 	 To do that, we iterate over all probe_ops, querying each one about
533*ef5ccd6cSJohn Marino 	 its extra fields, and incrementing `ui_out_extra_fields' to reflect
534*ef5ccd6cSJohn Marino 	 that number.  */
535*ef5ccd6cSJohn Marino 
536*ef5ccd6cSJohn Marino       for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
537*ef5ccd6cSJohn Marino 	ui_out_extra_fields += get_number_extra_fields (po);
538*ef5ccd6cSJohn Marino     }
539*ef5ccd6cSJohn Marino   else
540*ef5ccd6cSJohn Marino     ui_out_extra_fields = get_number_extra_fields (pops);
541*ef5ccd6cSJohn Marino 
542*ef5ccd6cSJohn Marino   probes = collect_probes (objname, provider, probe_name, pops);
543*ef5ccd6cSJohn Marino   make_cleanup (VEC_cleanup (probe_p), &probes);
544*ef5ccd6cSJohn Marino   make_cleanup_ui_out_table_begin_end (current_uiout,
545*ef5ccd6cSJohn Marino 				       4 + ui_out_extra_fields,
546*ef5ccd6cSJohn Marino 				       VEC_length (probe_p, probes),
547*ef5ccd6cSJohn Marino 				       "StaticProbes");
548*ef5ccd6cSJohn Marino 
549*ef5ccd6cSJohn Marino   if (!VEC_empty (probe_p, probes))
550*ef5ccd6cSJohn Marino     qsort (VEC_address (probe_p, probes), VEC_length (probe_p, probes),
551*ef5ccd6cSJohn Marino 	   sizeof (probe_p), compare_probes);
552*ef5ccd6cSJohn Marino 
553*ef5ccd6cSJohn Marino   /* What's the size of an address in our architecture?  */
554*ef5ccd6cSJohn Marino   size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
555*ef5ccd6cSJohn Marino 
556*ef5ccd6cSJohn Marino   /* Determining the maximum size of each field (`provider', `name' and
557*ef5ccd6cSJohn Marino      `objname').  */
558*ef5ccd6cSJohn Marino   for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
559*ef5ccd6cSJohn Marino     {
560*ef5ccd6cSJohn Marino       size_name = max (strlen (probe->name), size_name);
561*ef5ccd6cSJohn Marino       size_provider = max (strlen (probe->provider), size_provider);
562*ef5ccd6cSJohn Marino       size_objname = max (strlen (probe->objfile->name), size_objname);
563*ef5ccd6cSJohn Marino     }
564*ef5ccd6cSJohn Marino 
565*ef5ccd6cSJohn Marino   ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
566*ef5ccd6cSJohn Marino 		       _("Provider"));
567*ef5ccd6cSJohn Marino   ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
568*ef5ccd6cSJohn Marino   ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));
569*ef5ccd6cSJohn Marino 
570*ef5ccd6cSJohn Marino   if (pops == NULL)
571*ef5ccd6cSJohn Marino     {
572*ef5ccd6cSJohn Marino       const struct probe_ops *po;
573*ef5ccd6cSJohn Marino       int ix;
574*ef5ccd6cSJohn Marino 
575*ef5ccd6cSJohn Marino       /* We have to generate the table header for each new probe type that we
576*ef5ccd6cSJohn Marino 	 will print.  */
577*ef5ccd6cSJohn Marino       for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
578*ef5ccd6cSJohn Marino 	gen_ui_out_table_header_info (probes, po);
579*ef5ccd6cSJohn Marino     }
580*ef5ccd6cSJohn Marino   else
581*ef5ccd6cSJohn Marino     gen_ui_out_table_header_info (probes, pops);
582*ef5ccd6cSJohn Marino 
583*ef5ccd6cSJohn Marino   ui_out_table_header (current_uiout, size_objname, ui_left, "object",
584*ef5ccd6cSJohn Marino 		       _("Object"));
585*ef5ccd6cSJohn Marino   ui_out_table_body (current_uiout);
586*ef5ccd6cSJohn Marino 
587*ef5ccd6cSJohn Marino   for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
588*ef5ccd6cSJohn Marino     {
589*ef5ccd6cSJohn Marino       struct cleanup *inner;
590*ef5ccd6cSJohn Marino 
591*ef5ccd6cSJohn Marino       inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
592*ef5ccd6cSJohn Marino 
593*ef5ccd6cSJohn Marino       ui_out_field_string (current_uiout, "provider", probe->provider);
594*ef5ccd6cSJohn Marino       ui_out_field_string (current_uiout, "name", probe->name);
595*ef5ccd6cSJohn Marino       ui_out_field_core_addr (current_uiout, "addr",
596*ef5ccd6cSJohn Marino 			      get_objfile_arch (probe->objfile),
597*ef5ccd6cSJohn Marino 			      probe->address);
598*ef5ccd6cSJohn Marino 
599*ef5ccd6cSJohn Marino       if (pops == NULL)
600*ef5ccd6cSJohn Marino 	{
601*ef5ccd6cSJohn Marino 	  const struct probe_ops *po;
602*ef5ccd6cSJohn Marino 	  int ix;
603*ef5ccd6cSJohn Marino 
604*ef5ccd6cSJohn Marino 	  for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
605*ef5ccd6cSJohn Marino 	       ++ix)
606*ef5ccd6cSJohn Marino 	    if (probe->pops == po)
607*ef5ccd6cSJohn Marino 	      print_ui_out_info (probe);
608*ef5ccd6cSJohn Marino 	}
609*ef5ccd6cSJohn Marino       else
610*ef5ccd6cSJohn Marino 	print_ui_out_info (probe);
611*ef5ccd6cSJohn Marino 
612*ef5ccd6cSJohn Marino       ui_out_field_string (current_uiout, "object", probe->objfile->name);
613*ef5ccd6cSJohn Marino       ui_out_text (current_uiout, "\n");
614*ef5ccd6cSJohn Marino 
615*ef5ccd6cSJohn Marino       do_cleanups (inner);
616*ef5ccd6cSJohn Marino     }
617*ef5ccd6cSJohn Marino 
618*ef5ccd6cSJohn Marino   any_found = !VEC_empty (probe_p, probes);
619*ef5ccd6cSJohn Marino   do_cleanups (cleanup);
620*ef5ccd6cSJohn Marino 
621*ef5ccd6cSJohn Marino   if (!any_found)
622*ef5ccd6cSJohn Marino     ui_out_message (current_uiout, 0, _("No probes matched.\n"));
623*ef5ccd6cSJohn Marino }
624*ef5ccd6cSJohn Marino 
625*ef5ccd6cSJohn Marino /* Implementation of the `info probes' command.  */
626*ef5ccd6cSJohn Marino 
627*ef5ccd6cSJohn Marino static void
info_probes_command(char * arg,int from_tty)628*ef5ccd6cSJohn Marino info_probes_command (char *arg, int from_tty)
629*ef5ccd6cSJohn Marino {
630*ef5ccd6cSJohn Marino   info_probes_for_ops (arg, from_tty, NULL);
631*ef5ccd6cSJohn Marino }
632*ef5ccd6cSJohn Marino 
633*ef5ccd6cSJohn Marino /* See comments in probe.h.  */
634*ef5ccd6cSJohn Marino 
635*ef5ccd6cSJohn Marino struct value *
probe_safe_evaluate_at_pc(struct frame_info * frame,unsigned n)636*ef5ccd6cSJohn Marino probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
637*ef5ccd6cSJohn Marino {
638*ef5ccd6cSJohn Marino   struct probe *probe;
639*ef5ccd6cSJohn Marino   const struct sym_probe_fns *probe_fns;
640*ef5ccd6cSJohn Marino   unsigned n_args;
641*ef5ccd6cSJohn Marino 
642*ef5ccd6cSJohn Marino   probe = find_probe_by_pc (get_frame_pc (frame));
643*ef5ccd6cSJohn Marino   if (!probe)
644*ef5ccd6cSJohn Marino     return NULL;
645*ef5ccd6cSJohn Marino 
646*ef5ccd6cSJohn Marino   gdb_assert (probe->objfile != NULL);
647*ef5ccd6cSJohn Marino   gdb_assert (probe->objfile->sf != NULL);
648*ef5ccd6cSJohn Marino   gdb_assert (probe->objfile->sf->sym_probe_fns != NULL);
649*ef5ccd6cSJohn Marino 
650*ef5ccd6cSJohn Marino   probe_fns = probe->objfile->sf->sym_probe_fns;
651*ef5ccd6cSJohn Marino   n_args = probe_fns->sym_get_probe_argument_count (probe);
652*ef5ccd6cSJohn Marino 
653*ef5ccd6cSJohn Marino   if (n >= n_args)
654*ef5ccd6cSJohn Marino     return NULL;
655*ef5ccd6cSJohn Marino 
656*ef5ccd6cSJohn Marino   return probe_fns->sym_evaluate_probe_argument (probe, n);
657*ef5ccd6cSJohn Marino }
658*ef5ccd6cSJohn Marino 
659*ef5ccd6cSJohn Marino /* See comment in probe.h.  */
660*ef5ccd6cSJohn Marino 
661*ef5ccd6cSJohn Marino const struct probe_ops *
probe_linespec_to_ops(const char ** linespecp)662*ef5ccd6cSJohn Marino probe_linespec_to_ops (const char **linespecp)
663*ef5ccd6cSJohn Marino {
664*ef5ccd6cSJohn Marino   int ix;
665*ef5ccd6cSJohn Marino   const struct probe_ops *probe_ops;
666*ef5ccd6cSJohn Marino 
667*ef5ccd6cSJohn Marino   for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops); ix++)
668*ef5ccd6cSJohn Marino     if (probe_ops->is_linespec (linespecp))
669*ef5ccd6cSJohn Marino       return probe_ops;
670*ef5ccd6cSJohn Marino 
671*ef5ccd6cSJohn Marino   return NULL;
672*ef5ccd6cSJohn Marino }
673*ef5ccd6cSJohn Marino 
674*ef5ccd6cSJohn Marino /* See comment in probe.h.  */
675*ef5ccd6cSJohn Marino 
676*ef5ccd6cSJohn Marino int
probe_is_linespec_by_keyword(const char ** linespecp,const char * const * keywords)677*ef5ccd6cSJohn Marino probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords)
678*ef5ccd6cSJohn Marino {
679*ef5ccd6cSJohn Marino   const char *s = *linespecp;
680*ef5ccd6cSJohn Marino   const char *const *csp;
681*ef5ccd6cSJohn Marino 
682*ef5ccd6cSJohn Marino   for (csp = keywords; *csp; csp++)
683*ef5ccd6cSJohn Marino     {
684*ef5ccd6cSJohn Marino       const char *keyword = *csp;
685*ef5ccd6cSJohn Marino       size_t len = strlen (keyword);
686*ef5ccd6cSJohn Marino 
687*ef5ccd6cSJohn Marino       if (strncmp (s, keyword, len) == 0 && isspace (s[len]))
688*ef5ccd6cSJohn Marino 	{
689*ef5ccd6cSJohn Marino 	  *linespecp += len + 1;
690*ef5ccd6cSJohn Marino 	  return 1;
691*ef5ccd6cSJohn Marino 	}
692*ef5ccd6cSJohn Marino     }
693*ef5ccd6cSJohn Marino 
694*ef5ccd6cSJohn Marino   return 0;
695*ef5ccd6cSJohn Marino }
696*ef5ccd6cSJohn Marino 
697*ef5ccd6cSJohn Marino /* Implementation of `is_linespec' method for `struct probe_ops'.  */
698*ef5ccd6cSJohn Marino 
699*ef5ccd6cSJohn Marino static int
probe_any_is_linespec(const char ** linespecp)700*ef5ccd6cSJohn Marino probe_any_is_linespec (const char **linespecp)
701*ef5ccd6cSJohn Marino {
702*ef5ccd6cSJohn Marino   static const char *const keywords[] = { "-p", "-probe", NULL };
703*ef5ccd6cSJohn Marino 
704*ef5ccd6cSJohn Marino   return probe_is_linespec_by_keyword (linespecp, keywords);
705*ef5ccd6cSJohn Marino }
706*ef5ccd6cSJohn Marino 
707*ef5ccd6cSJohn Marino /* Dummy method used for `probe_ops_any'.  */
708*ef5ccd6cSJohn Marino 
709*ef5ccd6cSJohn Marino static void
probe_any_get_probes(VEC (probe_p)** probesp,struct objfile * objfile)710*ef5ccd6cSJohn Marino probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
711*ef5ccd6cSJohn Marino {
712*ef5ccd6cSJohn Marino   /* No probes can be provided by this dummy backend.  */
713*ef5ccd6cSJohn Marino }
714*ef5ccd6cSJohn Marino 
715*ef5ccd6cSJohn Marino /* Operations associated with a generic probe.  */
716*ef5ccd6cSJohn Marino 
717*ef5ccd6cSJohn Marino const struct probe_ops probe_ops_any =
718*ef5ccd6cSJohn Marino {
719*ef5ccd6cSJohn Marino   probe_any_is_linespec,
720*ef5ccd6cSJohn Marino   probe_any_get_probes,
721*ef5ccd6cSJohn Marino };
722*ef5ccd6cSJohn Marino 
723*ef5ccd6cSJohn Marino /* See comments in probe.h.  */
724*ef5ccd6cSJohn Marino 
725*ef5ccd6cSJohn Marino struct cmd_list_element **
info_probes_cmdlist_get(void)726*ef5ccd6cSJohn Marino info_probes_cmdlist_get (void)
727*ef5ccd6cSJohn Marino {
728*ef5ccd6cSJohn Marino   static struct cmd_list_element *info_probes_cmdlist;
729*ef5ccd6cSJohn Marino 
730*ef5ccd6cSJohn Marino   if (info_probes_cmdlist == NULL)
731*ef5ccd6cSJohn Marino     add_prefix_cmd ("probes", class_info, info_probes_command,
732*ef5ccd6cSJohn Marino 		    _("\
733*ef5ccd6cSJohn Marino Show available static probes.\n\
734*ef5ccd6cSJohn Marino Usage: info probes [all|TYPE [ARGS]]\n\
735*ef5ccd6cSJohn Marino TYPE specifies the type of the probe, and can be one of the following:\n\
736*ef5ccd6cSJohn Marino   - stap\n\
737*ef5ccd6cSJohn Marino If you specify TYPE, there may be additional arguments needed by the\n\
738*ef5ccd6cSJohn Marino subcommand.\n\
739*ef5ccd6cSJohn Marino If you do not specify any argument, or specify `all', then the command\n\
740*ef5ccd6cSJohn Marino will show information about all types of probes."),
741*ef5ccd6cSJohn Marino 		    &info_probes_cmdlist, "info probes ",
742*ef5ccd6cSJohn Marino 		    0/*allow-unknown*/, &infolist);
743*ef5ccd6cSJohn Marino 
744*ef5ccd6cSJohn Marino   return &info_probes_cmdlist;
745*ef5ccd6cSJohn Marino }
746*ef5ccd6cSJohn Marino 
747*ef5ccd6cSJohn Marino VEC (probe_ops_cp) *all_probe_ops;
748*ef5ccd6cSJohn Marino 
749*ef5ccd6cSJohn Marino void _initialize_probe (void);
750*ef5ccd6cSJohn Marino 
751*ef5ccd6cSJohn Marino void
_initialize_probe(void)752*ef5ccd6cSJohn Marino _initialize_probe (void)
753*ef5ccd6cSJohn Marino {
754*ef5ccd6cSJohn Marino   VEC_safe_push (probe_ops_cp, all_probe_ops, &probe_ops_any);
755*ef5ccd6cSJohn Marino 
756*ef5ccd6cSJohn Marino   add_cmd ("all", class_info, info_probes_command,
757*ef5ccd6cSJohn Marino 	   _("\
758*ef5ccd6cSJohn Marino Show information about all type of probes."),
759*ef5ccd6cSJohn Marino 	   info_probes_cmdlist_get ());
760*ef5ccd6cSJohn Marino }
761