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