Home | History | Annotate | Download | only in ltrace
      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 		/* 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 
    253 int
    254 expr_is_compile_constant(struct expr_node *node)
    255 {
    256 	return node->kind == EXPR_OP_CONST;
    257 }
    258 
    259 static int
    260 eval_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 
    274 static int
    275 eval_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 
    293 static int
    294 eval_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 
    319 int
    320 eval_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 
    339 int
    340 expr_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 
    384 int
    385 expr_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 
    398 int
    399 expr_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 
    405 struct expr_node *
    406 expr_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