1 /* 2 * This file is part of ltrace. 3 * Copyright (C) 2011,2012 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 <errno.h> 22 23 #include "zero.h" 24 #include "common.h" 25 #include "type.h" 26 #include "value.h" 27 #include "expr.h" 28 29 static int 30 zero_callback_max(struct value *ret_value, struct value *lhs, 31 struct value_dict *arguments, 32 size_t max, void *data) 33 { 34 size_t i; 35 for (i = 0; i < max; ++i) { 36 struct value element; 37 if (value_init_element(&element, lhs, i) < 0) 38 return -1; 39 40 int zero = value_is_zero(&element, arguments); 41 42 value_destroy(&element); 43 44 if (zero) 45 break; 46 } 47 48 struct arg_type_info *long_type = type_get_simple(ARGTYPE_LONG); 49 value_init_detached(ret_value, NULL, long_type, 0); 50 value_set_word(ret_value, i); 51 return 0; 52 } 53 54 /* LHS->zero(RHS). Looks for a length of zero-terminated array, but 55 * looks no further than first RHS bytes. */ 56 static int 57 zero_callback(struct value *ret_value, struct value *lhs, 58 struct value *rhs, struct value_dict *arguments, void *data) 59 { 60 long l; 61 if (value_extract_word(rhs, &l, arguments) < 0) 62 return -1; 63 if (l < 0) 64 /* It might just be a positive value >2GB, but that's 65 * not likely. */ 66 report_global_error("maximum array length seems negative"); 67 size_t max = (size_t)l; 68 return zero_callback_max(ret_value, lhs, arguments, max, data); 69 } 70 71 /* LHS->zero. Looks for a length of zero-terminated array, without 72 * limit. */ 73 static int 74 zero1_callback(struct value *ret_value, struct value *lhs, 75 struct value_dict *arguments, void *data) 76 { 77 return zero_callback_max(ret_value, lhs, arguments, (size_t)-1, data); 78 } 79 80 struct expr_node * 81 build_zero_w_arg(struct expr_node *expr, int own) 82 { 83 struct expr_node *e_z = malloc(sizeof(*e_z)); 84 if (e_z == NULL) 85 return NULL; 86 87 expr_init_cb2(e_z, &zero_callback, 88 expr_self(), 0, expr, own, NULL); 89 return e_z; 90 } 91 92 struct expr_node * 93 expr_node_zero(void) 94 { 95 static struct expr_node *nodep = NULL; 96 if (nodep == NULL) { 97 static struct expr_node node; 98 expr_init_cb1(&node, &zero1_callback, 99 expr_self(), 0, (void *)-1); 100 nodep = &node; 101 } 102 return nodep; 103 } 104