xref: /dragonfly/contrib/gdb-7/gdb/stap-probe.c (revision ef5ccd6c)
1*ef5ccd6cSJohn Marino /* SystemTap 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 "stap-probe.h"
22*ef5ccd6cSJohn Marino #include "probe.h"
23*ef5ccd6cSJohn Marino #include "vec.h"
24*ef5ccd6cSJohn Marino #include "ui-out.h"
25*ef5ccd6cSJohn Marino #include "objfiles.h"
26*ef5ccd6cSJohn Marino #include "arch-utils.h"
27*ef5ccd6cSJohn Marino #include "command.h"
28*ef5ccd6cSJohn Marino #include "gdbcmd.h"
29*ef5ccd6cSJohn Marino #include "filenames.h"
30*ef5ccd6cSJohn Marino #include "value.h"
31*ef5ccd6cSJohn Marino #include "exceptions.h"
32*ef5ccd6cSJohn Marino #include "ax.h"
33*ef5ccd6cSJohn Marino #include "ax-gdb.h"
34*ef5ccd6cSJohn Marino #include "complaints.h"
35*ef5ccd6cSJohn Marino #include "cli/cli-utils.h"
36*ef5ccd6cSJohn Marino #include "linespec.h"
37*ef5ccd6cSJohn Marino #include "user-regs.h"
38*ef5ccd6cSJohn Marino #include "parser-defs.h"
39*ef5ccd6cSJohn Marino #include "language.h"
40*ef5ccd6cSJohn Marino #include "elf-bfd.h"
41*ef5ccd6cSJohn Marino 
42*ef5ccd6cSJohn Marino #include <ctype.h>
43*ef5ccd6cSJohn Marino 
44*ef5ccd6cSJohn Marino /* The name of the SystemTap section where we will find information about
45*ef5ccd6cSJohn Marino    the probes.  */
46*ef5ccd6cSJohn Marino 
47*ef5ccd6cSJohn Marino #define STAP_BASE_SECTION_NAME ".stapsdt.base"
48*ef5ccd6cSJohn Marino 
49*ef5ccd6cSJohn Marino /* Forward declaration. */
50*ef5ccd6cSJohn Marino 
51*ef5ccd6cSJohn Marino static const struct probe_ops stap_probe_ops;
52*ef5ccd6cSJohn Marino 
53*ef5ccd6cSJohn Marino /* Should we display debug information for the probe's argument expression
54*ef5ccd6cSJohn Marino    parsing?  */
55*ef5ccd6cSJohn Marino 
56*ef5ccd6cSJohn Marino static unsigned int stap_expression_debug = 0;
57*ef5ccd6cSJohn Marino 
58*ef5ccd6cSJohn Marino /* The various possibilities of bitness defined for a probe's argument.
59*ef5ccd6cSJohn Marino 
60*ef5ccd6cSJohn Marino    The relationship is:
61*ef5ccd6cSJohn Marino 
62*ef5ccd6cSJohn Marino    - STAP_ARG_BITNESS_UNDEFINED:  The user hasn't specified the bitness.
63*ef5ccd6cSJohn Marino    - STAP_ARG_BITNESS_32BIT_UNSIGNED:  argument string starts with `4@'.
64*ef5ccd6cSJohn Marino    - STAP_ARG_BITNESS_32BIT_SIGNED:  argument string starts with `-4@'.
65*ef5ccd6cSJohn Marino    - STAP_ARG_BITNESS_64BIT_UNSIGNED:  argument string starts with `8@'.
66*ef5ccd6cSJohn Marino    - STAP_ARG_BITNESS_64BIT_SIGNED:  argument string starts with `-8@'.  */
67*ef5ccd6cSJohn Marino 
68*ef5ccd6cSJohn Marino enum stap_arg_bitness
69*ef5ccd6cSJohn Marino {
70*ef5ccd6cSJohn Marino   STAP_ARG_BITNESS_UNDEFINED,
71*ef5ccd6cSJohn Marino   STAP_ARG_BITNESS_32BIT_UNSIGNED,
72*ef5ccd6cSJohn Marino   STAP_ARG_BITNESS_32BIT_SIGNED,
73*ef5ccd6cSJohn Marino   STAP_ARG_BITNESS_64BIT_UNSIGNED,
74*ef5ccd6cSJohn Marino   STAP_ARG_BITNESS_64BIT_SIGNED,
75*ef5ccd6cSJohn Marino };
76*ef5ccd6cSJohn Marino 
77*ef5ccd6cSJohn Marino /* The following structure represents a single argument for the probe.  */
78*ef5ccd6cSJohn Marino 
79*ef5ccd6cSJohn Marino struct stap_probe_arg
80*ef5ccd6cSJohn Marino {
81*ef5ccd6cSJohn Marino   /* The bitness of this argument.  */
82*ef5ccd6cSJohn Marino   enum stap_arg_bitness bitness;
83*ef5ccd6cSJohn Marino 
84*ef5ccd6cSJohn Marino   /* The corresponding `struct type *' to the bitness.  */
85*ef5ccd6cSJohn Marino   struct type *atype;
86*ef5ccd6cSJohn Marino 
87*ef5ccd6cSJohn Marino   /* The argument converted to an internal GDB expression.  */
88*ef5ccd6cSJohn Marino   struct expression *aexpr;
89*ef5ccd6cSJohn Marino };
90*ef5ccd6cSJohn Marino 
91*ef5ccd6cSJohn Marino typedef struct stap_probe_arg stap_probe_arg_s;
92*ef5ccd6cSJohn Marino DEF_VEC_O (stap_probe_arg_s);
93*ef5ccd6cSJohn Marino 
94*ef5ccd6cSJohn Marino struct stap_probe
95*ef5ccd6cSJohn Marino {
96*ef5ccd6cSJohn Marino   /* Generic information about the probe.  This shall be the first element
97*ef5ccd6cSJohn Marino      of this struct, in order to maintain binary compatibility with the
98*ef5ccd6cSJohn Marino      `struct probe' and be able to fully abstract it.  */
99*ef5ccd6cSJohn Marino   struct probe p;
100*ef5ccd6cSJohn Marino 
101*ef5ccd6cSJohn Marino   /* If the probe has a semaphore associated, then this is the value of
102*ef5ccd6cSJohn Marino      it.  */
103*ef5ccd6cSJohn Marino   CORE_ADDR sem_addr;
104*ef5ccd6cSJohn Marino 
105*ef5ccd6cSJohn Marino   unsigned int args_parsed : 1;
106*ef5ccd6cSJohn Marino   union
107*ef5ccd6cSJohn Marino     {
108*ef5ccd6cSJohn Marino       const char *text;
109*ef5ccd6cSJohn Marino 
110*ef5ccd6cSJohn Marino       /* Information about each argument.  This is an array of `stap_probe_arg',
111*ef5ccd6cSJohn Marino 	 with each entry representing one argument.  */
112*ef5ccd6cSJohn Marino       VEC (stap_probe_arg_s) *vec;
113*ef5ccd6cSJohn Marino     }
114*ef5ccd6cSJohn Marino   args_u;
115*ef5ccd6cSJohn Marino };
116*ef5ccd6cSJohn Marino 
117*ef5ccd6cSJohn Marino /* When parsing the arguments, we have to establish different precedences
118*ef5ccd6cSJohn Marino    for the various kinds of asm operators.  This enumeration represents those
119*ef5ccd6cSJohn Marino    precedences.
120*ef5ccd6cSJohn Marino 
121*ef5ccd6cSJohn Marino    This logic behind this is available at
122*ef5ccd6cSJohn Marino    <http://sourceware.org/binutils/docs/as/Infix-Ops.html#Infix-Ops>, or using
123*ef5ccd6cSJohn Marino    the command "info '(as)Infix Ops'".  */
124*ef5ccd6cSJohn Marino 
125*ef5ccd6cSJohn Marino enum stap_operand_prec
126*ef5ccd6cSJohn Marino {
127*ef5ccd6cSJohn Marino   /* Lowest precedence, used for non-recognized operands or for the beginning
128*ef5ccd6cSJohn Marino      of the parsing process.  */
129*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_NONE = 0,
130*ef5ccd6cSJohn Marino 
131*ef5ccd6cSJohn Marino   /* Precedence of logical OR.  */
132*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_LOGICAL_OR,
133*ef5ccd6cSJohn Marino 
134*ef5ccd6cSJohn Marino   /* Precedence of logical AND.  */
135*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_LOGICAL_AND,
136*ef5ccd6cSJohn Marino 
137*ef5ccd6cSJohn Marino   /* Precedence of additive (plus, minus) and comparative (equal, less,
138*ef5ccd6cSJohn Marino      greater-than, etc) operands.  */
139*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_ADD_CMP,
140*ef5ccd6cSJohn Marino 
141*ef5ccd6cSJohn Marino   /* Precedence of bitwise operands (bitwise OR, XOR, bitwise AND,
142*ef5ccd6cSJohn Marino      logical NOT).  */
143*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_BITWISE,
144*ef5ccd6cSJohn Marino 
145*ef5ccd6cSJohn Marino   /* Precedence of multiplicative operands (multiplication, division,
146*ef5ccd6cSJohn Marino      remainder, left shift and right shift).  */
147*ef5ccd6cSJohn Marino   STAP_OPERAND_PREC_MUL
148*ef5ccd6cSJohn Marino };
149*ef5ccd6cSJohn Marino 
150*ef5ccd6cSJohn Marino static void stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
151*ef5ccd6cSJohn Marino 				   enum stap_operand_prec prec);
152*ef5ccd6cSJohn Marino 
153*ef5ccd6cSJohn Marino static void stap_parse_argument_conditionally (struct stap_parse_info *p);
154*ef5ccd6cSJohn Marino 
155*ef5ccd6cSJohn Marino /* Returns 1 if *S is an operator, zero otherwise.  */
156*ef5ccd6cSJohn Marino 
157*ef5ccd6cSJohn Marino static int stap_is_operator (const char *op);
158*ef5ccd6cSJohn Marino 
159*ef5ccd6cSJohn Marino static void
show_stapexpressiondebug(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)160*ef5ccd6cSJohn Marino show_stapexpressiondebug (struct ui_file *file, int from_tty,
161*ef5ccd6cSJohn Marino 			  struct cmd_list_element *c, const char *value)
162*ef5ccd6cSJohn Marino {
163*ef5ccd6cSJohn Marino   fprintf_filtered (file, _("SystemTap Probe expression debugging is %s.\n"),
164*ef5ccd6cSJohn Marino 		    value);
165*ef5ccd6cSJohn Marino }
166*ef5ccd6cSJohn Marino 
167*ef5ccd6cSJohn Marino /* Returns the operator precedence level of OP, or STAP_OPERAND_PREC_NONE
168*ef5ccd6cSJohn Marino    if the operator code was not recognized.  */
169*ef5ccd6cSJohn Marino 
170*ef5ccd6cSJohn Marino static enum stap_operand_prec
stap_get_operator_prec(enum exp_opcode op)171*ef5ccd6cSJohn Marino stap_get_operator_prec (enum exp_opcode op)
172*ef5ccd6cSJohn Marino {
173*ef5ccd6cSJohn Marino   switch (op)
174*ef5ccd6cSJohn Marino     {
175*ef5ccd6cSJohn Marino     case BINOP_LOGICAL_OR:
176*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_LOGICAL_OR;
177*ef5ccd6cSJohn Marino 
178*ef5ccd6cSJohn Marino     case BINOP_LOGICAL_AND:
179*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_LOGICAL_AND;
180*ef5ccd6cSJohn Marino 
181*ef5ccd6cSJohn Marino     case BINOP_ADD:
182*ef5ccd6cSJohn Marino     case BINOP_SUB:
183*ef5ccd6cSJohn Marino     case BINOP_EQUAL:
184*ef5ccd6cSJohn Marino     case BINOP_NOTEQUAL:
185*ef5ccd6cSJohn Marino     case BINOP_LESS:
186*ef5ccd6cSJohn Marino     case BINOP_LEQ:
187*ef5ccd6cSJohn Marino     case BINOP_GTR:
188*ef5ccd6cSJohn Marino     case BINOP_GEQ:
189*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_ADD_CMP;
190*ef5ccd6cSJohn Marino 
191*ef5ccd6cSJohn Marino     case BINOP_BITWISE_IOR:
192*ef5ccd6cSJohn Marino     case BINOP_BITWISE_AND:
193*ef5ccd6cSJohn Marino     case BINOP_BITWISE_XOR:
194*ef5ccd6cSJohn Marino     case UNOP_LOGICAL_NOT:
195*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_BITWISE;
196*ef5ccd6cSJohn Marino 
197*ef5ccd6cSJohn Marino     case BINOP_MUL:
198*ef5ccd6cSJohn Marino     case BINOP_DIV:
199*ef5ccd6cSJohn Marino     case BINOP_REM:
200*ef5ccd6cSJohn Marino     case BINOP_LSH:
201*ef5ccd6cSJohn Marino     case BINOP_RSH:
202*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_MUL;
203*ef5ccd6cSJohn Marino 
204*ef5ccd6cSJohn Marino     default:
205*ef5ccd6cSJohn Marino       return STAP_OPERAND_PREC_NONE;
206*ef5ccd6cSJohn Marino     }
207*ef5ccd6cSJohn Marino }
208*ef5ccd6cSJohn Marino 
209*ef5ccd6cSJohn Marino /* Given S, read the operator in it and fills the OP pointer with its code.
210*ef5ccd6cSJohn Marino    Return 1 on success, zero if the operator was not recognized.  */
211*ef5ccd6cSJohn Marino 
212*ef5ccd6cSJohn Marino static enum exp_opcode
stap_get_opcode(const char ** s)213*ef5ccd6cSJohn Marino stap_get_opcode (const char **s)
214*ef5ccd6cSJohn Marino {
215*ef5ccd6cSJohn Marino   const char c = **s;
216*ef5ccd6cSJohn Marino   enum exp_opcode op;
217*ef5ccd6cSJohn Marino 
218*ef5ccd6cSJohn Marino   *s += 1;
219*ef5ccd6cSJohn Marino 
220*ef5ccd6cSJohn Marino   switch (c)
221*ef5ccd6cSJohn Marino     {
222*ef5ccd6cSJohn Marino     case '*':
223*ef5ccd6cSJohn Marino       op = BINOP_MUL;
224*ef5ccd6cSJohn Marino       break;
225*ef5ccd6cSJohn Marino 
226*ef5ccd6cSJohn Marino     case '/':
227*ef5ccd6cSJohn Marino       op = BINOP_DIV;
228*ef5ccd6cSJohn Marino       break;
229*ef5ccd6cSJohn Marino 
230*ef5ccd6cSJohn Marino     case '%':
231*ef5ccd6cSJohn Marino       op = BINOP_REM;
232*ef5ccd6cSJohn Marino     break;
233*ef5ccd6cSJohn Marino 
234*ef5ccd6cSJohn Marino     case '<':
235*ef5ccd6cSJohn Marino       op = BINOP_LESS;
236*ef5ccd6cSJohn Marino       if (**s == '<')
237*ef5ccd6cSJohn Marino 	{
238*ef5ccd6cSJohn Marino 	  *s += 1;
239*ef5ccd6cSJohn Marino 	  op = BINOP_LSH;
240*ef5ccd6cSJohn Marino 	}
241*ef5ccd6cSJohn Marino       else if (**s == '=')
242*ef5ccd6cSJohn Marino 	{
243*ef5ccd6cSJohn Marino 	  *s += 1;
244*ef5ccd6cSJohn Marino 	  op = BINOP_LEQ;
245*ef5ccd6cSJohn Marino 	}
246*ef5ccd6cSJohn Marino       else if (**s == '>')
247*ef5ccd6cSJohn Marino 	{
248*ef5ccd6cSJohn Marino 	  *s += 1;
249*ef5ccd6cSJohn Marino 	  op = BINOP_NOTEQUAL;
250*ef5ccd6cSJohn Marino 	}
251*ef5ccd6cSJohn Marino     break;
252*ef5ccd6cSJohn Marino 
253*ef5ccd6cSJohn Marino     case '>':
254*ef5ccd6cSJohn Marino       op = BINOP_GTR;
255*ef5ccd6cSJohn Marino       if (**s == '>')
256*ef5ccd6cSJohn Marino 	{
257*ef5ccd6cSJohn Marino 	  *s += 1;
258*ef5ccd6cSJohn Marino 	  op = BINOP_RSH;
259*ef5ccd6cSJohn Marino 	}
260*ef5ccd6cSJohn Marino       else if (**s == '=')
261*ef5ccd6cSJohn Marino 	{
262*ef5ccd6cSJohn Marino 	  *s += 1;
263*ef5ccd6cSJohn Marino 	  op = BINOP_GEQ;
264*ef5ccd6cSJohn Marino 	}
265*ef5ccd6cSJohn Marino     break;
266*ef5ccd6cSJohn Marino 
267*ef5ccd6cSJohn Marino     case '|':
268*ef5ccd6cSJohn Marino       op = BINOP_BITWISE_IOR;
269*ef5ccd6cSJohn Marino       if (**s == '|')
270*ef5ccd6cSJohn Marino 	{
271*ef5ccd6cSJohn Marino 	  *s += 1;
272*ef5ccd6cSJohn Marino 	  op = BINOP_LOGICAL_OR;
273*ef5ccd6cSJohn Marino 	}
274*ef5ccd6cSJohn Marino     break;
275*ef5ccd6cSJohn Marino 
276*ef5ccd6cSJohn Marino     case '&':
277*ef5ccd6cSJohn Marino       op = BINOP_BITWISE_AND;
278*ef5ccd6cSJohn Marino       if (**s == '&')
279*ef5ccd6cSJohn Marino 	{
280*ef5ccd6cSJohn Marino 	  *s += 1;
281*ef5ccd6cSJohn Marino 	  op = BINOP_LOGICAL_AND;
282*ef5ccd6cSJohn Marino 	}
283*ef5ccd6cSJohn Marino     break;
284*ef5ccd6cSJohn Marino 
285*ef5ccd6cSJohn Marino     case '^':
286*ef5ccd6cSJohn Marino       op = BINOP_BITWISE_XOR;
287*ef5ccd6cSJohn Marino       break;
288*ef5ccd6cSJohn Marino 
289*ef5ccd6cSJohn Marino     case '!':
290*ef5ccd6cSJohn Marino       op = UNOP_LOGICAL_NOT;
291*ef5ccd6cSJohn Marino       break;
292*ef5ccd6cSJohn Marino 
293*ef5ccd6cSJohn Marino     case '+':
294*ef5ccd6cSJohn Marino       op = BINOP_ADD;
295*ef5ccd6cSJohn Marino       break;
296*ef5ccd6cSJohn Marino 
297*ef5ccd6cSJohn Marino     case '-':
298*ef5ccd6cSJohn Marino       op = BINOP_SUB;
299*ef5ccd6cSJohn Marino       break;
300*ef5ccd6cSJohn Marino 
301*ef5ccd6cSJohn Marino     case '=':
302*ef5ccd6cSJohn Marino       gdb_assert (**s == '=');
303*ef5ccd6cSJohn Marino       op = BINOP_EQUAL;
304*ef5ccd6cSJohn Marino       break;
305*ef5ccd6cSJohn Marino 
306*ef5ccd6cSJohn Marino     default:
307*ef5ccd6cSJohn Marino       internal_error (__FILE__, __LINE__,
308*ef5ccd6cSJohn Marino 		      _("Invalid opcode in expression `%s' for SystemTap"
309*ef5ccd6cSJohn Marino 			"probe"), *s);
310*ef5ccd6cSJohn Marino     }
311*ef5ccd6cSJohn Marino 
312*ef5ccd6cSJohn Marino   return op;
313*ef5ccd6cSJohn Marino }
314*ef5ccd6cSJohn Marino 
315*ef5ccd6cSJohn Marino /* Given the bitness of the argument, represented by B, return the
316*ef5ccd6cSJohn Marino    corresponding `struct type *'.  */
317*ef5ccd6cSJohn Marino 
318*ef5ccd6cSJohn Marino static struct type *
stap_get_expected_argument_type(struct gdbarch * gdbarch,enum stap_arg_bitness b)319*ef5ccd6cSJohn Marino stap_get_expected_argument_type (struct gdbarch *gdbarch,
320*ef5ccd6cSJohn Marino 				 enum stap_arg_bitness b)
321*ef5ccd6cSJohn Marino {
322*ef5ccd6cSJohn Marino   switch (b)
323*ef5ccd6cSJohn Marino     {
324*ef5ccd6cSJohn Marino     case STAP_ARG_BITNESS_UNDEFINED:
325*ef5ccd6cSJohn Marino       if (gdbarch_addr_bit (gdbarch) == 32)
326*ef5ccd6cSJohn Marino 	return builtin_type (gdbarch)->builtin_uint32;
327*ef5ccd6cSJohn Marino       else
328*ef5ccd6cSJohn Marino 	return builtin_type (gdbarch)->builtin_uint64;
329*ef5ccd6cSJohn Marino 
330*ef5ccd6cSJohn Marino     case STAP_ARG_BITNESS_32BIT_SIGNED:
331*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_int32;
332*ef5ccd6cSJohn Marino 
333*ef5ccd6cSJohn Marino     case STAP_ARG_BITNESS_32BIT_UNSIGNED:
334*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_uint32;
335*ef5ccd6cSJohn Marino 
336*ef5ccd6cSJohn Marino     case STAP_ARG_BITNESS_64BIT_SIGNED:
337*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_int64;
338*ef5ccd6cSJohn Marino 
339*ef5ccd6cSJohn Marino     case STAP_ARG_BITNESS_64BIT_UNSIGNED:
340*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_uint64;
341*ef5ccd6cSJohn Marino 
342*ef5ccd6cSJohn Marino     default:
343*ef5ccd6cSJohn Marino       internal_error (__FILE__, __LINE__,
344*ef5ccd6cSJohn Marino 		      _("Undefined bitness for probe."));
345*ef5ccd6cSJohn Marino       break;
346*ef5ccd6cSJohn Marino     }
347*ef5ccd6cSJohn Marino }
348*ef5ccd6cSJohn Marino 
349*ef5ccd6cSJohn Marino /* Function responsible for parsing a register operand according to
350*ef5ccd6cSJohn Marino    SystemTap parlance.  Assuming:
351*ef5ccd6cSJohn Marino 
352*ef5ccd6cSJohn Marino    RP  = register prefix
353*ef5ccd6cSJohn Marino    RS  = register suffix
354*ef5ccd6cSJohn Marino    RIP = register indirection prefix
355*ef5ccd6cSJohn Marino    RIS = register indirection suffix
356*ef5ccd6cSJohn Marino 
357*ef5ccd6cSJohn Marino    Then a register operand can be:
358*ef5ccd6cSJohn Marino 
359*ef5ccd6cSJohn Marino    [RIP] [RP] REGISTER [RS] [RIS]
360*ef5ccd6cSJohn Marino 
361*ef5ccd6cSJohn Marino    This function takes care of a register's indirection, displacement and
362*ef5ccd6cSJohn Marino    direct access.  It also takes into consideration the fact that some
363*ef5ccd6cSJohn Marino    registers are named differently inside and outside GDB, e.g., PPC's
364*ef5ccd6cSJohn Marino    general-purpose registers are represented by integers in the assembly
365*ef5ccd6cSJohn Marino    language (e.g., `15' is the 15th general-purpose register), but inside
366*ef5ccd6cSJohn Marino    GDB they have a prefix (the letter `r') appended.  */
367*ef5ccd6cSJohn Marino 
368*ef5ccd6cSJohn Marino static void
stap_parse_register_operand(struct stap_parse_info * p)369*ef5ccd6cSJohn Marino stap_parse_register_operand (struct stap_parse_info *p)
370*ef5ccd6cSJohn Marino {
371*ef5ccd6cSJohn Marino   /* Simple flag to indicate whether we have seen a minus signal before
372*ef5ccd6cSJohn Marino      certain number.  */
373*ef5ccd6cSJohn Marino   int got_minus = 0;
374*ef5ccd6cSJohn Marino 
375*ef5ccd6cSJohn Marino   /* Flags to indicate whether this register access is being displaced and/or
376*ef5ccd6cSJohn Marino      indirected.  */
377*ef5ccd6cSJohn Marino   int disp_p = 0, indirect_p = 0;
378*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = p->gdbarch;
379*ef5ccd6cSJohn Marino 
380*ef5ccd6cSJohn Marino   /* Needed to generate the register name as a part of an expression.  */
381*ef5ccd6cSJohn Marino   struct stoken str;
382*ef5ccd6cSJohn Marino 
383*ef5ccd6cSJohn Marino   /* Variables used to extract the register name from the probe's
384*ef5ccd6cSJohn Marino      argument.  */
385*ef5ccd6cSJohn Marino   const char *start;
386*ef5ccd6cSJohn Marino   char *regname;
387*ef5ccd6cSJohn Marino   int len;
388*ef5ccd6cSJohn Marino 
389*ef5ccd6cSJohn Marino   /* Prefixes for the parser.  */
390*ef5ccd6cSJohn Marino   const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
391*ef5ccd6cSJohn Marino   const char *reg_ind_prefix
392*ef5ccd6cSJohn Marino     = gdbarch_stap_register_indirection_prefix (gdbarch);
393*ef5ccd6cSJohn Marino   const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch);
394*ef5ccd6cSJohn Marino   int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
395*ef5ccd6cSJohn Marino   int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
396*ef5ccd6cSJohn Marino   int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0;
397*ef5ccd6cSJohn Marino 
398*ef5ccd6cSJohn Marino   /* Suffixes for the parser.  */
399*ef5ccd6cSJohn Marino   const char *reg_suffix = gdbarch_stap_register_suffix (gdbarch);
400*ef5ccd6cSJohn Marino   const char *reg_ind_suffix
401*ef5ccd6cSJohn Marino     = gdbarch_stap_register_indirection_suffix (gdbarch);
402*ef5ccd6cSJohn Marino   const char *gdb_reg_suffix = gdbarch_stap_gdb_register_suffix (gdbarch);
403*ef5ccd6cSJohn Marino   int reg_suffix_len = reg_suffix ? strlen (reg_suffix) : 0;
404*ef5ccd6cSJohn Marino   int reg_ind_suffix_len = reg_ind_suffix ? strlen (reg_ind_suffix) : 0;
405*ef5ccd6cSJohn Marino   int gdb_reg_suffix_len = gdb_reg_suffix ? strlen (gdb_reg_suffix) : 0;
406*ef5ccd6cSJohn Marino 
407*ef5ccd6cSJohn Marino   /* Checking for a displacement argument.  */
408*ef5ccd6cSJohn Marino   if (*p->arg == '+')
409*ef5ccd6cSJohn Marino     {
410*ef5ccd6cSJohn Marino       /* If it's a plus sign, we don't need to do anything, just advance the
411*ef5ccd6cSJohn Marino 	 pointer.  */
412*ef5ccd6cSJohn Marino       ++p->arg;
413*ef5ccd6cSJohn Marino     }
414*ef5ccd6cSJohn Marino 
415*ef5ccd6cSJohn Marino   if (*p->arg == '-')
416*ef5ccd6cSJohn Marino     {
417*ef5ccd6cSJohn Marino       got_minus = 1;
418*ef5ccd6cSJohn Marino       ++p->arg;
419*ef5ccd6cSJohn Marino     }
420*ef5ccd6cSJohn Marino 
421*ef5ccd6cSJohn Marino   if (isdigit (*p->arg))
422*ef5ccd6cSJohn Marino     {
423*ef5ccd6cSJohn Marino       /* The value of the displacement.  */
424*ef5ccd6cSJohn Marino       long displacement;
425*ef5ccd6cSJohn Marino 
426*ef5ccd6cSJohn Marino       disp_p = 1;
427*ef5ccd6cSJohn Marino       displacement = strtol (p->arg, (char **) &p->arg, 10);
428*ef5ccd6cSJohn Marino 
429*ef5ccd6cSJohn Marino       /* Generating the expression for the displacement.  */
430*ef5ccd6cSJohn Marino       write_exp_elt_opcode (OP_LONG);
431*ef5ccd6cSJohn Marino       write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
432*ef5ccd6cSJohn Marino       write_exp_elt_longcst (displacement);
433*ef5ccd6cSJohn Marino       write_exp_elt_opcode (OP_LONG);
434*ef5ccd6cSJohn Marino       if (got_minus)
435*ef5ccd6cSJohn Marino 	write_exp_elt_opcode (UNOP_NEG);
436*ef5ccd6cSJohn Marino     }
437*ef5ccd6cSJohn Marino 
438*ef5ccd6cSJohn Marino   /* Getting rid of register indirection prefix.  */
439*ef5ccd6cSJohn Marino   if (reg_ind_prefix
440*ef5ccd6cSJohn Marino       && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)
441*ef5ccd6cSJohn Marino     {
442*ef5ccd6cSJohn Marino       indirect_p = 1;
443*ef5ccd6cSJohn Marino       p->arg += reg_ind_prefix_len;
444*ef5ccd6cSJohn Marino     }
445*ef5ccd6cSJohn Marino 
446*ef5ccd6cSJohn Marino   if (disp_p && !indirect_p)
447*ef5ccd6cSJohn Marino     error (_("Invalid register displacement syntax on expression `%s'."),
448*ef5ccd6cSJohn Marino 	   p->saved_arg);
449*ef5ccd6cSJohn Marino 
450*ef5ccd6cSJohn Marino   /* Getting rid of register prefix.  */
451*ef5ccd6cSJohn Marino   if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
452*ef5ccd6cSJohn Marino     p->arg += reg_prefix_len;
453*ef5ccd6cSJohn Marino 
454*ef5ccd6cSJohn Marino   /* Now we should have only the register name.  Let's extract it and get
455*ef5ccd6cSJohn Marino      the associated number.  */
456*ef5ccd6cSJohn Marino   start = p->arg;
457*ef5ccd6cSJohn Marino 
458*ef5ccd6cSJohn Marino   /* We assume the register name is composed by letters and numbers.  */
459*ef5ccd6cSJohn Marino   while (isalnum (*p->arg))
460*ef5ccd6cSJohn Marino     ++p->arg;
461*ef5ccd6cSJohn Marino 
462*ef5ccd6cSJohn Marino   len = p->arg - start;
463*ef5ccd6cSJohn Marino 
464*ef5ccd6cSJohn Marino   regname = alloca (len + gdb_reg_prefix_len + gdb_reg_suffix_len + 1);
465*ef5ccd6cSJohn Marino   regname[0] = '\0';
466*ef5ccd6cSJohn Marino 
467*ef5ccd6cSJohn Marino   /* We only add the GDB's register prefix/suffix if we are dealing with
468*ef5ccd6cSJohn Marino      a numeric register.  */
469*ef5ccd6cSJohn Marino   if (gdb_reg_prefix && isdigit (*start))
470*ef5ccd6cSJohn Marino     {
471*ef5ccd6cSJohn Marino       strncpy (regname, gdb_reg_prefix, gdb_reg_prefix_len);
472*ef5ccd6cSJohn Marino       strncpy (regname + gdb_reg_prefix_len, start, len);
473*ef5ccd6cSJohn Marino 
474*ef5ccd6cSJohn Marino       if (gdb_reg_suffix)
475*ef5ccd6cSJohn Marino 	strncpy (regname + gdb_reg_prefix_len + len,
476*ef5ccd6cSJohn Marino 		 gdb_reg_suffix, gdb_reg_suffix_len);
477*ef5ccd6cSJohn Marino 
478*ef5ccd6cSJohn Marino       len += gdb_reg_prefix_len + gdb_reg_suffix_len;
479*ef5ccd6cSJohn Marino     }
480*ef5ccd6cSJohn Marino   else
481*ef5ccd6cSJohn Marino     strncpy (regname, start, len);
482*ef5ccd6cSJohn Marino 
483*ef5ccd6cSJohn Marino   regname[len] = '\0';
484*ef5ccd6cSJohn Marino 
485*ef5ccd6cSJohn Marino   /* Is this a valid register name?  */
486*ef5ccd6cSJohn Marino   if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
487*ef5ccd6cSJohn Marino     error (_("Invalid register name `%s' on expression `%s'."),
488*ef5ccd6cSJohn Marino 	   regname, p->saved_arg);
489*ef5ccd6cSJohn Marino 
490*ef5ccd6cSJohn Marino   write_exp_elt_opcode (OP_REGISTER);
491*ef5ccd6cSJohn Marino   str.ptr = regname;
492*ef5ccd6cSJohn Marino   str.length = len;
493*ef5ccd6cSJohn Marino   write_exp_string (str);
494*ef5ccd6cSJohn Marino   write_exp_elt_opcode (OP_REGISTER);
495*ef5ccd6cSJohn Marino 
496*ef5ccd6cSJohn Marino   if (indirect_p)
497*ef5ccd6cSJohn Marino     {
498*ef5ccd6cSJohn Marino       if (disp_p)
499*ef5ccd6cSJohn Marino 	write_exp_elt_opcode (BINOP_ADD);
500*ef5ccd6cSJohn Marino 
501*ef5ccd6cSJohn Marino       /* Casting to the expected type.  */
502*ef5ccd6cSJohn Marino       write_exp_elt_opcode (UNOP_CAST);
503*ef5ccd6cSJohn Marino       write_exp_elt_type (lookup_pointer_type (p->arg_type));
504*ef5ccd6cSJohn Marino       write_exp_elt_opcode (UNOP_CAST);
505*ef5ccd6cSJohn Marino 
506*ef5ccd6cSJohn Marino       write_exp_elt_opcode (UNOP_IND);
507*ef5ccd6cSJohn Marino     }
508*ef5ccd6cSJohn Marino 
509*ef5ccd6cSJohn Marino   /* Getting rid of the register name suffix.  */
510*ef5ccd6cSJohn Marino   if (reg_suffix)
511*ef5ccd6cSJohn Marino     {
512*ef5ccd6cSJohn Marino       if (strncmp (p->arg, reg_suffix, reg_suffix_len) != 0)
513*ef5ccd6cSJohn Marino 	error (_("Missing register name suffix `%s' on expression `%s'."),
514*ef5ccd6cSJohn Marino 	       reg_suffix, p->saved_arg);
515*ef5ccd6cSJohn Marino 
516*ef5ccd6cSJohn Marino       p->arg += reg_suffix_len;
517*ef5ccd6cSJohn Marino     }
518*ef5ccd6cSJohn Marino 
519*ef5ccd6cSJohn Marino   /* Getting rid of the register indirection suffix.  */
520*ef5ccd6cSJohn Marino   if (indirect_p && reg_ind_suffix)
521*ef5ccd6cSJohn Marino     {
522*ef5ccd6cSJohn Marino       if (strncmp (p->arg, reg_ind_suffix, reg_ind_suffix_len) != 0)
523*ef5ccd6cSJohn Marino 	error (_("Missing indirection suffix `%s' on expression `%s'."),
524*ef5ccd6cSJohn Marino 	       reg_ind_suffix, p->saved_arg);
525*ef5ccd6cSJohn Marino 
526*ef5ccd6cSJohn Marino       p->arg += reg_ind_suffix_len;
527*ef5ccd6cSJohn Marino     }
528*ef5ccd6cSJohn Marino }
529*ef5ccd6cSJohn Marino 
530*ef5ccd6cSJohn Marino /* This function is responsible for parsing a single operand.
531*ef5ccd6cSJohn Marino 
532*ef5ccd6cSJohn Marino    A single operand can be:
533*ef5ccd6cSJohn Marino 
534*ef5ccd6cSJohn Marino       - an unary operation (e.g., `-5', `~2', or even with subexpressions
535*ef5ccd6cSJohn Marino         like `-(2 + 1)')
536*ef5ccd6cSJohn Marino       - a register displacement, which will be treated as a register
537*ef5ccd6cSJohn Marino         operand (e.g., `-4(%eax)' on x86)
538*ef5ccd6cSJohn Marino       - a numeric constant, or
539*ef5ccd6cSJohn Marino       - a register operand (see function `stap_parse_register_operand')
540*ef5ccd6cSJohn Marino 
541*ef5ccd6cSJohn Marino    The function also calls special-handling functions to deal with
542*ef5ccd6cSJohn Marino    unrecognized operands, allowing arch-specific parsers to be
543*ef5ccd6cSJohn Marino    created.  */
544*ef5ccd6cSJohn Marino 
545*ef5ccd6cSJohn Marino static void
stap_parse_single_operand(struct stap_parse_info * p)546*ef5ccd6cSJohn Marino stap_parse_single_operand (struct stap_parse_info *p)
547*ef5ccd6cSJohn Marino {
548*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = p->gdbarch;
549*ef5ccd6cSJohn Marino 
550*ef5ccd6cSJohn Marino   /* Prefixes for the parser.  */
551*ef5ccd6cSJohn Marino   const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch);
552*ef5ccd6cSJohn Marino   const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
553*ef5ccd6cSJohn Marino   const char *reg_ind_prefix
554*ef5ccd6cSJohn Marino     = gdbarch_stap_register_indirection_prefix (gdbarch);
555*ef5ccd6cSJohn Marino   int const_prefix_len = const_prefix ? strlen (const_prefix) : 0;
556*ef5ccd6cSJohn Marino   int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
557*ef5ccd6cSJohn Marino   int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
558*ef5ccd6cSJohn Marino 
559*ef5ccd6cSJohn Marino   /* Suffixes for the parser.  */
560*ef5ccd6cSJohn Marino   const char *const_suffix = gdbarch_stap_integer_suffix (gdbarch);
561*ef5ccd6cSJohn Marino   int const_suffix_len = const_suffix ? strlen (const_suffix) : 0;
562*ef5ccd6cSJohn Marino 
563*ef5ccd6cSJohn Marino   /* We first try to parse this token as a "special token".  */
564*ef5ccd6cSJohn Marino   if (gdbarch_stap_parse_special_token_p (gdbarch))
565*ef5ccd6cSJohn Marino     {
566*ef5ccd6cSJohn Marino       int ret = gdbarch_stap_parse_special_token (gdbarch, p);
567*ef5ccd6cSJohn Marino 
568*ef5ccd6cSJohn Marino       if (ret)
569*ef5ccd6cSJohn Marino 	{
570*ef5ccd6cSJohn Marino 	  /* If the return value of the above function is not zero,
571*ef5ccd6cSJohn Marino 	     it means it successfully parsed the special token.
572*ef5ccd6cSJohn Marino 
573*ef5ccd6cSJohn Marino 	     If it is NULL, we try to parse it using our method.  */
574*ef5ccd6cSJohn Marino 	  return;
575*ef5ccd6cSJohn Marino 	}
576*ef5ccd6cSJohn Marino     }
577*ef5ccd6cSJohn Marino 
578*ef5ccd6cSJohn Marino   if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+')
579*ef5ccd6cSJohn Marino     {
580*ef5ccd6cSJohn Marino       char c = *p->arg;
581*ef5ccd6cSJohn Marino       int number;
582*ef5ccd6cSJohn Marino 
583*ef5ccd6cSJohn Marino       /* We use this variable to do a lookahead.  */
584*ef5ccd6cSJohn Marino       const char *tmp = p->arg;
585*ef5ccd6cSJohn Marino 
586*ef5ccd6cSJohn Marino       ++tmp;
587*ef5ccd6cSJohn Marino 
588*ef5ccd6cSJohn Marino       /* This is an unary operation.  Here is a list of allowed tokens
589*ef5ccd6cSJohn Marino 	 here:
590*ef5ccd6cSJohn Marino 
591*ef5ccd6cSJohn Marino 	 - numeric literal;
592*ef5ccd6cSJohn Marino 	 - number (from register displacement)
593*ef5ccd6cSJohn Marino 	 - subexpression (beginning with `(')
594*ef5ccd6cSJohn Marino 
595*ef5ccd6cSJohn Marino 	 We handle the register displacement here, and the other cases
596*ef5ccd6cSJohn Marino 	 recursively.  */
597*ef5ccd6cSJohn Marino       if (p->inside_paren_p)
598*ef5ccd6cSJohn Marino 	tmp = skip_spaces_const (tmp);
599*ef5ccd6cSJohn Marino 
600*ef5ccd6cSJohn Marino       if (isdigit (*tmp))
601*ef5ccd6cSJohn Marino 	number = strtol (tmp, (char **) &tmp, 10);
602*ef5ccd6cSJohn Marino 
603*ef5ccd6cSJohn Marino       if (!reg_ind_prefix
604*ef5ccd6cSJohn Marino 	  || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
605*ef5ccd6cSJohn Marino 	{
606*ef5ccd6cSJohn Marino 	  /* This is not a displacement.  We skip the operator, and deal
607*ef5ccd6cSJohn Marino 	     with it later.  */
608*ef5ccd6cSJohn Marino 	  ++p->arg;
609*ef5ccd6cSJohn Marino 	  stap_parse_argument_conditionally (p);
610*ef5ccd6cSJohn Marino 	  if (c == '-')
611*ef5ccd6cSJohn Marino 	    write_exp_elt_opcode (UNOP_NEG);
612*ef5ccd6cSJohn Marino 	  else if (c == '~')
613*ef5ccd6cSJohn Marino 	    write_exp_elt_opcode (UNOP_COMPLEMENT);
614*ef5ccd6cSJohn Marino 	}
615*ef5ccd6cSJohn Marino       else
616*ef5ccd6cSJohn Marino 	{
617*ef5ccd6cSJohn Marino 	  /* If we are here, it means it is a displacement.  The only
618*ef5ccd6cSJohn Marino 	     operations allowed here are `-' and `+'.  */
619*ef5ccd6cSJohn Marino 	  if (c == '~')
620*ef5ccd6cSJohn Marino 	    error (_("Invalid operator `%c' for register displacement "
621*ef5ccd6cSJohn Marino 		     "on expression `%s'."), c, p->saved_arg);
622*ef5ccd6cSJohn Marino 
623*ef5ccd6cSJohn Marino 	  stap_parse_register_operand (p);
624*ef5ccd6cSJohn Marino 	}
625*ef5ccd6cSJohn Marino     }
626*ef5ccd6cSJohn Marino   else if (isdigit (*p->arg))
627*ef5ccd6cSJohn Marino     {
628*ef5ccd6cSJohn Marino       /* A temporary variable, needed for lookahead.  */
629*ef5ccd6cSJohn Marino       const char *tmp = p->arg;
630*ef5ccd6cSJohn Marino       long number;
631*ef5ccd6cSJohn Marino 
632*ef5ccd6cSJohn Marino       /* We can be dealing with a numeric constant (if `const_prefix' is
633*ef5ccd6cSJohn Marino 	 NULL), or with a register displacement.  */
634*ef5ccd6cSJohn Marino       number = strtol (tmp, (char **) &tmp, 10);
635*ef5ccd6cSJohn Marino 
636*ef5ccd6cSJohn Marino       if (p->inside_paren_p)
637*ef5ccd6cSJohn Marino 	tmp = skip_spaces_const (tmp);
638*ef5ccd6cSJohn Marino       if (!const_prefix && reg_ind_prefix
639*ef5ccd6cSJohn Marino 	  && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
640*ef5ccd6cSJohn Marino 	{
641*ef5ccd6cSJohn Marino 	  /* We are dealing with a numeric constant.  */
642*ef5ccd6cSJohn Marino 	  write_exp_elt_opcode (OP_LONG);
643*ef5ccd6cSJohn Marino 	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
644*ef5ccd6cSJohn Marino 	  write_exp_elt_longcst (number);
645*ef5ccd6cSJohn Marino 	  write_exp_elt_opcode (OP_LONG);
646*ef5ccd6cSJohn Marino 
647*ef5ccd6cSJohn Marino 	  p->arg = tmp;
648*ef5ccd6cSJohn Marino 
649*ef5ccd6cSJohn Marino 	  if (const_suffix)
650*ef5ccd6cSJohn Marino 	    {
651*ef5ccd6cSJohn Marino 	      if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
652*ef5ccd6cSJohn Marino 		p->arg += const_suffix_len;
653*ef5ccd6cSJohn Marino 	      else
654*ef5ccd6cSJohn Marino 		error (_("Invalid constant suffix on expression `%s'."),
655*ef5ccd6cSJohn Marino 		       p->saved_arg);
656*ef5ccd6cSJohn Marino 	    }
657*ef5ccd6cSJohn Marino 	}
658*ef5ccd6cSJohn Marino       else if (reg_ind_prefix
659*ef5ccd6cSJohn Marino 	       && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0)
660*ef5ccd6cSJohn Marino 	stap_parse_register_operand (p);
661*ef5ccd6cSJohn Marino       else
662*ef5ccd6cSJohn Marino 	error (_("Unknown numeric token on expression `%s'."),
663*ef5ccd6cSJohn Marino 	       p->saved_arg);
664*ef5ccd6cSJohn Marino     }
665*ef5ccd6cSJohn Marino   else if (const_prefix
666*ef5ccd6cSJohn Marino 	   && strncmp (p->arg, const_prefix, const_prefix_len) == 0)
667*ef5ccd6cSJohn Marino     {
668*ef5ccd6cSJohn Marino       /* We are dealing with a numeric constant.  */
669*ef5ccd6cSJohn Marino       long number;
670*ef5ccd6cSJohn Marino 
671*ef5ccd6cSJohn Marino       p->arg += const_prefix_len;
672*ef5ccd6cSJohn Marino       number = strtol (p->arg, (char **) &p->arg, 10);
673*ef5ccd6cSJohn Marino 
674*ef5ccd6cSJohn Marino       write_exp_elt_opcode (OP_LONG);
675*ef5ccd6cSJohn Marino       write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
676*ef5ccd6cSJohn Marino       write_exp_elt_longcst (number);
677*ef5ccd6cSJohn Marino       write_exp_elt_opcode (OP_LONG);
678*ef5ccd6cSJohn Marino 
679*ef5ccd6cSJohn Marino       if (const_suffix)
680*ef5ccd6cSJohn Marino 	{
681*ef5ccd6cSJohn Marino 	  if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
682*ef5ccd6cSJohn Marino 	    p->arg += const_suffix_len;
683*ef5ccd6cSJohn Marino 	  else
684*ef5ccd6cSJohn Marino 	    error (_("Invalid constant suffix on expression `%s'."),
685*ef5ccd6cSJohn Marino 		   p->saved_arg);
686*ef5ccd6cSJohn Marino 	}
687*ef5ccd6cSJohn Marino     }
688*ef5ccd6cSJohn Marino   else if ((reg_prefix
689*ef5ccd6cSJohn Marino 	    && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
690*ef5ccd6cSJohn Marino 	   || (reg_ind_prefix
691*ef5ccd6cSJohn Marino 	       && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0))
692*ef5ccd6cSJohn Marino     stap_parse_register_operand (p);
693*ef5ccd6cSJohn Marino   else
694*ef5ccd6cSJohn Marino     error (_("Operator `%c' not recognized on expression `%s'."),
695*ef5ccd6cSJohn Marino 	   *p->arg, p->saved_arg);
696*ef5ccd6cSJohn Marino }
697*ef5ccd6cSJohn Marino 
698*ef5ccd6cSJohn Marino /* This function parses an argument conditionally, based on single or
699*ef5ccd6cSJohn Marino    non-single operands.  A non-single operand would be a parenthesized
700*ef5ccd6cSJohn Marino    expression (e.g., `(2 + 1)'), and a single operand is anything that
701*ef5ccd6cSJohn Marino    starts with `-', `~', `+' (i.e., unary operators), a digit, or
702*ef5ccd6cSJohn Marino    something recognized by `gdbarch_stap_is_single_operand'.  */
703*ef5ccd6cSJohn Marino 
704*ef5ccd6cSJohn Marino static void
stap_parse_argument_conditionally(struct stap_parse_info * p)705*ef5ccd6cSJohn Marino stap_parse_argument_conditionally (struct stap_parse_info *p)
706*ef5ccd6cSJohn Marino {
707*ef5ccd6cSJohn Marino   if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary.  */
708*ef5ccd6cSJohn Marino       || isdigit (*p->arg)
709*ef5ccd6cSJohn Marino       || gdbarch_stap_is_single_operand (p->gdbarch, p->arg))
710*ef5ccd6cSJohn Marino     stap_parse_single_operand (p);
711*ef5ccd6cSJohn Marino   else if (*p->arg == '(')
712*ef5ccd6cSJohn Marino     {
713*ef5ccd6cSJohn Marino       /* We are dealing with a parenthesized operand.  It means we
714*ef5ccd6cSJohn Marino 	 have to parse it as it was a separate expression, without
715*ef5ccd6cSJohn Marino 	 left-side or precedence.  */
716*ef5ccd6cSJohn Marino       ++p->arg;
717*ef5ccd6cSJohn Marino       p->arg = skip_spaces_const (p->arg);
718*ef5ccd6cSJohn Marino       ++p->inside_paren_p;
719*ef5ccd6cSJohn Marino 
720*ef5ccd6cSJohn Marino       stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE);
721*ef5ccd6cSJohn Marino 
722*ef5ccd6cSJohn Marino       --p->inside_paren_p;
723*ef5ccd6cSJohn Marino       if (*p->arg != ')')
724*ef5ccd6cSJohn Marino 	error (_("Missign close-paren on expression `%s'."),
725*ef5ccd6cSJohn Marino 	       p->saved_arg);
726*ef5ccd6cSJohn Marino 
727*ef5ccd6cSJohn Marino       ++p->arg;
728*ef5ccd6cSJohn Marino       if (p->inside_paren_p)
729*ef5ccd6cSJohn Marino 	p->arg = skip_spaces_const (p->arg);
730*ef5ccd6cSJohn Marino     }
731*ef5ccd6cSJohn Marino   else
732*ef5ccd6cSJohn Marino     error (_("Cannot parse expression `%s'."), p->saved_arg);
733*ef5ccd6cSJohn Marino }
734*ef5ccd6cSJohn Marino 
735*ef5ccd6cSJohn Marino /* Helper function for `stap_parse_argument'.  Please, see its comments to
736*ef5ccd6cSJohn Marino    better understand what this function does.  */
737*ef5ccd6cSJohn Marino 
738*ef5ccd6cSJohn Marino static void
stap_parse_argument_1(struct stap_parse_info * p,int has_lhs,enum stap_operand_prec prec)739*ef5ccd6cSJohn Marino stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
740*ef5ccd6cSJohn Marino 		       enum stap_operand_prec prec)
741*ef5ccd6cSJohn Marino {
742*ef5ccd6cSJohn Marino   /* This is an operator-precedence parser.
743*ef5ccd6cSJohn Marino 
744*ef5ccd6cSJohn Marino      We work with left- and right-sides of expressions, and
745*ef5ccd6cSJohn Marino      parse them depending on the precedence of the operators
746*ef5ccd6cSJohn Marino      we find.  */
747*ef5ccd6cSJohn Marino 
748*ef5ccd6cSJohn Marino   if (p->inside_paren_p)
749*ef5ccd6cSJohn Marino     p->arg = skip_spaces_const (p->arg);
750*ef5ccd6cSJohn Marino 
751*ef5ccd6cSJohn Marino   if (!has_lhs)
752*ef5ccd6cSJohn Marino     {
753*ef5ccd6cSJohn Marino       /* We were called without a left-side, either because this is the
754*ef5ccd6cSJohn Marino 	 first call, or because we were called to parse a parenthesized
755*ef5ccd6cSJohn Marino 	 expression.  It doesn't really matter; we have to parse the
756*ef5ccd6cSJohn Marino 	 left-side in order to continue the process.  */
757*ef5ccd6cSJohn Marino       stap_parse_argument_conditionally (p);
758*ef5ccd6cSJohn Marino     }
759*ef5ccd6cSJohn Marino 
760*ef5ccd6cSJohn Marino   /* Start to parse the right-side, and to "join" left and right sides
761*ef5ccd6cSJohn Marino      depending on the operation specified.
762*ef5ccd6cSJohn Marino 
763*ef5ccd6cSJohn Marino      This loop shall continue until we run out of characters in the input,
764*ef5ccd6cSJohn Marino      or until we find a close-parenthesis, which means that we've reached
765*ef5ccd6cSJohn Marino      the end of a sub-expression.  */
766*ef5ccd6cSJohn Marino   while (p->arg && *p->arg && *p->arg != ')' && !isspace (*p->arg))
767*ef5ccd6cSJohn Marino     {
768*ef5ccd6cSJohn Marino       const char *tmp_exp_buf;
769*ef5ccd6cSJohn Marino       enum exp_opcode opcode;
770*ef5ccd6cSJohn Marino       enum stap_operand_prec cur_prec;
771*ef5ccd6cSJohn Marino 
772*ef5ccd6cSJohn Marino       if (!stap_is_operator (p->arg))
773*ef5ccd6cSJohn Marino 	error (_("Invalid operator `%c' on expression `%s'."), *p->arg,
774*ef5ccd6cSJohn Marino 	       p->saved_arg);
775*ef5ccd6cSJohn Marino 
776*ef5ccd6cSJohn Marino       /* We have to save the current value of the expression buffer because
777*ef5ccd6cSJohn Marino 	 the `stap_get_opcode' modifies it in order to get the current
778*ef5ccd6cSJohn Marino 	 operator.  If this operator's precedence is lower than PREC, we
779*ef5ccd6cSJohn Marino 	 should return and not advance the expression buffer pointer.  */
780*ef5ccd6cSJohn Marino       tmp_exp_buf = p->arg;
781*ef5ccd6cSJohn Marino       opcode = stap_get_opcode (&tmp_exp_buf);
782*ef5ccd6cSJohn Marino 
783*ef5ccd6cSJohn Marino       cur_prec = stap_get_operator_prec (opcode);
784*ef5ccd6cSJohn Marino       if (cur_prec < prec)
785*ef5ccd6cSJohn Marino 	{
786*ef5ccd6cSJohn Marino 	  /* If the precedence of the operator that we are seeing now is
787*ef5ccd6cSJohn Marino 	     lower than the precedence of the first operator seen before
788*ef5ccd6cSJohn Marino 	     this parsing process began, it means we should stop parsing
789*ef5ccd6cSJohn Marino 	     and return.  */
790*ef5ccd6cSJohn Marino 	  break;
791*ef5ccd6cSJohn Marino 	}
792*ef5ccd6cSJohn Marino 
793*ef5ccd6cSJohn Marino       p->arg = tmp_exp_buf;
794*ef5ccd6cSJohn Marino       if (p->inside_paren_p)
795*ef5ccd6cSJohn Marino 	p->arg = skip_spaces_const (p->arg);
796*ef5ccd6cSJohn Marino 
797*ef5ccd6cSJohn Marino       /* Parse the right-side of the expression.  */
798*ef5ccd6cSJohn Marino       stap_parse_argument_conditionally (p);
799*ef5ccd6cSJohn Marino 
800*ef5ccd6cSJohn Marino       /* While we still have operators, try to parse another
801*ef5ccd6cSJohn Marino 	 right-side, but using the current right-side as a left-side.  */
802*ef5ccd6cSJohn Marino       while (*p->arg && stap_is_operator (p->arg))
803*ef5ccd6cSJohn Marino 	{
804*ef5ccd6cSJohn Marino 	  enum exp_opcode lookahead_opcode;
805*ef5ccd6cSJohn Marino 	  enum stap_operand_prec lookahead_prec;
806*ef5ccd6cSJohn Marino 
807*ef5ccd6cSJohn Marino 	  /* Saving the current expression buffer position.  The explanation
808*ef5ccd6cSJohn Marino 	     is the same as above.  */
809*ef5ccd6cSJohn Marino 	  tmp_exp_buf = p->arg;
810*ef5ccd6cSJohn Marino 	  lookahead_opcode = stap_get_opcode (&tmp_exp_buf);
811*ef5ccd6cSJohn Marino 	  lookahead_prec = stap_get_operator_prec (lookahead_opcode);
812*ef5ccd6cSJohn Marino 
813*ef5ccd6cSJohn Marino 	  if (lookahead_prec <= prec)
814*ef5ccd6cSJohn Marino 	    {
815*ef5ccd6cSJohn Marino 	      /* If we are dealing with an operator whose precedence is lower
816*ef5ccd6cSJohn Marino 		 than the first one, just abandon the attempt.  */
817*ef5ccd6cSJohn Marino 	      break;
818*ef5ccd6cSJohn Marino 	    }
819*ef5ccd6cSJohn Marino 
820*ef5ccd6cSJohn Marino 	  /* Parse the right-side of the expression, but since we already
821*ef5ccd6cSJohn Marino 	     have a left-side at this point, set `has_lhs' to 1.  */
822*ef5ccd6cSJohn Marino 	  stap_parse_argument_1 (p, 1, lookahead_prec);
823*ef5ccd6cSJohn Marino 	}
824*ef5ccd6cSJohn Marino 
825*ef5ccd6cSJohn Marino       write_exp_elt_opcode (opcode);
826*ef5ccd6cSJohn Marino     }
827*ef5ccd6cSJohn Marino }
828*ef5ccd6cSJohn Marino 
829*ef5ccd6cSJohn Marino /* Parse a probe's argument.
830*ef5ccd6cSJohn Marino 
831*ef5ccd6cSJohn Marino    Assuming that:
832*ef5ccd6cSJohn Marino 
833*ef5ccd6cSJohn Marino    LP = literal integer prefix
834*ef5ccd6cSJohn Marino    LS = literal integer suffix
835*ef5ccd6cSJohn Marino 
836*ef5ccd6cSJohn Marino    RP = register prefix
837*ef5ccd6cSJohn Marino    RS = register suffix
838*ef5ccd6cSJohn Marino 
839*ef5ccd6cSJohn Marino    RIP = register indirection prefix
840*ef5ccd6cSJohn Marino    RIS = register indirection suffix
841*ef5ccd6cSJohn Marino 
842*ef5ccd6cSJohn Marino    This routine assumes that arguments' tokens are of the form:
843*ef5ccd6cSJohn Marino 
844*ef5ccd6cSJohn Marino    - [LP] NUMBER [LS]
845*ef5ccd6cSJohn Marino    - [RP] REGISTER [RS]
846*ef5ccd6cSJohn Marino    - [RIP] [RP] REGISTER [RS] [RIS]
847*ef5ccd6cSJohn Marino    - If we find a number without LP, we try to parse it as a literal integer
848*ef5ccd6cSJohn Marino    constant (if LP == NULL), or as a register displacement.
849*ef5ccd6cSJohn Marino    - We count parenthesis, and only skip whitespaces if we are inside them.
850*ef5ccd6cSJohn Marino    - If we find an operator, we skip it.
851*ef5ccd6cSJohn Marino 
852*ef5ccd6cSJohn Marino    This function can also call a special function that will try to match
853*ef5ccd6cSJohn Marino    unknown tokens.  It will return 1 if the argument has been parsed
854*ef5ccd6cSJohn Marino    successfully, or zero otherwise.  */
855*ef5ccd6cSJohn Marino 
856*ef5ccd6cSJohn Marino static struct expression *
stap_parse_argument(const char ** arg,struct type * atype,struct gdbarch * gdbarch)857*ef5ccd6cSJohn Marino stap_parse_argument (const char **arg, struct type *atype,
858*ef5ccd6cSJohn Marino 		     struct gdbarch *gdbarch)
859*ef5ccd6cSJohn Marino {
860*ef5ccd6cSJohn Marino   struct stap_parse_info p;
861*ef5ccd6cSJohn Marino   struct cleanup *back_to;
862*ef5ccd6cSJohn Marino 
863*ef5ccd6cSJohn Marino   /* We need to initialize the expression buffer, in order to begin
864*ef5ccd6cSJohn Marino      our parsing efforts.  The language here does not matter, since we
865*ef5ccd6cSJohn Marino      are using our own parser.  */
866*ef5ccd6cSJohn Marino   initialize_expout (10, current_language, gdbarch);
867*ef5ccd6cSJohn Marino   back_to = make_cleanup (free_current_contents, &expout);
868*ef5ccd6cSJohn Marino 
869*ef5ccd6cSJohn Marino   p.saved_arg = *arg;
870*ef5ccd6cSJohn Marino   p.arg = *arg;
871*ef5ccd6cSJohn Marino   p.arg_type = atype;
872*ef5ccd6cSJohn Marino   p.gdbarch = gdbarch;
873*ef5ccd6cSJohn Marino   p.inside_paren_p = 0;
874*ef5ccd6cSJohn Marino 
875*ef5ccd6cSJohn Marino   stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE);
876*ef5ccd6cSJohn Marino 
877*ef5ccd6cSJohn Marino   discard_cleanups (back_to);
878*ef5ccd6cSJohn Marino 
879*ef5ccd6cSJohn Marino   gdb_assert (p.inside_paren_p == 0);
880*ef5ccd6cSJohn Marino 
881*ef5ccd6cSJohn Marino   /* Casting the final expression to the appropriate type.  */
882*ef5ccd6cSJohn Marino   write_exp_elt_opcode (UNOP_CAST);
883*ef5ccd6cSJohn Marino   write_exp_elt_type (atype);
884*ef5ccd6cSJohn Marino   write_exp_elt_opcode (UNOP_CAST);
885*ef5ccd6cSJohn Marino 
886*ef5ccd6cSJohn Marino   reallocate_expout ();
887*ef5ccd6cSJohn Marino 
888*ef5ccd6cSJohn Marino   p.arg = skip_spaces_const (p.arg);
889*ef5ccd6cSJohn Marino   *arg = p.arg;
890*ef5ccd6cSJohn Marino 
891*ef5ccd6cSJohn Marino   return expout;
892*ef5ccd6cSJohn Marino }
893*ef5ccd6cSJohn Marino 
894*ef5ccd6cSJohn Marino /* Function which parses an argument string from PROBE, correctly splitting
895*ef5ccd6cSJohn Marino    the arguments and storing their information in properly ways.
896*ef5ccd6cSJohn Marino 
897*ef5ccd6cSJohn Marino    Consider the following argument string (x86 syntax):
898*ef5ccd6cSJohn Marino 
899*ef5ccd6cSJohn Marino    `4@%eax 4@$10'
900*ef5ccd6cSJohn Marino 
901*ef5ccd6cSJohn Marino    We have two arguments, `%eax' and `$10', both with 32-bit unsigned bitness.
902*ef5ccd6cSJohn Marino    This function basically handles them, properly filling some structures with
903*ef5ccd6cSJohn Marino    this information.  */
904*ef5ccd6cSJohn Marino 
905*ef5ccd6cSJohn Marino static void
stap_parse_probe_arguments(struct stap_probe * probe)906*ef5ccd6cSJohn Marino stap_parse_probe_arguments (struct stap_probe *probe)
907*ef5ccd6cSJohn Marino {
908*ef5ccd6cSJohn Marino   const char *cur;
909*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = get_objfile_arch (probe->p.objfile);
910*ef5ccd6cSJohn Marino 
911*ef5ccd6cSJohn Marino   gdb_assert (!probe->args_parsed);
912*ef5ccd6cSJohn Marino   cur = probe->args_u.text;
913*ef5ccd6cSJohn Marino   probe->args_parsed = 1;
914*ef5ccd6cSJohn Marino   probe->args_u.vec = NULL;
915*ef5ccd6cSJohn Marino 
916*ef5ccd6cSJohn Marino   if (!cur || !*cur || *cur == ':')
917*ef5ccd6cSJohn Marino     return;
918*ef5ccd6cSJohn Marino 
919*ef5ccd6cSJohn Marino   while (*cur)
920*ef5ccd6cSJohn Marino     {
921*ef5ccd6cSJohn Marino       struct stap_probe_arg arg;
922*ef5ccd6cSJohn Marino       enum stap_arg_bitness b;
923*ef5ccd6cSJohn Marino       int got_minus = 0;
924*ef5ccd6cSJohn Marino       struct expression *expr;
925*ef5ccd6cSJohn Marino 
926*ef5ccd6cSJohn Marino       memset (&arg, 0, sizeof (arg));
927*ef5ccd6cSJohn Marino 
928*ef5ccd6cSJohn Marino       /* We expect to find something like:
929*ef5ccd6cSJohn Marino 
930*ef5ccd6cSJohn Marino 	 N@OP
931*ef5ccd6cSJohn Marino 
932*ef5ccd6cSJohn Marino 	 Where `N' can be [+,-][4,8].  This is not mandatory, so
933*ef5ccd6cSJohn Marino 	 we check it here.  If we don't find it, go to the next
934*ef5ccd6cSJohn Marino 	 state.  */
935*ef5ccd6cSJohn Marino       if ((*cur == '-' && cur[1] && cur[2] != '@')
936*ef5ccd6cSJohn Marino 	  && cur[1] != '@')
937*ef5ccd6cSJohn Marino 	arg.bitness = STAP_ARG_BITNESS_UNDEFINED;
938*ef5ccd6cSJohn Marino       else
939*ef5ccd6cSJohn Marino 	{
940*ef5ccd6cSJohn Marino 	  if (*cur == '-')
941*ef5ccd6cSJohn Marino 	    {
942*ef5ccd6cSJohn Marino 	      /* Discard the `-'.  */
943*ef5ccd6cSJohn Marino 	      ++cur;
944*ef5ccd6cSJohn Marino 	      got_minus = 1;
945*ef5ccd6cSJohn Marino 	    }
946*ef5ccd6cSJohn Marino 
947*ef5ccd6cSJohn Marino 	  if (*cur == '4')
948*ef5ccd6cSJohn Marino 	    b = (got_minus ? STAP_ARG_BITNESS_32BIT_SIGNED
949*ef5ccd6cSJohn Marino 		 : STAP_ARG_BITNESS_32BIT_UNSIGNED);
950*ef5ccd6cSJohn Marino 	  else if (*cur == '8')
951*ef5ccd6cSJohn Marino 	    b = (got_minus ? STAP_ARG_BITNESS_64BIT_SIGNED
952*ef5ccd6cSJohn Marino 		 : STAP_ARG_BITNESS_64BIT_UNSIGNED);
953*ef5ccd6cSJohn Marino 	  else
954*ef5ccd6cSJohn Marino 	    {
955*ef5ccd6cSJohn Marino 	      /* We have an error, because we don't expect anything
956*ef5ccd6cSJohn Marino 		 except 4 and 8.  */
957*ef5ccd6cSJohn Marino 	      complaint (&symfile_complaints,
958*ef5ccd6cSJohn Marino 			 _("unrecognized bitness `%c' for probe `%s'"),
959*ef5ccd6cSJohn Marino 			 *cur, probe->p.name);
960*ef5ccd6cSJohn Marino 	      return;
961*ef5ccd6cSJohn Marino 	    }
962*ef5ccd6cSJohn Marino 
963*ef5ccd6cSJohn Marino 	  arg.bitness = b;
964*ef5ccd6cSJohn Marino 	  arg.atype = stap_get_expected_argument_type (gdbarch, b);
965*ef5ccd6cSJohn Marino 
966*ef5ccd6cSJohn Marino 	  /* Discard the number and the `@' sign.  */
967*ef5ccd6cSJohn Marino 	  cur += 2;
968*ef5ccd6cSJohn Marino 	}
969*ef5ccd6cSJohn Marino 
970*ef5ccd6cSJohn Marino       expr = stap_parse_argument (&cur, arg.atype, gdbarch);
971*ef5ccd6cSJohn Marino 
972*ef5ccd6cSJohn Marino       if (stap_expression_debug)
973*ef5ccd6cSJohn Marino 	dump_raw_expression (expr, gdb_stdlog,
974*ef5ccd6cSJohn Marino 			     "before conversion to prefix form");
975*ef5ccd6cSJohn Marino 
976*ef5ccd6cSJohn Marino       prefixify_expression (expr);
977*ef5ccd6cSJohn Marino 
978*ef5ccd6cSJohn Marino       if (stap_expression_debug)
979*ef5ccd6cSJohn Marino 	dump_prefix_expression (expr, gdb_stdlog);
980*ef5ccd6cSJohn Marino 
981*ef5ccd6cSJohn Marino       arg.aexpr = expr;
982*ef5ccd6cSJohn Marino 
983*ef5ccd6cSJohn Marino       /* Start it over again.  */
984*ef5ccd6cSJohn Marino       cur = skip_spaces_const (cur);
985*ef5ccd6cSJohn Marino 
986*ef5ccd6cSJohn Marino       VEC_safe_push (stap_probe_arg_s, probe->args_u.vec, &arg);
987*ef5ccd6cSJohn Marino     }
988*ef5ccd6cSJohn Marino }
989*ef5ccd6cSJohn Marino 
990*ef5ccd6cSJohn Marino /* Given PROBE, returns the number of arguments present in that probe's
991*ef5ccd6cSJohn Marino    argument string.  */
992*ef5ccd6cSJohn Marino 
993*ef5ccd6cSJohn Marino static unsigned
stap_get_probe_argument_count(struct probe * probe_generic)994*ef5ccd6cSJohn Marino stap_get_probe_argument_count (struct probe *probe_generic)
995*ef5ccd6cSJohn Marino {
996*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
997*ef5ccd6cSJohn Marino 
998*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
999*ef5ccd6cSJohn Marino 
1000*ef5ccd6cSJohn Marino   if (!probe->args_parsed)
1001*ef5ccd6cSJohn Marino     stap_parse_probe_arguments (probe);
1002*ef5ccd6cSJohn Marino 
1003*ef5ccd6cSJohn Marino   gdb_assert (probe->args_parsed);
1004*ef5ccd6cSJohn Marino   return VEC_length (stap_probe_arg_s, probe->args_u.vec);
1005*ef5ccd6cSJohn Marino }
1006*ef5ccd6cSJohn Marino 
1007*ef5ccd6cSJohn Marino /* Return 1 if OP is a valid operator inside a probe argument, or zero
1008*ef5ccd6cSJohn Marino    otherwise.  */
1009*ef5ccd6cSJohn Marino 
1010*ef5ccd6cSJohn Marino static int
stap_is_operator(const char * op)1011*ef5ccd6cSJohn Marino stap_is_operator (const char *op)
1012*ef5ccd6cSJohn Marino {
1013*ef5ccd6cSJohn Marino   int ret = 1;
1014*ef5ccd6cSJohn Marino 
1015*ef5ccd6cSJohn Marino   switch (*op)
1016*ef5ccd6cSJohn Marino     {
1017*ef5ccd6cSJohn Marino     case '*':
1018*ef5ccd6cSJohn Marino     case '/':
1019*ef5ccd6cSJohn Marino     case '%':
1020*ef5ccd6cSJohn Marino     case '^':
1021*ef5ccd6cSJohn Marino     case '!':
1022*ef5ccd6cSJohn Marino     case '+':
1023*ef5ccd6cSJohn Marino     case '-':
1024*ef5ccd6cSJohn Marino     case '<':
1025*ef5ccd6cSJohn Marino     case '>':
1026*ef5ccd6cSJohn Marino     case '|':
1027*ef5ccd6cSJohn Marino     case '&':
1028*ef5ccd6cSJohn Marino       break;
1029*ef5ccd6cSJohn Marino 
1030*ef5ccd6cSJohn Marino     case '=':
1031*ef5ccd6cSJohn Marino       if (op[1] != '=')
1032*ef5ccd6cSJohn Marino 	ret = 0;
1033*ef5ccd6cSJohn Marino       break;
1034*ef5ccd6cSJohn Marino 
1035*ef5ccd6cSJohn Marino     default:
1036*ef5ccd6cSJohn Marino       /* We didn't find any operator.  */
1037*ef5ccd6cSJohn Marino       ret = 0;
1038*ef5ccd6cSJohn Marino     }
1039*ef5ccd6cSJohn Marino 
1040*ef5ccd6cSJohn Marino   return ret;
1041*ef5ccd6cSJohn Marino }
1042*ef5ccd6cSJohn Marino 
1043*ef5ccd6cSJohn Marino static struct stap_probe_arg *
stap_get_arg(struct stap_probe * probe,unsigned n)1044*ef5ccd6cSJohn Marino stap_get_arg (struct stap_probe *probe, unsigned n)
1045*ef5ccd6cSJohn Marino {
1046*ef5ccd6cSJohn Marino   if (!probe->args_parsed)
1047*ef5ccd6cSJohn Marino     stap_parse_probe_arguments (probe);
1048*ef5ccd6cSJohn Marino 
1049*ef5ccd6cSJohn Marino   return VEC_index (stap_probe_arg_s, probe->args_u.vec, n);
1050*ef5ccd6cSJohn Marino }
1051*ef5ccd6cSJohn Marino 
1052*ef5ccd6cSJohn Marino /* Evaluate the probe's argument N (indexed from 0), returning a value
1053*ef5ccd6cSJohn Marino    corresponding to it.  Assertion is thrown if N does not exist.  */
1054*ef5ccd6cSJohn Marino 
1055*ef5ccd6cSJohn Marino static struct value *
stap_evaluate_probe_argument(struct probe * probe_generic,unsigned n)1056*ef5ccd6cSJohn Marino stap_evaluate_probe_argument (struct probe *probe_generic, unsigned n)
1057*ef5ccd6cSJohn Marino {
1058*ef5ccd6cSJohn Marino   struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
1059*ef5ccd6cSJohn Marino   struct stap_probe_arg *arg;
1060*ef5ccd6cSJohn Marino   int pos = 0;
1061*ef5ccd6cSJohn Marino 
1062*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1063*ef5ccd6cSJohn Marino 
1064*ef5ccd6cSJohn Marino   arg = stap_get_arg (stap_probe, n);
1065*ef5ccd6cSJohn Marino   return evaluate_subexp_standard (arg->atype, arg->aexpr, &pos, EVAL_NORMAL);
1066*ef5ccd6cSJohn Marino }
1067*ef5ccd6cSJohn Marino 
1068*ef5ccd6cSJohn Marino /* Compile the probe's argument N (indexed from 0) to agent expression.
1069*ef5ccd6cSJohn Marino    Assertion is thrown if N does not exist.  */
1070*ef5ccd6cSJohn Marino 
1071*ef5ccd6cSJohn Marino static void
stap_compile_to_ax(struct probe * probe_generic,struct agent_expr * expr,struct axs_value * value,unsigned n)1072*ef5ccd6cSJohn Marino stap_compile_to_ax (struct probe *probe_generic, struct agent_expr *expr,
1073*ef5ccd6cSJohn Marino 		    struct axs_value *value, unsigned n)
1074*ef5ccd6cSJohn Marino {
1075*ef5ccd6cSJohn Marino   struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
1076*ef5ccd6cSJohn Marino   struct stap_probe_arg *arg;
1077*ef5ccd6cSJohn Marino   union exp_element *pc;
1078*ef5ccd6cSJohn Marino 
1079*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1080*ef5ccd6cSJohn Marino 
1081*ef5ccd6cSJohn Marino   arg = stap_get_arg (stap_probe, n);
1082*ef5ccd6cSJohn Marino 
1083*ef5ccd6cSJohn Marino   pc = arg->aexpr->elts;
1084*ef5ccd6cSJohn Marino   gen_expr (arg->aexpr, &pc, expr, value);
1085*ef5ccd6cSJohn Marino 
1086*ef5ccd6cSJohn Marino   require_rvalue (expr, value);
1087*ef5ccd6cSJohn Marino   value->type = arg->atype;
1088*ef5ccd6cSJohn Marino }
1089*ef5ccd6cSJohn Marino 
1090*ef5ccd6cSJohn Marino /* Destroy (free) the data related to PROBE.  PROBE memory itself is not feed
1091*ef5ccd6cSJohn Marino    as it is allocated from OBJFILE_OBSTACK.  */
1092*ef5ccd6cSJohn Marino 
1093*ef5ccd6cSJohn Marino static void
stap_probe_destroy(struct probe * probe_generic)1094*ef5ccd6cSJohn Marino stap_probe_destroy (struct probe *probe_generic)
1095*ef5ccd6cSJohn Marino {
1096*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
1097*ef5ccd6cSJohn Marino 
1098*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1099*ef5ccd6cSJohn Marino 
1100*ef5ccd6cSJohn Marino   if (probe->args_parsed)
1101*ef5ccd6cSJohn Marino     {
1102*ef5ccd6cSJohn Marino       struct stap_probe_arg *arg;
1103*ef5ccd6cSJohn Marino       int ix;
1104*ef5ccd6cSJohn Marino 
1105*ef5ccd6cSJohn Marino       for (ix = 0; VEC_iterate (stap_probe_arg_s, probe->args_u.vec, ix, arg);
1106*ef5ccd6cSJohn Marino 	   ++ix)
1107*ef5ccd6cSJohn Marino 	xfree (arg->aexpr);
1108*ef5ccd6cSJohn Marino       VEC_free (stap_probe_arg_s, probe->args_u.vec);
1109*ef5ccd6cSJohn Marino     }
1110*ef5ccd6cSJohn Marino }
1111*ef5ccd6cSJohn Marino 
1112*ef5ccd6cSJohn Marino 
1113*ef5ccd6cSJohn Marino 
1114*ef5ccd6cSJohn Marino /* This is called to compute the value of one of the $_probe_arg*
1115*ef5ccd6cSJohn Marino    convenience variables.  */
1116*ef5ccd6cSJohn Marino 
1117*ef5ccd6cSJohn Marino static struct value *
compute_probe_arg(struct gdbarch * arch,struct internalvar * ivar,void * data)1118*ef5ccd6cSJohn Marino compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
1119*ef5ccd6cSJohn Marino 		   void *data)
1120*ef5ccd6cSJohn Marino {
1121*ef5ccd6cSJohn Marino   struct frame_info *frame = get_selected_frame (_("No frame selected"));
1122*ef5ccd6cSJohn Marino   CORE_ADDR pc = get_frame_pc (frame);
1123*ef5ccd6cSJohn Marino   int sel = (int) (uintptr_t) data;
1124*ef5ccd6cSJohn Marino   struct probe *pc_probe;
1125*ef5ccd6cSJohn Marino   const struct sym_probe_fns *pc_probe_fns;
1126*ef5ccd6cSJohn Marino   unsigned n_args;
1127*ef5ccd6cSJohn Marino 
1128*ef5ccd6cSJohn Marino   /* SEL == -1 means "_probe_argc".  */
1129*ef5ccd6cSJohn Marino   gdb_assert (sel >= -1);
1130*ef5ccd6cSJohn Marino 
1131*ef5ccd6cSJohn Marino   pc_probe = find_probe_by_pc (pc);
1132*ef5ccd6cSJohn Marino   if (pc_probe == NULL)
1133*ef5ccd6cSJohn Marino     error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
1134*ef5ccd6cSJohn Marino 
1135*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile != NULL);
1136*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile->sf != NULL);
1137*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile->sf->sym_probe_fns != NULL);
1138*ef5ccd6cSJohn Marino 
1139*ef5ccd6cSJohn Marino   pc_probe_fns = pc_probe->objfile->sf->sym_probe_fns;
1140*ef5ccd6cSJohn Marino 
1141*ef5ccd6cSJohn Marino   n_args = pc_probe_fns->sym_get_probe_argument_count (pc_probe);
1142*ef5ccd6cSJohn Marino   if (sel == -1)
1143*ef5ccd6cSJohn Marino     return value_from_longest (builtin_type (arch)->builtin_int, n_args);
1144*ef5ccd6cSJohn Marino 
1145*ef5ccd6cSJohn Marino   if (sel >= n_args)
1146*ef5ccd6cSJohn Marino     error (_("Invalid probe argument %d -- probe has %u arguments available"),
1147*ef5ccd6cSJohn Marino 	   sel, n_args);
1148*ef5ccd6cSJohn Marino 
1149*ef5ccd6cSJohn Marino   return pc_probe_fns->sym_evaluate_probe_argument (pc_probe, sel);
1150*ef5ccd6cSJohn Marino }
1151*ef5ccd6cSJohn Marino 
1152*ef5ccd6cSJohn Marino /* This is called to compile one of the $_probe_arg* convenience
1153*ef5ccd6cSJohn Marino    variables into an agent expression.  */
1154*ef5ccd6cSJohn Marino 
1155*ef5ccd6cSJohn Marino static void
compile_probe_arg(struct internalvar * ivar,struct agent_expr * expr,struct axs_value * value,void * data)1156*ef5ccd6cSJohn Marino compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
1157*ef5ccd6cSJohn Marino 		   struct axs_value *value, void *data)
1158*ef5ccd6cSJohn Marino {
1159*ef5ccd6cSJohn Marino   CORE_ADDR pc = expr->scope;
1160*ef5ccd6cSJohn Marino   int sel = (int) (uintptr_t) data;
1161*ef5ccd6cSJohn Marino   struct probe *pc_probe;
1162*ef5ccd6cSJohn Marino   const struct sym_probe_fns *pc_probe_fns;
1163*ef5ccd6cSJohn Marino   int n_args;
1164*ef5ccd6cSJohn Marino 
1165*ef5ccd6cSJohn Marino   /* SEL == -1 means "_probe_argc".  */
1166*ef5ccd6cSJohn Marino   gdb_assert (sel >= -1);
1167*ef5ccd6cSJohn Marino 
1168*ef5ccd6cSJohn Marino   pc_probe = find_probe_by_pc (pc);
1169*ef5ccd6cSJohn Marino   if (pc_probe == NULL)
1170*ef5ccd6cSJohn Marino     error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
1171*ef5ccd6cSJohn Marino 
1172*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile != NULL);
1173*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile->sf != NULL);
1174*ef5ccd6cSJohn Marino   gdb_assert (pc_probe->objfile->sf->sym_probe_fns != NULL);
1175*ef5ccd6cSJohn Marino 
1176*ef5ccd6cSJohn Marino   pc_probe_fns = pc_probe->objfile->sf->sym_probe_fns;
1177*ef5ccd6cSJohn Marino 
1178*ef5ccd6cSJohn Marino   n_args = pc_probe_fns->sym_get_probe_argument_count (pc_probe);
1179*ef5ccd6cSJohn Marino 
1180*ef5ccd6cSJohn Marino   if (sel == -1)
1181*ef5ccd6cSJohn Marino     {
1182*ef5ccd6cSJohn Marino       value->kind = axs_rvalue;
1183*ef5ccd6cSJohn Marino       value->type = builtin_type (expr->gdbarch)->builtin_int;
1184*ef5ccd6cSJohn Marino       ax_const_l (expr, n_args);
1185*ef5ccd6cSJohn Marino       return;
1186*ef5ccd6cSJohn Marino     }
1187*ef5ccd6cSJohn Marino 
1188*ef5ccd6cSJohn Marino   gdb_assert (sel >= 0);
1189*ef5ccd6cSJohn Marino   if (sel >= n_args)
1190*ef5ccd6cSJohn Marino     error (_("Invalid probe argument %d -- probe has %d arguments available"),
1191*ef5ccd6cSJohn Marino 	   sel, n_args);
1192*ef5ccd6cSJohn Marino 
1193*ef5ccd6cSJohn Marino   pc_probe_fns->sym_compile_to_ax (pc_probe, expr, value, sel);
1194*ef5ccd6cSJohn Marino }
1195*ef5ccd6cSJohn Marino 
1196*ef5ccd6cSJohn Marino 
1197*ef5ccd6cSJohn Marino 
1198*ef5ccd6cSJohn Marino /* Set or clear a SystemTap semaphore.  ADDRESS is the semaphore's
1199*ef5ccd6cSJohn Marino    address.  SET is zero if the semaphore should be cleared, or one
1200*ef5ccd6cSJohn Marino    if it should be set.  This is a helper function for `stap_semaphore_down'
1201*ef5ccd6cSJohn Marino    and `stap_semaphore_up'.  */
1202*ef5ccd6cSJohn Marino 
1203*ef5ccd6cSJohn Marino static void
stap_modify_semaphore(CORE_ADDR address,int set,struct gdbarch * gdbarch)1204*ef5ccd6cSJohn Marino stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
1205*ef5ccd6cSJohn Marino {
1206*ef5ccd6cSJohn Marino   gdb_byte bytes[sizeof (LONGEST)];
1207*ef5ccd6cSJohn Marino   /* The ABI specifies "unsigned short".  */
1208*ef5ccd6cSJohn Marino   struct type *type = builtin_type (gdbarch)->builtin_unsigned_short;
1209*ef5ccd6cSJohn Marino   ULONGEST value;
1210*ef5ccd6cSJohn Marino 
1211*ef5ccd6cSJohn Marino   if (address == 0)
1212*ef5ccd6cSJohn Marino     return;
1213*ef5ccd6cSJohn Marino 
1214*ef5ccd6cSJohn Marino   /* Swallow errors.  */
1215*ef5ccd6cSJohn Marino   if (target_read_memory (address, bytes, TYPE_LENGTH (type)) != 0)
1216*ef5ccd6cSJohn Marino     {
1217*ef5ccd6cSJohn Marino       warning (_("Could not read the value of a SystemTap semaphore."));
1218*ef5ccd6cSJohn Marino       return;
1219*ef5ccd6cSJohn Marino     }
1220*ef5ccd6cSJohn Marino 
1221*ef5ccd6cSJohn Marino   value = extract_unsigned_integer (bytes, TYPE_LENGTH (type),
1222*ef5ccd6cSJohn Marino 				    gdbarch_byte_order (gdbarch));
1223*ef5ccd6cSJohn Marino   /* Note that we explicitly don't worry about overflow or
1224*ef5ccd6cSJohn Marino      underflow.  */
1225*ef5ccd6cSJohn Marino   if (set)
1226*ef5ccd6cSJohn Marino     ++value;
1227*ef5ccd6cSJohn Marino   else
1228*ef5ccd6cSJohn Marino     --value;
1229*ef5ccd6cSJohn Marino 
1230*ef5ccd6cSJohn Marino   store_unsigned_integer (bytes, TYPE_LENGTH (type),
1231*ef5ccd6cSJohn Marino 			  gdbarch_byte_order (gdbarch), value);
1232*ef5ccd6cSJohn Marino 
1233*ef5ccd6cSJohn Marino   if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0)
1234*ef5ccd6cSJohn Marino     warning (_("Could not write the value of a SystemTap semaphore."));
1235*ef5ccd6cSJohn Marino }
1236*ef5ccd6cSJohn Marino 
1237*ef5ccd6cSJohn Marino /* Set a SystemTap semaphore.  SEM is the semaphore's address.  Semaphores
1238*ef5ccd6cSJohn Marino    act as reference counters, so calls to this function must be paired with
1239*ef5ccd6cSJohn Marino    calls to `stap_semaphore_down'.
1240*ef5ccd6cSJohn Marino 
1241*ef5ccd6cSJohn Marino    This function and `stap_semaphore_down' race with another tool changing
1242*ef5ccd6cSJohn Marino    the probes, but that is too rare to care.  */
1243*ef5ccd6cSJohn Marino 
1244*ef5ccd6cSJohn Marino static void
stap_set_semaphore(struct probe * probe_generic,struct gdbarch * gdbarch)1245*ef5ccd6cSJohn Marino stap_set_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
1246*ef5ccd6cSJohn Marino {
1247*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
1248*ef5ccd6cSJohn Marino 
1249*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1250*ef5ccd6cSJohn Marino 
1251*ef5ccd6cSJohn Marino   stap_modify_semaphore (probe->sem_addr, 1, gdbarch);
1252*ef5ccd6cSJohn Marino }
1253*ef5ccd6cSJohn Marino 
1254*ef5ccd6cSJohn Marino /* Clear a SystemTap semaphore.  SEM is the semaphore's address.  */
1255*ef5ccd6cSJohn Marino 
1256*ef5ccd6cSJohn Marino static void
stap_clear_semaphore(struct probe * probe_generic,struct gdbarch * gdbarch)1257*ef5ccd6cSJohn Marino stap_clear_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
1258*ef5ccd6cSJohn Marino {
1259*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
1260*ef5ccd6cSJohn Marino 
1261*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1262*ef5ccd6cSJohn Marino 
1263*ef5ccd6cSJohn Marino   stap_modify_semaphore (probe->sem_addr, 0, gdbarch);
1264*ef5ccd6cSJohn Marino }
1265*ef5ccd6cSJohn Marino 
1266*ef5ccd6cSJohn Marino /* Implementation of `$_probe_arg*' set of variables.  */
1267*ef5ccd6cSJohn Marino 
1268*ef5ccd6cSJohn Marino static const struct internalvar_funcs probe_funcs =
1269*ef5ccd6cSJohn Marino {
1270*ef5ccd6cSJohn Marino   compute_probe_arg,
1271*ef5ccd6cSJohn Marino   compile_probe_arg,
1272*ef5ccd6cSJohn Marino   NULL
1273*ef5ccd6cSJohn Marino };
1274*ef5ccd6cSJohn Marino 
1275*ef5ccd6cSJohn Marino /* Helper function that parses the information contained in a
1276*ef5ccd6cSJohn Marino    SystemTap's probe.  Basically, the information consists in:
1277*ef5ccd6cSJohn Marino 
1278*ef5ccd6cSJohn Marino    - Probe's PC address;
1279*ef5ccd6cSJohn Marino    - Link-time section address of `.stapsdt.base' section;
1280*ef5ccd6cSJohn Marino    - Link-time address of the semaphore variable, or ZERO if the
1281*ef5ccd6cSJohn Marino      probe doesn't have an associated semaphore;
1282*ef5ccd6cSJohn Marino    - Probe's provider name;
1283*ef5ccd6cSJohn Marino    - Probe's name;
1284*ef5ccd6cSJohn Marino    - Probe's argument format
1285*ef5ccd6cSJohn Marino 
1286*ef5ccd6cSJohn Marino    This function returns 1 if the handling was successful, and zero
1287*ef5ccd6cSJohn Marino    otherwise.  */
1288*ef5ccd6cSJohn Marino 
1289*ef5ccd6cSJohn Marino static void
handle_stap_probe(struct objfile * objfile,struct sdt_note * el,VEC (probe_p)** probesp,CORE_ADDR base)1290*ef5ccd6cSJohn Marino handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
1291*ef5ccd6cSJohn Marino 		   VEC (probe_p) **probesp, CORE_ADDR base)
1292*ef5ccd6cSJohn Marino {
1293*ef5ccd6cSJohn Marino   bfd *abfd = objfile->obfd;
1294*ef5ccd6cSJohn Marino   int size = bfd_get_arch_size (abfd) / 8;
1295*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = get_objfile_arch (objfile);
1296*ef5ccd6cSJohn Marino   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
1297*ef5ccd6cSJohn Marino   CORE_ADDR base_ref;
1298*ef5ccd6cSJohn Marino   const char *probe_args = NULL;
1299*ef5ccd6cSJohn Marino   struct stap_probe *ret;
1300*ef5ccd6cSJohn Marino 
1301*ef5ccd6cSJohn Marino   ret = obstack_alloc (&objfile->objfile_obstack, sizeof (*ret));
1302*ef5ccd6cSJohn Marino   ret->p.pops = &stap_probe_ops;
1303*ef5ccd6cSJohn Marino   ret->p.objfile = objfile;
1304*ef5ccd6cSJohn Marino 
1305*ef5ccd6cSJohn Marino   /* Provider and the name of the probe.  */
1306*ef5ccd6cSJohn Marino   ret->p.provider = (char *) &el->data[3 * size];
1307*ef5ccd6cSJohn Marino   ret->p.name = memchr (ret->p.provider, '\0',
1308*ef5ccd6cSJohn Marino 			(char *) el->data + el->size - ret->p.provider);
1309*ef5ccd6cSJohn Marino   /* Making sure there is a name.  */
1310*ef5ccd6cSJohn Marino   if (!ret->p.name)
1311*ef5ccd6cSJohn Marino     {
1312*ef5ccd6cSJohn Marino       complaint (&symfile_complaints, _("corrupt probe name when "
1313*ef5ccd6cSJohn Marino 					"reading `%s'"), objfile->name);
1314*ef5ccd6cSJohn Marino 
1315*ef5ccd6cSJohn Marino       /* There is no way to use a probe without a name or a provider, so
1316*ef5ccd6cSJohn Marino 	 returning zero here makes sense.  */
1317*ef5ccd6cSJohn Marino       return;
1318*ef5ccd6cSJohn Marino     }
1319*ef5ccd6cSJohn Marino   else
1320*ef5ccd6cSJohn Marino     ++ret->p.name;
1321*ef5ccd6cSJohn Marino 
1322*ef5ccd6cSJohn Marino   /* Retrieving the probe's address.  */
1323*ef5ccd6cSJohn Marino   ret->p.address = extract_typed_address (&el->data[0], ptr_type);
1324*ef5ccd6cSJohn Marino 
1325*ef5ccd6cSJohn Marino   /* Link-time sh_addr of `.stapsdt.base' section.  */
1326*ef5ccd6cSJohn Marino   base_ref = extract_typed_address (&el->data[size], ptr_type);
1327*ef5ccd6cSJohn Marino 
1328*ef5ccd6cSJohn Marino   /* Semaphore address.  */
1329*ef5ccd6cSJohn Marino   ret->sem_addr = extract_typed_address (&el->data[2 * size], ptr_type);
1330*ef5ccd6cSJohn Marino 
1331*ef5ccd6cSJohn Marino   ret->p.address += (ANOFFSET (objfile->section_offsets,
1332*ef5ccd6cSJohn Marino 			       SECT_OFF_TEXT (objfile))
1333*ef5ccd6cSJohn Marino 		     + base - base_ref);
1334*ef5ccd6cSJohn Marino   if (ret->sem_addr)
1335*ef5ccd6cSJohn Marino     ret->sem_addr += (ANOFFSET (objfile->section_offsets,
1336*ef5ccd6cSJohn Marino 				SECT_OFF_DATA (objfile))
1337*ef5ccd6cSJohn Marino 		      + base - base_ref);
1338*ef5ccd6cSJohn Marino 
1339*ef5ccd6cSJohn Marino   /* Arguments.  We can only extract the argument format if there is a valid
1340*ef5ccd6cSJohn Marino      name for this probe.  */
1341*ef5ccd6cSJohn Marino   probe_args = memchr (ret->p.name, '\0',
1342*ef5ccd6cSJohn Marino 		       (char *) el->data + el->size - ret->p.name);
1343*ef5ccd6cSJohn Marino 
1344*ef5ccd6cSJohn Marino   if (probe_args != NULL)
1345*ef5ccd6cSJohn Marino     ++probe_args;
1346*ef5ccd6cSJohn Marino 
1347*ef5ccd6cSJohn Marino   if (probe_args == NULL || (memchr (probe_args, '\0',
1348*ef5ccd6cSJohn Marino 				     (char *) el->data + el->size - ret->p.name)
1349*ef5ccd6cSJohn Marino 			     != el->data + el->size - 1))
1350*ef5ccd6cSJohn Marino     {
1351*ef5ccd6cSJohn Marino       complaint (&symfile_complaints, _("corrupt probe argument when "
1352*ef5ccd6cSJohn Marino 					"reading `%s'"), objfile->name);
1353*ef5ccd6cSJohn Marino       /* If the argument string is NULL, it means some problem happened with
1354*ef5ccd6cSJohn Marino 	 it.  So we return 0.  */
1355*ef5ccd6cSJohn Marino       return;
1356*ef5ccd6cSJohn Marino     }
1357*ef5ccd6cSJohn Marino 
1358*ef5ccd6cSJohn Marino   ret->args_parsed = 0;
1359*ef5ccd6cSJohn Marino   ret->args_u.text = (void *) probe_args;
1360*ef5ccd6cSJohn Marino 
1361*ef5ccd6cSJohn Marino   /* Successfully created probe.  */
1362*ef5ccd6cSJohn Marino   VEC_safe_push (probe_p, *probesp, (struct probe *) ret);
1363*ef5ccd6cSJohn Marino }
1364*ef5ccd6cSJohn Marino 
1365*ef5ccd6cSJohn Marino /* Helper function which tries to find the base address of the SystemTap
1366*ef5ccd6cSJohn Marino    base section named STAP_BASE_SECTION_NAME.  */
1367*ef5ccd6cSJohn Marino 
1368*ef5ccd6cSJohn Marino static void
get_stap_base_address_1(bfd * abfd,asection * sect,void * obj)1369*ef5ccd6cSJohn Marino get_stap_base_address_1 (bfd *abfd, asection *sect, void *obj)
1370*ef5ccd6cSJohn Marino {
1371*ef5ccd6cSJohn Marino   asection **ret = obj;
1372*ef5ccd6cSJohn Marino 
1373*ef5ccd6cSJohn Marino   if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
1374*ef5ccd6cSJohn Marino       && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME))
1375*ef5ccd6cSJohn Marino     *ret = sect;
1376*ef5ccd6cSJohn Marino }
1377*ef5ccd6cSJohn Marino 
1378*ef5ccd6cSJohn Marino /* Helper function which iterates over every section in the BFD file,
1379*ef5ccd6cSJohn Marino    trying to find the base address of the SystemTap base section.
1380*ef5ccd6cSJohn Marino    Returns 1 if found (setting BASE to the proper value), zero otherwise.  */
1381*ef5ccd6cSJohn Marino 
1382*ef5ccd6cSJohn Marino static int
get_stap_base_address(bfd * obfd,bfd_vma * base)1383*ef5ccd6cSJohn Marino get_stap_base_address (bfd *obfd, bfd_vma *base)
1384*ef5ccd6cSJohn Marino {
1385*ef5ccd6cSJohn Marino   asection *ret = NULL;
1386*ef5ccd6cSJohn Marino 
1387*ef5ccd6cSJohn Marino   bfd_map_over_sections (obfd, get_stap_base_address_1, (void *) &ret);
1388*ef5ccd6cSJohn Marino 
1389*ef5ccd6cSJohn Marino   if (!ret)
1390*ef5ccd6cSJohn Marino     {
1391*ef5ccd6cSJohn Marino       complaint (&symfile_complaints, _("could not obtain base address for "
1392*ef5ccd6cSJohn Marino 					"SystemTap section on objfile `%s'."),
1393*ef5ccd6cSJohn Marino 		 obfd->filename);
1394*ef5ccd6cSJohn Marino       return 0;
1395*ef5ccd6cSJohn Marino     }
1396*ef5ccd6cSJohn Marino 
1397*ef5ccd6cSJohn Marino   if (base)
1398*ef5ccd6cSJohn Marino     *base = ret->vma;
1399*ef5ccd6cSJohn Marino 
1400*ef5ccd6cSJohn Marino   return 1;
1401*ef5ccd6cSJohn Marino }
1402*ef5ccd6cSJohn Marino 
1403*ef5ccd6cSJohn Marino /* Helper function for `elf_get_probes', which gathers information about all
1404*ef5ccd6cSJohn Marino    SystemTap probes from OBJFILE.  */
1405*ef5ccd6cSJohn Marino 
1406*ef5ccd6cSJohn Marino static void
stap_get_probes(VEC (probe_p)** probesp,struct objfile * objfile)1407*ef5ccd6cSJohn Marino stap_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
1408*ef5ccd6cSJohn Marino {
1409*ef5ccd6cSJohn Marino   /* If we are here, then this is the first time we are parsing the
1410*ef5ccd6cSJohn Marino      SystemTap probe's information.  We basically have to count how many
1411*ef5ccd6cSJohn Marino      probes the objfile has, and then fill in the necessary information
1412*ef5ccd6cSJohn Marino      for each one.  */
1413*ef5ccd6cSJohn Marino   bfd *obfd = objfile->obfd;
1414*ef5ccd6cSJohn Marino   bfd_vma base;
1415*ef5ccd6cSJohn Marino   struct sdt_note *iter;
1416*ef5ccd6cSJohn Marino   unsigned save_probesp_len = VEC_length (probe_p, *probesp);
1417*ef5ccd6cSJohn Marino 
1418*ef5ccd6cSJohn Marino   if (objfile->separate_debug_objfile_backlink != NULL)
1419*ef5ccd6cSJohn Marino     {
1420*ef5ccd6cSJohn Marino       /* This is a .debug file, not the objfile itself.  */
1421*ef5ccd6cSJohn Marino       return;
1422*ef5ccd6cSJohn Marino     }
1423*ef5ccd6cSJohn Marino 
1424*ef5ccd6cSJohn Marino   if (!elf_tdata (obfd)->sdt_note_head)
1425*ef5ccd6cSJohn Marino     {
1426*ef5ccd6cSJohn Marino       /* There isn't any probe here.  */
1427*ef5ccd6cSJohn Marino       return;
1428*ef5ccd6cSJohn Marino     }
1429*ef5ccd6cSJohn Marino 
1430*ef5ccd6cSJohn Marino   if (!get_stap_base_address (obfd, &base))
1431*ef5ccd6cSJohn Marino     {
1432*ef5ccd6cSJohn Marino       /* There was an error finding the base address for the section.
1433*ef5ccd6cSJohn Marino 	 Just return NULL.  */
1434*ef5ccd6cSJohn Marino       return;
1435*ef5ccd6cSJohn Marino     }
1436*ef5ccd6cSJohn Marino 
1437*ef5ccd6cSJohn Marino   /* Parsing each probe's information.  */
1438*ef5ccd6cSJohn Marino   for (iter = elf_tdata (obfd)->sdt_note_head; iter; iter = iter->next)
1439*ef5ccd6cSJohn Marino     {
1440*ef5ccd6cSJohn Marino       /* We first have to handle all the information about the
1441*ef5ccd6cSJohn Marino 	 probe which is present in the section.  */
1442*ef5ccd6cSJohn Marino       handle_stap_probe (objfile, iter, probesp, base);
1443*ef5ccd6cSJohn Marino     }
1444*ef5ccd6cSJohn Marino 
1445*ef5ccd6cSJohn Marino   if (save_probesp_len == VEC_length (probe_p, *probesp))
1446*ef5ccd6cSJohn Marino     {
1447*ef5ccd6cSJohn Marino       /* If we are here, it means we have failed to parse every known
1448*ef5ccd6cSJohn Marino 	 probe.  */
1449*ef5ccd6cSJohn Marino       complaint (&symfile_complaints, _("could not parse SystemTap probe(s) "
1450*ef5ccd6cSJohn Marino 					"from inferior"));
1451*ef5ccd6cSJohn Marino       return;
1452*ef5ccd6cSJohn Marino     }
1453*ef5ccd6cSJohn Marino }
1454*ef5ccd6cSJohn Marino 
1455*ef5ccd6cSJohn Marino static void
stap_relocate(struct probe * probe_generic,CORE_ADDR delta)1456*ef5ccd6cSJohn Marino stap_relocate (struct probe *probe_generic, CORE_ADDR delta)
1457*ef5ccd6cSJohn Marino {
1458*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
1459*ef5ccd6cSJohn Marino 
1460*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1461*ef5ccd6cSJohn Marino 
1462*ef5ccd6cSJohn Marino   probe->p.address += delta;
1463*ef5ccd6cSJohn Marino   if (probe->sem_addr)
1464*ef5ccd6cSJohn Marino     probe->sem_addr += delta;
1465*ef5ccd6cSJohn Marino }
1466*ef5ccd6cSJohn Marino 
1467*ef5ccd6cSJohn Marino static int
stap_probe_is_linespec(const char ** linespecp)1468*ef5ccd6cSJohn Marino stap_probe_is_linespec (const char **linespecp)
1469*ef5ccd6cSJohn Marino {
1470*ef5ccd6cSJohn Marino   static const char *const keywords[] = { "-pstap", "-probe-stap", NULL };
1471*ef5ccd6cSJohn Marino 
1472*ef5ccd6cSJohn Marino   return probe_is_linespec_by_keyword (linespecp, keywords);
1473*ef5ccd6cSJohn Marino }
1474*ef5ccd6cSJohn Marino 
1475*ef5ccd6cSJohn Marino static void
stap_gen_info_probes_table_header(VEC (info_probe_column_s)** heads)1476*ef5ccd6cSJohn Marino stap_gen_info_probes_table_header (VEC (info_probe_column_s) **heads)
1477*ef5ccd6cSJohn Marino {
1478*ef5ccd6cSJohn Marino   info_probe_column_s stap_probe_column;
1479*ef5ccd6cSJohn Marino 
1480*ef5ccd6cSJohn Marino   stap_probe_column.field_name = "semaphore";
1481*ef5ccd6cSJohn Marino   stap_probe_column.print_name = _("Semaphore");
1482*ef5ccd6cSJohn Marino 
1483*ef5ccd6cSJohn Marino   VEC_safe_push (info_probe_column_s, *heads, &stap_probe_column);
1484*ef5ccd6cSJohn Marino }
1485*ef5ccd6cSJohn Marino 
1486*ef5ccd6cSJohn Marino static void
stap_gen_info_probes_table_values(struct probe * probe_generic,VEC (const_char_ptr)** ret)1487*ef5ccd6cSJohn Marino stap_gen_info_probes_table_values (struct probe *probe_generic,
1488*ef5ccd6cSJohn Marino 				   VEC (const_char_ptr) **ret)
1489*ef5ccd6cSJohn Marino {
1490*ef5ccd6cSJohn Marino   struct stap_probe *probe = (struct stap_probe *) probe_generic;
1491*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch;
1492*ef5ccd6cSJohn Marino   const char *val = NULL;
1493*ef5ccd6cSJohn Marino 
1494*ef5ccd6cSJohn Marino   gdb_assert (probe_generic->pops == &stap_probe_ops);
1495*ef5ccd6cSJohn Marino 
1496*ef5ccd6cSJohn Marino   gdbarch = get_objfile_arch (probe->p.objfile);
1497*ef5ccd6cSJohn Marino 
1498*ef5ccd6cSJohn Marino   if (probe->sem_addr)
1499*ef5ccd6cSJohn Marino     val = print_core_address (gdbarch, probe->sem_addr);
1500*ef5ccd6cSJohn Marino 
1501*ef5ccd6cSJohn Marino   VEC_safe_push (const_char_ptr, *ret, val);
1502*ef5ccd6cSJohn Marino }
1503*ef5ccd6cSJohn Marino 
1504*ef5ccd6cSJohn Marino /* SystemTap probe_ops.  */
1505*ef5ccd6cSJohn Marino 
1506*ef5ccd6cSJohn Marino static const struct probe_ops stap_probe_ops =
1507*ef5ccd6cSJohn Marino {
1508*ef5ccd6cSJohn Marino   stap_probe_is_linespec,
1509*ef5ccd6cSJohn Marino   stap_get_probes,
1510*ef5ccd6cSJohn Marino   stap_relocate,
1511*ef5ccd6cSJohn Marino   stap_get_probe_argument_count,
1512*ef5ccd6cSJohn Marino   stap_evaluate_probe_argument,
1513*ef5ccd6cSJohn Marino   stap_compile_to_ax,
1514*ef5ccd6cSJohn Marino   stap_set_semaphore,
1515*ef5ccd6cSJohn Marino   stap_clear_semaphore,
1516*ef5ccd6cSJohn Marino   stap_probe_destroy,
1517*ef5ccd6cSJohn Marino   stap_gen_info_probes_table_header,
1518*ef5ccd6cSJohn Marino   stap_gen_info_probes_table_values,
1519*ef5ccd6cSJohn Marino };
1520*ef5ccd6cSJohn Marino 
1521*ef5ccd6cSJohn Marino /* Implementation of the `info probes stap' command.  */
1522*ef5ccd6cSJohn Marino 
1523*ef5ccd6cSJohn Marino static void
info_probes_stap_command(char * arg,int from_tty)1524*ef5ccd6cSJohn Marino info_probes_stap_command (char *arg, int from_tty)
1525*ef5ccd6cSJohn Marino {
1526*ef5ccd6cSJohn Marino   info_probes_for_ops (arg, from_tty, &stap_probe_ops);
1527*ef5ccd6cSJohn Marino }
1528*ef5ccd6cSJohn Marino 
1529*ef5ccd6cSJohn Marino void _initialize_stap_probe (void);
1530*ef5ccd6cSJohn Marino 
1531*ef5ccd6cSJohn Marino void
_initialize_stap_probe(void)1532*ef5ccd6cSJohn Marino _initialize_stap_probe (void)
1533*ef5ccd6cSJohn Marino {
1534*ef5ccd6cSJohn Marino   VEC_safe_push (probe_ops_cp, all_probe_ops, &stap_probe_ops);
1535*ef5ccd6cSJohn Marino 
1536*ef5ccd6cSJohn Marino   add_setshow_zuinteger_cmd ("stap-expression", class_maintenance,
1537*ef5ccd6cSJohn Marino 			     &stap_expression_debug,
1538*ef5ccd6cSJohn Marino 			     _("Set SystemTap expression debugging."),
1539*ef5ccd6cSJohn Marino 			     _("Show SystemTap expression debugging."),
1540*ef5ccd6cSJohn Marino 			     _("When non-zero, the internal representation "
1541*ef5ccd6cSJohn Marino 			       "of SystemTap expressions will be printed."),
1542*ef5ccd6cSJohn Marino 			     NULL,
1543*ef5ccd6cSJohn Marino 			     show_stapexpressiondebug,
1544*ef5ccd6cSJohn Marino 			     &setdebuglist, &showdebuglist);
1545*ef5ccd6cSJohn Marino 
1546*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_argc", &probe_funcs,
1547*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) -1);
1548*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg0", &probe_funcs,
1549*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 0);
1550*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg1", &probe_funcs,
1551*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 1);
1552*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg2", &probe_funcs,
1553*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 2);
1554*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg3", &probe_funcs,
1555*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 3);
1556*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg4", &probe_funcs,
1557*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 4);
1558*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg5", &probe_funcs,
1559*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 5);
1560*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg6", &probe_funcs,
1561*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 6);
1562*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg7", &probe_funcs,
1563*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 7);
1564*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg8", &probe_funcs,
1565*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 8);
1566*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg9", &probe_funcs,
1567*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 9);
1568*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg10", &probe_funcs,
1569*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 10);
1570*ef5ccd6cSJohn Marino   create_internalvar_type_lazy ("_probe_arg11", &probe_funcs,
1571*ef5ccd6cSJohn Marino 				(void *) (uintptr_t) 11);
1572*ef5ccd6cSJohn Marino 
1573*ef5ccd6cSJohn Marino   add_cmd ("stap", class_info, info_probes_stap_command,
1574*ef5ccd6cSJohn Marino 	   _("\
1575*ef5ccd6cSJohn Marino Show information about SystemTap static probes.\n\
1576*ef5ccd6cSJohn Marino Usage: info probes stap [PROVIDER [NAME [OBJECT]]]\n\
1577*ef5ccd6cSJohn Marino Each argument is a regular expression, used to select probes.\n\
1578*ef5ccd6cSJohn Marino PROVIDER matches probe provider names.\n\
1579*ef5ccd6cSJohn Marino NAME matches the probe names.\n\
1580*ef5ccd6cSJohn Marino OBJECT matches the executable or shared library name."),
1581*ef5ccd6cSJohn Marino 	   info_probes_cmdlist_get ());
1582*ef5ccd6cSJohn Marino 
1583*ef5ccd6cSJohn Marino }
1584