Excluding riscv64 because it does not support riscv64.
[platform/upstream/ltrace.git] / expr.c
1 /*
2  * This file is part of ltrace.
3  * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  */
20
21 #include <string.h>
22 #include <assert.h>
23 #include <errno.h>
24 #include <stdlib.h>
25
26 #include "expr.h"
27
28 static void
29 expr_init_common(struct expr_node *node, enum expr_node_kind kind)
30 {
31         node->kind = kind;
32         node->lhs = NULL;
33         node->own_lhs = 0;
34         memset(&node->u, 0, sizeof(node->u));
35 }
36
37 void
38 expr_init_self(struct expr_node *node)
39 {
40         expr_init_common(node, EXPR_OP_SELF);
41 }
42
43 void
44 expr_init_named(struct expr_node *node,
45                 const char *name, int own_name)
46 {
47         expr_init_common(node, EXPR_OP_NAMED);
48         node->u.name.s = name;
49         node->u.name.own = own_name;
50 }
51
52 void
53 expr_init_argno(struct expr_node *node, size_t num)
54 {
55         expr_init_common(node, EXPR_OP_ARGNO);
56         node->u.num = num;
57 }
58
59 void
60 expr_init_const(struct expr_node *node, struct value *val)
61 {
62         expr_init_common(node, EXPR_OP_CONST);
63         node->u.value = *val;
64 }
65
66 void
67 expr_init_const_word(struct expr_node *node, long l,
68                      struct arg_type_info *type, int own_type)
69 {
70         struct value val;
71         value_init_detached(&val, NULL, type, own_type);
72         value_set_word(&val, l);
73         expr_init_const(node, &val);
74 }
75
76 void
77 expr_init_index(struct expr_node *node,
78                 struct expr_node *lhs, int own_lhs,
79                 struct expr_node *rhs, int own_rhs)
80 {
81         expr_init_common(node, EXPR_OP_INDEX);
82         node->lhs = lhs;
83         node->own_lhs = own_lhs;
84         node->u.node.n = rhs;
85         node->u.node.own = own_rhs;
86 }
87
88 void
89 expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs)
90 {
91         assert(lhs != NULL);
92         expr_init_common(node, EXPR_OP_UP);
93         node->lhs = lhs;
94         node->own_lhs = own_lhs;
95 }
96
97 void
98 expr_init_cb1(struct expr_node *node,
99               int (*cb)(struct value *ret_value, struct value *value,
100                         struct value_dict *arguments, void *data),
101               struct expr_node *lhs, int own_lhs, void *data)
102 {
103         expr_init_common(node, EXPR_OP_CALL1);
104         node->lhs = lhs;
105         node->own_lhs = own_lhs;
106         node->u.call.u.cb1 = cb;
107         node->u.call.data = data;
108 }
109
110 void
111 expr_init_cb2(struct expr_node *node,
112               int (*cb)(struct value *ret_value,
113                         struct value *lhs, struct value *rhs,
114                         struct value_dict *arguments, void *data),
115               struct expr_node *lhs, int own_lhs,
116               struct expr_node *rhs, int own_rhs, void *data)
117 {
118         expr_init_common(node, EXPR_OP_CALL2);
119         node->lhs = lhs;
120         node->own_lhs = own_lhs;
121         node->u.call.rhs = rhs;
122         node->u.call.own_rhs = own_rhs;
123         node->u.call.u.cb2 = cb;
124         node->u.call.data = data;
125 }
126
127 static void
128 release_expr(struct expr_node *node, int own)
129 {
130         if (own) {
131                 expr_destroy(node);
132                 free(node);
133         }
134 }
135
136 void
137 expr_destroy(struct expr_node *node)
138 {
139         if (node == NULL)
140                 return;
141
142         switch (node->kind) {
143         case EXPR_OP_ARGNO:
144         case EXPR_OP_SELF:
145                 return;
146
147         case EXPR_OP_CONST:
148                 value_destroy(&node->u.value);
149                 return;
150
151         case EXPR_OP_NAMED:
152                 if (node->u.name.own)
153                         free((char *)node->u.name.s);
154                 return;
155
156         case EXPR_OP_INDEX:
157                 release_expr(node->lhs, node->own_lhs);
158                 release_expr(node->u.node.n, node->u.node.own);
159                 return;
160
161         case EXPR_OP_CALL2:
162                 release_expr(node->u.call.rhs, node->u.call.own_rhs);
163                 /* Fall through.  */
164         case EXPR_OP_UP:
165         case EXPR_OP_CALL1:
166                 release_expr(node->lhs, node->own_lhs);
167                 return;
168         }
169
170         assert(!"Invalid value of node kind");
171         abort();
172 }
173
174 static int
175 expr_alloc_and_clone(struct expr_node **retpp, struct expr_node *node, int own)
176 {
177         *retpp = node;
178         if (own) {
179                 *retpp = malloc(sizeof **retpp);
180                 if (*retpp == NULL || expr_clone(*retpp, node) < 0) {
181                         free(*retpp);
182                         return -1;
183                 }
184         }
185         return 0;
186 }
187
188 int
189 expr_clone(struct expr_node *retp, const struct expr_node *node)
190 {
191         *retp = *node;
192
193         switch (node->kind) {
194                 struct expr_node *nlhs;
195                 struct expr_node *nrhs;
196
197         case EXPR_OP_ARGNO:
198         case EXPR_OP_SELF:
199                 return 0;
200
201         case EXPR_OP_CONST:
202                 return value_clone(&retp->u.value, &node->u.value);
203
204         case EXPR_OP_NAMED:
205                 if (node->u.name.own
206                     && (retp->u.name.s = strdup(node->u.name.s)) == NULL)
207                         return -1;
208                 return 0;
209
210         case EXPR_OP_INDEX:
211                 if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0)
212                         return -1;
213
214                 if (expr_alloc_and_clone(&nrhs, node->u.node.n,
215                                          node->u.node.own) < 0) {
216                         if (nlhs != node->lhs) {
217                                 expr_destroy(nlhs);
218                                 free(nlhs);
219                         }
220                         return -1;
221                 }
222
223                 retp->lhs = nlhs;
224                 retp->u.node.n = nrhs;
225                 return 0;
226
227         case EXPR_OP_CALL2:
228                 if (expr_alloc_and_clone(&nrhs, node->u.call.rhs,
229                                          node->u.call.own_rhs) < 0)
230                         return -1;
231                 retp->u.call.rhs = nrhs;
232
233                 if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0) {
234                         if (node->u.call.own_rhs) {
235                                 expr_destroy(nrhs);
236                                 free(nrhs);
237                         }
238                         return -1;
239                 }
240
241                 retp->lhs = nlhs;
242                 return 0;
243
244         case EXPR_OP_UP:
245         case EXPR_OP_CALL1:
246                 if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0)
247                         return -1;
248
249                 retp->lhs = nlhs;
250                 return 0;
251         }
252
253         assert(!"Invalid value of node kind");
254         abort();
255 }
256
257 int
258 expr_is_compile_constant(struct expr_node *node)
259 {
260         return node->kind == EXPR_OP_CONST;
261 }
262
263 static int
264 eval_up(struct expr_node *node, struct value *context,
265         struct value_dict *arguments, struct value *ret_value)
266 {
267         if (expr_eval(node->lhs, context, arguments, ret_value) < 0)
268                 return -1;
269         struct value *parent = value_get_parental_struct(ret_value);
270         if (parent == NULL) {
271                 value_destroy(ret_value);
272                 return -1;
273         }
274         *ret_value = *parent;
275         return 0;
276 }
277
278 static int
279 eval_cb1(struct expr_node *node, struct value *context,
280          struct value_dict *arguments, struct value *ret_value)
281 {
282         struct value val;
283         if (expr_eval(node->lhs, context, arguments, &val) < 0)
284                 return -1;
285
286         int ret = 0;
287         if (node->u.call.u.cb1(ret_value, &val, arguments,
288                                node->u.call.data) < 0)
289                 ret = -1;
290
291         /* N.B. the callback must return its own value, or somehow
292          * clone the incoming argument.  */
293         value_destroy(&val);
294         return ret;
295 }
296
297 static int
298 eval_cb2(struct expr_node *node, struct value *context,
299          struct value_dict *arguments, struct value *ret_value)
300 {
301         struct value lhs;
302         if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
303                 return -1;
304
305         struct value rhs;
306         if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) {
307                 value_destroy(&lhs);
308                 return -1;
309         }
310
311         int ret = 0;
312         if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments,
313                                node->u.call.data) < 0)
314                 ret = -1;
315
316         /* N.B. the callback must return its own value, or somehow
317          * clone the incoming argument.  */
318         value_destroy(&lhs);
319         value_destroy(&rhs);
320         return ret;
321 }
322
323 int
324 eval_index(struct expr_node *node, struct value *context,
325            struct value_dict *arguments, struct value *ret_value)
326 {
327         struct value lhs;
328         if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
329                 return -1;
330
331         long l;
332         if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) {
333         fail:
334                 value_destroy(&lhs);
335                 return -1;
336         }
337
338         if (value_init_element(ret_value, &lhs, (size_t)l) < 0)
339                 goto fail;
340         return 0;
341 }
342
343 int
344 expr_eval(struct expr_node *node, struct value *context,
345           struct value_dict *arguments, struct value *ret_value)
346 {
347         switch (node->kind) {
348                 struct value *valp;
349         case EXPR_OP_ARGNO:
350                 valp = val_dict_get_num(arguments, node->u.num);
351                 if (valp == NULL)
352                         return -1;
353                 *ret_value = *valp;
354                 return 0;
355
356         case EXPR_OP_NAMED:
357                 valp = val_dict_get_name(arguments, node->u.name.s);
358                 if (valp == NULL)
359                         return -1;
360                 *ret_value = *valp;
361                 return 0;
362
363         case EXPR_OP_SELF:
364                 *ret_value = *context;
365                 return 0;
366
367         case EXPR_OP_CONST:
368                 *ret_value = node->u.value;
369                 return 0;
370
371         case EXPR_OP_INDEX:
372                 return eval_index(node, context, arguments, ret_value);
373
374         case EXPR_OP_UP:
375                 return eval_up(node, context, arguments, ret_value);
376
377         case EXPR_OP_CALL1:
378                 return eval_cb1(node, context, arguments, ret_value);
379
380         case EXPR_OP_CALL2:
381                 return eval_cb2(node, context, arguments, ret_value);
382         }
383
384         assert(!"Unknown node kind.");
385         abort();
386 }
387
388 int
389 expr_eval_word(struct expr_node *node, struct value *context,
390                struct value_dict *arguments, long *ret_value)
391 {
392         struct value val;
393         if (expr_eval(node, context, arguments, &val) < 0)
394                 return -1;
395         int ret = 0;
396         if (value_extract_word(&val, ret_value, arguments) < 0)
397                 ret = -1;
398         value_destroy(&val);
399         return ret;
400 }
401
402 int
403 expr_eval_constant(struct expr_node *node, long *valuep)
404 {
405         assert(expr_is_compile_constant(node));
406         return expr_eval_word(node, NULL, NULL, valuep);
407 }
408
409 struct expr_node *
410 expr_self(void)
411 {
412         static struct expr_node *nodep = NULL;
413         if (nodep == NULL) {
414                 static struct expr_node node;
415                 expr_init_self(&node);
416                 nodep = &node;
417         }
418         return nodep;
419 }