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