#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
 
-#define PRINTF __attribute__ ((format (printf, 1, 2)))
-
-PRINTF void fatal(const char *fmt, ...)
+void __attribute__((format(printf, 2, 3)))
+modpost_log(enum loglevel loglevel, const char *fmt, ...)
 {
        va_list arglist;
 
-       fprintf(stderr, "FATAL: ");
-
-       va_start(arglist, fmt);
-       vfprintf(stderr, fmt, arglist);
-       va_end(arglist);
-
-       exit(1);
-}
-
-PRINTF void warn(const char *fmt, ...)
-{
-       va_list arglist;
+       switch (loglevel) {
+       case LOG_WARN:
+               fprintf(stderr, "WARNING: ");
+               break;
+       case LOG_ERROR:
+               fprintf(stderr, "ERROR: ");
+               break;
+       case LOG_FATAL:
+               fprintf(stderr, "FATAL: ");
+               break;
+       default: /* invalid loglevel, ignore */
+               break;
+       }
 
-       fprintf(stderr, "WARNING: ");
+       fprintf(stderr, "modpost: ");
 
        va_start(arglist, fmt);
        vfprintf(stderr, fmt, arglist);
        va_end(arglist);
-}
-
-PRINTF void merror(const char *fmt, ...)
-{
-       va_list arglist;
-
-       fprintf(stderr, "ERROR: ");
 
-       va_start(arglist, fmt);
-       vfprintf(stderr, fmt, arglist);
-       va_end(arglist);
+       if (loglevel == LOG_FATAL)
+               exit(1);
 }
 
 static inline bool strends(const char *str, const char *postfix)
 void *do_nofail(void *ptr, const char *expr)
 {
        if (!ptr)
-               fatal("modpost: Memory allocation failure: %s.\n", expr);
+               fatal("Memory allocation failure: %s.\n", expr);
 
        return ptr;
 }
 
        license = get_modinfo(&info, "license");
        if (!license && !is_vmlinux(modname))
-               warn("modpost: missing MODULE_LICENSE() in %s\n"
+               warn("missing MODULE_LICENSE() in %s\n"
                     "see include/linux/module.h for "
                     "more information\n", modname);
        while (license) {
 
        switch (exp) {
        case export_gpl:
-               fatal("modpost: GPL-incompatible module %s%s "
+               fatal("GPL-incompatible module %s%s "
                      "uses GPL-only symbol '%s'\n", m, e, s);
                break;
        case export_unused_gpl:
-               fatal("modpost: GPL-incompatible module %s%s "
+               fatal("GPL-incompatible module %s%s "
                      "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
                break;
        case export_gpl_future:
-               warn("modpost: GPL-incompatible module %s%s "
+               warn("GPL-incompatible module %s%s "
                      "uses future GPL-only symbol '%s'\n", m, e, s);
                break;
        case export_plain:
        switch (exp) {
        case export_unused:
        case export_unused_gpl:
-               warn("modpost: module %s%s "
+               warn("module %s%s "
                      "uses symbol '%s' marked UNUSED\n", m, e, s);
                break;
        default:
                exp = find_symbol(s->name);
                if (!exp || exp->module == mod) {
                        if (have_vmlinux && !s->weak) {
-                               if (warn_unresolved) {
-                                       warn("\"%s\" [%s.ko] undefined!\n",
-                                            s->name, mod->name);
-                               } else {
-                                       merror("\"%s\" [%s.ko] undefined!\n",
-                                              s->name, mod->name);
+                               modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
+                                           "\"%s\" [%s.ko] undefined!\n",
+                                           s->name, mod->name);
+                               if (!warn_unresolved)
                                        err = 1;
-                               }
                        }
                        continue;
                }
        if (dump_write)
                write_dump(dump_write);
        if (sec_mismatch_count && sec_mismatch_fatal)
-               fatal("modpost: Section mismatches detected.\n"
+               fatal("Section mismatches detected.\n"
                      "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
        for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
                struct symbol *s;
 
 char* get_next_line(unsigned long *pos, void *file, unsigned long size);
 void release_file(void *file, unsigned long size);
 
-void fatal(const char *fmt, ...);
-void warn(const char *fmt, ...);
-void merror(const char *fmt, ...);
+enum loglevel {
+       LOG_WARN,
+       LOG_ERROR,
+       LOG_FATAL
+};
+
+void modpost_log(enum loglevel loglevel, const char *fmt, ...);
+
+#define warn(fmt, args...)     modpost_log(LOG_WARN, fmt, ##args)
+#define merror(fmt, args...)   modpost_log(LOG_ERROR, fmt, ##args)
+#define fatal(fmt, args...)    modpost_log(LOG_FATAL, fmt, ##args)