1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2019 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * Parse and handle [pragma] directives. The preprocessor handles
36 * %pragma preproc directives separately, all other namespaces are
37 * simply converted to [pragma].
50 static enum directive_result
ignore_pragma(const struct pragma
*pragma
);
51 static enum directive_result
output_pragma(const struct pragma
*pragma
);
52 static enum directive_result
debug_pragma(const struct pragma
*pragma
);
53 static enum directive_result
limit_pragma(const struct pragma
*pragma
);
56 * Handle [pragma] directives. [pragma] is generally produced by
57 * the %pragma preprocessor directive, which simply passes on any
58 * string that it finds *except* %pragma preproc. The idea is
59 * that pragmas are of the form:
61 * %pragma <facility> <opname> [<options>...]
63 * ... where "facility" can be either a generic facility or a backend
66 * The following names are currently reserved for global facilities;
67 * so far none of these have any defined pragmas at all:
69 * preproc - preprocessor
70 * limit - limit setting
72 * list - listing generator
73 * file - generic file handling
74 * input - input file handling
75 * output - backend-independent output handling
76 * debug - backend-independent debug handling
77 * ignore - dummy pragma (can be used to "comment out")
79 * This function should generally not error out if it doesn't understand
80 * what a pragma is for, for unknown arguments, etc; the whole point of
81 * a pragma is that future releases might add new ones that should be
82 * ignored rather than be an error. Erroring out is acceptable for
83 * known pragmas suffering from parsing errors and so on.
85 * Adding default-suppressed warnings would, however, be a good idea
88 static struct pragma_facility global_pragmas
[] =
91 { "limit", limit_pragma
},
92 { "list", list_pragma
},
95 { "output", output_pragma
},
96 { "debug", debug_pragma
},
97 { "ignore", ignore_pragma
},
99 /* This will never actually get this far... */
100 { "preproc", NULL
}, /* Handled in the preprocessor by necessity */
105 * Invoke a pragma handler
107 static enum directive_result
108 call_pragma(const struct pragma_facility
*pf
, struct pragma
*pragma
)
110 if (!pf
|| !pf
->handler
)
113 pragma
->facility
= pf
;
114 return pf
->handler(pragma
);
118 * Search a pragma list for a known pragma facility and if so, invoke
119 * the handler. Return true if processing is complete. The "default
120 * name", *or def->name*, if set, matches the final NULL entry (used
121 * for backends, so multiple backends can share the same list under
122 * some circumstances, and the backends can implement common operations.)
124 static enum directive_result
125 search_pragma_list(const struct pragma_facility
*list
,
126 const char *defaultname
,
127 const struct pragma_facility
*def
,
128 const struct pragma
*cpragma
)
130 const struct pragma_facility
*pf
= NULL
;
131 enum directive_result rv
;
132 bool facility_match
, is_default
;
133 struct pragma pragma
= *cpragma
;
134 const char *facname
= pragma
.facility_name
;
136 /* Is there a default facility and we match its name? */
137 is_default
= def
&& def
->name
&& !nasm_stricmp(facname
, def
->name
);
138 facility_match
= is_default
;
141 * Promote def->name to defaultname if both are set. This handles
142 * e.g. output -> elf32 so that we can handle elf32-specific
143 * directives in that handler.
147 facname
= defaultname
;
149 facility_match
= !nasm_stricmp(facname
, defaultname
);
152 if (facname
&& list
) {
153 for (pf
= list
; pf
->name
; pf
++) {
154 if (!nasm_stricmp(facname
, pf
->name
)) {
155 facility_match
= true;
156 rv
= call_pragma(pf
, &pragma
);
157 if (rv
!= DIRR_UNKNOWN
)
162 if (facility_match
) {
164 * Facility name match but no matching directive; handler in NULL
165 * entry at end of list?
167 rv
= call_pragma(pf
, &pragma
);
168 if (rv
!= DIRR_UNKNOWN
)
173 if (facility_match
) {
175 * Facility match but still nothing: def->handler if it exists
177 rv
= call_pragma(def
, &pragma
);
180 * No facility matched
186 * Otherwise we found the facility but not any supported directive,
193 switch (pragma
.opcode
) {
196 *!pragma-bad [off] malformed %pragma
198 *! warns about a malformed or otherwise unparsable
199 *! \c{%pragma} directive.
201 nasm_warn(ERR_PASS2
|WARN_PRAGMA_BAD
,
202 "empty %%pragma %s", pragma
.facility_name
);
206 *!pragma-unknown [off] unknown %pragma facility or directive
208 *! warns about an unknown \c{%pragma} directive.
209 *! This is not yet implemented for most cases.
211 nasm_warn(ERR_PASS2
|WARN_PRAGMA_UNKNOWN
,
212 "unknown %%pragma %s %s",
213 pragma
.facility_name
, pragma
.opname
);
216 rv
= DIRR_ERROR
; /* Already printed an error message */
221 break; /* Nothing to do */
225 * This one is an error. Don't use it if forward compatibility
226 * would be compromised, as opposed to an inherent error.
228 nasm_error(ERR_NONFATAL
, "bad argument to %%pragma %s %s",
229 pragma
.facility_name
, pragma
.opname
);
238 /* This warning message is intended for future use */
240 *!pragma-na [off] %pragma not applicable to this compilation
242 *! warns about a \c{%pragma} directive which is not applicable to
243 *! this particular assembly session. This is not yet implemented.
248 *!pragma-empty [off] empty %pragma directive
249 *! warns about a \c{%pragma} directive containing nothing.
250 *! This is treated identically to \c{%pragma ignore} except
251 *! for this optional warning.
253 void process_pragma(char *str
)
255 const struct pragma_facility
*pf
;
256 struct pragma pragma
;
261 pragma
.facility_name
= nasm_get_word(str
, &p
);
262 if (!pragma
.facility_name
) {
264 nasm_warn(ERR_PASS2
|WARN_PRAGMA_EMPTY
,
265 "empty %%pragma directive, ignored");
269 pragma
.opname
= nasm_get_word(p
, &p
);
271 pragma
.opcode
= D_none
;
273 pragma
.opcode
= directive_find(pragma
.opname
);
275 pragma
.tail
= nasm_trim_spaces(p
);
278 * Search the global pragma namespaces. This is done
279 * as a loop rather than than letting search_pragma_list()
280 * just run, because we don't want to keep searching if
281 * we have a facility match, thus we want to call
282 * search_pragma_list() individually for each namespace.
284 for (pf
= global_pragmas
; pf
->name
; pf
++) {
285 if (search_pragma_list(NULL
, NULL
, pf
, &pragma
) != DIRR_UNKNOWN
)
289 /* Is it an output pragma? */
290 if (output_pragma(&pragma
) != DIRR_UNKNOWN
)
293 /* Is it a debug pragma */
294 if (debug_pragma(&pragma
) != DIRR_UNKNOWN
)
298 * Note: it would be nice to warn for an unknown namespace,
299 * but in order to do so we need to walk *ALL* the backends
300 * in order to make sure we aren't dealing with a pragma that
301 * is for another backend. On the other hand, that could
302 * also be a warning with a separate warning flag.
304 * Leave this for the future, however, the warning classes are
305 * already defined for future compatibility.
310 static enum directive_result
ignore_pragma(const struct pragma
*pragma
)
313 return DIRR_OK
; /* Even for D_none! */
317 * Process output and debug pragmas, by either list name or generic
318 * name. Note that the output/debug format list can hook the default
319 * names if they so choose.
321 static enum directive_result
output_pragma_common(const struct pragma
*);
322 static enum directive_result
output_pragma(const struct pragma
*pragma
)
324 static const struct pragma_facility
325 output_pragma_def
= { "output", output_pragma_common
};
327 return search_pragma_list(ofmt
->pragmas
, ofmt
->shortname
,
328 &output_pragma_def
, pragma
);
331 /* Generic pragmas that apply to all output backends */
332 static enum directive_result
output_pragma_common(const struct pragma
*pragma
)
334 switch (pragma
->opcode
) {
337 set_label_mangle(LM_GPREFIX
, pragma
->tail
);
341 set_label_mangle(LM_GSUFFIX
, pragma
->tail
);
344 set_label_mangle(LM_LPREFIX
, pragma
->tail
);
347 set_label_mangle(LM_LSUFFIX
, pragma
->tail
);
354 static enum directive_result
debug_pragma(const struct pragma
*pragma
)
356 static const struct pragma_facility
357 debug_pragma_def
= { "debug", NULL
};
359 return search_pragma_list(dfmt
->pragmas
, dfmt
->shortname
,
360 &debug_pragma_def
, pragma
);
364 * %pragma limit to set resource limits
366 static enum directive_result
limit_pragma(const struct pragma
*pragma
)
368 return nasm_set_limit(pragma
->opname
, pragma
->tail
);