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#ifndef PARAM_H 22#define PARAM_H 23 24#include "forward.h" 25 26/* The structure param holds information about a parameter of a 27 * function. It's used to configure a function prototype. There are 28 * two flavors of parameters: 29 * 30 * - simple types 31 * - parameter packs 32 * 33 * Parameter packs are used to describe various vararg constructs. 34 * They themselves are parametrized by ltrace expressions. Those will 35 * typically be references to other arguments, but constants might 36 * also make sense, and it principle, anything can be used. */ 37 38enum param_flavor { 39 PARAM_FLAVOR_TYPE, 40 PARAM_FLAVOR_PACK, 41 42 /* This is for emitting arguments in two bunches. This is 43 * where we should stop emitting "left" bunch. All that's 44 * after this parameter should be emitted in the "right" 45 * bunch. */ 46 PARAM_FLAVOR_STOP, 47}; 48 49enum param_pack_flavor { 50 /* This parameter pack expands to a list of ordinary 51 * arguments. For example if the last argument is sometimes 52 * ignored, that would be described by a PARAM_PACK_ARGS 53 * parameter pack. ioctl or ptrace are two examples that 54 * would benefit from this. */ 55 PARAM_PACK_ARGS, 56 57 /* This parameter pack represents a vararg argument. */ 58 PARAM_PACK_VARARGS, 59}; 60 61enum param_status { 62 PPCB_ERR = -1, /* An error occurred. */ 63 PPCB_STOP, /* Stop fetching the arguments. */ 64 PPCB_CONT, /* Display this argument and keep going. */ 65}; 66 67/* Each parameter enumerator defines its own context object. 68 * Definitions of these are in respective .c files of each 69 * enumerator. */ 70struct param_enum; 71 72struct param { 73 enum param_flavor flavor; 74 union { 75 struct { 76 struct arg_type_info *type; 77 int own_type; 78 } type; 79 struct { 80 struct expr_node *args; 81 size_t nargs; 82 int own_args; 83 enum param_pack_flavor ppflavor; 84 85 struct param_enum *(*init)(struct value *cb_args, 86 size_t nargs, 87 struct value_dict *arguments); 88 int (*next)(struct param_enum *self, 89 struct arg_type_info *info, 90 int *insert_stop); 91 enum param_status (*stop)(struct param_enum *self, 92 struct value *value); 93 void (*done)(struct param_enum *self); 94 } pack; 95 } u; 96}; 97 98/* Initialize simple type parameter. TYPE is owned and released by 99 * PARAM if OWN_TYPE. */ 100void param_init_type(struct param *param, 101 struct arg_type_info *type, int own_type); 102 103/* Initialize a stop. */ 104void param_init_stop(struct param *param); 105 106/* Initialize parameter pack PARAM. ARGS is an array of expressions 107 * with parameters. ARGS is owned and released by the pack if 108 * OWN_ARGS. NARGS is number of ARGS. 109 * 110 * When the parameter pack should be expanded, those expressions are 111 * evaluated and passed to the INIT callback. This has to return a 112 * non-NULL context object. 113 * 114 * The NEXT callback is then called repeatedly, and should initialize 115 * its INFOP argument to a type of the next parameter in the pack. 116 * When there are no more parameters in the pack, the NEXT callback 117 * will set INFOP to a VOID parameter. If the callback sets 118 * INSERT_STOP to a non-zero value, a stop parameter shall be inserted 119 * before this actual parameter. 120 * 121 * Core then uses the passed-in type to fetch the next argument, which 122 * is in turn passed to STOP callback. This callback then tells 123 * ltrace core what to do next: whether there are more arguments, and 124 * if not, whether this argument should be displayed. 125 * 126 * After the enumeration is ended, DONE callback is called. */ 127void param_init_pack(struct param *param, enum param_pack_flavor ppflavor, 128 struct expr_node *args, size_t nargs, int own_args, 129 struct param_enum *(*init)(struct value *cb_args, 130 size_t nargs, 131 struct value_dict *arguments), 132 int (*next)(struct param_enum *self, 133 struct arg_type_info *infop, 134 int *insert_stop), 135 enum param_status (*stop)(struct param_enum *self, 136 struct value *value), 137 void (*done)(struct param_enum *self)); 138 139/* Start enumerating types in parameter pack. This evaluates the 140 * parameter the pack arguments and calls the init callback. See the 141 * documentation of param_init_pack for details. */ 142struct param_enum *param_pack_init(struct param *param, 143 struct value_dict *fargs); 144 145/* Ask for next type in enumeration. See the documentation of 146 * param_init_pack for details. */ 147int param_pack_next(struct param *param, struct param_enum *self, 148 struct arg_type_info *infop, int *insert_stop); 149 150/* Ask whether we should stop enumerating. See the documentation of 151 * param_init_pack for details. */ 152enum param_status param_pack_stop(struct param *param, 153 struct param_enum *self, struct value *value); 154 155/* Finish enumerating types in parameter pack. See the documentation 156 * of param_init_pack for details. */ 157void param_pack_done(struct param *param, struct param_enum *self); 158 159/* Destroy data held by PARAM, but not the PARAM pointer itself. */ 160void param_destroy(struct param *param); 161 162#endif /* PARAM_H */ 163