blob: 42c15ee9b6cb8791d43998de6dbf6be3bd4539d1 [file] [log] [blame]
H. Peter Anvina6e26d92017-03-07 21:32:37 -08001/* ----------------------------------------------------------------------- *
2 *
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -07003 * Copyright 1996-2019 The NASM Authors - All Rights Reserved
H. Peter Anvina6e26d92017-03-07 21:32:37 -08004 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
10 *
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.
17 *
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.
31 *
32 * ----------------------------------------------------------------------- */
33
34/*
35 * Parse and handle [pragma] directives. The preprocessor handles
36 * %pragma preproc directives separately, all other namespaces are
37 * simply converted to [pragma].
38 */
39
40#include "compiler.h"
41
H. Peter Anvinc2f3f262018-12-27 12:37:25 -080042#include "nctype.h"
H. Peter Anvina6e26d92017-03-07 21:32:37 -080043
44#include "nasm.h"
45#include "nasmlib.h"
Cyrill Gorcunov48541332017-03-08 11:39:42 +030046#include "assemble.h"
H. Peter Anvina6e26d92017-03-07 21:32:37 -080047#include "error.h"
H. Peter Anvin59d4ccc2019-08-10 06:45:12 -070048#include "listing.h"
H. Peter Anvina6e26d92017-03-07 21:32:37 -080049
H. Peter Anvin1dd926e2019-09-30 13:14:29 -070050static enum directive_result ignore_pragma(const struct pragma *pragma);
H. Peter Anvinf7be8b32018-06-18 11:32:17 -070051static enum directive_result output_pragma(const struct pragma *pragma);
H. Peter Anvin1dd926e2019-09-30 13:14:29 -070052static enum directive_result debug_pragma(const struct pragma *pragma);
H. Peter Anvin987dc9c2018-06-12 13:50:37 -070053static enum directive_result limit_pragma(const struct pragma *pragma);
H. Peter Anvin98578072018-06-01 18:02:54 -070054
H. Peter Anvina6e26d92017-03-07 21:32:37 -080055/*
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:
60 *
61 * %pragma <facility> <opname> [<options>...]
62 *
63 * ... where "facility" can be either a generic facility or a backend
64 * name.
65 *
66 * The following names are currently reserved for global facilities;
67 * so far none of these have any defined pragmas at all:
68 *
69 * preproc - preprocessor
H. Peter Anvin987dc9c2018-06-12 13:50:37 -070070 * limit - limit setting
H. Peter Anvina6e26d92017-03-07 21:32:37 -080071 * asm - assembler
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")
78 *
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.
84 *
85 * Adding default-suppressed warnings would, however, be a good idea
86 * at some point.
87 */
88static struct pragma_facility global_pragmas[] =
89{
H. Peter Anvinf7be8b32018-06-18 11:32:17 -070090 { "asm", NULL },
H. Peter Anvin987dc9c2018-06-12 13:50:37 -070091 { "limit", limit_pragma },
H. Peter Anvin59d4ccc2019-08-10 06:45:12 -070092 { "list", list_pragma },
H. Peter Anvina6e26d92017-03-07 21:32:37 -080093 { "file", NULL },
94 { "input", NULL },
H. Peter Anvin1dd926e2019-09-30 13:14:29 -070095 { "output", output_pragma },
96 { "debug", debug_pragma },
97 { "ignore", ignore_pragma },
H. Peter Anvinb7136482018-05-30 14:42:06 -070098
H. Peter Anvin1dd926e2019-09-30 13:14:29 -070099 /* This will never actually get this far... */
H. Peter Anvinf7be8b32018-06-18 11:32:17 -0700100 { "preproc", NULL }, /* Handled in the preprocessor by necessity */
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800101 { NULL, NULL }
102};
103
104/*
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700105 * Invoke a pragma handler
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800106 */
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700107static enum directive_result
108call_pragma(const struct pragma_facility *pf, struct pragma *pragma)
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800109{
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700110 if (!pf || !pf->handler)
111 return DIRR_UNKNOWN;
112
113 pragma->facility = pf;
114 return pf->handler(pragma);
115}
116
117/*
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.)
123 */
124static enum directive_result
125search_pragma_list(const struct pragma_facility *list,
126 const char *defaultname,
127 const struct pragma_facility *def,
128 const struct pragma *cpragma)
129{
130 const struct pragma_facility *pf = NULL;
H. Peter Anvin87534252017-03-08 20:28:13 -0800131 enum directive_result rv;
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700132 bool facility_match, is_default;
133 struct pragma pragma = *cpragma;
134 const char *facname = pragma.facility_name;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800135
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700136 /* 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;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800139
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700140 /*
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.
144 */
145 if (defaultname) {
146 if (is_default)
147 facname = defaultname;
148 else
149 facility_match = !nasm_stricmp(facname, defaultname);
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800150 }
151
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700152 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)
158 goto found_it;
159 }
160 }
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800161
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700162 if (facility_match) {
163 /*
164 * Facility name match but no matching directive; handler in NULL
165 * entry at end of list?
166 */
167 rv = call_pragma(pf, &pragma);
168 if (rv != DIRR_UNKNOWN)
169 goto found_it;
170 }
171 }
172
173 if (facility_match) {
174 /*
175 * Facility match but still nothing: def->handler if it exists
176 */
177 rv = call_pragma(def, &pragma);
178 } else {
179 /*
180 * No facility matched
181 */
182 return DIRR_UNKNOWN;
183 }
184
185 /*
186 * Otherwise we found the facility but not any supported directive,
187 * fall through...
188 */
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800189
190found_it:
H. Peter Anvin87534252017-03-08 20:28:13 -0800191 switch (rv) {
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800192 case DIRR_UNKNOWN:
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700193 switch (pragma.opcode) {
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800194 case D_none:
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800195 /*!
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700196 *!pragma-bad [off] malformed %pragma
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700197 *!=bad-pragma
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800198 *! warns about a malformed or otherwise unparsable
199 *! \c{%pragma} directive.
200 */
H. Peter Anvin (Intel)873ceee2019-08-06 19:18:36 -0700201 nasm_warn(ERR_PASS2|WARN_PRAGMA_BAD,
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700202 "empty %%pragma %s", pragma.facility_name);
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800203 break;
204 default:
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800205 /*!
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700206 *!pragma-unknown [off] unknown %pragma facility or directive
207 *!=unknown-pragma
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800208 *! warns about an unknown \c{%pragma} directive.
209 *! This is not yet implemented for most cases.
210 */
H. Peter Anvin (Intel)873ceee2019-08-06 19:18:36 -0700211 nasm_warn(ERR_PASS2|WARN_PRAGMA_UNKNOWN,
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800212 "unknown %%pragma %s %s",
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700213 pragma.facility_name, pragma.opname);
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800214 break;
215 }
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700216 rv = DIRR_ERROR; /* Already printed an error message */
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800217 break;
218
219 case DIRR_OK:
220 case DIRR_ERROR:
221 break; /* Nothing to do */
222
223 case DIRR_BADPARAM:
224 /*
225 * This one is an error. Don't use it if forward compatibility
226 * would be compromised, as opposed to an inherent error.
227 */
228 nasm_error(ERR_NONFATAL, "bad argument to %%pragma %s %s",
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700229 pragma.facility_name, pragma.opname);
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800230 break;
231
232 default:
233 panic();
234 }
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700235 return rv;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800236}
237
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800238/* This warning message is intended for future use */
239/*!
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700240 *!pragma-na [off] %pragma not applicable to this compilation
241 *!=not-my-pragma
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800242 *! warns about a \c{%pragma} directive which is not applicable to
243 *! this particular assembly session. This is not yet implemented.
244 */
245
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700246/* Naked %pragma */
247/*!
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.
252 */
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800253void process_pragma(char *str)
254{
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700255 const struct pragma_facility *pf;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800256 struct pragma pragma;
257 char *p;
258
H. Peter Anvine886c0e2017-03-31 14:56:17 -0700259 nasm_zero(pragma);
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800260
261 pragma.facility_name = nasm_get_word(str, &p);
262 if (!pragma.facility_name) {
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700263 /* Empty %pragma */
264 nasm_warn(ERR_PASS2|WARN_PRAGMA_EMPTY,
265 "empty %%pragma directive, ignored");
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800266 return;
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700267 }
H. Peter Anvinb7136482018-05-30 14:42:06 -0700268
H. Peter Anvind9493fa2017-03-08 20:05:41 -0800269 pragma.opname = nasm_get_word(p, &p);
270 if (!pragma.opname)
271 pragma.opcode = D_none;
272 else
H. Peter Anvin5253f582017-04-03 00:09:58 -0700273 pragma.opcode = directive_find(pragma.opname);
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800274
H. Peter Anvin98578072018-06-01 18:02:54 -0700275 pragma.tail = nasm_trim_spaces(p);
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800276
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700277 /*
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.
283 */
284 for (pf = global_pragmas; pf->name; pf++) {
285 if (search_pragma_list(NULL, NULL, pf, &pragma) != DIRR_UNKNOWN)
286 return;
287 }
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800288
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700289 /* Is it an output pragma? */
290 if (output_pragma(&pragma) != DIRR_UNKNOWN)
291 return;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800292
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700293 /* Is it a debug pragma */
294 if (debug_pragma(&pragma) != DIRR_UNKNOWN)
295 return;
H. Peter Anvina6e26d92017-03-07 21:32:37 -0800296
297 /*
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.
303 *
304 * Leave this for the future, however, the warning classes are
305 * already defined for future compatibility.
306 */
307}
H. Peter Anvin98578072018-06-01 18:02:54 -0700308
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700309/* %pragma ignore */
310static enum directive_result ignore_pragma(const struct pragma *pragma)
311{
312 (void)pragma;
313 return DIRR_OK; /* Even for D_none! */
314}
315
H. Peter Anvin98578072018-06-01 18:02:54 -0700316/*
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700317 * 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.
H. Peter Anvin98578072018-06-01 18:02:54 -0700320 */
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700321static enum directive_result output_pragma_common(const struct pragma *);
H. Peter Anvinf7be8b32018-06-18 11:32:17 -0700322static enum directive_result output_pragma(const struct pragma *pragma)
H. Peter Anvin98578072018-06-01 18:02:54 -0700323{
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700324 static const struct pragma_facility
325 output_pragma_def = { "output", output_pragma_common };
326
327 return search_pragma_list(ofmt->pragmas, ofmt->shortname,
328 &output_pragma_def, pragma);
329}
330
331/* Generic pragmas that apply to all output backends */
332static enum directive_result output_pragma_common(const struct pragma *pragma)
333{
H. Peter Anvin98578072018-06-01 18:02:54 -0700334 switch (pragma->opcode) {
335 case D_PREFIX:
336 case D_GPREFIX:
337 set_label_mangle(LM_GPREFIX, pragma->tail);
338 return DIRR_OK;
339 case D_SUFFIX:
340 case D_GSUFFIX:
341 set_label_mangle(LM_GSUFFIX, pragma->tail);
342 return DIRR_OK;
343 case D_LPREFIX:
344 set_label_mangle(LM_LPREFIX, pragma->tail);
345 return DIRR_OK;
346 case D_LSUFFIX:
347 set_label_mangle(LM_LSUFFIX, pragma->tail);
348 return DIRR_OK;
349 default:
350 return DIRR_UNKNOWN;
351 }
352}
H. Peter Anvin987dc9c2018-06-12 13:50:37 -0700353
H. Peter Anvin1dd926e2019-09-30 13:14:29 -0700354static enum directive_result debug_pragma(const struct pragma *pragma)
355{
356 static const struct pragma_facility
357 debug_pragma_def = { "debug", NULL };
358
359 return search_pragma_list(dfmt->pragmas, dfmt->shortname,
360 &debug_pragma_def, pragma);
361}
362
H. Peter Anvinf7be8b32018-06-18 11:32:17 -0700363/*
364 * %pragma limit to set resource limits
365 */
H. Peter Anvin987dc9c2018-06-12 13:50:37 -0700366static enum directive_result limit_pragma(const struct pragma *pragma)
367{
368 return nasm_set_limit(pragma->opname, pragma->tail);
369}