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