1 /*
   2  * Copyright (C) 2015 Rasmus Villemoes.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #define _GNU_SOURCE
  19 
  20 #include <assert.h>
  21 #include <ctype.h>
  22 #include <string.h>
  23 #include "smatch.h"
  24 #include "smatch_slist.h"
  25 
  26 #define spam(args...) do {                      \
  27         if (option_spammy)                      \
  28                 sm_msg(args);                   \
  29         } while (0)
  30 
  31 static int my_id;
  32 
  33 /*
  34  * Much of this is taken directly from the kernel (mostly vsprintf.c),
  35  * with a few modifications here and there.
  36  */
  37 
  38 #define KERN_SOH_ASCII  '\001'
  39 
  40 typedef unsigned char u8;
  41 typedef signed short s16;
  42 
  43 #define SIGN    1               /* unsigned/signed, must be 1 */
  44 #define LEFT    2               /* left justified */
  45 #define PLUS    4               /* show plus */
  46 #define SPACE   8               /* space if plus */
  47 #define ZEROPAD 16              /* pad with zero, must be 16 == '0' - ' ' */
  48 #define SMALL   32              /* use lowercase in hex (must be 32 == 0x20) */
  49 #define SPECIAL 64              /* prefix hex with "0x", octal with "0" */
  50 
  51 enum format_type {
  52         FORMAT_TYPE_NONE, /* Just a string part */
  53         FORMAT_TYPE_WIDTH,
  54         FORMAT_TYPE_PRECISION,
  55         FORMAT_TYPE_CHAR,
  56         FORMAT_TYPE_STR,
  57         FORMAT_TYPE_PTR,
  58         FORMAT_TYPE_PERCENT_CHAR,
  59         FORMAT_TYPE_INVALID,
  60         FORMAT_TYPE_LONG_LONG,
  61         FORMAT_TYPE_ULONG,
  62         FORMAT_TYPE_LONG,
  63         FORMAT_TYPE_UBYTE,
  64         FORMAT_TYPE_BYTE,
  65         FORMAT_TYPE_USHORT,
  66         FORMAT_TYPE_SHORT,
  67         FORMAT_TYPE_UINT,
  68         FORMAT_TYPE_INT,
  69         FORMAT_TYPE_SIZE_T,
  70         FORMAT_TYPE_PTRDIFF,
  71         FORMAT_TYPE_NRCHARS, /* Reintroduced for this checker */
  72         FORMAT_TYPE_FLOAT, /* for various floating point formatters */
  73 };
  74 
  75 struct printf_spec {
  76         unsigned int    type:8;         /* format_type enum */
  77         signed int      field_width:24; /* width of output field */
  78         unsigned int    flags:8;        /* flags to number() */
  79         unsigned int    base:8;         /* number base, 8, 10 or 16 only */
  80         signed int      precision:16;   /* # of digits/chars */
  81 } __packed;
  82 #define FIELD_WIDTH_MAX ((1 << 23) - 1)
  83 #define PRECISION_MAX ((1 << 15) - 1)
  84 extern char __check_printf_spec[1-2*(sizeof(struct printf_spec) != 8)];
  85 
  86 static int
  87 skip_atoi(const char **s)
  88 {
  89         int i = 0;
  90 
  91         while (isdigit(**s))
  92                 i = i*10 + *((*s)++) - '0';
  93 
  94         return i;
  95 }
  96 
  97 static int
  98 format_decode(const char *fmt, struct printf_spec *spec)
  99 {
 100         const char *start = fmt;
 101         char qualifier;
 102 
 103         /* we finished early by reading the field width */
 104         if (spec->type == FORMAT_TYPE_WIDTH) {
 105                 if (spec->field_width < 0) {
 106                         spec->field_width = -spec->field_width;
 107                         spec->flags |= LEFT;
 108                 }
 109                 spec->type = FORMAT_TYPE_NONE;
 110                 goto precision;
 111         }
 112 
 113         /* we finished early by reading the precision */
 114         if (spec->type == FORMAT_TYPE_PRECISION) {
 115                 if (spec->precision < 0)
 116                         spec->precision = 0;
 117 
 118                 spec->type = FORMAT_TYPE_NONE;
 119                 goto qualifier;
 120         }
 121 
 122         /* By default */
 123         spec->type = FORMAT_TYPE_NONE;
 124 
 125         for (; *fmt ; ++fmt) {
 126                 if (*fmt == '%')
 127                         break;
 128         }
 129 
 130         /* Return the current non-format string */
 131         if (fmt != start || !*fmt)
 132                 return fmt - start;
 133 
 134         /* Process flags */
 135         spec->flags = 0;
 136 
 137         while (1) { /* this also skips first '%' */
 138                 bool found = true;
 139 
 140                 ++fmt;
 141 
 142                 switch (*fmt) {
 143                 case '-': spec->flags |= LEFT;    break;
 144                 case '+': spec->flags |= PLUS;    break;
 145                 case ' ': spec->flags |= SPACE;   break;
 146                 case '#': spec->flags |= SPECIAL; break;
 147                 case '0': spec->flags |= ZEROPAD; break;
 148                 default:  found = false;
 149                 }
 150 
 151                 if (!found)
 152                         break;
 153         }
 154 
 155         /* get field width */
 156         spec->field_width = -1;
 157 
 158         if (isdigit(*fmt))
 159                 spec->field_width = skip_atoi(&fmt);
 160         else if (*fmt == '*') {
 161                 /* it's the next argument */
 162                 spec->type = FORMAT_TYPE_WIDTH;
 163                 return ++fmt - start;
 164         }
 165 
 166 precision:
 167         /* get the precision */
 168         spec->precision = -1;
 169         if (*fmt == '.') {
 170                 ++fmt;
 171                 if (isdigit(*fmt)) {
 172                         spec->precision = skip_atoi(&fmt);
 173                         if (spec->precision < 0)
 174                                 spec->precision = 0;
 175                 } else if (*fmt == '*') {
 176                         /* it's the next argument */
 177                         spec->type = FORMAT_TYPE_PRECISION;
 178                         return ++fmt - start;
 179                 }
 180         }
 181 
 182 qualifier:
 183         /* get the conversion qualifier */
 184         qualifier = 0;
 185         if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
 186             _tolower(*fmt) == 'z' || *fmt == 't') {
 187                 qualifier = *fmt++;
 188                 if (qualifier == *fmt) {
 189                         if (qualifier == 'l') {
 190                                 qualifier = 'L';
 191                                 ++fmt;
 192                         } else if (qualifier == 'h') {
 193                                 qualifier = 'H';
 194                                 ++fmt;
 195                         } else {
 196                                 sm_warning("invalid repeated qualifier '%c'", *fmt);
 197                         }
 198                 }
 199         }
 200 
 201         /* default base */
 202         spec->base = 10;
 203         switch (*fmt) {
 204         case 'c':
 205                 if (qualifier)
 206                         sm_warning("qualifier '%c' ignored for %%c specifier", qualifier);
 207 
 208                 spec->type = FORMAT_TYPE_CHAR;
 209                 return ++fmt - start;
 210 
 211         case 's':
 212                 if (qualifier && qualifier != 'l')
 213                         sm_warning("qualifier '%c' ignored for %%s specifier", qualifier);
 214 
 215                 spec->type = FORMAT_TYPE_STR;
 216                 return ++fmt - start;
 217 
 218         case 'p':
 219                 spec->type = FORMAT_TYPE_PTR;
 220                 return ++fmt - start;
 221 
 222         case '%':
 223                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
 224                 return ++fmt - start;
 225 
 226         /* integer number formats - set up the flags and "break" */
 227         case 'o':
 228                 spec->base = 8;
 229                 break;
 230 
 231         case 'x':
 232                 spec->flags |= SMALL;
 233 
 234         case 'X':
 235                 spec->base = 16;
 236                 break;
 237 
 238         case 'd':
 239         case 'i':
 240                 spec->flags |= SIGN;
 241         case 'u':
 242                 break;
 243 
 244         case 'n':
 245                 spec->type = FORMAT_TYPE_NRCHARS;
 246                 return ++fmt - start;
 247 
 248         case 'a': case 'A':
 249         case 'e': case 'E':
 250         case 'f': case 'F':
 251         case 'g': case 'G':
 252                 spec->type = FORMAT_TYPE_FLOAT;
 253                 return ++fmt - start;
 254 
 255         default:
 256                 spec->type = FORMAT_TYPE_INVALID;
 257                 /* Unlike the kernel code, we 'consume' the invalid
 258                  * character so that it can get included in the
 259                  * report. After that, we bail out. */
 260                 return ++fmt - start;
 261         }
 262 
 263         if (qualifier == 'L')
 264                 spec->type = FORMAT_TYPE_LONG_LONG;
 265         else if (qualifier == 'l') {
 266                 if (spec->flags & SIGN)
 267                         spec->type = FORMAT_TYPE_LONG;
 268                 else
 269                         spec->type = FORMAT_TYPE_ULONG;
 270         } else if (_tolower(qualifier) == 'z') {
 271                 spec->type = FORMAT_TYPE_SIZE_T;
 272         } else if (qualifier == 't') {
 273                 spec->type = FORMAT_TYPE_PTRDIFF;
 274         } else if (qualifier == 'H') {
 275                 if (spec->flags & SIGN)
 276                         spec->type = FORMAT_TYPE_BYTE;
 277                 else
 278                         spec->type = FORMAT_TYPE_UBYTE;
 279         } else if (qualifier == 'h') {
 280                 if (spec->flags & SIGN)
 281                         spec->type = FORMAT_TYPE_SHORT;
 282                 else
 283                         spec->type = FORMAT_TYPE_USHORT;
 284         } else {
 285                 if (spec->flags & SIGN)
 286                         spec->type = FORMAT_TYPE_INT;
 287                 else
 288                         spec->type = FORMAT_TYPE_UINT;
 289         }
 290 
 291         return ++fmt - start;
 292 }
 293 
 294 static int is_struct_tag(struct symbol *type, const char *tag)
 295 {
 296         return type->type == SYM_STRUCT && type->ident && !strcmp(type->ident->name, tag);
 297 }
 298 
 299 static int has_struct_tag(struct symbol *type, const char *tag)
 300 {
 301         struct symbol *tmp;
 302 
 303         if (type->type == SYM_STRUCT)
 304                 return is_struct_tag(type, tag);
 305         if (type->type == SYM_UNION) {
 306                 FOR_EACH_PTR(type->symbol_list, tmp) {
 307                         tmp = get_real_base_type(tmp);
 308                         if (tmp && is_struct_tag(tmp, tag))
 309                                 return 1;
 310                 } END_FOR_EACH_PTR(tmp);
 311         }
 312         return 0;
 313 }
 314 
 315 static int is_char_type(struct symbol *type)
 316 {
 317         return type == &uchar_ctype || type == &char_ctype || type == &schar_ctype;
 318 }
 319 
 320 /*
 321  * I have absolutely no idea if this is how one is supposed to get the
 322  * symbol representing a typedef, but it seems to work.
 323  */
 324 struct typedef_lookup {
 325         const char *name;
 326         struct symbol *sym;
 327         int failed;
 328 };
 329 
 330 static struct symbol *_typedef_lookup(const char *name)
 331 {
 332         struct ident *id;
 333         struct symbol *node;
 334 
 335         id = built_in_ident(name);
 336         if (!id)
 337                 return NULL;
 338         node = lookup_symbol(id, NS_TYPEDEF);
 339         if (!node || node->type != SYM_NODE)
 340                 return NULL;
 341         return get_real_base_type(node);
 342 }
 343 
 344 static void typedef_lookup(struct typedef_lookup *tl)
 345 {
 346         if (tl->sym || tl->failed)
 347                 return;
 348         tl->sym = _typedef_lookup(tl->name);
 349         if (!tl->sym) {
 350                 sm_perror(" could not find typedef '%s'", tl->name);
 351                 tl->failed = 1;
 352         }
 353 }
 354 
 355 
 356 static void ip4(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 357 {
 358         enum { ENDIAN_BIG, ENDIAN_LITTLE, ENDIAN_HOST } endian = ENDIAN_BIG;
 359 
 360         assert(fmt[0] == 'i' || fmt[0] == 'I');
 361         assert(fmt[1] == '4');
 362 
 363         if (isalnum(fmt[2])) {
 364                 switch (fmt[2]) {
 365                 case 'h':
 366                         endian = ENDIAN_HOST;
 367                         break;
 368                 case 'l':
 369                         endian = ENDIAN_LITTLE;
 370                         break;
 371                 case 'n':
 372                 case 'b':
 373                         endian = ENDIAN_BIG;
 374                         break;
 375                 default:
 376                         sm_warning("'%%p%c4' can only be followed by one of [hnbl], not '%c'", fmt[0], fmt[2]);
 377                 }
 378                 if (isalnum(fmt[3]))
 379                         sm_warning("'%%p%c4' can only be followed by precisely one of [hnbl]", fmt[0]);
 380         }
 381 
 382 
 383         if (type->ctype.modifiers & MOD_NODEREF)
 384                 sm_error("passing __user pointer to '%%p%c4'", fmt[0]);
 385 
 386         /*
 387          * If we have a pointer to char/u8/s8, we expect the caller to
 388          * handle endianness; I don't think there's anything we can
 389          * do. I'd like to check that if we're passed a pointer to a
 390          * __bitwise u32 (most likely a __be32), we should have endian
 391          * == ENDIAN_BIG. But I can't figure out how to get that
 392          * information (it also seems to require ensuring certain
 393          * macros are defined). But struct in_addr certainly consists
 394          * of only a single __be32, so in that case we can do a check.
 395          */
 396         if (is_char_type(basetype))
 397                 return;
 398 
 399         if (is_struct_tag(basetype, "in_addr") && endian != ENDIAN_BIG)
 400                 sm_warning("passing struct in_addr* to '%%p%c4%c', is the endianness ok?", fmt[0], fmt[2]);
 401 
 402         /* ... */
 403 }
 404 
 405 static void ip6(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 406 {
 407         assert(fmt[0] == 'i' || fmt[0] == 'I');
 408         assert(fmt[1] == '6');
 409 
 410         if (isalnum(fmt[2])) {
 411                 if (fmt[2] != 'c')
 412                         sm_warning("'%%p%c6' can only be followed by c", fmt[0]);
 413                 else if (fmt[0] == 'i')
 414                         sm_warning("'%%pi6' does not allow flag c");
 415                 if (isalnum(fmt[3]))
 416                         sm_warning("'%%p%c6%c' cannot be followed by other alphanumerics", fmt[0], fmt[2]);
 417         }
 418 
 419         if (type->ctype.modifiers & MOD_NODEREF)
 420                 sm_error("passing __user pointer to '%%p%c6'", fmt[0]);
 421 }
 422 
 423 static void ipS(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 424 {
 425         const char *f;
 426 
 427         assert(tolower(fmt[0]) == 'i');
 428         assert(fmt[1] == 'S');
 429 
 430         for (f = fmt+2; isalnum(*f); ++f) {
 431                 /* It's probably too anal checking for duplicate flags. */
 432                 if (!strchr("pfschnbl", *f))
 433                         sm_warning("'%%p%cS' cannot be followed by '%c'", fmt[0], *f);
 434         }
 435 
 436         /*
 437          * XXX: Should we also allow passing a pointer to a union, one
 438          * member of which is a struct sockaddr? It may be slightly
 439          * cleaner actually passing &u.raw instead of just &u, though
 440          * the generated code is of course exactly the same. For now,
 441          * we do accept struct sockaddr_in and struct sockaddr_in6,
 442          * since those are easy to handle and rather harmless.
 443          */
 444         if (!has_struct_tag(basetype, "sockaddr") &&
 445             !has_struct_tag(basetype, "sockaddr_in") &&
 446             !has_struct_tag(basetype, "sockaddr_in6") &&
 447             !has_struct_tag(basetype, "__kernel_sockaddr_storage"))
 448                 sm_error("'%%p%cS' expects argument of type struct sockaddr *, "
 449                         "argument %d has type '%s'", fmt[0], vaidx, type_to_str(type));
 450 }
 451 
 452 static void hex_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 453 {
 454         assert(fmt[0] == 'h');
 455         if (isalnum(fmt[1])) {
 456                 if (!strchr("CDN", fmt[1]))
 457                         sm_warning("'%%ph' cannot be followed by '%c'", fmt[1]);
 458                 if (isalnum(fmt[2]))
 459                         sm_warning("'%%ph' can be followed by at most one of [CDN], and no other alphanumerics");
 460         }
 461         if (type->ctype.modifiers & MOD_NODEREF)
 462                 sm_error("passing __user pointer to %%ph");
 463 }
 464 
 465 static void escaped_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 466 {
 467         assert(fmt[0] == 'E');
 468         while (isalnum(*++fmt)) {
 469                 if (!strchr("achnops", *fmt))
 470                         sm_warning("%%pE can only be followed by a combination of [achnops]");
 471         }
 472         if (type->ctype.modifiers & MOD_NODEREF)
 473                 sm_error("passing __user pointer to %%pE");
 474 }
 475 
 476 static void resource_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 477 {
 478         assert(tolower(fmt[0]) == 'r');
 479         if (!is_struct_tag(basetype, "resource")) {
 480                 sm_error("'%%p%c' expects argument of type struct resource *, "
 481                         "but argument %d has type '%s'", fmt[0], vaidx, type_to_str(type));
 482         }
 483         if (isalnum(fmt[1]))
 484                 sm_warning("'%%p%c' cannot be followed by '%c'", fmt[0], fmt[1]);
 485 }
 486 
 487 static void mac_address_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 488 {
 489         assert(tolower(fmt[0]) == 'm');
 490         if (isalnum(fmt[1])) {
 491                 if (!(fmt[1] == 'F' || fmt[1] == 'R'))
 492                         sm_warning("'%%p%c' cannot be followed by '%c'", fmt[0], fmt[1]);
 493                 if (fmt[0] == 'm' && fmt[1] == 'F')
 494                         sm_warning("it is pointless to pass flag F to %%pm");
 495                 if (isalnum(fmt[2]))
 496                         sm_warning("'%%p%c%c' cannot be followed by other alphanumeric", fmt[0], fmt[1]);
 497         }
 498         /* Technically, bdaddr_t is a typedef for an anonymous struct, but this still seems to work. */
 499         if (!is_char_type(basetype) && !is_struct_tag(basetype, "bdaddr_t") && basetype != &void_ctype) {
 500                 sm_warning("'%%p%c' expects argument of type u8 * or bdaddr_t *, argument %d has type '%s'",
 501                         fmt[0], vaidx, type_to_str(type));
 502         }
 503         if (type->ctype.modifiers & MOD_NODEREF)
 504                 sm_error("passing __user pointer to '%%p%c'", fmt[0]);
 505 }
 506 
 507 static void dentry_file(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 508 {
 509         const char *tag;
 510 
 511         assert(tolower(fmt[0]) == 'd');
 512         tag = fmt[0] == 'd' ? "dentry" : "file";
 513 
 514         if (isalnum(fmt[1])) {
 515                 if (!strchr("234", fmt[1]))
 516                         sm_warning("'%%p%c' can only be followed by one of [234]", fmt[0]);
 517                 if (isalnum(fmt[2]))
 518                         sm_warning("'%%p%c%c' cannot be followed by '%c'", fmt[0], fmt[1], fmt[2]);
 519         }
 520 
 521         if (!is_struct_tag(basetype, tag))
 522                 sm_error("'%%p%c' expects argument of type struct '%s*', argument %d has type '%s'",
 523                         fmt[0], tag, vaidx, type_to_str(type));
 524 }
 525 
 526 static void time_and_date(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 527 {
 528         assert(tolower(fmt[0]) == 't');
 529 
 530         if (fmt[1] == 'R' && !is_struct_tag(basetype, "rtc_time"))
 531                 sm_error("'%%ptR' expects argument of type struct 'rtc_time', argument %d has type '%s'",
 532                          vaidx, type_to_str(type));
 533 }
 534 
 535 static void check_clock(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 536 {
 537         assert(fmt[0] == 'C');
 538         if (isalnum(fmt[1])) {
 539                 if (!strchr("nr", fmt[1]))
 540                         sm_warning("'%%pC' can only be followed by one of [nr]");
 541                 if (isalnum(fmt[2]))
 542                         sm_warning("'%%pC%c' cannot be followed by '%c'", fmt[1], fmt[2]);
 543         }
 544         if (!is_struct_tag(basetype, "clk"))
 545                 sm_error("'%%pC' expects argument of type 'struct clk*', argument %d has type '%s'",
 546                        vaidx, type_to_str(type));
 547 }
 548 
 549 static void va_format(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 550 {
 551         assert(fmt[0] == 'V');
 552         if (isalnum(fmt[1]))
 553                 sm_warning("%%pV cannot be followed by any alphanumerics");
 554         if (!is_struct_tag(basetype, "va_format"))
 555                 sm_error("%%pV expects argument of type struct va_format*, argument %d has type '%s'", vaidx, type_to_str(type));
 556 }
 557 
 558 static void netdev_feature(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 559 {
 560         static struct typedef_lookup netdev = { .name = "netdev_features_t" };
 561 
 562         assert(fmt[0] == 'N');
 563         if (fmt[1] != 'F') {
 564                 sm_error("%%pN must be followed by 'F'");
 565                 return;
 566         }
 567         if (isalnum(fmt[2]))
 568                 sm_warning("%%pNF cannot be followed by '%c'", fmt[2]);
 569 
 570         typedef_lookup(&netdev);
 571         if (!netdev.sym)
 572                 return;
 573         if (basetype != netdev.sym)
 574                 sm_error("%%pNF expects argument of type netdev_features_t*, argument %d has type '%s'",
 575                         vaidx, type_to_str(type));
 576 
 577 }
 578 static void address_val(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 579 {
 580         static struct typedef_lookup dma = { .name = "dma_addr_t" };
 581         static struct typedef_lookup phys = { .name = "phys_addr_t" };
 582         struct typedef_lookup *which = &phys;
 583         const char *suf = "";
 584         assert(fmt[0] == 'a');
 585 
 586         if (isalnum(fmt[1])) {
 587                 switch (fmt[1]) {
 588                 case 'd':
 589                         which = &dma;
 590                         suf = "d";
 591                         break;
 592                 case 'p':
 593                         suf = "p";
 594                         break;
 595                 default:
 596                         sm_error("'%%pa' can only be followed by one of [dp]");
 597                 }
 598                 if (isalnum(fmt[2]))
 599                         sm_error("'%%pa%c' cannot be followed by '%c'", fmt[1], fmt[2]);
 600         }
 601 
 602         typedef_lookup(which);
 603         if (!which->sym)
 604                 return;
 605         if (basetype != which->sym) {
 606                 sm_error("'%%pa%s' expects argument of type '%s*', argument %d has type '%s'",
 607                         suf, which->name, vaidx, type_to_str(type));
 608         }
 609 }
 610 
 611 static void block_device(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 612 {
 613         const char *tag = "block_device";
 614 
 615         assert(fmt[0] == 'g');
 616         if (isalnum(fmt[1])) {
 617                 sm_warning("%%pg cannot be followed by '%c'", fmt[1]);
 618         }
 619         if (!is_struct_tag(basetype, tag))
 620                 sm_error("'%%p%c' expects argument of type struct '%s*', argument %d has type '%s'",
 621                         fmt[0], tag, vaidx, type_to_str(type));
 622 }
 623 
 624 static void flag_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 625 {
 626         static struct typedef_lookup gfp = { .name = "gfp_t" };
 627 
 628         assert(fmt[0] == 'G');
 629         if (!isalnum(fmt[1])) {
 630                 sm_error("%%pG must be followed by one of [gpv]");
 631                 return;
 632         }
 633         switch (fmt[1]) {
 634         case 'p':
 635         case 'v':
 636                 if (basetype != &ulong_ctype)
 637                         sm_error("'%%pG%c' expects argument of type 'unsigned long *', argument %d has type '%s'",
 638                                 fmt[1], vaidx, type_to_str(type));
 639                 break;
 640         case 'g':
 641                 typedef_lookup(&gfp);
 642                 if (basetype != gfp.sym)
 643                         sm_error("'%%pGg' expects argument of type 'gfp_t *', argument %d has type '%s'",
 644                                 vaidx, type_to_str(type));
 645                 break;
 646         default:
 647                 sm_error("'%%pG' must be followed by one of [gpv]");
 648         }
 649 }
 650 
 651 static void device_node_string(const char *fmt, struct symbol *type, struct symbol *basetype, int vaidx)
 652 {
 653         if (fmt[1] != 'F') {
 654                 sm_error("%%pO can only be followed by 'F'");
 655                 return;
 656         }
 657         if (!is_struct_tag(basetype, "device_node"))
 658                 sm_error("'%%pOF' expects argument of type 'struct device_node*', argument %d has type '%s'",
 659                        vaidx, type_to_str(type));
 660 }
 661 
 662 static void
 663 pointer(const char *fmt, struct expression *arg, int vaidx)
 664 {
 665         struct symbol *type, *basetype;
 666 
 667         type = get_type(arg);
 668         if (!type) {
 669                 sm_warning("could not determine type of argument %d", vaidx);
 670                 return;
 671         }
 672         if (!is_ptr_type(type)) {
 673                 sm_error("%%p expects pointer argument, but argument %d has type '%s'",
 674                         vaidx, type_to_str(type));
 675                 return;
 676         }
 677 
 678         /* error pointers */
 679         if (*fmt == 'e')
 680                 fmt++;
 681 
 682 
 683         /* Just plain %p, nothing to check. */
 684         if (!isalnum(*fmt))
 685                 return;
 686 
 687         basetype = get_real_base_type(type);
 688         if (is_void_type(basetype))
 689                 return;
 690         /*
 691          * Passing a pointer-to-array is harmless, but most likely one
 692          * meant to pass pointer-to-first-element. If basetype is
 693          * array type, we issue a notice and "dereference" the types
 694          * once more.
 695          */
 696         if (basetype->type == SYM_ARRAY) {
 697                 spam("note: passing pointer-to-array; is the address-of redundant?");
 698                 type = basetype;
 699                 basetype = get_real_base_type(type);
 700         }
 701 
 702         /*
 703          * We pass both the type and the basetype to the helpers. If,
 704          * for example, the pointer is really a decayed array which is
 705          * passed to %pI4, we might want to check that it is in fact
 706          * an array of four bytes. But most are probably only
 707          * interested in whether the basetype makes sense. Also, the
 708          * pointer may carry some annotation such as __user which
 709          * might be worth checking in the handlers which actually
 710          * dereference the pointer.
 711          */
 712 
 713         switch (*fmt) {
 714         case 'b':
 715         case 'F':
 716         case 'f':
 717         case 'S':
 718         case 's':
 719         case 'B':
 720                 /* Can we do anything sensible? Check that the arg is a function pointer, for example? */
 721                 break;
 722 
 723         case 'R':
 724         case 'r':
 725                 resource_string(fmt, type, basetype, vaidx);
 726                 break;
 727         case 'M':
 728         case 'm':
 729                 mac_address_string(fmt, type, basetype, vaidx);
 730                 break;
 731         case 'I':
 732         case 'i':
 733                 switch (fmt[1]) {
 734                 case '4':
 735                         ip4(fmt, type, basetype, vaidx);
 736                         break;
 737                 case '6':
 738                         ip6(fmt, type, basetype, vaidx);
 739                         break;
 740                 case 'S':
 741                         ipS(fmt, type, basetype, vaidx);
 742                         break;
 743                 default:
 744                         sm_warning("'%%p%c' must be followed by one of [46S]", fmt[0]);
 745                         break;
 746                 }
 747                 break;
 748        /*
 749         * %pE and %ph can handle any valid pointer. We still check
 750         * whether all the subsequent alphanumerics are valid for the
 751         * particular %pX conversion.
 752         */
 753         case 'E':
 754                 escaped_string(fmt, type, basetype, vaidx);
 755                 break;
 756         case 'h':
 757                 hex_string(fmt, type, basetype, vaidx);
 758                 break;
 759         case 'U': /* TODO */
 760                 break;
 761         case 'V':
 762                 va_format(fmt, type, basetype, vaidx);
 763                 break;
 764         case 'K': /* TODO */
 765                 break;
 766         case 'N':
 767                 netdev_feature(fmt, type, basetype, vaidx);
 768                 break;
 769         case 'a':
 770                 address_val(fmt, type, basetype, vaidx);
 771                 break;
 772         case 'D':
 773         case 'd':
 774                 dentry_file(fmt, type, basetype, vaidx);
 775                 break;
 776         case 't':
 777                 time_and_date(fmt, type, basetype, vaidx);
 778                 break;
 779         case 'C':
 780                 check_clock(fmt, type, basetype, vaidx);
 781                 break;
 782         case 'g':
 783                 block_device(fmt, type, basetype, vaidx);
 784                 break;
 785         case 'G':
 786                 flag_string(fmt, type, basetype, vaidx);
 787                 break;
 788         case 'O':
 789                 device_node_string(fmt, type, basetype, vaidx);
 790                 break;
 791         case 'x':
 792                 /* 'x' is for an unhashed pointer */
 793                 break;
 794         default:
 795                 sm_error("unrecognized %%p extension '%c', treated as normal %%p", *fmt);
 796         }
 797 }
 798 
 799 /*
 800  * A common error is to pass a "char" or "signed char" to %02x (or
 801  * %.2X or some other variant). This can actually be a security
 802  * problem, because a lot of code expects this to produce exactly two
 803  * characters of output. Unfortunately this also produces false
 804  * positives, since we're sometimes in arch-specific code on an arch
 805  * where char is always unsigned.
 806  */
 807 static void
 808 hexbyte(const char *fmt, int fmt_len, struct expression *arg, int vaidx, struct printf_spec spec)
 809 {
 810         struct symbol *type;
 811 
 812         /*
 813          * For now, just check the most common and obvious, which is
 814          * roughly %[.0]2[xX].
 815          */
 816         if (spec.field_width != 2 && spec.precision != 2)
 817                 return;
 818         if (spec.base != 16)
 819                 return;
 820 
 821         type = get_type(arg);
 822         if (!type) {
 823                 sm_warning("could not determine type of argument %d", vaidx);
 824                 return;
 825         }
 826         if (type == &char_ctype || type == &schar_ctype)
 827                 sm_warning("argument %d to %.*s specifier has type '%s'",
 828                        vaidx, fmt_len, fmt, type_to_str(type));
 829 }
 830 
 831 static int
 832 check_format_string(const char *fmt, const char *caller)
 833 {
 834         const char *f;
 835 
 836         for (f = fmt; *f; ++f) {
 837                 unsigned char c = *f;
 838                 switch (c) {
 839                 case KERN_SOH_ASCII:
 840                         /*
 841                          * This typically arises from bad conversion
 842                          * to pr_*, e.g. pr_warn(KERN_WARNING "something").
 843                          */
 844                         if (f != fmt)
 845                                 sm_warning("KERN_* level not at start of string");
 846                         /*
 847                          * In a very few cases, the level is actually
 848                          * computed and passed via %c, as in KERN_SOH
 849                          * "%c...". printk explicitly supports
 850                          * this.
 851                          */
 852                         if (!(('0' <= f[1] && f[1] <= '7') ||
 853                               f[1] == 'd' || /* KERN_DEFAULT */
 854                               f[1] == 'c' || /* KERN_CONT */
 855                               (f[1] == '%' && f[2] == 'c')))
 856                                 sm_warning("invalid KERN_* level: KERN_SOH_ASCII followed by '\\x%02x'", (unsigned char)f[1]);
 857                         break;
 858                 case '\t':
 859                 case '\n':
 860                 case '\r':
 861                 case 0x20 ... 0x7e:
 862                         break;
 863                 case 0x80 ... 0xff:
 864                         sm_warning("format string contains non-ascii character '\\x%02x'", c);
 865                         break;
 866                 case 0x08:
 867                         if (f == fmt)
 868                                 break;
 869                         /* fall through */
 870                 default:
 871                         sm_warning("format string contains unusual character '\\x%02x'", c);
 872                         break;
 873                 }
 874         }
 875 
 876         f = strstr(fmt, caller);
 877         if (f && strstr(f+1, caller))
 878                 sm_warning("format string contains name of enclosing function '%s' twice", caller);
 879 
 880         return f != NULL;
 881 }
 882 
 883 static int arg_is___func__(struct expression *arg)
 884 {
 885         if (arg->type != EXPR_SYMBOL)
 886                 return 0;
 887         return !strcmp(arg->symbol_name->name, "__func__") ||
 888                !strcmp(arg->symbol_name->name, "__FUNCTION__") ||
 889                !strcmp(arg->symbol_name->name, "__PRETTY_FUNCTION__");
 890 }
 891 static int arg_contains_caller(struct expression *arg, const char *caller)
 892 {
 893         if (arg->type != EXPR_STRING)
 894                 return 0;
 895         return strstr(arg->string->data, caller) != NULL;
 896 }
 897 
 898 static int is_array_of_const_char(struct symbol *sym)
 899 {
 900         struct symbol *base = sym->ctype.base_type;
 901         if (base->type != SYM_ARRAY)
 902                 return 0;
 903         if (!(base->ctype.modifiers & MOD_CONST))
 904                 return 0;
 905         if (!is_char_type(base->ctype.base_type)) {
 906                 spam("weird: format argument is array of const '%s'", type_to_str(base->ctype.base_type));
 907                 return 0;
 908         }
 909         return 1;
 910 }
 911 
 912 static int is_const_pointer_to_const_char(struct symbol *sym)
 913 {
 914         struct symbol *base = sym->ctype.base_type;
 915         if (!(sym->ctype.modifiers & MOD_CONST))
 916                 return 0;
 917         if (base->type != SYM_PTR)
 918                 return 0;
 919         if (!(base->ctype.modifiers & MOD_CONST))
 920                 return 0;
 921         if (!is_char_type(base->ctype.base_type)) {
 922                 spam("weird: format argument is pointer to const '%s'", type_to_str(base->ctype.base_type));
 923                 return 0;
 924         }
 925         return 1;
 926 }
 927 
 928 static int unknown_format(struct expression *expr)
 929 {
 930         struct state_list *slist;
 931 
 932         slist = get_strings(expr);
 933         if (!slist)
 934                 return 1;
 935         if (slist_has_state(slist, &undefined))
 936                 return 1;
 937         free_slist(&slist);
 938         return 0;
 939 }
 940 
 941 static bool has_hex_prefix(const char *orig_fmt, const char *old_fmt)
 942 {
 943         return old_fmt >= orig_fmt + 2 &&
 944                 old_fmt[-2] == '0' && _tolower(old_fmt[-1]) == 'x';
 945 }
 946 
 947 static bool is_integer_specifier(int type)
 948 {
 949         switch (type) {
 950         case FORMAT_TYPE_LONG_LONG:
 951         case FORMAT_TYPE_ULONG:
 952         case FORMAT_TYPE_LONG:
 953         case FORMAT_TYPE_UBYTE:
 954         case FORMAT_TYPE_BYTE:
 955         case FORMAT_TYPE_USHORT:
 956         case FORMAT_TYPE_SHORT:
 957         case FORMAT_TYPE_UINT:
 958         case FORMAT_TYPE_INT:
 959         case FORMAT_TYPE_SIZE_T:
 960         case FORMAT_TYPE_PTRDIFF:
 961                 return true;
 962         default:
 963                 return false;
 964         }
 965 }
 966 
 967 static int
 968 is_cast_expr(struct expression *expr)
 969 {
 970         if (!expr)
 971                 return 0;
 972 
 973         switch (expr->type) {
 974         case EXPR_CAST:
 975         case EXPR_FORCE_CAST:
 976                 /* not EXPR_IMPLIED_CAST for our purposes */
 977                 return 1;
 978         default:
 979                 return 0;
 980         }
 981 }
 982 
 983 static void
 984 check_cast_from_pointer(const char *fmt, int len, struct expression *arg, int va_idx)
 985 {
 986         /*
 987          * This can easily be fooled by passing 0+(long)ptr or doing
 988          * "long local_var = (long)ptr" and passing local_var to
 989          * %lx. Tough.
 990          */
 991         if (!is_cast_expr(arg))
 992                 return;
 993         while (is_cast_expr(arg))
 994                 arg = arg->cast_expression;
 995         if (is_ptr_type(get_final_type(arg)))
 996                 sm_warning("argument %d to %.*s specifier is cast from pointer",
 997                         va_idx, len, fmt);
 998 }
 999 
1000 static void
1001 do_check_printf_call(const char *caller, const char *name, struct expression *callexpr, struct expression *fmtexpr, int vaidx)
1002 {
1003         struct printf_spec spec = {0};
1004         const char *fmt, *orig_fmt;
1005         int caller_in_fmt;
1006 
1007         fmtexpr = strip_parens(fmtexpr);
1008         if (fmtexpr->type == EXPR_CONDITIONAL) {
1009                 do_check_printf_call(caller, name, callexpr, fmtexpr->cond_true ? : fmtexpr->conditional, vaidx);
1010                 do_check_printf_call(caller, name, callexpr, fmtexpr->cond_false, vaidx);
1011                 return;
1012         }
1013         if (fmtexpr->type == EXPR_SYMBOL) {
1014                 /*
1015                  * If the symbol has an initializer, we can handle
1016                  *
1017                  *   const char foo[] = "abc";         and
1018                  *   const char * const foo = "abc";
1019                  *
1020                  * We simply replace fmtexpr with the initializer
1021                  * expression. If foo is not one of the above, or if
1022                  * the initializer expression is somehow not a string
1023                  * literal, fmtexpr->type != EXPR_STRING will trigger
1024                  * below and we'll spam+return.
1025                  */
1026                 struct symbol *sym = fmtexpr->symbol;
1027                 if (sym && sym->initializer &&
1028                     (is_array_of_const_char(sym) ||
1029                      is_const_pointer_to_const_char(sym))) {
1030                         fmtexpr = strip_parens(sym->initializer);
1031                 }
1032         }
1033 
1034         if (fmtexpr->type != EXPR_STRING) {
1035                 if (!unknown_format(fmtexpr))
1036                         return;
1037                 /*
1038                  * Since we're now handling both ?: and static const
1039                  * char[] arguments, we don't get as much noise. It's
1040                  * still spammy, though.
1041                  */
1042                 spam("warn: call of '%s' with non-constant format argument", name);
1043                 return;
1044         }
1045 
1046         orig_fmt = fmt = fmtexpr->string->data;
1047         caller_in_fmt = check_format_string(fmt, caller);
1048 
1049         while (*fmt) {
1050                 const char *old_fmt = fmt;
1051                 int read = format_decode(fmt, &spec);
1052                 struct expression *arg;
1053 
1054                 fmt += read;
1055                 if (spec.type == FORMAT_TYPE_NONE ||
1056                     spec.type == FORMAT_TYPE_PERCENT_CHAR)
1057                         continue;
1058 
1059                 /*
1060                  * vaidx is currently the correct 0-based index for
1061                  * get_argument_from_call_expr. We post-increment it
1062                  * here so that it is the correct 1-based index for
1063                  * all the handlers below. This of course requires
1064                  * that we handle all FORMAT_TYPE_* things not taking
1065                  * an argument above.
1066                  */
1067                 arg = get_argument_from_call_expr(callexpr->args, vaidx++);
1068 
1069                 if (spec.flags & SPECIAL && has_hex_prefix(orig_fmt, old_fmt))
1070                         sm_warning("'%.2s' prefix is redundant when # flag is used", old_fmt-2);
1071                 if (is_integer_specifier(spec.type)) {
1072                         if (spec.base != 16 && has_hex_prefix(orig_fmt, old_fmt))
1073                                 sm_warning("'%.2s' prefix is confusing together with '%.*s' specifier",
1074                                        old_fmt-2, (int)(fmt-old_fmt), old_fmt);
1075 
1076                         check_cast_from_pointer(old_fmt, read, arg, vaidx);
1077                 }
1078 
1079                 switch (spec.type) {
1080                 /* case FORMAT_TYPE_NONE: */
1081                 /* case FORMAT_TYPE_PERCENT_CHAR: */
1082                 /*      break; */
1083 
1084                 case FORMAT_TYPE_INVALID:
1085                         sm_error("format specifier '%.*s' invalid", read, old_fmt);
1086                         return;
1087 
1088                 case FORMAT_TYPE_FLOAT:
1089                         sm_error("no floats in the kernel; invalid format specifier '%.*s'", read, old_fmt);
1090                         return;
1091 
1092                 case FORMAT_TYPE_NRCHARS:
1093                         sm_error("%%n not supported in kernel");
1094                         return;
1095 
1096                 case FORMAT_TYPE_WIDTH:
1097                 case FORMAT_TYPE_PRECISION:
1098                         /* check int argument */
1099                         break;
1100 
1101                 case FORMAT_TYPE_STR:
1102                         /*
1103                          * If the format string already contains the
1104                          * function name, it probably doesn't make
1105                          * sense to pass __func__ as well (or rather
1106                          * vice versa: If pr_fmt(fmt) has been defined
1107                          * to '"%s: " fmt, __func__', it doesn't make
1108                          * sense to use a format string containing the
1109                          * function name).
1110                          *
1111                          * This produces a lot of hits. They are not
1112                          * false positives, but it is easier to handle
1113                          * the things which don't occur that often
1114                          * first, so we use spam().
1115                          */
1116                         if (caller_in_fmt) {
1117                                 if (arg_is___func__(arg))
1118                                         spam("warn: passing __func__ while the format string already contains the name of the function '%s'",
1119                                              caller);
1120                                 else if (arg_contains_caller(arg, caller))
1121                                         sm_warning("passing string constant '%s' containing '%s' which is already part of the format string",
1122                                                arg->string->data, caller);
1123                         }
1124                         break;
1125 
1126                 case FORMAT_TYPE_PTR:
1127                         /* This is the most important part: Checking %p extensions. */
1128                         pointer(fmt, arg, vaidx);
1129                         while (isalnum(*fmt))
1130                                 fmt++;
1131                         break;
1132 
1133                 case FORMAT_TYPE_CHAR:
1134 
1135                 case FORMAT_TYPE_UBYTE:
1136                 case FORMAT_TYPE_BYTE:
1137                 case FORMAT_TYPE_USHORT:
1138                 case FORMAT_TYPE_SHORT:
1139                 case FORMAT_TYPE_INT:
1140                         /* argument should have integer type of width <= sizeof(int) */
1141                         break;
1142 
1143                 case FORMAT_TYPE_UINT:
1144                         hexbyte(old_fmt, fmt-old_fmt, arg, vaidx, spec);
1145                 case FORMAT_TYPE_LONG:
1146                 case FORMAT_TYPE_ULONG:
1147                 case FORMAT_TYPE_LONG_LONG:
1148                 case FORMAT_TYPE_PTRDIFF:
1149                 case FORMAT_TYPE_SIZE_T:
1150                         break;
1151                 }
1152 
1153 
1154         }
1155 
1156         if (get_argument_from_call_expr(callexpr->args, vaidx))
1157                 sm_warning("excess argument passed to '%s'", name);
1158 
1159 
1160 }
1161 
1162 static void
1163 check_printf_call(const char *name, struct expression *callexpr, void *_info)
1164 {
1165         /*
1166          * Note: attribute(printf) uses 1-based indexing, but
1167          * get_argument_from_call_expr() uses 0-based indexing.
1168          */
1169         int info = PTR_INT(_info);
1170         int fmtidx = (info & 0xff) - 1;
1171         int vaidx = ((info >> 8) & 0xff) - 1;
1172         struct expression *fmtexpr;
1173         const char *caller = get_function();
1174 
1175         if (!caller)
1176                 return;
1177 
1178         /*
1179          * Calling a v*printf function with a literal format arg is
1180          * extremely rare, so we don't bother doing the only checking
1181          * we could do, namely checking that the format string is
1182          * valid.
1183          */
1184         if (vaidx < 0)
1185                 return;
1186 
1187         /*
1188          * For the things we use the name of the calling function for,
1189          * it is more appropriate to skip a potential SyS_ prefix; the
1190          * same goes for leading underscores.
1191          */
1192         if (!strncmp(caller, "SyS_", 4))
1193                 caller += 4;
1194         while (*caller == '_')
1195                 ++caller;
1196 
1197         /* Lack of format argument is a bug. */
1198         fmtexpr = get_argument_from_call_expr(callexpr->args, fmtidx);
1199         if (!fmtexpr) {
1200                 sm_error("call of '%s' with no format argument", name);
1201                 return;
1202         }
1203 
1204         do_check_printf_call(caller, name, callexpr, fmtexpr, vaidx);
1205 }
1206 
1207 
1208 void check_kernel_printf(int id)
1209 {
1210         if (option_project != PROJ_KERNEL)
1211                 return;
1212 
1213         my_id = id;
1214 
1215 #define printf_hook(func, fmt, first_to_check)  \
1216         add_function_hook(#func, check_printf_call, INT_PTR(fmt + (first_to_check << 8)))
1217 
1218         /* Extracted using stupid perl script. */
1219 
1220 #if 0
1221         printf_hook(srm_printk, 1, 2);                    /* arch/alpha/include/asm/console.h */
1222         printf_hook(die_if_kernel, 1, 2);                 /* arch/frv/include/asm/bug.h */
1223         printf_hook(ia64_mca_printk, 1, 2);               /* arch/ia64/include/asm/mca.h */
1224         printf_hook(nfprint, 1, 2);                       /* arch/m68k/include/asm/natfeat.h */
1225         printf_hook(gdbstub_printk, 1, 2);                /* arch/mn10300/include/asm/gdb-stub.h */
1226         printf_hook(DBG, 1, 2);                           /* arch/powerpc/boot/ps3.c */
1227         printf_hook(printf, 1, 2);                        /* arch/powerpc/boot/stdio.h */
1228         printf_hook(udbg_printf, 1, 2);                   /* arch/powerpc/include/asm/udbg.h */
1229         printf_hook(__debug_sprintf_event, 3, 4);         /* arch/s390/include/asm/debug.h */
1230         printf_hook(__debug_sprintf_exception, 3, 4);     /* arch/s390/include/asm/debug.h */
1231         printf_hook(prom_printf, 1, 2);                   /* arch/sparc/include/asm/oplib_32.h */
1232 
1233         printf_hook(fail, 1, 2);                          /* arch/x86/vdso/vdso2c.c */
1234 #endif
1235 
1236         printf_hook(_ldm_printk, 3, 4);                   /* block/partitions/ldm.c */
1237         printf_hook(rbd_warn, 2, 3);                      /* drivers/block/rbd.c */
1238         printf_hook(fw_err, 2, 3);                        /* drivers/firewire/core.h */
1239         printf_hook(fw_notice, 2, 3);                     /* drivers/firewire/core.h */
1240         printf_hook(i915_error_printf, 2, 3);             /* drivers/gpu/drm/i915/i915_drv.h */
1241         printf_hook(i915_handle_error, 3, 4);             /* drivers/gpu/drm/i915/i915_drv.h */
1242         printf_hook(nv_printk_, 3, 4);                    /* drivers/gpu/drm/nouveau/core/include/core/printk.h */
1243         printf_hook(host1x_debug_output, 2, 3);           /* drivers/gpu/host1x/debug.h */
1244         printf_hook(callc_debug, 2, 3);                   /* drivers/isdn/hisax/callc.c */
1245         printf_hook(link_debug, 3, 4);                    /* drivers/isdn/hisax/callc.c */
1246         printf_hook(HiSax_putstatus, 3, 4);               /* drivers/isdn/hisax/hisax.h */
1247         printf_hook(VHiSax_putstatus, 3, 0);              /* drivers/isdn/hisax/hisax.h */
1248         printf_hook(debugl1, 2, 3);                       /* drivers/isdn/hisax/isdnl1.h */
1249         printf_hook(l3m_debug, 2, 3);                     /* drivers/isdn/hisax/isdnl3.c */
1250         printf_hook(dout_debug, 2, 3);                    /* drivers/isdn/hisax/st5481_d.c */
1251         printf_hook(l1m_debug, 2, 3);                     /* drivers/isdn/hisax/st5481_d.c */
1252         printf_hook(bch_cache_set_error, 2, 3);           /* drivers/md/bcache/bcache.h */
1253         printf_hook(_tda_printk, 4, 5);                   /* drivers/media/tuners/tda18271-priv.h */
1254         printf_hook(i40evf_debug_d, 3, 4);                /* drivers/net/ethernet/intel/i40evf/i40e_osdep.h */
1255         printf_hook(en_print, 3, 4);                      /* drivers/net/ethernet/mellanox/mlx4/mlx4_en.h */
1256         printf_hook(_ath_dbg, 3, 4);                      /* drivers/net/wireless/ath/ath.h */
1257         printf_hook(ath_printk, 3, 4);                    /* drivers/net/wireless/ath/ath.h */
1258         printf_hook(ath10k_dbg, 3, 4);                    /* drivers/net/wireless/ath/ath10k/debug.h */
1259         printf_hook(ath10k_err, 2, 3);                    /* drivers/net/wireless/ath/ath10k/debug.h */
1260         printf_hook(ath10k_info, 2, 3);                   /* drivers/net/wireless/ath/ath10k/debug.h */
1261         printf_hook(ath10k_warn, 2, 3);                   /* drivers/net/wireless/ath/ath10k/debug.h */
1262         printf_hook(_ath5k_printk, 3, 4);                 /* drivers/net/wireless/ath/ath5k/ath5k.h */
1263         printf_hook(ATH5K_DBG, 3, 4);                     /* drivers/net/wireless/ath/ath5k/debug.h */
1264         printf_hook(ATH5K_DBG_UNLIMIT, 3, 4);             /* drivers/net/wireless/ath/ath5k/debug.h */
1265         printf_hook(ath6kl_printk, 2, 3);                 /* drivers/net/wireless/ath/ath6kl/common.h */
1266         printf_hook(ath6kl_err, 1, 2);                    /* drivers/net/wireless/ath/ath6kl/debug.h */
1267         printf_hook(ath6kl_info, 1, 2);                   /* drivers/net/wireless/ath/ath6kl/debug.h */
1268         printf_hook(ath6kl_warn, 1, 2);                   /* drivers/net/wireless/ath/ath6kl/debug.h */
1269         printf_hook(wil_dbg_trace, 2, 3);                 /* drivers/net/wireless/ath/wil6210/wil6210.h */
1270         printf_hook(wil_err, 2, 3);                       /* drivers/net/wireless/ath/wil6210/wil6210.h */
1271         printf_hook(wil_err_ratelimited, 2, 3);           /* drivers/net/wireless/ath/wil6210/wil6210.h */
1272         printf_hook(wil_info, 2, 3);                      /* drivers/net/wireless/ath/wil6210/wil6210.h */
1273         printf_hook(b43dbg, 2, 3);                        /* drivers/net/wireless/b43/b43.h */
1274         printf_hook(b43err, 2, 3);                        /* drivers/net/wireless/b43/b43.h */
1275         printf_hook(b43info, 2, 3);                       /* drivers/net/wireless/b43/b43.h */
1276         printf_hook(b43warn, 2, 3);                       /* drivers/net/wireless/b43/b43.h */
1277         printf_hook(b43legacydbg, 2, 3);                  /* drivers/net/wireless/b43legacy/b43legacy.h */
1278         printf_hook(b43legacyerr, 2, 3);                  /* drivers/net/wireless/b43legacy/b43legacy.h */
1279         printf_hook(b43legacyinfo, 2, 3);                 /* drivers/net/wireless/b43legacy/b43legacy.h */
1280         printf_hook(b43legacywarn, 2, 3);                 /* drivers/net/wireless/b43legacy/b43legacy.h */
1281         printf_hook(__brcmf_dbg, 3, 4);                   /* drivers/net/wireless/brcm80211/brcmfmac/debug.h */
1282         printf_hook(__brcmf_err, 2, 3);                   /* drivers/net/wireless/brcm80211/brcmfmac/debug.h */
1283         printf_hook(__brcms_crit, 2, 3);                  /* drivers/net/wireless/brcm80211/brcmsmac/debug.h */
1284         printf_hook(__brcms_dbg, 4, 5);                   /* drivers/net/wireless/brcm80211/brcmsmac/debug.h */
1285         printf_hook(__brcms_err, 2, 3);                   /* drivers/net/wireless/brcm80211/brcmsmac/debug.h */
1286         printf_hook(__brcms_info, 2, 3);                  /* drivers/net/wireless/brcm80211/brcmsmac/debug.h */
1287         printf_hook(__brcms_warn, 2, 3);                  /* drivers/net/wireless/brcm80211/brcmsmac/debug.h */
1288         printf_hook(brcmu_dbg_hex_dump, 3, 4);            /* drivers/net/wireless/brcm80211/include/brcmu_utils.h */
1289         printf_hook(__iwl_crit, 2, 3);                    /* drivers/net/wireless/iwlwifi/iwl-debug.h */
1290         printf_hook(__iwl_dbg, 5, 6);                     /* drivers/net/wireless/iwlwifi/iwl-debug.h */
1291         printf_hook(__iwl_err, 4, 5);                     /* drivers/net/wireless/iwlwifi/iwl-debug.h */
1292         printf_hook(__iwl_info, 2, 3);                    /* drivers/net/wireless/iwlwifi/iwl-debug.h */
1293         printf_hook(__iwl_warn, 2, 3);                    /* drivers/net/wireless/iwlwifi/iwl-debug.h */
1294         printf_hook(rsi_dbg, 2, 3);                       /* drivers/net/wireless/rsi/rsi_main.h */
1295         printf_hook(RTPRINT, 4, 5);                       /* drivers/net/wireless/rtlwifi/debug.h */
1296         printf_hook(RT_ASSERT, 2, 3);                     /* drivers/net/wireless/rtlwifi/debug.h */
1297         printf_hook(RT_TRACE, 4, 5);                      /* drivers/net/wireless/rtlwifi/debug.h */
1298         printf_hook(__of_node_dup, 2, 3);                 /* drivers/of/of_private.h */
1299         printf_hook(BNX2FC_HBA_DBG, 2, 3);                /* drivers/scsi/bnx2fc/bnx2fc_debug.h */
1300         printf_hook(BNX2FC_IO_DBG, 2, 3);                 /* drivers/scsi/bnx2fc/bnx2fc_debug.h */
1301         printf_hook(BNX2FC_TGT_DBG, 2, 3);                /* drivers/scsi/bnx2fc/bnx2fc_debug.h */
1302         printf_hook(ql_dbg, 4, 5);                        /* drivers/scsi/qla2xxx/qla_dbg.h */
1303         printf_hook(ql_dbg_pci, 4, 5);                    /* drivers/scsi/qla2xxx/qla_dbg.h */
1304         printf_hook(ql_log, 4, 5);                        /* drivers/scsi/qla2xxx/qla_dbg.h */
1305         printf_hook(ql_log_pci, 4, 5);                    /* drivers/scsi/qla2xxx/qla_dbg.h */
1306         printf_hook(libcfs_debug_msg, 2, 3);              /* drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h */
1307         printf_hook(libcfs_debug_vmsg2, 4, 5);            /* drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h */
1308         printf_hook(_ldlm_lock_debug, 3, 4);              /* drivers/staging/lustre/lustre/include/lustre_dlm.h */
1309         printf_hook(_debug_req, 3, 4);                    /* drivers/staging/lustre/lustre/include/lustre_net.h */
1310         printf_hook(iscsi_change_param_sprintf, 2, 3);    /* drivers/target/iscsi/iscsi_target_login.c */
1311         printf_hook(dbg, 1, 2);                           /* drivers/tty/serial/samsung.c */
1312         printf_hook(_usb_stor_dbg, 2, 3);                 /* drivers/usb/storage/debug.h */
1313         printf_hook(usb_stor_dbg, 2, 3);                  /* drivers/usb/storage/debug.h */
1314         printf_hook(vringh_bad, 1, 2);                    /* drivers/vhost/vringh.c */
1315         printf_hook(__adfs_error, 3, 4);                  /* fs/adfs/adfs.h */
1316         printf_hook(affs_error, 3, 4);                    /* fs/affs/affs.h */
1317         printf_hook(affs_warning, 3, 4);                  /* fs/affs/affs.h */
1318         printf_hook(befs_debug, 2, 3);                    /* fs/befs/befs.h */
1319         printf_hook(befs_error, 2, 3);                    /* fs/befs/befs.h */
1320         printf_hook(befs_warning, 2, 3);                  /* fs/befs/befs.h */
1321         printf_hook(__btrfs_panic, 5, 6);                 /* fs/btrfs/ctree.h */
1322         printf_hook(__btrfs_std_error, 5, 6);             /* fs/btrfs/ctree.h */
1323         printf_hook(btrfs_printk, 2, 3);                  /* fs/btrfs/ctree.h */
1324         printf_hook(cifs_vfs_err, 1, 2);                  /* fs/cifs/cifs_debug.h */
1325         printf_hook(__ecryptfs_printk, 1, 2);             /* fs/ecryptfs/ecryptfs_kernel.h */
1326         printf_hook(ext2_error, 3, 4);                    /* fs/ext2/ext2.h */
1327         printf_hook(ext2_msg, 3, 4);                      /* fs/ext2/ext2.h */
1328         printf_hook(ext3_abort, 3, 4);                    /* fs/ext3/ext3.h */
1329         printf_hook(ext3_error, 3, 4);                    /* fs/ext3/ext3.h */
1330         printf_hook(ext3_msg, 3, 4);                      /* fs/ext3/ext3.h */
1331         printf_hook(ext3_warning, 3, 4);                  /* fs/ext3/ext3.h */
1332         printf_hook(__ext4_abort, 4, 5);                  /* fs/ext4/ext4.h */
1333         printf_hook(__ext4_error, 4, 5);                  /* fs/ext4/ext4.h */
1334         printf_hook(__ext4_error_file, 5, 6);             /* fs/ext4/ext4.h */
1335         printf_hook(__ext4_error_inode, 5, 6);            /* fs/ext4/ext4.h */
1336         printf_hook(__ext4_grp_locked_error, 7, 8);       /* fs/ext4/ext4.h */
1337         printf_hook(__ext4_msg, 3, 4);                    /* fs/ext4/ext4.h */
1338         printf_hook(__ext4_warning, 4, 5);                /* fs/ext4/ext4.h */
1339         printf_hook(f2fs_msg, 3, 4);                      /* fs/f2fs/f2fs.h */
1340         printf_hook(__fat_fs_error, 3, 4);                /* fs/fat/fat.h */
1341         printf_hook(fat_msg, 3, 4);                       /* fs/fat/fat.h */
1342         printf_hook(gfs2_print_dbg, 2, 3);                /* fs/gfs2/glock.h */
1343         printf_hook(gfs2_lm_withdraw, 2, 3);              /* fs/gfs2/util.h */
1344         printf_hook(hpfs_error, 2, 3);                    /* fs/hpfs/hpfs_fn.h */
1345         printf_hook(jfs_error, 2, 3);                     /* fs/jfs/jfs_superblock.h */
1346         printf_hook(nilfs_error, 3, 4);                   /* fs/nilfs2/nilfs.h */
1347         printf_hook(nilfs_warning, 3, 4);                 /* fs/nilfs2/nilfs.h */
1348         printf_hook(__ntfs_debug, 4, 5);                  /* fs/ntfs/debug.h */
1349         printf_hook(__ntfs_error, 3, 4);                  /* fs/ntfs/debug.h */
1350         printf_hook(__ntfs_warning, 3, 4);                /* fs/ntfs/debug.h */
1351         printf_hook(__ocfs2_abort, 3, 4);                 /* fs/ocfs2/super.h */
1352         printf_hook(__ocfs2_error, 3, 4);                 /* fs/ocfs2/super.h */
1353         printf_hook(_udf_err, 3, 4);                      /* fs/udf/udfdecl.h */
1354         printf_hook(_udf_warn, 3, 4);                     /* fs/udf/udfdecl.h */
1355         printf_hook(ufs_error, 3, 4);                     /* fs/ufs/ufs.h */
1356         printf_hook(ufs_panic, 3, 4);                     /* fs/ufs/ufs.h */
1357         printf_hook(ufs_warning, 3, 4);                   /* fs/ufs/ufs.h */
1358         printf_hook(xfs_alert, 2, 3);                     /* fs/xfs/xfs_message.h */
1359         printf_hook(xfs_alert_tag, 3, 4);                 /* fs/xfs/xfs_message.h */
1360         printf_hook(xfs_crit, 2, 3);                      /* fs/xfs/xfs_message.h */
1361         printf_hook(xfs_debug, 2, 3);                     /* fs/xfs/xfs_message.h */
1362         printf_hook(xfs_emerg, 2, 3);                     /* fs/xfs/xfs_message.h */
1363         printf_hook(xfs_err, 2, 3);                       /* fs/xfs/xfs_message.h */
1364         printf_hook(xfs_info, 2, 3);                      /* fs/xfs/xfs_message.h */
1365         printf_hook(xfs_notice, 2, 3);                    /* fs/xfs/xfs_message.h */
1366         printf_hook(xfs_warn, 2, 3);                      /* fs/xfs/xfs_message.h */
1367         printf_hook(warn_slowpath_fmt, 3, 4);             /* include/asm-generic/bug.h */
1368         printf_hook(warn_slowpath_fmt_taint, 4, 5);       /* include/asm-generic/bug.h */
1369         printf_hook(drm_err, 1, 2);                       /* include/drm/drmP.h */
1370         printf_hook(drm_ut_debug_printk, 2, 3);           /* include/drm/drmP.h */
1371         printf_hook(__acpi_handle_debug, 3, 4);           /* include/linux/acpi.h */
1372         printf_hook(acpi_handle_printk, 3, 4);            /* include/linux/acpi.h */
1373         printf_hook(audit_log, 4, 5);                     /* include/linux/audit.h */
1374         printf_hook(audit_log_format, 2, 3);              /* include/linux/audit.h */
1375         printf_hook(bdi_register, 3, 4);                  /* include/linux/backing-dev.h */
1376         printf_hook(__trace_note_message, 2, 3);          /* include/linux/blktrace_api.h */
1377         printf_hook(_dev_info, 2, 3);                     /* include/linux/device.h */
1378         printf_hook(dev_alert, 2, 3);                     /* include/linux/device.h */
1379         printf_hook(dev_crit, 2, 3);                      /* include/linux/device.h */
1380         printf_hook(dev_emerg, 2, 3);                     /* include/linux/device.h */
1381         printf_hook(dev_err, 2, 3);                       /* include/linux/device.h */
1382         printf_hook(dev_notice, 2, 3);                    /* include/linux/device.h */
1383         printf_hook(dev_printk, 3, 4);                    /* include/linux/device.h */
1384         printf_hook(dev_printk_emit, 3, 4);               /* include/linux/device.h */
1385         printf_hook(dev_set_name, 2, 3);                  /* include/linux/device.h */
1386         printf_hook(dev_vprintk_emit, 3, 0);              /* include/linux/device.h */
1387         printf_hook(dev_warn, 2, 3);                      /* include/linux/device.h */
1388         printf_hook(device_create, 5, 6);                 /* include/linux/device.h */
1389         printf_hook(device_create_with_groups, 6, 7);     /* include/linux/device.h */
1390         printf_hook(devm_kasprintf, 3, 4);                /* include/linux/device.h */
1391         printf_hook(__dynamic_dev_dbg, 3, 4);             /* include/linux/dynamic_debug.h */
1392         printf_hook(__dynamic_netdev_dbg, 3, 4);          /* include/linux/dynamic_debug.h */
1393         printf_hook(__dynamic_pr_debug, 2, 3);            /* include/linux/dynamic_debug.h */
1394         printf_hook(__simple_attr_check_format, 1, 2);    /* include/linux/fs.h */
1395         printf_hook(fscache_init_cache, 3, 4);            /* include/linux/fscache-cache.h */
1396         printf_hook(gameport_set_phys, 2, 3);             /* include/linux/gameport.h */
1397         printf_hook(iio_trigger_alloc, 1, 2);             /* include/linux/iio/trigger.h */
1398         printf_hook(__check_printsym_format, 1, 2);       /* include/linux/kallsyms.h */
1399         printf_hook(kdb_printf, 1, 2);                    /* include/linux/kdb.h */
1400         printf_hook(vkdb_printf, 1, 0);                   /* include/linux/kdb.h */
1401         printf_hook(____trace_printk_check_format, 1, 2);  /* include/linux/kernel.h */
1402         printf_hook(__trace_bprintk, 2, 3);               /* include/linux/kernel.h */
1403         printf_hook(__trace_printk, 2, 3);                /* include/linux/kernel.h */
1404         printf_hook(kasprintf, 2, 3);                     /* include/linux/kernel.h */
1405         printf_hook(panic, 1, 2);                         /* include/linux/kernel.h */
1406         printf_hook(scnprintf, 3, 4);                     /* include/linux/kernel.h */
1407         printf_hook(snprintf, 3, 4);                      /* include/linux/kernel.h */
1408         printf_hook(sprintf, 2, 3);                       /* include/linux/kernel.h */
1409         printf_hook(trace_printk, 1, 2);                  /* include/linux/kernel.h */
1410         printf_hook(vscnprintf, 3, 0);                    /* include/linux/kernel.h */
1411         printf_hook(vsnprintf, 3, 0);                     /* include/linux/kernel.h */
1412         printf_hook(vsprintf, 2, 0);                      /* include/linux/kernel.h */
1413         printf_hook(vmcoreinfo_append_str, 1, 2);         /* include/linux/kexec.h */
1414         printf_hook(__request_module, 2, 3);              /* include/linux/kmod.h */
1415         printf_hook(add_uevent_var, 2, 3);                /* include/linux/kobject.h */
1416         printf_hook(kobject_add, 3, 4);                   /* include/linux/kobject.h */
1417         printf_hook(kobject_init_and_add, 4, 5);          /* include/linux/kobject.h */
1418         printf_hook(kobject_set_name, 2, 3);              /* include/linux/kobject.h */
1419         printf_hook(kthread_create_on_node, 4, 5);        /* include/linux/kthread.h */
1420         printf_hook(__ata_ehi_push_desc, 2, 3);           /* include/linux/libata.h */
1421         printf_hook(ata_dev_printk, 3, 4);                /* include/linux/libata.h */
1422         printf_hook(ata_ehi_push_desc, 2, 3);             /* include/linux/libata.h */
1423         printf_hook(ata_link_printk, 3, 4);               /* include/linux/libata.h */
1424         printf_hook(ata_port_desc, 2, 3);                 /* include/linux/libata.h */
1425         printf_hook(ata_port_printk, 3, 4);               /* include/linux/libata.h */
1426         printf_hook(warn_alloc_failed, 3, 4);             /* include/linux/mm.h */
1427         printf_hook(mmiotrace_printk, 1, 2);              /* include/linux/mmiotrace.h */
1428         printf_hook(netdev_alert, 2, 3);                  /* include/linux/netdevice.h */
1429         printf_hook(netdev_crit, 2, 3);                   /* include/linux/netdevice.h */
1430         printf_hook(netdev_emerg, 2, 3);                  /* include/linux/netdevice.h */
1431         printf_hook(netdev_err, 2, 3);                    /* include/linux/netdevice.h */
1432         printf_hook(netdev_info, 2, 3);                   /* include/linux/netdevice.h */
1433         printf_hook(netdev_notice, 2, 3);                 /* include/linux/netdevice.h */
1434         printf_hook(netdev_printk, 3, 4);                 /* include/linux/netdevice.h */
1435         printf_hook(netdev_warn, 2, 3);                   /* include/linux/netdevice.h */
1436         printf_hook(early_printk, 1, 2);                  /* include/linux/printk.h */
1437         printf_hook(no_printk, 1, 2);                     /* include/linux/printk.h */
1438         printf_hook(printk, 1, 2);                        /* include/linux/printk.h */
1439         printf_hook(printk_deferred, 1, 2);               /* include/linux/printk.h */
1440         printf_hook(printk_emit, 5, 6);                   /* include/linux/printk.h */
1441         printf_hook(vprintk, 1, 0);                       /* include/linux/printk.h */
1442         printf_hook(vprintk_emit, 5, 0);                  /* include/linux/printk.h */
1443         printf_hook(__quota_error, 3, 4);                 /* include/linux/quotaops.h */
1444         printf_hook(seq_buf_printf, 2, 3);                /* include/linux/seq_buf.h */
1445         printf_hook(seq_buf_vprintf, 2, 0);               /* include/linux/seq_buf.h */
1446         printf_hook(seq_printf, 2, 3);                    /* include/linux/seq_file.h */
1447         printf_hook(seq_vprintf, 2, 0);                   /* include/linux/seq_file.h */
1448         printf_hook(bprintf, 3, 4);                       /* include/linux/string.h */
1449         printf_hook(trace_seq_printf, 2, 3);              /* include/linux/trace_seq.h */
1450         printf_hook(trace_seq_vprintf, 2, 0);             /* include/linux/trace_seq.h */
1451         printf_hook(__alloc_workqueue_key, 1, 6);         /* include/linux/workqueue.h */
1452         printf_hook(set_worker_desc, 1, 2);               /* include/linux/workqueue.h */
1453         printf_hook(_p9_debug, 3, 4);                     /* include/net/9p/9p.h */
1454         printf_hook(bt_err, 1, 2);                        /* include/net/bluetooth/bluetooth.h */
1455         printf_hook(bt_info, 1, 2);                       /* include/net/bluetooth/bluetooth.h */
1456         printf_hook(nf_ct_helper_log, 3, 4);              /* include/net/netfilter/nf_conntrack_helper.h */
1457         printf_hook(nf_log_buf_add, 2, 3);                /* include/net/netfilter/nf_log.h */
1458         printf_hook(nf_log_packet, 8, 9);                 /* include/net/netfilter/nf_log.h */
1459         printf_hook(SOCK_DEBUG, 2, 3);                    /* include/net/sock.h */
1460         printf_hook(__snd_printk, 4, 5);                  /* include/sound/core.h */
1461         printf_hook(_snd_printd, 2, 3);                   /* include/sound/core.h */
1462         printf_hook(snd_printd, 1, 2);                    /* include/sound/core.h */
1463         printf_hook(snd_printdd, 1, 2);                   /* include/sound/core.h */
1464         printf_hook(snd_iprintf, 2, 3);                   /* include/sound/info.h */
1465         printf_hook(snd_seq_create_kernel_client, 3, 4);  /* include/sound/seq_kernel.h */
1466         printf_hook(xen_raw_printk, 1, 2);                /* include/xen/hvc-console.h */
1467         printf_hook(xenbus_dev_error, 3, 4);              /* include/xen/xenbus.h */
1468         printf_hook(xenbus_dev_fatal, 3, 4);              /* include/xen/xenbus.h */
1469         printf_hook(xenbus_printf, 4, 5);                 /* include/xen/xenbus.h */
1470         printf_hook(xenbus_watch_pathfmt, 4, 5);          /* include/xen/xenbus.h */
1471         printf_hook(batadv_fdebug_log, 2, 3);             /* net/batman-adv/debugfs.c */
1472         printf_hook(_batadv_dbg, 4, 5);                   /* net/batman-adv/main.h */
1473         printf_hook(batadv_debug_log, 2, 3);              /* net/batman-adv/main.h */
1474         printf_hook(__sdata_dbg, 2, 3);                   /* net/mac80211/debug.h */
1475         printf_hook(__sdata_err, 1, 2);                   /* net/mac80211/debug.h */
1476         printf_hook(__sdata_info, 1, 2);                  /* net/mac80211/debug.h */
1477         printf_hook(__wiphy_dbg, 3, 4);                   /* net/mac80211/debug.h */
1478         printf_hook(mac80211_format_buffer, 4, 5);        /* net/mac80211/debugfs.h */
1479         printf_hook(__rds_conn_error, 2, 3);              /* net/rds/rds.h */
1480         printf_hook(rdsdebug, 1, 2);                      /* net/rds/rds.h */
1481         printf_hook(printl, 1, 2);                        /* net/sctp/probe.c */
1482         printf_hook(svc_printk, 2, 3);                    /* net/sunrpc/svc.c */
1483         printf_hook(tomoyo_io_printf, 2, 3);              /* security/tomoyo/common.c */
1484         printf_hook(tomoyo_supervisor, 2, 3);             /* security/tomoyo/common.h */
1485         printf_hook(tomoyo_write_log, 2, 3);              /* security/tomoyo/common.h */
1486         printf_hook(cmp_error, 2, 3);                     /* sound/firewire/cmp.c */
1487 }