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
28static void
29expr_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
37void
38expr_init_self(struct expr_node *node)
39{
40	expr_init_common(node, EXPR_OP_SELF);
41}
42
43void
44expr_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
52void
53expr_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
59void
60expr_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
66void
67expr_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
76void
77expr_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
88void
89expr_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
97void
98expr_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
110void
111expr_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
127static void
128release_expr(struct expr_node *node, int own)
129{
130	if (own) {
131		expr_destroy(node);
132		free(node);
133	}
134}
135
136void
137expr_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
174static int
175expr_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
188int
189expr_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		/* Fall through.  */
233
234	case EXPR_OP_UP:
235	case EXPR_OP_CALL1:
236		if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0) {
237			if (node->kind == EXPR_OP_CALL2
238			    && node->u.call.own_rhs) {
239				expr_destroy(nrhs);
240				free(nrhs);
241				return -1;
242			}
243		}
244
245		retp->lhs = nlhs;
246		return 0;
247	}
248
249	assert(!"Invalid value of node kind");
250	abort();
251}
252
253int
254expr_is_compile_constant(struct expr_node *node)
255{
256	return node->kind == EXPR_OP_CONST;
257}
258
259static int
260eval_up(struct expr_node *node, struct value *context,
261	struct value_dict *arguments, struct value *ret_value)
262{
263	if (expr_eval(node->lhs, context, arguments, ret_value) < 0)
264		return -1;
265	struct value *parent = value_get_parental_struct(ret_value);
266	if (parent == NULL) {
267		value_destroy(ret_value);
268		return -1;
269	}
270	*ret_value = *parent;
271	return 0;
272}
273
274static int
275eval_cb1(struct expr_node *node, struct value *context,
276	 struct value_dict *arguments, struct value *ret_value)
277{
278	struct value val;
279	if (expr_eval(node->lhs, context, arguments, &val) < 0)
280		return -1;
281
282	int ret = 0;
283	if (node->u.call.u.cb1(ret_value, &val, arguments,
284			       node->u.call.data) < 0)
285		ret = -1;
286
287	/* N.B. the callback must return its own value, or somehow
288	 * clone the incoming argument.  */
289	value_destroy(&val);
290	return ret;
291}
292
293static int
294eval_cb2(struct expr_node *node, struct value *context,
295	 struct value_dict *arguments, struct value *ret_value)
296{
297	struct value lhs;
298	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
299		return -1;
300
301	struct value rhs;
302	if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) {
303		value_destroy(&lhs);
304		return -1;
305	}
306
307	int ret = 0;
308	if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments,
309			       node->u.call.data) < 0)
310		ret = -1;
311
312	/* N.B. the callback must return its own value, or somehow
313	 * clone the incoming argument.  */
314	value_destroy(&lhs);
315	value_destroy(&rhs);
316	return ret;
317}
318
319int
320eval_index(struct expr_node *node, struct value *context,
321	   struct value_dict *arguments, struct value *ret_value)
322{
323	struct value lhs;
324	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
325		return -1;
326
327	long l;
328	if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) {
329	fail:
330		value_destroy(&lhs);
331		return -1;
332	}
333
334	if (value_init_element(ret_value, &lhs, (size_t)l) < 0)
335		goto fail;
336	return 0;
337}
338
339int
340expr_eval(struct expr_node *node, struct value *context,
341	  struct value_dict *arguments, struct value *ret_value)
342{
343	switch (node->kind) {
344		struct value *valp;
345	case EXPR_OP_ARGNO:
346		valp = val_dict_get_num(arguments, node->u.num);
347		if (valp == NULL)
348			return -1;
349		*ret_value = *valp;
350		return 0;
351
352	case EXPR_OP_NAMED:
353		valp = val_dict_get_name(arguments, node->u.name.s);
354		if (valp == NULL)
355			return -1;
356		*ret_value = *valp;
357		return 0;
358
359	case EXPR_OP_SELF:
360		*ret_value = *context;
361		return 0;
362
363	case EXPR_OP_CONST:
364		*ret_value = node->u.value;
365		return 0;
366
367	case EXPR_OP_INDEX:
368		return eval_index(node, context, arguments, ret_value);
369
370	case EXPR_OP_UP:
371		return eval_up(node, context, arguments, ret_value);
372
373	case EXPR_OP_CALL1:
374		return eval_cb1(node, context, arguments, ret_value);
375
376	case EXPR_OP_CALL2:
377		return eval_cb2(node, context, arguments, ret_value);
378	}
379
380	assert(!"Unknown node kind.");
381	abort();
382}
383
384int
385expr_eval_word(struct expr_node *node, struct value *context,
386	       struct value_dict *arguments, long *ret_value)
387{
388	struct value val;
389	if (expr_eval(node, context, arguments, &val) < 0)
390		return -1;
391	int ret = 0;
392	if (value_extract_word(&val, ret_value, arguments) < 0)
393		ret = -1;
394	value_destroy(&val);
395	return ret;
396}
397
398int
399expr_eval_constant(struct expr_node *node, long *valuep)
400{
401	assert(expr_is_compile_constant(node));
402	return expr_eval_word(node, NULL, NULL, valuep);
403}
404
405struct expr_node *
406expr_self(void)
407{
408	static struct expr_node *nodep = NULL;
409	if (nodep == NULL) {
410		static struct expr_node node;
411		expr_init_self(&node);
412		nodep = &node;
413	}
414	return nodep;
415}
416