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