Fix lookup of prototypes from non-leader threads
[platform/upstream/ltrace.git] / prototype.h
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_ */