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 29static int 30zero_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. */ 56static int 57zero_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. */ 73static int 74zero1_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 80struct expr_node * 81build_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 92struct expr_node * 93expr_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