prototype.h revision 08cdf328add7b723b94b151866e5d0173662f6c6
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 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 _PROTOTYPE_H_ 22#define _PROTOTYPE_H_ 23 24#include "forward.h" 25#include "dict.h" 26#include "vect.h" 27 28/* Function prototype. */ 29struct prototype { 30 /* Vector of struct param. */ 31 struct vect params; 32 33 struct arg_type_info *return_info; 34 int own_return_info : 1; 35}; 36 37/* Initialize a prototype PROTO. The name will be NAME, and the 38 * corresponding string will be owned and freed on destroy if 39 * OWN_NAME. */ 40void prototype_init(struct prototype *proto); 41 42/* Destroy PROTO (but don't free the memory block pointed-to by 43 * PROTO). */ 44void prototype_destroy(struct prototype *proto); 45 46/* Add new parameter PARAM to PROTO. The structure contents are 47 * copied and PARAM pointer itself is not owned by PROTO. */ 48int prototype_push_param(struct prototype *proto, struct param *param); 49 50/* Return number of parameters of prototype. */ 51size_t prototype_num_params(struct prototype *proto); 52 53/* Destroy N-th parameter from PROTO. N shall be smaller than the 54 * number of parameters. */ 55void prototype_destroy_nth_param(struct prototype *proto, size_t n); 56 57/* Get N-th parameter of PROTO. N shall be smaller than the number of 58 * parameters. */ 59struct param *prototype_get_nth_param(struct prototype *proto, size_t n); 60 61/* Iterate through the parameters of PROTO. See callback.h for notes 62 * on iteration interfaces. */ 63struct param *prototype_each_param 64 (struct prototype *proto, struct param *start_after, 65 enum callback_status (*cb)(struct prototype *, struct param *, void *), 66 void *data); 67 68/* For storing type aliases. */ 69struct named_type { 70 struct arg_type_info *info; 71 int forward : 1; 72 int own_type : 1; 73}; 74 75/* Initialize a named type INFO, which, if OWN_TYPE, is destroyed when 76 * named_type_destroy is called. */ 77void named_type_init(struct named_type *named, 78 struct arg_type_info *info, int own_type); 79 80void named_type_destroy(struct named_type *named); 81 82/* One prototype library. */ 83struct protolib { 84 /* Other libraries to look through if the definition is not 85 * found here. Note that due to the way imports are stored, 86 * there is no way to distinguish where exactly (at which 87 * place of the config file) the import was made. */ 88 struct vect imports; 89 90 /* Dictionary of name->struct prototype. */ 91 struct dict prototypes; 92 93 /* Dictionary of name->struct named_type. */ 94 struct dict named_types; 95}; 96 97/* Initialize PLIB. */ 98void protolib_init(struct protolib *plib); 99 100/* Destroy PLIB. */ 101void protolib_destroy(struct protolib *plib); 102 103/* Push IMPORT to PLIB. Returns 0 on success or a negative value on 104 * failure. In particular, -2 is returned if mutual import is 105 * detected. */ 106int protolib_add_import(struct protolib *plib, struct protolib *import); 107 108/* Add a prototype PROTO to PLIB. Returns 0 on success or a negative 109 * value on failure. NAME is owned and released on PLIB destruction 110 * if OWN_NAME. */ 111int protolib_add_prototype(struct protolib *plib, 112 const char *name, int own_name, 113 struct prototype *proto); 114 115/* Add a named type NAMED to PLIB. Returns 0 on success or a negative 116 * value on failure. NAME is owned and released on PLIB destruction 117 * if OWN_NAME. NAMED _pointer_ is copied to PLIB. */ 118int protolib_add_named_type(struct protolib *plib, 119 const char *name, int own_name, 120 struct named_type *named); 121 122/* Lookup prototype named NAME in PLIB. If none is found, look 123 * recursively in each of the imports. Returns the corresponding 124 * prototype, or NULL if none was found. */ 125struct prototype *protolib_lookup_prototype(struct protolib *plib, 126 const char *name); 127 128/* Add a named type NAMED to PLIB. Returns 0 on success or a negative 129 * value on failure. */ 130int protolib_add_type(struct protolib *plib, struct named_type *named); 131 132/* Lookup type named NAME in PLIB. If none is found, look recursively 133 * in each of the imports. Returns the corresponding type, or NULL if 134 * none was found. */ 135struct named_type *protolib_lookup_type(struct protolib *plib, 136 const char *name); 137 138/* A cache of prototype libraries. Can load prototype libraries on 139 * demand. 140 * 141 * XXX ltrace should open one config per ABI, which maps long, int, 142 * etc. to uint32_t etc. It would also map char to either of 143 * {u,}int8_t. Other protolibs would have this as implicit import. 144 * That would mean that the cache needs ABI tagging--each ABI should 145 * have a separate prototype cache, because the types will potentially 146 * differ between the ABI's. protolib cache would then naturally be 147 * stored in the ABI object, when this is introduced. */ 148struct protolib_cache { 149 /* Dictionary of filename->protolib*. */ 150 struct dict protolibs; 151 152 /* Fake module for implicit imports. This is populated by all 153 * files coming from -F. When -F is empty, it also contains 154 * either $HOME/.ltrace.conf, or /etc/ltrace.conf (whichever 155 * comes first). */ 156 struct protolib imports; 157 158 /* For tracking uses of cache during cache's own 159 * initialization. */ 160 int bootstrap : 1; 161}; 162 163/* Initialize CACHE. Returns 0 on success or a negative value on 164 * failure. */ 165int protolib_cache_init(struct protolib_cache *cache, 166 struct protolib *import); 167 168/* Destroy CACHE. */ 169void protolib_cache_destroy(struct protolib_cache *cache); 170 171/* Get protolib corresponding to KEY from CACHE. KEY would typically 172 * be the soname of a library for which a protolib should be obtained. 173 * If none has been loaded yet, load a new protolib, cache and return 174 * it. Returns NULL for failures. 175 * 176 * Protolibs are loaded from a config directory. If -F contains 177 * directory names, those are checked first. Next, os_get_config_dirs 178 * callback is used to get a list of directories to look into. In the 179 * first round, if ALLOW_PRIVATE, ltrace looks in user's private 180 * directories. If the config file wasn't found, the second round is 181 * made through system directories. If it still wasn't found, an 182 * empty protolib (but with the following includes) is provided 183 * instead. 184 * 185 * In each directory, ltrace looks and reads the file named KEY.conf. 186 * This file is augmented with the following implicit includes, in 187 * this order: 188 * 189 * - Legacy typedefs 190 * - The INCLUDE argument passed to protolib_cache_init, if non-NULL 191 * - Any configure _files_ passed in -F 192 * - When looking into private directories, $HOME/.ltrace.conf 193 * - When looking into system directories, @sysconfdir@/ltrace.conf 194 * 195 * This function returns either the loaded protolib, or NULL when 196 * there was an error. */ 197struct protolib *protolib_cache_search(struct protolib_cache *cache, 198 const char *key, 199 int allow_private); 200 201/* This is similar to above, but instead of looking for the file to 202 * load in directories, the filename is given. */ 203struct protolib *protolib_cache_file(struct protolib_cache *cache, 204 const char *filename); 205 206/* This is similar to protolib_cache_file, but the library to cache is 207 * given in argument. Returns 0 on success or a negative value on 208 * failure. PLIB is thereafter owned by CACHE. */ 209int protolib_cache_protolib(struct protolib_cache *cache, 210 const char *filename, 211 struct protolib *plib); 212 213/* Single global prototype cache. 214 * 215 * XXX Eventually each ABI should have its own cache. The idea is 216 * that there's one per-ABI config file that all others use for 217 * elementary typedefs (long, char, size_t). Ltrace then only deals 218 * in fixed-width integral types (and pointers etc.). */ 219extern struct protolib_cache g_protocache; 220 221void init_global_config(void); 222void destroy_global_config(void); 223 224#endif /* _PROTOTYPE_H_ */ 225