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