Adapt ASLR to ltrace
[platform/upstream/ltrace.git] / read_config_file.c
1 /*
2  * This file is part of ltrace.
3  * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc.
4  * Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes
5  * Copyright (C) 2006 Ian Wienand
6  * Copyright (C) 2006 Steve Fink
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #define _GNU_SOURCE
25
26 #include "config.h"
27
28 #include <string.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include <assert.h>
33
34 #include "common.h"
35 #include "output.h"
36 #include "expr.h"
37 #include "param.h"
38 #include "printf.h"
39 #include "prototype.h"
40 #include "zero.h"
41 #include "type.h"
42 #include "lens.h"
43 #include "lens_default.h"
44 #include "lens_enum.h"
45
46 /* Lifted from GCC: The ctype functions are often implemented as
47  * macros which do lookups in arrays using the parameter as the
48  * offset.  If the ctype function parameter is a char, then gcc will
49  * (appropriately) warn that a "subscript has type char".  Using a
50  * (signed) char as a subscript is bad because you may get negative
51  * offsets and thus it is not 8-bit safe.  The CTYPE_CONV macro
52  * ensures that the parameter is cast to an unsigned char when a char
53  * is passed in.  When an int is passed in, the parameter is left
54  * alone so we don't lose EOF.  */
55
56 #define CTYPE_CONV(CH) \
57   (sizeof(CH) == sizeof(unsigned char) ? (int)(unsigned char)(CH) : (int)(CH))
58
59 struct locus
60 {
61         const char *filename;
62         int line_no;
63 };
64
65 static struct arg_type_info *parse_nonpointer_type(struct protolib *plib,
66                                                    struct locus *loc,
67                                                    char **str,
68                                                    struct param **extra_param,
69                                                    size_t param_num,
70                                                    int *ownp, int *forwardp);
71 static struct arg_type_info *parse_type(struct protolib *plib,
72                                         struct locus *loc,
73                                         char **str, struct param **extra_param,
74                                         size_t param_num, int *ownp,
75                                         int *forwardp);
76 static struct arg_type_info *parse_lens(struct protolib *plib,
77                                         struct locus *loc,
78                                         char **str, struct param **extra_param,
79                                         size_t param_num, int *ownp,
80                                         int *forwardp);
81 static int parse_enum(struct protolib *plib, struct locus *loc,
82                       char **str, struct arg_type_info **retp, int *ownp);
83
84 struct prototype *list_of_functions = NULL;
85
86 static int
87 parse_arg_type(char **name, enum arg_type *ret)
88 {
89         char *rest = NULL;
90         enum arg_type candidate;
91
92 #define KEYWORD(KWD, TYPE)                                              \
93         do {                                                            \
94                 if (strncmp(*name, KWD, sizeof(KWD) - 1) == 0) {        \
95                         rest = *name + sizeof(KWD) - 1;                 \
96                         candidate = TYPE;                               \
97                         goto ok;                                        \
98                 }                                                       \
99         } while (0)
100
101         KEYWORD("void", ARGTYPE_VOID);
102         KEYWORD("int", ARGTYPE_INT);
103         KEYWORD("uint", ARGTYPE_UINT);
104         KEYWORD("long", ARGTYPE_LONG);
105         KEYWORD("ulong", ARGTYPE_ULONG);
106         KEYWORD("char", ARGTYPE_CHAR);
107         KEYWORD("short", ARGTYPE_SHORT);
108         KEYWORD("ushort", ARGTYPE_USHORT);
109         KEYWORD("float", ARGTYPE_FLOAT);
110         KEYWORD("double", ARGTYPE_DOUBLE);
111         KEYWORD("array", ARGTYPE_ARRAY);
112         KEYWORD("struct", ARGTYPE_STRUCT);
113
114         /* Misspelling of int used in ltrace.conf that we used to
115          * ship.  */
116         KEYWORD("itn", ARGTYPE_INT);
117
118         assert(rest == NULL);
119         return -1;
120
121 #undef KEYWORD
122
123 ok:
124         if (isalnum(CTYPE_CONV(*rest)) || *rest == '_')
125                 return -1;
126
127         *name = rest;
128         *ret = candidate;
129         return 0;
130 }
131
132 static void
133 eat_spaces(char **str) {
134         while (**str == ' ') {
135                 (*str)++;
136         }
137 }
138
139 static char *
140 xstrndup(char *str, size_t len) {
141         char *ret = (char *) malloc(len + 1);
142         if (ret == NULL) {
143                 report_global_error("malloc: %s", strerror(errno));
144                 return NULL;
145         }
146         strncpy(ret, str, len);
147         ret[len] = 0;
148         return ret;
149 }
150
151 static char *
152 parse_ident(struct locus *loc, char **str)
153 {
154         char *ident = *str;
155
156         if (!isalpha(CTYPE_CONV(**str)) && **str != '_') {
157                 report_error(loc->filename, loc->line_no, "bad identifier");
158                 return NULL;
159         }
160
161         while (**str && (isalnum(CTYPE_CONV(**str)) || **str == '_')) {
162                 ++(*str);
163         }
164
165         return xstrndup(ident, *str - ident);
166 }
167
168 static int
169 parse_int(struct locus *loc, char **str, long *ret)
170 {
171         char *end;
172         long n = strtol(*str, &end, 0);
173         if (end == *str) {
174                 report_error(loc->filename, loc->line_no, "bad number");
175                 return -1;
176         }
177
178         *str = end;
179         if (ret != NULL)
180                 *ret = n;
181         return 0;
182 }
183
184 static int
185 check_nonnegative(struct locus *loc, long l)
186 {
187         if (l < 0) {
188                 report_error(loc->filename, loc->line_no,
189                              "expected non-negative value, got %ld", l);
190                 return -1;
191         }
192         return 0;
193 }
194
195 static int
196 check_int(struct locus *loc, long l)
197 {
198         int i = l;
199         if ((long)i != l) {
200                 report_error(loc->filename, loc->line_no,
201                              "Number too large: %ld", l);
202                 return -1;
203         }
204         return 0;
205 }
206
207 static int
208 parse_char(struct locus *loc, char **str, char expected)
209 {
210         if (**str != expected) {
211                 report_error(loc->filename, loc->line_no,
212                              "expected '%c', got '%c'", expected, **str);
213                 return -1;
214         }
215
216         ++*str;
217         return 0;
218 }
219
220 static struct expr_node *parse_argnum(struct locus *loc,
221                                       char **str, int *ownp, int zero);
222
223 static struct expr_node *
224 parse_zero(struct locus *loc, char **str, int *ownp)
225 {
226         eat_spaces(str);
227         if (**str == '(') {
228                 ++*str;
229                 int own;
230                 struct expr_node *arg = parse_argnum(loc, str, &own, 0);
231                 if (arg == NULL)
232                         return NULL;
233                 if (parse_char(loc, str, ')') < 0) {
234                 fail:
235                         expr_destroy(arg);
236                         free(arg);
237                         return NULL;
238                 }
239
240                 struct expr_node *ret = build_zero_w_arg(arg, own);
241                 if (ret == NULL)
242                         goto fail;
243                 *ownp = 1;
244                 return ret;
245
246         } else {
247                 *ownp = 0;
248                 return expr_node_zero();
249         }
250 }
251
252 static int
253 wrap_in_zero(struct expr_node **nodep)
254 {
255         struct expr_node *n = build_zero_w_arg(*nodep, 1);
256         if (n == NULL)
257                 return -1;
258         *nodep = n;
259         return 0;
260 }
261
262 /*
263  * Input:
264  *  argN   : The value of argument #N, counting from 1
265  *  eltN   : The value of element #N of the containing structure
266  *  retval : The return value
267  *  N      : The numeric value N
268  */
269 static struct expr_node *
270 parse_argnum(struct locus *loc, char **str, int *ownp, int zero)
271 {
272         struct expr_node *expr = malloc(sizeof(*expr));
273         if (expr == NULL)
274                 return NULL;
275
276         if (isdigit(CTYPE_CONV(**str))) {
277                 long l;
278                 if (parse_int(loc, str, &l) < 0
279                     || check_nonnegative(loc, l) < 0
280                     || check_int(loc, l) < 0)
281                         goto fail;
282
283                 expr_init_const_word(expr, l, type_get_simple(ARGTYPE_LONG), 0);
284
285                 if (zero && wrap_in_zero(&expr) < 0)
286                         goto fail;
287
288                 *ownp = 1;
289                 return expr;
290
291         } else {
292                 char *const name = parse_ident(loc, str);
293                 if (name == NULL) {
294                 fail_ident:
295                         free(name);
296                         goto fail;
297                 }
298
299                 int is_arg = strncmp(name, "arg", 3) == 0;
300                 if (is_arg || strncmp(name, "elt", 3) == 0) {
301                         long l;
302                         char *num = name + 3;
303                         if (parse_int(loc, &num, &l) < 0
304                             || check_int(loc, l) < 0)
305                                 goto fail_ident;
306
307                         if (is_arg) {
308                                 if (l == 0)
309                                         expr_init_named(expr, "retval", 0);
310                                 else
311                                         expr_init_argno(expr, l - 1);
312                         } else {
313                                 struct expr_node *e_up = malloc(sizeof(*e_up));
314                                 struct expr_node *e_ix = malloc(sizeof(*e_ix));
315                                 if (e_up == NULL || e_ix == NULL) {
316                                         free(e_up);
317                                         free(e_ix);
318                                         goto fail_ident;
319                                 }
320
321                                 expr_init_up(e_up, expr_self(), 0);
322                                 struct arg_type_info *ti
323                                         = type_get_simple(ARGTYPE_LONG);
324                                 expr_init_const_word(e_ix, l - 1, ti, 0);
325                                 expr_init_index(expr, e_up, 1, e_ix, 1);
326                         }
327
328                 } else if (strcmp(name, "retval") == 0) {
329                         expr_init_named(expr, "retval", 0);
330
331                 } else if (strcmp(name, "zero") == 0) {
332                         struct expr_node *ret
333                                 = parse_zero(loc, str, ownp);
334                         if (ret == NULL)
335                                 goto fail_ident;
336                         free(expr);
337                         free(name);
338                         return ret;
339
340                 } else {
341                         report_error(loc->filename, loc->line_no,
342                                      "Unknown length specifier: '%s'", name);
343                         goto fail_ident;
344                 }
345
346                 if (zero && wrap_in_zero(&expr) < 0)
347                         goto fail_ident;
348
349                 free(name);
350                 *ownp = 1;
351                 return expr;
352         }
353
354 fail:
355         free(expr);
356         return NULL;
357 }
358
359 static struct arg_type_info *
360 parse_typedef_name(struct protolib *plib, char **str)
361 {
362         char *end = *str;
363         while (*end && (isalnum(CTYPE_CONV(*end)) || *end == '_'))
364                 ++end;
365         if (end == *str)
366                 return NULL;
367
368         size_t len = end - *str;
369         char buf[len + 1];
370         memcpy(buf, *str, len);
371         *str += len;
372         buf[len] = 0;
373
374         struct named_type *nt = protolib_lookup_type(plib, buf, true);
375         if (nt == NULL)
376                 return NULL;
377         return nt->info;
378 }
379
380 static int
381 parse_typedef(struct protolib *plib, struct locus *loc, char **str)
382 {
383         (*str) += strlen("typedef");
384         eat_spaces(str);
385         char *name = parse_ident(loc, str);
386
387         /* Look through the typedef list whether we already have a
388          * forward of this type.  If we do, it must be forward
389          * structure.  */
390         struct named_type *forward = protolib_lookup_type(plib, name, true);
391         if (forward != NULL
392             && (forward->info->type != ARGTYPE_STRUCT
393                 || !forward->forward)) {
394                 report_error(loc->filename, loc->line_no,
395                              "Redefinition of typedef '%s'", name);
396         err:
397                 free(name);
398                 return -1;
399         }
400
401         // Skip = sign
402         eat_spaces(str);
403         if (parse_char(loc, str, '=') < 0)
404                 goto err;
405         eat_spaces(str);
406
407         int fwd = 0;
408         int own = 0;
409         struct arg_type_info *info
410                 = parse_lens(plib, loc, str, NULL, 0, &own, &fwd);
411         if (info == NULL)
412                 goto err;
413
414         struct named_type this_nt;
415         named_type_init(&this_nt, info, own);
416         this_nt.forward = fwd;
417
418         if (forward == NULL) {
419                 if (protolib_add_named_type(plib, name, 1, &this_nt) < 0) {
420                         named_type_destroy(&this_nt);
421                         goto err;
422                 }
423                 return 0;
424         }
425
426         /* If we are defining a forward, make sure the definition is a
427          * structure as well.  */
428         if (this_nt.info->type != ARGTYPE_STRUCT) {
429                 report_error(loc->filename, loc->line_no,
430                              "Definition of forward '%s' must be a structure.",
431                              name);
432                 named_type_destroy(&this_nt);
433                 goto err;
434         }
435
436         /* Now move guts of the actual type over to the forward type.
437          * We can't just move pointers around, because references to
438          * forward must stay intact.  */
439         assert(this_nt.own_type);
440         type_destroy(forward->info);
441         *forward->info = *this_nt.info;
442         forward->forward = 0;
443         free(this_nt.info);
444         free(name);
445         return 0;
446 }
447
448 /* Syntax: struct ( type,type,type,... ) */
449 static int
450 parse_struct(struct protolib *plib, struct locus *loc,
451              char **str, struct arg_type_info *info,
452              int *forwardp)
453 {
454         eat_spaces(str);
455
456         if (**str == ';') {
457                 if (forwardp == NULL) {
458                         report_error(loc->filename, loc->line_no,
459                                      "Forward struct can be declared only "
460                                      "directly after a typedef.");
461                         return -1;
462                 }
463
464                 /* Forward declaration is currently handled as an
465                  * empty struct.  */
466                 type_init_struct(info);
467                 *forwardp = 1;
468                 return 0;
469         }
470
471         if (parse_char(loc, str, '(') < 0)
472                 return -1;
473
474         eat_spaces(str); // Empty arg list with whitespace inside
475
476         type_init_struct(info);
477
478         while (1) {
479                 eat_spaces(str);
480                 if (**str == 0 || **str == ')') {
481                         parse_char(loc, str, ')');
482                         return 0;
483                 }
484
485                 /* Field delimiter.  */
486                 if (type_struct_size(info) > 0)
487                         parse_char(loc, str, ',');
488
489                 eat_spaces(str);
490                 int own;
491                 struct arg_type_info *field
492                         = parse_lens(plib, loc, str, NULL, 0, &own, NULL);
493                 if (field == NULL || type_struct_add(info, field, own)) {
494                         type_destroy(info);
495                         return -1;
496                 }
497         }
498 }
499
500 /* Make a copy of INFO and set the *OWN bit if it's not already
501  * owned.  */
502 static int
503 unshare_type_info(struct locus *loc, struct arg_type_info **infop, int *ownp)
504 {
505         if (*ownp)
506                 return 0;
507
508         struct arg_type_info *ninfo = malloc(sizeof(*ninfo));
509         if (ninfo == NULL || type_clone(ninfo, *infop) < 0) {
510                 report_error(loc->filename, loc->line_no,
511                              "malloc: %s", strerror(errno));
512                 free(ninfo);
513                 return -1;
514         }
515         *infop = ninfo;
516         *ownp = 1;
517         return 0;
518 }
519
520 static int
521 parse_string(struct protolib *plib, struct locus *loc,
522              char **str, struct arg_type_info **retp, int *ownp)
523 {
524         struct arg_type_info *info = NULL;
525         struct expr_node *length;
526         int own_length;
527
528         if (isdigit(CTYPE_CONV(**str))) {
529                 /* string0 is string[retval], length is zero(retval)
530                  * stringN is string[argN], length is zero(argN) */
531                 long l;
532                 if (parse_int(loc, str, &l) < 0
533                     || check_int(loc, l) < 0)
534                         return -1;
535
536                 struct expr_node *length_arg = malloc(sizeof(*length_arg));
537                 if (length_arg == NULL)
538                         return -1;
539
540                 if (l == 0)
541                         expr_init_named(length_arg, "retval", 0);
542                 else
543                         expr_init_argno(length_arg, l - 1);
544
545                 length = build_zero_w_arg(length_arg, 1);
546                 if (length == NULL) {
547                         expr_destroy(length_arg);
548                         free(length_arg);
549                         return -1;
550                 }
551                 own_length = 1;
552
553         } else {
554                 eat_spaces(str);
555                 if (**str == '[') {
556                         (*str)++;
557                         eat_spaces(str);
558
559                         length = parse_argnum(loc, str, &own_length, 1);
560                         if (length == NULL)
561                                 return -1;
562
563                         eat_spaces(str);
564                         parse_char(loc, str, ']');
565
566                 } else if (**str == '(') {
567                         /* Usage of "string" as lens.  */
568                         ++*str;
569
570                         eat_spaces(str);
571                         info = parse_type(plib, loc, str, NULL, 0, ownp, NULL);
572                         if (info == NULL)
573                                 return -1;
574
575                         length = NULL;
576                         own_length = 0;
577
578                         eat_spaces(str);
579                         parse_char(loc, str, ')');
580
581                 } else {
582                         /* It was just a simple string after all.  */
583                         length = expr_node_zero();
584                         own_length = 0;
585                 }
586         }
587
588         /* String is a pointer to array of chars.  */
589         if (info == NULL) {
590                 struct arg_type_info *info1 = malloc(sizeof(*info1));
591                 struct arg_type_info *info2 = malloc(sizeof(*info2));
592                 if (info1 == NULL || info2 == NULL) {
593                         free(info1);
594                         free(info2);
595                 fail:
596                         if (own_length) {
597                                 assert(length != NULL);
598                                 expr_destroy(length);
599                                 free(length);
600                         }
601                         return -1;
602                 }
603                 type_init_array(info2, type_get_simple(ARGTYPE_CHAR), 0,
604                                 length, own_length);
605                 type_init_pointer(info1, info2, 1);
606
607                 info = info1;
608                 *ownp = 1;
609         }
610
611         /* We'll need to set the lens, so unshare.  */
612         if (unshare_type_info(loc, &info, ownp) < 0)
613                 /* If unshare_type_info failed, it must have been as a
614                  * result of cloning attempt because *OWNP was 0.
615                  * Thus we don't need to destroy INFO.  */
616                 goto fail;
617
618         info->lens = &string_lens;
619         info->own_lens = 0;
620
621         *retp = info;
622         return 0;
623 }
624
625 static int
626 build_printf_pack(struct locus *loc, struct param **packp, size_t param_num)
627 {
628         if (packp == NULL) {
629                 report_error(loc->filename, loc->line_no,
630                              "'format' type in unexpected context");
631                 return -1;
632         }
633         if (*packp != NULL) {
634                 report_error(loc->filename, loc->line_no,
635                              "only one 'format' type per function supported");
636                 return -1;
637         }
638
639         *packp = malloc(sizeof(**packp));
640         if (*packp == NULL)
641                 return -1;
642
643         struct expr_node *node = malloc(sizeof(*node));
644         if (node == NULL) {
645                 free(*packp);
646                 *packp = NULL;
647                 return -1;
648         }
649
650         expr_init_argno(node, param_num);
651
652         param_pack_init_printf(*packp, node, 1);
653
654         return 0;
655 }
656
657 /* Match and consume KWD if it's next in stream, and return 0.
658  * Otherwise return negative number.  */
659 static int
660 try_parse_kwd(char **str, const char *kwd)
661 {
662         size_t len = strlen(kwd);
663         if (strncmp(*str, kwd, len) == 0
664             && !isalnum(CTYPE_CONV((*str)[len]))
665             && (*str)[len] != '_') {
666                 (*str) += len;
667                 return 0;
668         }
669         return -1;
670 }
671
672 /* XXX EXTRA_PARAM and PARAM_NUM are a kludge to get in
673  * backward-compatible support for "format" parameter type.  The
674  * latter is only valid if the former is non-NULL, which is only in
675  * top-level context.  */
676 static int
677 parse_alias(struct protolib *plib, struct locus *loc,
678             char **str, struct arg_type_info **retp, int *ownp,
679             struct param **extra_param, size_t param_num)
680 {
681         /* For backward compatibility, we need to support things like
682          * stringN (which is like string[argN], string[N], and also
683          * bare string.  We might, in theory, replace this by
684          * preprocessing configure file sources with M4, but for now,
685          * "string" is syntax.  */
686         if (strncmp(*str, "string", 6) == 0) {
687                 (*str) += 6;
688                 return parse_string(plib, loc, str, retp, ownp);
689
690         } else if (try_parse_kwd(str, "format") >= 0
691                    && extra_param != NULL) {
692                 /* For backward compatibility, format is parsed as
693                  * "string", but it smuggles to the parameter list of
694                  * a function a "printf" argument pack with this
695                  * parameter as argument.  */
696                 if (parse_string(plib, loc, str, retp, ownp) < 0)
697                         return -1;
698
699                 return build_printf_pack(loc, extra_param, param_num);
700
701         } else if (try_parse_kwd(str, "enum") >=0) {
702
703                 return parse_enum(plib, loc, str, retp, ownp);
704
705         } else {
706                 *retp = NULL;
707                 return 0;
708         }
709 }
710
711 /* Syntax: array ( type, N|argN ) */
712 static int
713 parse_array(struct protolib *plib, struct locus *loc,
714             char **str, struct arg_type_info *info)
715 {
716         eat_spaces(str);
717         if (parse_char(loc, str, '(') < 0)
718                 return -1;
719
720         eat_spaces(str);
721         int own;
722         struct arg_type_info *elt_info
723                 = parse_lens(plib, loc, str, NULL, 0, &own, NULL);
724         if (elt_info == NULL)
725                 return -1;
726
727         eat_spaces(str);
728         parse_char(loc, str, ',');
729
730         eat_spaces(str);
731         int own_length;
732         struct expr_node *length = parse_argnum(loc, str, &own_length, 0);
733         if (length == NULL) {
734                 if (own) {
735                         type_destroy(elt_info);
736                         free(elt_info);
737                 }
738                 return -1;
739         }
740
741         type_init_array(info, elt_info, own, length, own_length);
742
743         eat_spaces(str);
744         parse_char(loc, str, ')');
745         return 0;
746 }
747
748 /* Syntax:
749  *   enum (keyname[=value],keyname[=value],... )
750  *   enum<type> (keyname[=value],keyname[=value],... )
751  */
752 static int
753 parse_enum(struct protolib *plib, struct locus *loc, char **str,
754            struct arg_type_info **retp, int *ownp)
755 {
756         /* Optional type argument.  */
757         eat_spaces(str);
758         if (**str == '[') {
759                 parse_char(loc, str, '[');
760                 eat_spaces(str);
761                 *retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, 0);
762                 if (*retp == NULL)
763                         return -1;
764
765                 if (!type_is_integral((*retp)->type)) {
766                         report_error(loc->filename, loc->line_no,
767                                      "integral type required as enum argument");
768                 fail:
769                         if (*ownp) {
770                                 /* This also releases associated lens
771                                  * if any was set so far.  */
772                                 type_destroy(*retp);
773                                 free(*retp);
774                         }
775                         return -1;
776                 }
777
778                 eat_spaces(str);
779                 if (parse_char(loc, str, ']') < 0)
780                         goto fail;
781
782         } else {
783                 *retp = type_get_simple(ARGTYPE_INT);
784                 *ownp = 0;
785         }
786
787         /* We'll need to set the lens, so unshare.  */
788         if (unshare_type_info(loc, retp, ownp) < 0)
789                 goto fail;
790
791         eat_spaces(str);
792         if (parse_char(loc, str, '(') < 0)
793                 goto fail;
794
795         struct enum_lens *lens = malloc(sizeof(*lens));
796         if (lens == NULL) {
797                 report_error(loc->filename, loc->line_no,
798                              "malloc enum lens: %s", strerror(errno));
799                 return -1;
800         }
801
802         lens_init_enum(lens);
803         (*retp)->lens = &lens->super;
804         (*retp)->own_lens = 1;
805
806         long last_val = 0;
807         while (1) {
808                 eat_spaces(str);
809                 if (**str == 0 || **str == ')') {
810                         parse_char(loc, str, ')');
811                         return 0;
812                 }
813
814                 /* Field delimiter.  XXX should we support the C
815                  * syntax, where the enumeration can end in pending
816                  * comma?  */
817                 if (lens_enum_size(lens) > 0)
818                         parse_char(loc, str, ',');
819
820                 eat_spaces(str);
821                 char *key = parse_ident(loc, str);
822                 if (key == NULL) {
823                 err:
824                         free(key);
825                         goto fail;
826                 }
827
828                 if (**str == '=') {
829                         ++*str;
830                         eat_spaces(str);
831                         if (parse_int(loc, str, &last_val) < 0)
832                                 goto err;
833                 }
834
835                 struct value *value = malloc(sizeof(*value));
836                 if (value == NULL)
837                         goto err;
838                 value_init_detached(value, NULL, *retp, 0);
839                 value_set_word(value, last_val);
840
841                 if (lens_enum_add(lens, key, 1, value, 1) < 0)
842                         goto err;
843
844                 last_val++;
845         }
846
847         return 0;
848 }
849
850 static struct arg_type_info *
851 parse_nonpointer_type(struct protolib *plib, struct locus *loc,
852                       char **str, struct param **extra_param, size_t param_num,
853                       int *ownp, int *forwardp)
854 {
855         const char *orig_str = *str;
856         enum arg_type type;
857         if (parse_arg_type(str, &type) < 0) {
858                 struct arg_type_info *type;
859                 if (parse_alias(plib, loc, str, &type,
860                                 ownp, extra_param, param_num) < 0)
861                         return NULL;
862                 else if (type != NULL)
863                         return type;
864
865                 *ownp = 0;
866                 if ((type = parse_typedef_name(plib, str)) == NULL)
867                         report_error(loc->filename, loc->line_no,
868                                      "unknown type around '%s'", orig_str);
869                 return type;
870         }
871
872         /* For some types that's all we need.  */
873         switch (type) {
874         case ARGTYPE_VOID:
875         case ARGTYPE_INT:
876         case ARGTYPE_UINT:
877         case ARGTYPE_LONG:
878         case ARGTYPE_ULONG:
879         case ARGTYPE_CHAR:
880         case ARGTYPE_SHORT:
881         case ARGTYPE_USHORT:
882         case ARGTYPE_FLOAT:
883         case ARGTYPE_DOUBLE:
884                 *ownp = 0;
885                 return type_get_simple(type);
886
887         case ARGTYPE_ARRAY:
888         case ARGTYPE_STRUCT:
889                 break;
890
891         case ARGTYPE_POINTER:
892                 /* Pointer syntax is not based on keyword, so we
893                  * should never get this type.  */
894                 assert(type != ARGTYPE_POINTER);
895                 abort();
896         }
897
898         struct arg_type_info *info = malloc(sizeof(*info));
899         if (info == NULL) {
900                 report_error(loc->filename, loc->line_no,
901                              "malloc: %s", strerror(errno));
902                 return NULL;
903         }
904         *ownp = 1;
905
906         if (type == ARGTYPE_ARRAY) {
907                 if (parse_array(plib, loc, str, info) < 0) {
908                 fail:
909                         free(info);
910                         return NULL;
911                 }
912         } else {
913                 assert(type == ARGTYPE_STRUCT);
914                 if (parse_struct(plib, loc, str, info, forwardp) < 0)
915                         goto fail;
916         }
917
918         return info;
919 }
920
921 static struct named_lens {
922         const char *name;
923         struct lens *lens;
924 } lenses[] = {
925         { "hide", &blind_lens },
926         { "octal", &octal_lens },
927         { "oct", &octal_lens },
928         { "bitvec", &bitvect_lens },
929         { "hex", &hex_lens },
930         { "bool", &bool_lens },
931         { "guess", &guess_lens },
932 };
933
934 static struct lens *
935 name2lens(char **str, int *own_lensp)
936 {
937         size_t i;
938         for (i = 0; i < sizeof(lenses)/sizeof(*lenses); ++i)
939                 if (try_parse_kwd(str, lenses[i].name) == 0) {
940                         *own_lensp = 0;
941                         return lenses[i].lens;
942                 }
943
944         return NULL;
945 }
946
947 static struct arg_type_info *
948 parse_type(struct protolib *plib, struct locus *loc, char **str,
949            struct param **extra_param, size_t param_num,
950            int *ownp, int *forwardp)
951 {
952         struct arg_type_info *info
953                 = parse_nonpointer_type(plib, loc, str, extra_param,
954                                         param_num, ownp, forwardp);
955         if (info == NULL)
956                 return NULL;
957
958         while (1) {
959                 eat_spaces(str);
960                 if (**str == '*') {
961                         struct arg_type_info *outer = malloc(sizeof(*outer));
962                         if (outer == NULL) {
963                                 if (*ownp) {
964                                         type_destroy(info);
965                                         free(info);
966                                 }
967                                 report_error(loc->filename, loc->line_no,
968                                              "malloc: %s", strerror(errno));
969                                 return NULL;
970                         }
971                         type_init_pointer(outer, info, *ownp);
972                         *ownp = 1;
973                         (*str)++;
974                         info = outer;
975                 } else
976                         break;
977         }
978         return info;
979 }
980
981 static struct arg_type_info *
982 parse_lens(struct protolib *plib, struct locus *loc,
983            char **str, struct param **extra_param,
984            size_t param_num, int *ownp, int *forwardp)
985 {
986         int own_lens;
987         struct lens *lens = name2lens(str, &own_lens);
988         int has_args = 1;
989         struct arg_type_info *info;
990         if (lens != NULL) {
991                 eat_spaces(str);
992
993                 /* Octal lens gets special treatment, because of
994                  * backward compatibility.  */
995                 if (lens == &octal_lens && **str != '(') {
996                         has_args = 0;
997                         info = type_get_simple(ARGTYPE_INT);
998                         *ownp = 0;
999                 } else if (parse_char(loc, str, '(') < 0) {
1000                         report_error(loc->filename, loc->line_no,
1001                                      "expected type argument after the lens");
1002                         return NULL;
1003                 }
1004         }
1005
1006         if (has_args) {
1007                 eat_spaces(str);
1008                 info = parse_type(plib, loc, str, extra_param, param_num,
1009                                   ownp, forwardp);
1010                 if (info == NULL) {
1011                 fail:
1012                         if (own_lens && lens != NULL)
1013                                 lens_destroy(lens);
1014                         return NULL;
1015                 }
1016         }
1017
1018         if (lens != NULL && has_args) {
1019                 eat_spaces(str);
1020                 parse_char(loc, str, ')');
1021         }
1022
1023         /* We can't modify shared types.  Make a copy if we have a
1024          * lens.  */
1025         if (lens != NULL && unshare_type_info(loc, &info, ownp) < 0)
1026                 goto fail;
1027
1028         if (lens != NULL) {
1029                 info->lens = lens;
1030                 info->own_lens = own_lens;
1031         }
1032
1033         return info;
1034 }
1035
1036 static int
1037 param_is_void(struct param *param)
1038 {
1039         return param->flavor == PARAM_FLAVOR_TYPE
1040                 && param->u.type.type->type == ARGTYPE_VOID;
1041 }
1042
1043 static struct arg_type_info *
1044 get_hidden_int(void)
1045 {
1046         static struct arg_type_info info, *pinfo = NULL;
1047         if (pinfo != NULL)
1048                 return pinfo;
1049
1050         info = *type_get_simple(ARGTYPE_INT);
1051         info.lens = &blind_lens;
1052         pinfo = &info;
1053
1054         return pinfo;
1055 }
1056
1057 static enum callback_status
1058 void_to_hidden_int(struct prototype *proto, struct param *param, void *data)
1059 {
1060         struct locus *loc = data;
1061         if (param_is_void(param)) {
1062                 report_warning(loc->filename, loc->line_no,
1063                                "void parameter assumed to be 'hide(int)'");
1064
1065                 static struct arg_type_info *type = NULL;
1066                 if (type == NULL)
1067                         type = get_hidden_int();
1068                 param_destroy(param);
1069                 param_init_type(param, type, 0);
1070         }
1071         return CBS_CONT;
1072 }
1073
1074 static int
1075 process_line(struct protolib *plib, struct locus *loc, char *buf)
1076 {
1077         char *str = buf;
1078
1079         debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename);
1080         eat_spaces(&str);
1081
1082         /* A comment or empty line.  */
1083         if (*str == ';' || *str == 0 || *str == '\n' || *str == '#')
1084                 return 0;
1085
1086         if (strncmp(str, "typedef", 7) == 0) {
1087                 parse_typedef(plib, loc, &str);
1088                 return 0;
1089         }
1090
1091         struct prototype fun;
1092         prototype_init(&fun);
1093
1094         struct param *extra_param = NULL;
1095         char *proto_name = NULL;
1096         int own;
1097         fun.return_info = parse_lens(plib, loc, &str, NULL, 0, &own, NULL);
1098         if (fun.return_info == NULL) {
1099         err:
1100                 debug(3, " Skipping line %d", loc->line_no);
1101
1102                 if (extra_param != NULL) {
1103                         param_destroy(extra_param);
1104                         free(extra_param);
1105                 }
1106
1107                 prototype_destroy(&fun);
1108                 free(proto_name);
1109                 return -1;
1110         }
1111         fun.own_return_info = own;
1112         debug(4, " return_type = %d", fun.return_info->type);
1113
1114         eat_spaces(&str);
1115         proto_name = parse_ident(loc, &str);
1116         if (proto_name == NULL)
1117                 goto err;
1118
1119         eat_spaces(&str);
1120         if (parse_char(loc, &str, '(') < 0)
1121                 goto err;
1122         debug(3, " name = %s", proto_name);
1123
1124         int have_stop = 0;
1125
1126         while (1) {
1127                 eat_spaces(&str);
1128                 if (*str == ')')
1129                         break;
1130
1131                 if (str[0] == '+') {
1132                         if (have_stop == 0) {
1133                                 struct param param;
1134                                 param_init_stop(&param);
1135                                 if (prototype_push_param(&fun, &param) < 0) {
1136                                 oom:
1137                                         report_error(loc->filename,
1138                                                      loc->line_no,
1139                                                      "%s", strerror(errno));
1140                                         goto err;
1141                                 }
1142                                 have_stop = 1;
1143                         }
1144                         str++;
1145                 }
1146
1147                 int own;
1148                 size_t param_num = prototype_num_params(&fun) - have_stop;
1149                 struct arg_type_info *type
1150                         = parse_lens(plib, loc, &str, &extra_param,
1151                                      param_num, &own, NULL);
1152                 if (type == NULL) {
1153                         report_error(loc->filename, loc->line_no,
1154                                      "unknown argument type");
1155                         goto err;
1156                 }
1157
1158                 struct param param;
1159                 param_init_type(&param, type, own);
1160                 if (prototype_push_param(&fun, &param) < 0)
1161                         goto oom;
1162
1163                 eat_spaces(&str);
1164                 if (*str == ',') {
1165                         str++;
1166                         continue;
1167                 } else if (*str == ')') {
1168                         continue;
1169                 } else {
1170                         if (str[strlen(str) - 1] == '\n')
1171                                 str[strlen(str) - 1] = '\0';
1172                         report_error(loc->filename, loc->line_no,
1173                                      "syntax error around \"%s\"", str);
1174                         goto err;
1175                 }
1176         }
1177
1178         /* We used to allow void parameter as a synonym to an argument
1179          * that shouldn't be displayed.  But backends really need to
1180          * know the exact type that they are dealing with.  The proper
1181          * way to do this these days is to use the hide lens.
1182          *
1183          * So if there are any voids in the parameter list, show a
1184          * warning and assume that they are ints.  If there's a sole
1185          * void, assume the function doesn't take any arguments.  The
1186          * latter is conservative, we can drop the argument
1187          * altogether, instead of fetching and then not showing it,
1188          * without breaking any observable behavior.  */
1189         if (prototype_num_params(&fun) == 1
1190             && param_is_void(prototype_get_nth_param(&fun, 0))) {
1191                 if (0)
1192                         /* Don't show this warning.  Pre-0.7.0
1193                          * ltrace.conf often used this idiom.  This
1194                          * should be postponed until much later, when
1195                          * extant uses are likely gone.  */
1196                         report_warning(loc->filename, loc->line_no,
1197                                        "sole void parameter ignored");
1198                 prototype_destroy_nth_param(&fun, 0);
1199         } else {
1200                 prototype_each_param(&fun, NULL, void_to_hidden_int, loc);
1201         }
1202
1203         if (extra_param != NULL) {
1204                 prototype_push_param(&fun, extra_param);
1205                 free(extra_param);
1206                 extra_param = NULL;
1207         }
1208
1209         if (protolib_add_prototype(plib, proto_name, 1, &fun) < 0) {
1210                 report_error(loc->filename, loc->line_no,
1211                              "couldn't add prototype: %s",
1212                              strerror(errno));
1213                 goto err;
1214         }
1215
1216         return 0;
1217 }
1218
1219 int
1220 read_config_file(FILE *stream, const char *path, struct protolib *plib)
1221 {
1222         debug(DEBUG_FUNCTION, "Reading config file `%s'...", path);
1223
1224         struct locus loc = { path, 0 };
1225         char *line = NULL;
1226         size_t len = 0;
1227         while (getline(&line, &len, stream) >= 0) {
1228                 loc.line_no++;
1229                 process_line(plib, &loc, line);
1230         }
1231
1232         free(line);
1233         return 0;
1234 }