blob: ffe7a2e594ddf3e36a7c0e8c3b7d53e1b8a0c069 [file] [log] [blame]
H. Peter Anvin22538e22016-05-25 05:42:47 -07001/* ----------------------------------------------------------------------- *
H. Peter Anvinb2047cb2017-03-08 01:26:40 -08002 *
H. Peter Anvin (Intel)1df72632019-01-11 13:13:03 -08003 * Copyright 1996-2019 The NASM Authors - All Rights Reserved
H. Peter Anvin22538e22016-05-25 05:42:47 -07004 * 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.
H. Peter Anvinb2047cb2017-03-08 01:26:40 -080017 *
H. Peter Anvin22538e22016-05-25 05:42:47 -070018 * 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/*
H. Peter Anvinb20bc732017-03-07 19:23:03 -080035 * error.c - error message handling routines for the assembler
H. Peter Anvin22538e22016-05-25 05:42:47 -070036 */
37
38#include "compiler.h"
39
H. Peter Anvin22538e22016-05-25 05:42:47 -070040
41#include "nasmlib.h"
H. Peter Anvinb20bc732017-03-07 19:23:03 -080042#include "error.h"
43
H. Peter Anvind351efc2018-12-10 21:53:54 -080044/* Common function body */
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070045#define nasm_do_error(_sev,_flags) \
46 va_list ap; \
47 va_start(ap, fmt); \
48 if ((_sev) >= ERR_CRITICAL) \
49 nasm_verror_critical((_sev)|(_flags), fmt, ap); \
50 else \
51 nasm_verror((_sev)|(_flags), fmt, ap); \
52 va_end(ap); \
53 if ((_sev) >= ERR_FATAL) \
54 abort();
55
H. Peter Anvind351efc2018-12-10 21:53:54 -080056
H. Peter Anvin (Intel)6bde2ed2018-12-13 19:39:41 -080057void nasm_error(errflags severity, const char *fmt, ...)
H. Peter Anvin22538e22016-05-25 05:42:47 -070058{
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070059 nasm_do_error(severity & ERR_MASK, severity & ~ERR_MASK);
H. Peter Anvin22538e22016-05-25 05:42:47 -070060}
61
H. Peter Anvind351efc2018-12-10 21:53:54 -080062#define nasm_err_helpers(_type, _name, _sev) \
H. Peter Anvin (Intel)6bde2ed2018-12-13 19:39:41 -080063_type nasm_ ## _name ## f (errflags flags, const char *fmt, ...) \
H. Peter Anvind351efc2018-12-10 21:53:54 -080064{ \
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070065 nasm_do_error(_sev, flags); \
H. Peter Anvind351efc2018-12-10 21:53:54 -080066} \
67_type nasm_ ## _name (const char *fmt, ...) \
68{ \
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070069 nasm_do_error(_sev, 0); \
Cyrill Gorcunovc3527dd2018-11-24 22:17:47 +030070}
71
H. Peter Anvin (Intel)d66927a2019-08-09 04:28:55 -070072nasm_err_helpers(void, listmsg, ERR_LISTMSG)
H. Peter Anvind351efc2018-12-10 21:53:54 -080073nasm_err_helpers(void, debug, ERR_DEBUG)
H. Peter Anvin (Intel)d66927a2019-08-09 04:28:55 -070074nasm_err_helpers(void, info, ERR_INFO)
H. Peter Anvind351efc2018-12-10 21:53:54 -080075nasm_err_helpers(void, nonfatal, ERR_NONFATAL)
76nasm_err_helpers(fatal_func, fatal, ERR_FATAL)
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070077nasm_err_helpers(fatal_func, critical, ERR_CRITICAL)
H. Peter Anvind351efc2018-12-10 21:53:54 -080078nasm_err_helpers(fatal_func, panic, ERR_PANIC)
H. Peter Anvin22538e22016-05-25 05:42:47 -070079
H. Peter Anvin (Intel)80c4f232018-12-14 13:33:24 -080080/*
81 * Strongly discourage warnings without level by require flags on warnings.
82 * This means nasm_warn() is the equivalent of the -f variants of the
83 * other ones.
84 */
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070085void nasm_warn(errflags flags, const char *fmt, ...)
H. Peter Anvin (Intel)80c4f232018-12-14 13:33:24 -080086{
H. Peter Anvin6a4353c2019-08-28 18:32:46 -070087 nasm_do_error(ERR_WARNING, flags);
H. Peter Anvin (Intel)80c4f232018-12-14 13:33:24 -080088}
H. Peter Anvin (Intel)1df72632019-01-11 13:13:03 -080089
H. Peter Anvin6686fc62018-02-22 14:52:50 -080090fatal_func nasm_panic_from_macro(const char *file, int line)
H. Peter Anvin22538e22016-05-25 05:42:47 -070091{
Cyrill Gorcunov33510722018-11-24 18:58:11 +030092 nasm_panic("internal error at %s:%d\n", file, line);
H. Peter Anvin22538e22016-05-25 05:42:47 -070093}
94
H. Peter Anvin6686fc62018-02-22 14:52:50 -080095fatal_func nasm_assert_failed(const char *file, int line, const char *msg)
H. Peter Anvin22538e22016-05-25 05:42:47 -070096{
Cyrill Gorcunov33510722018-11-24 18:58:11 +030097 nasm_panic("assertion %s failed at %s:%d", msg, file, line);
H. Peter Anvinb2047cb2017-03-08 01:26:40 -080098}
99
H. Peter Anvin (Intel)1df72632019-01-11 13:13:03 -0800100
101/*
102 * Warning stack management. Note that there is an implicit "push"
103 * after the command line has been parsed, but this particular push
104 * cannot be popped.
105 */
106struct warning_stack {
107 struct warning_stack *next;
108 uint8_t state[sizeof warning_state];
109};
110static struct warning_stack *warning_stack, *warning_state_init;
111
112/* Push the warning status onto the warning stack */
113void push_warnings(void)
114{
115 struct warning_stack *ws;
116
117 ws = nasm_malloc(sizeof *ws);
118 memcpy(ws->state, warning_state, sizeof warning_state);
119 ws->next = warning_stack;
120 warning_stack = ws;
121}
122
123/* Pop the warning status off the warning stack */
124void pop_warnings(void)
125{
126 struct warning_stack *ws = warning_stack;
127
128 memcpy(warning_state, ws->state, sizeof warning_state);
129 if (!ws->next) {
130 /*!
131 *!warn-stack-empty [on] warning stack empty
132 *! a [WARNING POP] directive was executed when
133 *! the warning stack is empty. This is treated
134 *! as a [WARNING *all] directive.
135 */
136 nasm_warn(WARN_WARN_STACK_EMPTY, "warning stack empty");
137 } else {
138 warning_stack = ws->next;
139 nasm_free(ws);
140 }
141}
142
143/* Call after the command line is parsed, but before the first pass */
144void init_warnings(void)
145{
146 push_warnings();
147 warning_state_init = warning_stack;
148}
149
150
151/* Call after each pass */
152void reset_warnings(void)
153{
154 struct warning_stack *ws = warning_stack;
155
156 /* Unwind the warning stack. We do NOT delete the last entry! */
157 while (ws->next) {
158 struct warning_stack *wst = ws;
159 ws = ws->next;
160 nasm_free(wst);
161 }
162 warning_stack = ws;
163 memcpy(warning_state, ws->state, sizeof warning_state);
164}
165
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800166/*
167 * This is called when processing a -w or -W option, or a warning directive.
H. Peter Anvin (Intel)eb48c112018-12-12 16:11:08 -0800168 * Returns on if if the action was successful.
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800169 *
170 * Special pseudo-warnings:
171 *
172 *!other [on] any warning not specifially mentioned above
173 *! specifies any warning not included in any specific warning class.
174 *
175 *!all [all] all possible warnings
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700176 *! is an group alias for \e{all} warning classes. Thus, \c{-w+all}
177 *! enables all available warnings, and \c{-w-all} disables warnings
178 *! entirely (since NASM 2.13).
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800179 */
180bool set_warning_status(const char *value)
181{
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300182 enum warn_action { WID_OFF, WID_ON, WID_RESET };
183 enum warn_action action;
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700184 const struct warning_alias *wa;
185 size_t vlen;
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300186 bool ok = false;
187 uint8_t mask;
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800188
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300189 value = nasm_skip_spaces(value);
H. Peter Anvin (Intel)1df72632019-01-11 13:13:03 -0800190
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300191 switch (*value) {
192 case '-':
193 action = WID_OFF;
194 value++;
195 break;
196 case '+':
197 action = WID_ON;
198 value++;
199 break;
200 case '*':
201 action = WID_RESET;
202 value++;
203 break;
204 case 'N':
205 case 'n':
206 if (!nasm_strnicmp(value, "no-", 3)) {
207 action = WID_OFF;
208 value += 3;
209 break;
210 } else if (!nasm_stricmp(value, "none")) {
211 action = WID_OFF;
212 value = NULL;
213 break;
214 }
215 /* else fall through */
216 default:
217 action = WID_ON;
218 break;
219 }
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800220
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300221 mask = WARN_ST_ENABLED;
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800222
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300223 if (value && !nasm_strnicmp(value, "error", 5)) {
224 switch (value[5]) {
225 case '=':
226 mask = WARN_ST_ERROR;
227 value += 6;
228 break;
229 case '\0':
230 mask = WARN_ST_ERROR;
231 value = NULL;
232 break;
233 default:
234 /* Just an accidental prefix? */
235 break;
236 }
237 }
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800238
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300239 if (value && !nasm_stricmp(value, "all"))
240 value = NULL;
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800241
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700242 vlen = value ? strlen(value) : 0;
H. Peter Anvinb2047cb2017-03-08 01:26:40 -0800243
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700244 /* This is inefficient, but it shouldn't matter... */
245 for (wa = warning_alias; wa < &warning_alias[NUM_WARNING_ALIAS]; wa++) {
246 enum warn_index i = wa->warning;
247
248 if (value) {
249 char sep;
250
251 if (nasm_strnicmp(value, wa->name, vlen))
252 continue; /* Not a prefix */
253
254 sep = wa->name[vlen];
255 if (sep != '\0' && sep != '-')
256 continue; /* Not a valid prefix */
257 }
258
259 ok = true; /* At least one action taken */
260 switch (action) {
261 case WID_OFF:
262 warning_state[i] &= ~mask;
263 break;
264 case WID_ON:
265 warning_state[i] |= mask;
266 break;
267 case WID_RESET:
268 warning_state[i] &= ~mask;
269 warning_state[i] |= warning_state_init->state[i] & mask;
270 break;
271 }
272 }
273
274 if (!ok && value) {
275 /*!
276 *!unknown-warning [off] unknown warning in -W/-w or warning directive
277 *! warns about a \c{-w} or \c{-W} option or a \c{[WARNING]} directive
278 *! that contains an unknown warning name or is otherwise not possible to process.
279 */
280 nasm_warn(WARN_UNKNOWN_WARNING, "unknown warning name: %s", value);
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800281 }
H. Peter Anvin (Intel)1df72632019-01-11 13:13:03 -0800282
Cyrill Gorcunov33510722018-11-24 18:58:11 +0300283 return ok;
H. Peter Anvin22538e22016-05-25 05:42:47 -0700284}