From a6e26d9cca91ee2b008ece9f7298740ed0b2edf6 Mon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <hpa@linux.intel.com>
Date: Tue, 7 Mar 2017 21:32:37 -0800
Subject: [PATCH] Add a generic pragma-handling infrastructure

Add infrastructure for handling %pragmas with a variety of namespaces,
etc., etc...

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 Makefile.in          |   6 ++
 Mkfiles/msvc.mak     |   6 ++
 Mkfiles/netware.mak  |   4 +
 Mkfiles/openwcom.mak |   6 ++
 Mkfiles/owlinux.mak  |   6 ++
 asm/assemble.h       |   3 +
 asm/directiv.c       |  14 ++--
 asm/directiv.pl      |   1 -
 asm/error.c          |   3 +
 asm/nasm.c           |   2 +-
 asm/pragma.c         | 176 +++++++++++++++++++++++++++++++++++++++++++
 asm/preproc.c        |   2 +-
 include/error.h      |   5 +-
 include/nasm.h       |  37 +++++++++
 output/codeview.c    |   1 +
 output/nulldbg.c     |   3 +-
 output/outaout.c     |   6 +-
 output/outas86.c     |   3 +-
 output/outbin.c      |   9 ++-
 output/outcoff.c     |   9 ++-
 output/outdbg.c      |   4 +-
 output/outelf.c      |  35 ++++++---
 output/outieee.c     |   4 +-
 output/outmacho.c    |   6 +-
 output/outobj.c      |   4 +-
 output/outrdf2.c     |   3 +-
 26 files changed, 320 insertions(+), 38 deletions(-)
 create mode 100644 asm/pragma.c

diff --git a/Makefile.in b/Makefile.in
index ddbf60f2..6df47a20 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -107,6 +107,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
 	asm/error.$(O) \
 	asm/float.$(O) \
 	asm/directiv.$(O) asm/directbl.$(O) \
+	asm/pragma.$(O) \
 	asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) \
 	asm/preproc.$(O) asm/quote.$(O) asm/pptok.$(O) \
 	asm/listing.$(O) asm/eval.$(O) asm/exprlib.$(O) asm/exprdump.$(O) \
@@ -450,6 +451,11 @@ asm/parser.$(O): asm/parser.c asm/assemble.h asm/directiv.h asm/eval.h \
 asm/pptok.$(O): asm/pptok.c asm/pptok.h asm/preproc.h config/config.h \
  config/msvc.h config/unknown.h config/watcom.h include/compiler.h \
  include/hashtbl.h include/nasmint.h include/nasmlib.h
+asm/pragma.$(O): asm/pragma.c asm/directiv.h asm/pptok.h asm/preproc.h \
+ config/config.h config/msvc.h config/unknown.h config/watcom.h \
+ include/compiler.h include/error.h include/nasm.h include/nasmint.h \
+ include/nasmlib.h include/opflags.h include/strlist.h include/tables.h \
+ x86/insnsi.h x86/regs.h
 asm/preproc-nop.$(O): asm/preproc-nop.c asm/directiv.h asm/listing.h \
  asm/pptok.h asm/preproc.h config/config.h config/msvc.h config/unknown.h \
  config/watcom.h include/compiler.h include/error.h include/nasm.h \
diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak
index 3c33c972..fd44c506 100644
--- a/Mkfiles/msvc.mak
+++ b/Mkfiles/msvc.mak
@@ -75,6 +75,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
 	asm/error.$(O) \
 	asm/float.$(O) \
 	asm/directiv.$(O) asm/directbl.$(O) \
+	asm/pragma.$(O) \
 	asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) \
 	asm/preproc.$(O) asm/quote.$(O) asm/pptok.$(O) \
 	asm/listing.$(O) asm/eval.$(O) asm/exprlib.$(O) asm/exprdump.$(O) \
@@ -335,6 +336,11 @@ asm/parser.$(O): asm/parser.c asm/assemble.h asm/directiv.h asm/eval.h \
 asm/pptok.$(O): asm/pptok.c asm/pptok.h asm/preproc.h config/msvc.h \
  config/unknown.h config/watcom.h include/compiler.h include/hashtbl.h \
  include/nasmint.h include/nasmlib.h
+asm/pragma.$(O): asm/pragma.c asm/directiv.h asm/pptok.h asm/preproc.h \
+ config/msvc.h config/unknown.h config/watcom.h include/compiler.h \
+ include/error.h include/nasm.h include/nasmint.h include/nasmlib.h \
+ include/opflags.h include/strlist.h include/tables.h x86/insnsi.h \
+ x86/regs.h
 asm/preproc-nop.$(O): asm/preproc-nop.c asm/directiv.h asm/listing.h \
  asm/pptok.h asm/preproc.h config/msvc.h config/unknown.h config/watcom.h \
  include/compiler.h include/error.h include/nasm.h include/nasmint.h \
diff --git a/Mkfiles/netware.mak b/Mkfiles/netware.mak
index 5ede0a65..17865c27 100644
--- a/Mkfiles/netware.mak
+++ b/Mkfiles/netware.mak
@@ -52,6 +52,7 @@ LIBOBJ = snprintf.o vsnprintf.o strlcpy.o \
 	error.o \
 	float.o \
 	directiv.o directbl.o \
+	pragma.o \
 	assemble.o labels.o parser.o \
 	preproc.o quote.o pptok.o \
 	listing.o eval.o exprlib.o exprdump.o \
@@ -195,6 +196,9 @@ parser.o: parser.c assemble.h directiv.h eval.h float.h parser.h pptok.h \
  tables.h iflaggen.h insnsi.h regs.h
 pptok.o: pptok.c pptok.h preproc.h config.h msvc.h unknown.h watcom.h \
  compiler.h hashtbl.h nasmint.h nasmlib.h
+pragma.o: pragma.c directiv.h pptok.h preproc.h config.h msvc.h unknown.h \
+ watcom.h compiler.h error.h nasm.h nasmint.h nasmlib.h opflags.h strlist.h \
+ tables.h insnsi.h regs.h
 preproc-nop.o: preproc-nop.c directiv.h listing.h pptok.h preproc.h config.h \
  msvc.h unknown.h watcom.h compiler.h error.h nasm.h nasmint.h nasmlib.h \
  opflags.h strlist.h tables.h insnsi.h regs.h
diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak
index ae550181..20355ed8 100644
--- a/Mkfiles/openwcom.mak
+++ b/Mkfiles/openwcom.mak
@@ -68,6 +68,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) &
 	asm/error.$(O) &
 	asm/float.$(O) &
 	asm/directiv.$(O) asm/directbl.$(O) &
+	asm/pragma.$(O) &
 	asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) &
 	asm/preproc.$(O) asm/quote.$(O) asm/pptok.$(O) &
 	asm/listing.$(O) asm/eval.$(O) asm/exprlib.$(O) asm/exprdump.$(O) &
@@ -337,6 +338,11 @@ asm/parser.$(O): asm/parser.c asm/assemble.h asm/directiv.h asm/eval.h &
 asm/pptok.$(O): asm/pptok.c asm/pptok.h asm/preproc.h config/msvc.h &
  config/unknown.h config/watcom.h include/compiler.h include/hashtbl.h &
  include/nasmint.h include/nasmlib.h
+asm/pragma.$(O): asm/pragma.c asm/directiv.h asm/pptok.h asm/preproc.h &
+ config/msvc.h config/unknown.h config/watcom.h include/compiler.h &
+ include/error.h include/nasm.h include/nasmint.h include/nasmlib.h &
+ include/opflags.h include/strlist.h include/tables.h x86/insnsi.h &
+ x86/regs.h
 asm/preproc-nop.$(O): asm/preproc-nop.c asm/directiv.h asm/listing.h &
  asm/pptok.h asm/preproc.h config/msvc.h config/unknown.h config/watcom.h &
  include/compiler.h include/error.h include/nasm.h include/nasmint.h &
diff --git a/Mkfiles/owlinux.mak b/Mkfiles/owlinux.mak
index 3d343d25..c1cc32c0 100644
--- a/Mkfiles/owlinux.mak
+++ b/Mkfiles/owlinux.mak
@@ -79,6 +79,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
 	asm/error.$(O) \
 	asm/float.$(O) \
 	asm/directiv.$(O) asm/directbl.$(O) \
+	asm/pragma.$(O) \
 	asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) \
 	asm/preproc.$(O) asm/quote.$(O) asm/pptok.$(O) \
 	asm/listing.$(O) asm/eval.$(O) asm/exprlib.$(O) asm/exprdump.$(O) \
@@ -327,6 +328,11 @@ asm/parser.$(O): asm/parser.c asm/assemble.h asm/directiv.h asm/eval.h \
 asm/pptok.$(O): asm/pptok.c asm/pptok.h asm/preproc.h config/config.h \
  config/msvc.h config/unknown.h config/watcom.h include/compiler.h \
  include/hashtbl.h include/nasmint.h include/nasmlib.h
+asm/pragma.$(O): asm/pragma.c asm/directiv.h asm/pptok.h asm/preproc.h \
+ config/config.h config/msvc.h config/unknown.h config/watcom.h \
+ include/compiler.h include/error.h include/nasm.h include/nasmint.h \
+ include/nasmlib.h include/opflags.h include/strlist.h include/tables.h \
+ x86/insnsi.h x86/regs.h
 asm/preproc-nop.$(O): asm/preproc-nop.c asm/directiv.h asm/listing.h \
  asm/pptok.h asm/preproc.h config/config.h config/msvc.h config/unknown.h \
  config/watcom.h include/compiler.h include/error.h include/nasm.h \
diff --git a/asm/assemble.h b/asm/assemble.h
index 22ab34da..f47ae032 100644
--- a/asm/assemble.h
+++ b/asm/assemble.h
@@ -48,4 +48,7 @@ extern struct location absolute;
 int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction);
 int64_t assemble(int32_t segment, int64_t offset, int bits, insn *instruction);
 
+bool process_directives(char *);
+void process_pragma(char *);
+
 #endif
diff --git a/asm/directiv.c b/asm/directiv.c
index e2b7519b..e8bb42d3 100644
--- a/asm/directiv.c
+++ b/asm/directiv.c
@@ -182,12 +182,12 @@ static enum directives parse_directive_line(char **directive, char **value)
     return find_directive(*directive);
 }
 
-static void process_pragma(char *str)
-{
-    (void)str;
-}
-
-enum directives process_directives(char *directive)
+/*
+ * Process a line from the assembler and try to handle it if it
+ * is a directive.  Return true if the line was handled (including
+ * if it was an error), false otherwise.
+ */
+bool process_directives(char *directive)
 {
     enum directives d;
     char *value, *p, *q, *special;
@@ -563,5 +563,5 @@ enum directives process_directives(char *directive)
                    directive);
     }
 
-    return d;
+    return d != D_none;
 }
diff --git a/asm/directiv.pl b/asm/directiv.pl
index 05b84840..eef46f69 100755
--- a/asm/directiv.pl
+++ b/asm/directiv.pl
@@ -88,7 +88,6 @@ if ($output eq 'h') {
     printf H "extern const char * const directives[%d];\n",
         scalar(@directives)+scalar(@specials);
     print H "enum directives find_directive(const char *token);\n\n";
-    print H "enum directives process_directives(char *line); /* in asm/directiv.c */\n";
     print H "#endif /* NASM_DIRECTIV_H */\n";
 } elsif ($output eq 'c') {
     %directive = ();
diff --git a/asm/error.c b/asm/error.c
index 4b22f2d2..bfe833b8 100644
--- a/asm/error.c
+++ b/asm/error.c
@@ -65,6 +65,9 @@ const struct warning warnings[ERR_WARN_MAX+1] = {
     {"bnd", "invalid bnd prefixes", true},
     {"zext-reloc", "relocation zero-extended to match output format", true},
     {"ptr", "non-NASM keyword used in other assemblers", true},
+    {"bad-pragma", "empty or malformed %pragma", false},
+    {"unknown-pragma", "unknown %pragma facility or directive", false},
+    {"not-my-pragma", "%pragma not applicable to this compilation", false}
 };
 bool warning_on[ERR_WARN_MAX+1];        /* Current state */
 bool warning_on_global[ERR_WARN_MAX+1]; /* Command-line state, for reset */
diff --git a/asm/nasm.c b/asm/nasm.c
index 9e3c2344..62291bb8 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1260,7 +1260,7 @@ static void assemble_file(char *fname, StrList **depend_ptr)
              * Here we parse our directives; this is not handled by the
              * main parser.
              */
-            if (process_directives(line) != D_none)
+            if (process_directives(line))
                 goto end_of_line; /* Just do final cleanup */
 
             /* Not a directive, or even something that starts with [ */
diff --git a/asm/pragma.c b/asm/pragma.c
new file mode 100644
index 00000000..d0518e8b
--- /dev/null
+++ b/asm/pragma.c
@@ -0,0 +1,176 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1996-2017 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Parse and handle [pragma] directives.  The preprocessor handles
+ * %pragma preproc directives separately, all other namespaces are
+ * simply converted to [pragma].
+ */
+
+#include "compiler.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "error.h"
+
+/*
+ * Handle [pragma] directives.  [pragma] is generally produced by
+ * the %pragma preprocessor directive, which simply passes on any
+ * string that it finds *except* %pragma preproc.  The idea is
+ * that pragmas are of the form:
+ *
+ * %pragma <facility> <opname> [<options>...]
+ *
+ * ... where "facility" can be either a generic facility or a backend
+ * name.
+ *
+ * The following names are currently reserved for global facilities;
+ * so far none of these have any defined pragmas at all:
+ *
+ * preproc	- preprocessor
+ * asm		- assembler
+ * list		- listing generator
+ * file		- generic file handling
+ * input	- input file handling
+ * output	- backend-independent output handling
+ * debug	- backend-independent debug handling
+ * ignore	- dummy pragma (can be used to "comment out")
+ *
+ * This function should generally not error out if it doesn't understand
+ * what a pragma is for, for unknown arguments, etc; the whole point of
+ * a pragma is that future releases might add new ones that should be
+ * ignored rather than be an error.  Erroring out is acceptable for
+ * known pragmas suffering from parsing errors and so on.
+ *
+ * Adding default-suppressed warnings would, however, be a good idea
+ * at some point.
+ */
+static struct pragma_facility global_pragmas[] =
+{
+    { "preproc",	NULL }, /* This shouldn't happen... */
+    { "asm",		NULL },
+    { "list",		NULL },
+    { "file",		NULL },
+    { "input",		NULL },
+    { "output",		NULL },
+    { "debug",		NULL },
+    { "ignore",		NULL },
+    { NULL, NULL }
+};
+
+/*
+ * Search a pragma list for a known pragma facility and if so, invoke
+ * the handler.  Return true if processing is complete.
+ * The "default name", if set, matches the final NULL entry (used
+ * for backends, so multiple backends can share the same list under
+ * some circumstances.)
+ */
+static bool search_pragma_list(const struct pragma_facility *list,
+                               const char *default_name,
+			       struct pragma *pragma)
+{
+    const struct pragma_facility *pf;
+
+    if (!list)
+	return false;
+
+    for (pf = list; pf->name; pf++) {
+        if (!nasm_stricmp(pragma->facility_name, pf->name))
+            goto found_it;
+    }
+
+    if (default_name && !nasm_stricmp(pragma->facility_name, default_name))
+        goto found_it;
+
+    return false;
+
+found_it:
+    if (!pf->handler)
+        return true;
+
+    pragma->facility = pf;
+    pf->handler(pragma);
+    return true;
+}
+
+void process_pragma(char *str)
+{
+    struct pragma pragma;
+    char *p;
+
+    nasm_zero(&pragma);
+
+    pragma.facility_name = nasm_get_word(str, &p);
+    if (!pragma.facility_name) {
+	nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_BAD_PRAGMA,
+		   "empty pragma directive");
+        return;                 /* Empty pragma */
+    }
+
+    pragma.operation = nasm_get_word(p, &p);
+    if (!pragma.operation) {
+	nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_BAD_PRAGMA,
+		   "pragma directive contains only facility namespace");
+        return;                 /* Facility name only */
+    }
+
+    pragma.tail = nasm_skip_spaces(p);
+
+    /* Look for a global pragma namespace */
+    if (search_pragma_list(global_pragmas, NULL, &pragma))
+	return;
+
+    /* Look to see if it is an output backend pragma */
+    if (search_pragma_list(ofmt->pragmas, ofmt->shortname, &pragma))
+	return;
+
+    /* Look to see if it is a debug format pragma */
+    if (search_pragma_list(dfmt->pragmas, dfmt->shortname, &pragma))
+	return;
+
+    /*
+     * Note: it would be nice to warn for an unknown namespace,
+     * but in order to do so we need to walk *ALL* the backends
+     * in order to make sure we aren't dealing with a pragma that
+     * is for another backend.  On the other hand, that could
+     * also be a warning with a separate warning flag.
+     *
+     * Leave this for the future, however, the warning classes are
+     * already defined for future compatibility.
+     */
+}
diff --git a/asm/preproc.c b/asm/preproc.c
index 75d92f45..97e87d2c 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 1996-2016 The NASM Authors - All Rights Reserved
+ *   Copyright 1996-2017 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
  *
diff --git a/include/error.h b/include/error.h
index 542b313a..18a50073 100644
--- a/include/error.h
+++ b/include/error.h
@@ -107,7 +107,10 @@ static inline vefunc nasm_set_verror(vefunc ve)
 #define ERR_WARN_BND		WARN(14) /* bad BND prefixes */
 #define ERR_WARN_ZEXTRELOC	WARN(15) /* relocation zero-extended */
 #define ERR_WARN_PTR		WARN(16) /* not a NASM keyword */
-#define ERR_WARN_MAX            16       /* the highest numbered one */
+#define ERR_WARN_BAD_PRAGMA	WARN(17) /* malformed pragma */
+#define ERR_WARN_UNKNOWN_PRAGMA	WARN(18) /* unknown pragma */
+#define ERR_WARN_NOTMY_PRAGMA	WARN(19) /* pragma inapplicable */
+#define ERR_WARN_MAX            19       /* the highest numbered one */
 
 struct warning {
     const char *name;
diff --git a/include/nasm.h b/include/nasm.h
index f49d9feb..2a231411 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -684,6 +684,33 @@ enum geninfo { GI_SWITCH };
 /* Instruction flags type: IF_* flags are defined in insns.h */
 typedef uint64_t iflags_t;
 
+/*
+ * A pragma facility: this structure is used to request passing a
+ * parsed pragma directive for a specific facility.  If the handler is
+ * NULL then this pragma facility is recognized but ignored; pragma
+ * processing stops at that point, as if the handler had returned true.
+ *
+ * Note that the handler is passed a pointer to the facility structure
+ * as part of the struct pragma.
+ */
+struct pragma;
+
+struct pragma_facility {
+    const char *name;
+    void (*handler)(const struct pragma *);
+};
+
+/*
+ * This structure defines how a pragma directive is passed to a
+ * facility.  This structure may be augmented in the future.
+ */
+struct pragma {
+    const struct pragma_facility *facility;
+    const char *facility_name;  /* Facility name exactly as entered by user */
+    const char *operation;      /* First word after the facility name */
+    const char *tail;           /* Anything after the operation */
+};
+
 /*
  * The data structure defining an output format driver, and the
  * interfaces to the functions therein.
@@ -881,6 +908,11 @@ struct ofmt {
      * the output file pointer.
      */
     void (*cleanup)(void);
+
+    /*
+     * List of pragma facility names that apply to this backend.
+     */
+    const struct pragma_facility *pragmas;
 };
 
 /*
@@ -960,6 +992,11 @@ struct dfmt {
      * cleanup - called after processing of file is complete
      */
     void (*cleanup)(void);
+
+    /*
+     * List of pragma facility names that apply to this backend.
+     */
+    const struct pragma_facility *pragmas;
 };
 
 extern const struct dfmt *dfmt;
diff --git a/output/codeview.c b/output/codeview.c
index ba6bc61a..579ac8d6 100644
--- a/output/codeview.c
+++ b/output/codeview.c
@@ -71,6 +71,7 @@ const struct dfmt df_cv8 = {
     cv8_typevalue,              /* .debug_typevalue */
     cv8_output,                 /* .debug_output */
     cv8_cleanup,                /* .cleanup */
+    NULL                        /* pragma list */
 };
 
 /*******************************************************************************
diff --git a/output/nulldbg.c b/output/nulldbg.c
index 1a9607a9..c09ccd4b 100644
--- a/output/nulldbg.c
+++ b/output/nulldbg.c
@@ -86,7 +86,8 @@ const struct dfmt null_debug_form = {
     null_debug_directive,
     null_debug_typevalue,
     null_debug_output,
-    null_debug_cleanup
+    null_debug_cleanup,
+    NULL                        /* pragma list */
 };
 
 const struct dfmt * const null_debug_arr[2] = { &null_debug_form, NULL };
diff --git a/output/outaout.c b/output/outaout.c
index 193c75a0..0e3349d1 100644
--- a/output/outaout.c
+++ b/output/outaout.c
@@ -923,7 +923,8 @@ const struct ofmt of_aout = {
     aout_segbase,
     null_directive,
     aout_filename,
-    aout_cleanup
+    aout_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif
@@ -948,7 +949,8 @@ const struct ofmt of_aoutb = {
     aout_segbase,
     null_directive,
     aout_filename,
-    aout_cleanup
+    aout_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif
diff --git a/output/outas86.c b/output/outas86.c
index 5a36270e..15be1ea2 100644
--- a/output/outas86.c
+++ b/output/outas86.c
@@ -644,7 +644,8 @@ const struct ofmt of_as86 = {
     as86_segbase,
     null_directive,
     as86_filename,
-    as86_cleanup
+    as86_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif                          /* OF_AS86 */
diff --git a/output/outbin.c b/output/outbin.c
index 04f27f8c..25fdfcc7 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -1671,7 +1671,8 @@ const struct ofmt of_bin = {
     bin_segbase,
     bin_directive,
     bin_filename,
-    bin_cleanup
+    bin_cleanup,
+    NULL                        /* pragma list */
 };
 
 const struct ofmt of_ith = {
@@ -1692,7 +1693,8 @@ const struct ofmt of_ith = {
     bin_segbase,
     bin_directive,
     ith_filename,
-    bin_cleanup
+    bin_cleanup,
+    NULL                        /* pragma list */
 };
 
 const struct ofmt of_srec = {
@@ -1713,7 +1715,8 @@ const struct ofmt of_srec = {
     bin_segbase,
     bin_directive,
     srec_filename,
-    bin_cleanup
+    bin_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif                          /* #ifdef OF_BIN */
diff --git a/output/outcoff.c b/output/outcoff.c
index 9f791ff1..ee576d9f 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -1184,7 +1184,8 @@ const struct ofmt of_coff = {
     coff_segbase,
     coff_directives,
     coff_std_filename,
-    coff_cleanup
+    coff_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif
@@ -1213,7 +1214,8 @@ const struct ofmt of_win32 = {
     coff_segbase,
     coff_directives,
     coff_win32_filename,
-    coff_cleanup
+    coff_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif
@@ -1240,7 +1242,8 @@ const struct ofmt of_win64 = {
     coff_segbase,
     coff_directives,
     coff_win32_filename,
-    coff_cleanup
+    coff_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif
diff --git a/output/outdbg.c b/output/outdbg.c
index 783bd36f..acc4cd86 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -251,6 +251,7 @@ static const struct dfmt debug_debug_form = {
     dbgdbg_typevalue,
     dbgdbg_output,
     dbgdbg_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt * const debug_debug_arr[3] = {
@@ -277,7 +278,8 @@ const struct ofmt of_dbg = {
     dbg_segbase,
     dbg_directive,
     dbg_filename,
-    dbg_cleanup
+    dbg_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif                          /* OF_DBG */
diff --git a/output/outelf.c b/output/outelf.c
index f5968e2e..6ccfcf64 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -2235,7 +2235,8 @@ static const struct dfmt elf32_df_dwarf = {
     null_debug_directive,
     debug_typevalue,
     dwarf_output,
-    dwarf_cleanup
+    dwarf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt elf32_df_stabs = {
@@ -2247,7 +2248,8 @@ static const struct dfmt elf32_df_stabs = {
     null_debug_directive,
     debug_typevalue,
     stabs_output,
-    stabs_cleanup
+    stabs_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt * const elf32_debugs_arr[3] =
@@ -2271,7 +2273,8 @@ const struct ofmt of_elf32 = {
     elf_segbase,
     elf_directive,
     elf_filename,
-    elf_cleanup
+    elf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt elf64_df_dwarf = {
@@ -2283,7 +2286,8 @@ static const struct dfmt elf64_df_dwarf = {
     null_debug_directive,
     debug_typevalue,
     dwarf_output,
-    dwarf_cleanup
+    dwarf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt elf64_df_stabs = {
@@ -2295,7 +2299,8 @@ static const struct dfmt elf64_df_stabs = {
     null_debug_directive,
     debug_typevalue,
     stabs_output,
-    stabs_cleanup
+    stabs_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt * const elf64_debugs_arr[3] =
@@ -2319,7 +2324,8 @@ const struct ofmt of_elf64 = {
     elf_segbase,
     elf_directive,
     elf_filename,
-    elf_cleanup
+    elf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt elfx32_df_dwarf = {
@@ -2331,7 +2337,8 @@ static const struct dfmt elfx32_df_dwarf = {
     null_debug_directive,
     debug_typevalue,
     dwarf_output,
-    dwarf_cleanup
+    dwarf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt elfx32_df_stabs = {
@@ -2343,7 +2350,8 @@ static const struct dfmt elfx32_df_stabs = {
     null_debug_directive,
     debug_typevalue,
     stabs_output,
-    stabs_cleanup
+    stabs_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt * const elfx32_debugs_arr[3] =
@@ -2367,7 +2375,8 @@ const struct ofmt of_elfx32 = {
     elf_segbase,
     elf_directive,
     elf_filename,
-    elf_cleanup
+    elf_cleanup,
+    NULL                        /* pragma list */
 };
 
 static bool is_elf64(void)
@@ -2387,12 +2396,16 @@ static bool is_elfx32(void)
 
 static bool dfmt_is_stabs(void)
 {
-	return dfmt == &elf32_df_stabs || dfmt == &elfx32_df_stabs || dfmt == &elf64_df_stabs;
+	return dfmt == &elf32_df_stabs ||
+               dfmt == &elfx32_df_stabs ||
+               dfmt == &elf64_df_stabs;
 }
 
 static bool dfmt_is_dwarf(void)
 {
-	return dfmt == &elf32_df_dwarf || dfmt == &elfx32_df_dwarf || dfmt == &elf64_df_dwarf;
+	return dfmt == &elf32_df_dwarf ||
+               dfmt == &elfx32_df_dwarf ||
+               dfmt == &elf64_df_dwarf;
 }
 
 /* common debugging routines */
diff --git a/output/outieee.c b/output/outieee.c
index cff32458..7607e673 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -1507,6 +1507,7 @@ static const struct dfmt ladsoft_debug_form = {
     dbgls_typevalue,
     dbgls_output,
     dbgls_cleanup,
+    NULL                        /* pragma list */
 };
 static const struct dfmt * const ladsoft_debug_arr[3] = {
     &ladsoft_debug_form,
@@ -1531,7 +1532,8 @@ const struct ofmt of_ieee = {
     ieee_segbase,
     ieee_directive,
     ieee_filename,
-    ieee_cleanup
+    ieee_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif                          /* OF_IEEE */
diff --git a/output/outmacho.c b/output/outmacho.c
index f7ccd376..5ce3e45b 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -1636,7 +1636,8 @@ const struct ofmt of_macho32 = {
     macho_segbase,
     null_directive,
     macho_filename,
-    macho_cleanup
+    macho_cleanup,
+    NULL                        /* pragma list */
 };
 #endif
 
@@ -1684,7 +1685,8 @@ const struct ofmt of_macho64 = {
     macho_segbase,
     null_directive,
     macho_filename,
-    macho_cleanup
+    macho_cleanup,
+    NULL                        /* pragma list */
 };
 #endif
 
diff --git a/output/outobj.c b/output/outobj.c
index 2b6ce459..39712a74 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -2647,6 +2647,7 @@ static const struct dfmt borland_debug_form = {
     dbgbi_typevalue,
     dbgbi_output,
     dbgbi_cleanup,
+    NULL                        /* pragma list */
 };
 
 static const struct dfmt * const borland_debug_arr[3] = {
@@ -2673,6 +2674,7 @@ const struct ofmt of_obj = {
     obj_segbase,
     obj_directive,
     obj_filename,
-    obj_cleanup
+    obj_cleanup,
+    NULL                        /* pragma list */
 };
 #endif                          /* OF_OBJ */
diff --git a/output/outrdf2.c b/output/outrdf2.c
index b62808ac..eaba9329 100644
--- a/output/outrdf2.c
+++ b/output/outrdf2.c
@@ -791,7 +791,8 @@ const struct ofmt of_rdf2 = {
     rdf2_segbase,
     rdf2_directive,
     rdf2_filename,
-    rdf2_cleanup
+    rdf2_cleanup,
+    NULL                        /* pragma list */
 };
 
 #endif                          /* OF_RDF2 */