blob: 8a689e45983d913415c9282bdef27ca4b40221f2 [file] [log] [blame]
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001/* The Netwide Assembler main program module
2 *
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
Beroset095e6a22007-12-29 09:44:23 -05005 * redistributable under the license given in the file "LICENSE"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00006 * distributed in the NASM archive.
7 */
8
H. Peter Anvinfe501952007-10-02 21:53:51 -07009#include "compiler.h"
10
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000011#include <stdio.h>
12#include <stdarg.h>
13#include <stdlib.h>
14#include <string.h>
15#include <ctype.h>
Keith Kaniosb7a89542007-04-12 02:40:54 +000016#include <inttypes.h>
H. Peter Anvinfd7dd112007-10-10 14:06:59 -070017#include <limits.h>
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -080018#include <time.h>
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000019
20#include "nasm.h"
21#include "nasmlib.h"
H. Peter Anvin1803ded2008-06-09 17:32:43 -070022#include "saa.h"
H. Peter Anvinfcb89092008-06-09 17:40:16 -070023#include "raa.h"
H. Peter Anvinf6c9e652007-10-16 14:40:27 -070024#include "float.h"
H. Peter Anvin74cc5e52007-08-30 22:35:34 +000025#include "stdscan.h"
H. Peter Anvinaf535c12002-04-30 20:59:21 +000026#include "insns.h"
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000027#include "preproc.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000028#include "parser.h"
H. Peter Anvin76690a12002-04-30 20:52:49 +000029#include "eval.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000030#include "assemble.h"
31#include "labels.h"
32#include "outform.h"
H. Peter Anvin6768eb72002-04-30 20:52:26 +000033#include "listing.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000034
H. Peter Anvine2c80182005-01-15 22:15:51 +000035struct forwrefinfo { /* info held on forward refs. */
H. Peter Anvineba20a72002-04-30 20:53:55 +000036 int lineno;
37 int operand;
38};
39
Keith Kaniosa6dfa782007-04-13 16:47:53 +000040static int get_bits(char *value);
41static uint32_t get_cpu(char *cpu_str);
42static void parse_cmdline(int, char **);
H. Peter Anvin9e1f5282008-05-29 21:38:00 -070043static void assemble_file(char *, StrList **);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000044static void register_output_formats(void);
Keith Kaniosa6dfa782007-04-13 16:47:53 +000045static void report_error_gnu(int severity, const char *fmt, ...);
46static void report_error_vc(int severity, const char *fmt, ...);
47static void report_error_common(int severity, const char *fmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +000048 va_list args);
H. Peter Anvin2b046cf2008-01-22 14:08:36 -080049static bool is_suppressed_warning(int severity);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000050static void usage(void);
Ed Berosetfa771012002-06-09 20:56:40 +000051static efunc report_error;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000052
John Coffman0efaec92002-05-26 19:20:08 +000053static int using_debug_info, opt_verbose_info;
H. Peter Anvin6867acc2007-10-10 14:58:45 -070054bool tasm_compatible_mode = false;
H. Peter Anvin00835fe2008-01-08 23:03:57 -080055int pass0, passn;
Keith Kaniosb7a89542007-04-12 02:40:54 +000056int maxbits = 0;
H. Peter Anvin99c4ecd2007-08-28 23:06:00 +000057int globalrel = 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +000058
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -080059time_t official_compile_time;
60
Keith Kaniosa6dfa782007-04-13 16:47:53 +000061static char inname[FILENAME_MAX];
62static char outname[FILENAME_MAX];
63static char listname[FILENAME_MAX];
Charles Craynefcce07f2007-09-30 22:15:36 -070064static char errname[FILENAME_MAX];
H. Peter Anvine2c80182005-01-15 22:15:51 +000065static int globallineno; /* for forward-reference tracking */
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +000066/* static int pass = 0; */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000067static struct ofmt *ofmt = NULL;
68
H. Peter Anvine2c80182005-01-15 22:15:51 +000069static FILE *error_file; /* Where to write error messages */
H. Peter Anvin620515a2002-04-30 20:57:38 +000070
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000071static FILE *ofile = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +000072int optimizing = -1; /* number of optimization passes to take */
73static int sb, cmd_sb = 16; /* by default */
Keith Kaniosb7a89542007-04-12 02:40:54 +000074static uint32_t cmd_cpu = IF_PLEVEL; /* highest level by default */
75static uint32_t cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */
H. Peter Anvin70055962007-10-11 00:05:31 -070076bool global_offset_changed; /* referenced in labels.c */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000077
H. Peter Anvin12e46512007-10-03 21:30:57 -070078static struct location location;
H. Peter Anvine2c80182005-01-15 22:15:51 +000079int in_abs_seg; /* Flag we are in ABSOLUTE seg */
Keith Kaniosb7a89542007-04-12 02:40:54 +000080int32_t abs_seg; /* ABSOLUTE segment basis */
81int32_t abs_offset; /* ABSOLUTE offset */
H. Peter Anvin6768eb72002-04-30 20:52:26 +000082
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000083static struct RAA *offsets;
H. Peter Anvinea838272002-04-30 20:51:53 +000084
H. Peter Anvine2c80182005-01-15 22:15:51 +000085static struct SAA *forwrefs; /* keep track of forward references */
H. Peter Anvin9d637df2007-10-04 13:42:56 -070086static const struct forwrefinfo *forwref;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000087
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000088static Preproc *preproc;
H. Peter Anvin620515a2002-04-30 20:57:38 +000089enum op_type {
H. Peter Anvine2c80182005-01-15 22:15:51 +000090 op_normal, /* Preprocess and assemble */
91 op_preprocess, /* Preprocess only */
H. Peter Anvin37a321f2007-09-24 13:41:58 -070092 op_depend, /* Generate dependencies */
H. Peter Anvin620515a2002-04-30 20:57:38 +000093};
94static enum op_type operating_mode;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -070095/* Dependency flags */
H. Peter Anvin9e1f5282008-05-29 21:38:00 -070096static bool depend_emit_phony = false;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -070097static bool depend_missing_ok = false;
98static const char *depend_target = NULL;
99static const char *depend_file = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000100
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000101/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000102 * Which of the suppressible warnings are suppressed. Entry zero
H. Peter Anvinb030c922007-11-13 11:31:15 -0800103 * isn't an actual warning, but it used for -w+error/-Werror.
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000104 */
Victor van den Elzen819703a2008-07-16 15:20:56 +0200105static bool suppressed[ERR_WARN_MAX+1];
106
107static bool suppressed_global[ERR_WARN_MAX+1] = {
Victor van den Elzen22343c22008-08-06 14:47:54 +0200108 true, false, true, false, false, false, true, false, true, true, false
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000109};
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000110/*
111 * The option names for the suppressible warnings. As before, entry
112 * zero does nothing.
113 */
H. Peter Anvinb030c922007-11-13 11:31:15 -0800114static const char *suppressed_names[ERR_WARN_MAX+1] = {
Victor van den Elzen22343c22008-08-06 14:47:54 +0200115 "error", "macro-params", "macro-selfref", "macro-defaults",
116 "orphan-labels", "number-overflow", "gnu-elf-extensions",
117 "float-overflow", "float-denorm", "float-underflow", "float-toolong"
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000118};
119
120/*
121 * The explanations for the suppressible warnings. As before, entry
122 * zero does nothing.
123 */
H. Peter Anvinb030c922007-11-13 11:31:15 -0800124static const char *suppressed_what[ERR_WARN_MAX+1] = {
125 "treat warnings as errors",
H. Peter Anvinc68ec012007-11-13 11:34:34 -0800126 "macro calls with wrong parameter count",
127 "cyclic macro references",
Victor van den Elzen22343c22008-08-06 14:47:54 +0200128 "macros with more default than optional parameters",
H. Peter Anvin76690a12002-04-30 20:52:49 +0000129 "labels alone on lines without trailing `:'",
H. Peter Anvinc68ec012007-11-13 11:34:34 -0800130 "numeric constants does not fit in 64 bits",
H. Peter Anvinfab3a6c2007-10-16 11:48:07 -0700131 "using 8- or 16-bit relocation in ELF32, a GNU extension",
H. Peter Anvin125c8782007-10-16 11:32:58 -0700132 "floating point overflow",
133 "floating point denormal",
134 "floating point underflow",
H. Peter Anvinfab3a6c2007-10-16 11:48:07 -0700135 "too many digits in floating-point number"
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000136};
137
138/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000139 * This is a null preprocessor which just copies lines from input
140 * to output. It's used when someone explicitly requests that NASM
141 * not preprocess their source file.
142 */
143
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700144static void no_pp_reset(char *, int, efunc, evalfunc, ListGen *, StrList **);
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000145static char *no_pp_getline(void);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000146static void no_pp_cleanup(int);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000147static Preproc no_pp = {
148 no_pp_reset,
149 no_pp_getline,
150 no_pp_cleanup
151};
152
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000153/*
154 * get/set current offset...
155 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000156#define GET_CURR_OFFS (in_abs_seg?abs_offset:\
H. Peter Anvineba20a72002-04-30 20:53:55 +0000157 raa_read(offsets,location.segment))
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000158#define SET_CURR_OFFS(x) (in_abs_seg?(void)(abs_offset=(x)):\
H. Peter Anvineba20a72002-04-30 20:53:55 +0000159 (void)(offsets=raa_write(offsets,location.segment,(x))))
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000160
161static int want_usage;
162static int terminate_after_phase;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000163int user_nolist = 0; /* fbk 9/2/00 */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000164
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000165static void nasm_fputs(const char *line, FILE * outfile)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000166{
H. Peter Anvin310b3e12002-05-14 22:38:55 +0000167 if (outfile) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000168 fputs(line, outfile);
H. Peter Anvind1fb15c2007-11-13 09:37:59 -0800169 putc('\n', outfile);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000170 } else
H. Peter Anvine2c80182005-01-15 22:15:51 +0000171 puts(line);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000172}
173
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -0800174/* Convert a struct tm to a POSIX-style time constant */
175static int64_t posix_mktime(struct tm *tm)
176{
177 int64_t t;
178 int64_t y = tm->tm_year;
179
180 /* See IEEE 1003.1:2004, section 4.14 */
181
182 t = (y-70)*365 + (y-69)/4 - (y-1)/100 + (y+299)/400;
183 t += tm->tm_yday;
184 t *= 24;
185 t += tm->tm_hour;
186 t *= 60;
187 t += tm->tm_min;
188 t *= 60;
189 t += tm->tm_sec;
190
191 return t;
192}
193
194static void define_macros_early(void)
195{
196 char temp[128];
197 struct tm lt, *lt_p, gm, *gm_p;
198 int64_t posix_time;
199
200 lt_p = localtime(&official_compile_time);
201 if (lt_p) {
202 lt = *lt_p;
203
204 strftime(temp, sizeof temp, "__DATE__=\"%Y-%m-%d\"", &lt);
205 pp_pre_define(temp);
206 strftime(temp, sizeof temp, "__DATE_NUM__=%Y%m%d", &lt);
207 pp_pre_define(temp);
208 strftime(temp, sizeof temp, "__TIME__=\"%H:%M:%S\"", &lt);
209 pp_pre_define(temp);
210 strftime(temp, sizeof temp, "__TIME_NUM__=%H%M%S", &lt);
211 pp_pre_define(temp);
212 }
213
214 gm_p = gmtime(&official_compile_time);
215 if (gm_p) {
216 gm = *gm_p;
217
218 strftime(temp, sizeof temp, "__UTC_DATE__=\"%Y-%m-%d\"", &gm);
219 pp_pre_define(temp);
220 strftime(temp, sizeof temp, "__UTC_DATE_NUM__=%Y%m%d", &gm);
221 pp_pre_define(temp);
222 strftime(temp, sizeof temp, "__UTC_TIME__=\"%H:%M:%S\"", &gm);
223 pp_pre_define(temp);
224 strftime(temp, sizeof temp, "__UTC_TIME_NUM__=%H%M%S", &gm);
225 pp_pre_define(temp);
226 }
H. Peter Anvind85d2502008-05-04 17:53:31 -0700227
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -0800228 if (gm_p)
229 posix_time = posix_mktime(&gm);
230 else if (lt_p)
231 posix_time = posix_mktime(&lt);
232 else
233 posix_time = 0;
234
235 if (posix_time) {
236 snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, posix_time);
237 pp_pre_define(temp);
238 }
239}
240
241static void define_macros_late(void)
242{
243 char temp[128];
244
245 snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s\n",
246 ofmt->shortname);
247 pp_pre_define(temp);
248}
249
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700250static void emit_dependencies(StrList *list)
251{
252 FILE *deps;
253 int linepos, len;
254 StrList *l, *nl;
255
256 if (depend_file && strcmp(depend_file, "-")) {
257 deps = fopen(depend_file, "w");
258 if (!deps) {
259 report_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
260 "unable to write dependency file `%s'", depend_file);
261 return;
262 }
263 } else {
264 deps = stdout;
265 }
266
267 linepos = fprintf(deps, "%s:", depend_target);
268 for (l = list; l; l = l->next) {
269 len = strlen(l->str);
270 if (linepos + len > 62) {
271 fprintf(deps, " \\\n ");
272 linepos = 1;
273 }
274 fprintf(deps, " %s", l->str);
275 linepos += len+1;
276 }
277 fprintf(deps, "\n\n");
278
279 for (l = list; l; l = nl) {
280 if (depend_emit_phony)
281 fprintf(deps, "%s:\n\n", l->str);
282
283 nl = l->next;
284 nasm_free(l);
285 }
286
287 if (deps != stdout)
288 fclose(deps);
289}
290
H. Peter Anvin038d8612007-04-12 16:54:50 +0000291int main(int argc, char **argv)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000292{
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700293 StrList *depend_list = NULL, **depend_ptr;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700294
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -0800295 time(&official_compile_time);
296
Charles Crayne2581c862008-09-10 19:21:52 -0700297 pass0 = 0;
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700298 want_usage = terminate_after_phase = false;
Ed Berosetfa771012002-06-09 20:56:40 +0000299 report_error = report_error_gnu;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000300
H. Peter Anvin97e15752007-09-25 08:47:47 -0700301 error_file = stderr;
302
H. Peter Anvinac8f8fc2008-06-11 15:49:41 -0700303 tolower_init();
304
H. Peter Anvine2c80182005-01-15 22:15:51 +0000305 nasm_set_malloc_error(report_error);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000306 offsets = raa_init();
Keith Kaniosb7a89542007-04-12 02:40:54 +0000307 forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo));
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000308
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000309 preproc = &nasmpp;
H. Peter Anvin620515a2002-04-30 20:57:38 +0000310 operating_mode = op_normal;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000311
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000312 seg_init();
313
314 register_output_formats();
315
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -0800316 /* Define some macros dependent on the runtime, but not
317 on the command line. */
318 define_macros_early();
319
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000320 parse_cmdline(argc, argv);
321
H. Peter Anvine2c80182005-01-15 22:15:51 +0000322 if (terminate_after_phase) {
323 if (want_usage)
324 usage();
325 return 1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000326 }
327
H. Peter Anvinbb88d012003-09-10 23:34:23 +0000328 /* If debugging info is disabled, suppress any debug calls */
329 if (!using_debug_info)
330 ofmt->current_dfmt = &null_debug_form;
331
H. Peter Anvin76690a12002-04-30 20:52:49 +0000332 if (ofmt->stdmac)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000333 pp_extra_stdmac(ofmt->stdmac);
334 parser_global_info(ofmt, &location);
335 eval_global_info(ofmt, lookup_label, &location);
H. Peter Anvin76690a12002-04-30 20:52:49 +0000336
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000337 /* define some macros dependent of command-line */
H. Peter Anvin6b18bcc2008-02-16 14:54:10 -0800338 define_macros_late();
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000339
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700340 depend_ptr = (depend_file || (operating_mode == op_depend))
341 ? &depend_list : NULL;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700342 if (!depend_target)
343 depend_target = outname;
344
H. Peter Anvine2c80182005-01-15 22:15:51 +0000345 switch (operating_mode) {
H. Peter Anvin620515a2002-04-30 20:57:38 +0000346 case op_depend:
H. Peter Anvine2c80182005-01-15 22:15:51 +0000347 {
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000348 char *line;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700349
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700350 if (depend_missing_ok)
351 pp_include_path(NULL); /* "assume generated" */
352
353 preproc->reset(inname, 0, report_error, evaluate, &nasmlist,
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700354 depend_ptr);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000355 if (outname[0] == '\0')
356 ofmt->filename(inname, outname, report_error);
357 ofile = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000358 while ((line = preproc->getline()))
359 nasm_free(line);
360 preproc->cleanup(0);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000361 }
362 break;
H. Peter Anvin620515a2002-04-30 20:57:38 +0000363
364 case op_preprocess:
H. Peter Anvine2c80182005-01-15 22:15:51 +0000365 {
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000366 char *line;
367 char *file_name = NULL;
Keith Kaniosb7a89542007-04-12 02:40:54 +0000368 int32_t prior_linnum = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000369 int lineinc = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000370
H. Peter Anvine2c80182005-01-15 22:15:51 +0000371 if (*outname) {
372 ofile = fopen(outname, "w");
373 if (!ofile)
374 report_error(ERR_FATAL | ERR_NOFILE,
375 "unable to open output file `%s'",
376 outname);
377 } else
378 ofile = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000379
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700380 location.known = false;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000381
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700382 /* pass = 1; */
383 preproc->reset(inname, 2, report_error, evaluate, &nasmlist,
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700384 depend_ptr);
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700385
H. Peter Anvine2c80182005-01-15 22:15:51 +0000386 while ((line = preproc->getline())) {
387 /*
388 * We generate %line directives if needed for later programs
389 */
Keith Kaniosb7a89542007-04-12 02:40:54 +0000390 int32_t linnum = prior_linnum += lineinc;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000391 int altline = src_get(&linnum, &file_name);
392 if (altline) {
393 if (altline == 1 && lineinc == 1)
394 nasm_fputs("", ofile);
395 else {
396 lineinc = (altline != -1 || lineinc != 1);
397 fprintf(ofile ? ofile : stdout,
Keith Kanios93f2e9a2007-04-14 00:10:59 +0000398 "%%line %"PRId32"+%d %s\n", linnum, lineinc,
H. Peter Anvine2c80182005-01-15 22:15:51 +0000399 file_name);
400 }
401 prior_linnum = linnum;
402 }
403 nasm_fputs(line, ofile);
404 nasm_free(line);
405 }
406 nasm_free(file_name);
407 preproc->cleanup(0);
408 if (ofile)
409 fclose(ofile);
410 if (ofile && terminate_after_phase)
411 remove(outname);
412 }
413 break;
H. Peter Anvin620515a2002-04-30 20:57:38 +0000414
415 case op_normal:
H. Peter Anvine2c80182005-01-15 22:15:51 +0000416 {
417 /*
418 * We must call ofmt->filename _anyway_, even if the user
419 * has specified their own output file, because some
420 * formats (eg OBJ and COFF) use ofmt->filename to find out
421 * the name of the input file and then put that inside the
422 * file.
423 */
424 ofmt->filename(inname, outname, report_error);
425
426 ofile = fopen(outname, "wb");
427 if (!ofile) {
428 report_error(ERR_FATAL | ERR_NOFILE,
429 "unable to open output file `%s'", outname);
430 }
431
432 /*
433 * We must call init_labels() before ofmt->init() since
434 * some object formats will want to define labels in their
435 * init routines. (eg OS/2 defines the FLAT group)
436 */
437 init_labels();
438
439 ofmt->init(ofile, report_error, define_label, evaluate);
440
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700441 assemble_file(inname, depend_ptr);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000442
443 if (!terminate_after_phase) {
444 ofmt->cleanup(using_debug_info);
445 cleanup_labels();
446 } else {
447 /*
Victor van den Elzenc82c3722008-06-04 15:24:20 +0200448 * Despite earlier comments, we need this fclose.
449 * The object output drivers only fclose on cleanup,
450 * and we just skipped that.
H. Peter Anvine2c80182005-01-15 22:15:51 +0000451 */
Victor van den Elzenc82c3722008-06-04 15:24:20 +0200452 fclose (ofile);
453
H. Peter Anvine2c80182005-01-15 22:15:51 +0000454 remove(outname);
455 if (listname[0])
456 remove(listname);
457 }
458 }
459 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000460 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000461
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700462 if (depend_list)
463 emit_dependencies(depend_list);
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700464
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000465 if (want_usage)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000466 usage();
H. Peter Anvin734b1882002-04-30 21:01:08 +0000467
H. Peter Anvine2c80182005-01-15 22:15:51 +0000468 raa_free(offsets);
469 saa_free(forwrefs);
470 eval_cleanup();
H. Peter Anvin74cc5e52007-08-30 22:35:34 +0000471 stdscan_cleanup();
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000472
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000473 if (terminate_after_phase)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000474 return 1;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000475 else
H. Peter Anvine2c80182005-01-15 22:15:51 +0000476 return 0;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000477}
478
H. Peter Anvineba20a72002-04-30 20:53:55 +0000479/*
480 * Get a parameter for a command line option.
481 * First arg must be in the form of e.g. -f...
482 */
H. Peter Anvin423e3812007-11-15 17:12:29 -0800483static char *get_param(char *p, char *q, bool *advance)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000484{
H. Peter Anvin423e3812007-11-15 17:12:29 -0800485 *advance = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000486 if (p[2]) { /* the parameter's in the option */
487 p += 2;
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -0700488 while (nasm_isspace(*p))
H. Peter Anvine2c80182005-01-15 22:15:51 +0000489 p++;
490 return p;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000491 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000492 if (q && q[0]) {
H. Peter Anvin423e3812007-11-15 17:12:29 -0800493 *advance = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000494 return q;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000495 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000496 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
497 "option `-%c' requires an argument", p[1]);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000498 return NULL;
499}
500
H. Peter Anvindc242712007-11-18 11:55:10 -0800501/*
502 * Copy a filename
503 */
504static void copy_filename(char *dst, const char *src)
505{
506 size_t len = strlen(src);
507
508 if (len >= (size_t)FILENAME_MAX) {
509 report_error(ERR_FATAL | ERR_NOFILE, "file name too long");
510 return;
511 }
512 strncpy(dst, src, FILENAME_MAX);
513}
514
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700515/*
516 * Convert a string to Make-safe form
517 */
518static char *quote_for_make(const char *str)
519{
520 const char *p;
521 char *os, *q;
522
523 size_t n = 1; /* Terminating zero */
524 size_t nbs = 0;
525
526 if (!str)
527 return NULL;
528
529 for (p = str; *p; p++) {
530 switch (*p) {
531 case ' ':
532 case '\t':
533 /* Convert N backslashes + ws -> 2N+1 backslashes + ws */
534 n += nbs + 2;
535 nbs = 0;
536 break;
537 case '$':
538 case '#':
539 nbs = 0;
540 n += 2;
541 break;
542 case '\\':
543 nbs++;
544 n++;
545 break;
546 default:
547 nbs = 0;
548 n++;
549 break;
550 }
551 }
552
553 /* Convert N backslashes at the end of filename to 2N backslashes */
554 if (nbs)
555 n += nbs;
556
557 os = q = nasm_malloc(n);
558
559 nbs = 0;
560 for (p = str; *p; p++) {
561 switch (*p) {
562 case ' ':
563 case '\t':
564 while (nbs--)
565 *q++ = '\\';
566 *q++ = '\\';
567 *q++ = *p;
568 break;
569 case '$':
570 *q++ = *p;
571 *q++ = *p;
572 nbs = 0;
573 break;
574 case '#':
575 *q++ = '\\';
576 *q++ = *p;
577 nbs = 0;
578 break;
579 case '\\':
580 *q++ = *p;
581 nbs++;
582 break;
583 default:
584 *q++ = *p;
585 nbs = 0;
586 break;
587 }
588 }
589 while (nbs--)
590 *q++ = '\\';
591
592 *q = '\0';
593
594 return os;
595}
596
H. Peter Anvine2c80182005-01-15 22:15:51 +0000597struct textargs {
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000598 const char *label;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000599 int value;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000600};
601
602#define OPT_PREFIX 0
603#define OPT_POSTFIX 1
H. Peter Anvine2c80182005-01-15 22:15:51 +0000604struct textargs textopts[] = {
605 {"prefix", OPT_PREFIX},
606 {"postfix", OPT_POSTFIX},
607 {NULL, 0}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000608};
609
H. Peter Anvin423e3812007-11-15 17:12:29 -0800610static bool stopoptions = false;
611static bool process_arg(char *p, char *q)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000612{
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000613 char *param;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800614 int i;
615 bool advance = false;
H. Peter Anvinb030c922007-11-13 11:31:15 -0800616 bool suppress;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000617
618 if (!p || !p[0])
H. Peter Anvin423e3812007-11-15 17:12:29 -0800619 return false;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000620
H. Peter Anvine2c80182005-01-15 22:15:51 +0000621 if (p[0] == '-' && !stopoptions) {
H. Peter Anvin423e3812007-11-15 17:12:29 -0800622 if (strchr("oOfpPdDiIlFXuUZwW", p[1])) {
623 /* These parameters take values */
624 if (!(param = get_param(p, q, &advance)))
625 return advance;
626 }
627
H. Peter Anvine2c80182005-01-15 22:15:51 +0000628 switch (p[1]) {
629 case 's':
630 error_file = stdout;
631 break;
H. Peter Anvin70653092007-10-19 14:42:29 -0700632
H. Peter Anvin423e3812007-11-15 17:12:29 -0800633 case 'o': /* output file */
H. Peter Anvindc242712007-11-18 11:55:10 -0800634 copy_filename(outname, param);
H. Peter Anvin423e3812007-11-15 17:12:29 -0800635 break;
H. Peter Anvinfd7dd112007-10-10 14:06:59 -0700636
H. Peter Anvin423e3812007-11-15 17:12:29 -0800637 case 'f': /* output format */
638 ofmt = ofmt_find(param);
639 if (!ofmt) {
640 report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
641 "unrecognised output format `%s' - "
642 "use -hf for a list", param);
643 } else {
644 ofmt->current_dfmt = ofmt->debug_formats[0];
645 }
646 break;
H. Peter Anvin70653092007-10-19 14:42:29 -0700647
H. Peter Anvin423e3812007-11-15 17:12:29 -0800648 case 'O': /* Optimization level */
649 {
650 int opt;
H. Peter Anvind85d2502008-05-04 17:53:31 -0700651
H. Peter Anvin423e3812007-11-15 17:12:29 -0800652 if (!*param) {
653 /* Naked -O == -Ox */
654 optimizing = INT_MAX >> 1; /* Almost unlimited */
655 } else {
656 while (*param) {
657 switch (*param) {
658 case '0': case '1': case '2': case '3': case '4':
659 case '5': case '6': case '7': case '8': case '9':
660 opt = strtoul(param, &param, 10);
H. Peter Anvind85d2502008-05-04 17:53:31 -0700661
H. Peter Anvin423e3812007-11-15 17:12:29 -0800662 /* -O0 -> optimizing == -1, 0.98 behaviour */
663 /* -O1 -> optimizing == 0, 0.98.09 behaviour */
664 if (opt < 2)
665 optimizing = opt - 1;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800666 else
H. Peter Anvin34ec3002008-01-08 22:31:20 -0800667 optimizing = opt;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800668 break;
H. Peter Anvind85d2502008-05-04 17:53:31 -0700669
H. Peter Anvin423e3812007-11-15 17:12:29 -0800670 case 'v':
671 case '+':
672 param++;
673 opt_verbose_info = true;
674 break;
H. Peter Anvind85d2502008-05-04 17:53:31 -0700675
H. Peter Anvin423e3812007-11-15 17:12:29 -0800676 case 'x':
677 param++;
678 optimizing = INT_MAX >> 1; /* Almost unlimited */
679 break;
H. Peter Anvind85d2502008-05-04 17:53:31 -0700680
H. Peter Anvin423e3812007-11-15 17:12:29 -0800681 default:
682 report_error(ERR_FATAL,
683 "unknown optimization option -O%c\n",
684 *param);
685 break;
H. Peter Anvinfd7dd112007-10-10 14:06:59 -0700686 }
687 }
H. Peter Anvin423e3812007-11-15 17:12:29 -0800688 }
689 break;
690 }
691
692 case 'p': /* pre-include */
693 case 'P':
694 pp_pre_include(param);
695 break;
696
697 case 'd': /* pre-define */
698 case 'D':
699 pp_pre_define(param);
700 break;
701
702 case 'u': /* un-define */
703 case 'U':
704 pp_pre_undefine(param);
705 break;
706
707 case 'i': /* include search path */
708 case 'I':
709 pp_include_path(param);
710 break;
711
712 case 'l': /* listing file */
H. Peter Anvindc242712007-11-18 11:55:10 -0800713 copy_filename(listname, param);
H. Peter Anvin423e3812007-11-15 17:12:29 -0800714 break;
715
716 case 'Z': /* error messages file */
717 strcpy(errname, param);
718 break;
719
720 case 'F': /* specify debug format */
721 ofmt->current_dfmt = dfmt_find(ofmt, param);
722 if (!ofmt->current_dfmt) {
723 report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
724 "unrecognized debug format `%s' for"
725 " output format `%s'",
726 param, ofmt->shortname);
727 }
H. Peter Anvinca5ec7a2008-06-11 18:07:40 -0700728 using_debug_info = true;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800729 break;
730
731 case 'X': /* specify error reporting format */
732 if (nasm_stricmp("vc", param) == 0)
733 report_error = report_error_vc;
734 else if (nasm_stricmp("gnu", param) == 0)
735 report_error = report_error_gnu;
736 else
737 report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
738 "unrecognized error reporting format `%s'",
739 param);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000740 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800741
H. Peter Anvine2c80182005-01-15 22:15:51 +0000742 case 'g':
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700743 using_debug_info = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000744 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800745
H. Peter Anvine2c80182005-01-15 22:15:51 +0000746 case 'h':
747 printf
748 ("usage: nasm [-@ response file] [-o outfile] [-f format] "
749 "[-l listfile]\n"
750 " [options...] [--] filename\n"
H. Peter Anvin413fb902007-09-26 15:19:28 -0700751 " or nasm -v for version info\n\n"
H. Peter Anvine2c80182005-01-15 22:15:51 +0000752 " -t assemble in SciTech TASM compatible mode\n"
753 " -g generate debug information in selected format.\n");
754 printf
H. Peter Anvin413fb902007-09-26 15:19:28 -0700755 (" -E (or -e) preprocess only (writes output to stdout by default)\n"
H. Peter Anvine2c80182005-01-15 22:15:51 +0000756 " -a don't preprocess (assemble only)\n"
H. Peter Anvin37a321f2007-09-24 13:41:58 -0700757 " -M generate Makefile dependencies on stdout\n"
758 " -MG d:o, missing files assumed generated\n\n"
H. Peter Anvin413fb902007-09-26 15:19:28 -0700759 " -Z<file> redirect error messages to file\n"
H. Peter Anvine2c80182005-01-15 22:15:51 +0000760 " -s redirect error messages to stdout\n\n"
761 " -F format select a debugging format\n\n"
762 " -I<path> adds a pathname to the include file path\n");
763 printf
764 (" -O<digit> optimize branch offsets (-O0 disables, default)\n"
765 " -P<file> pre-includes a file\n"
766 " -D<macro>[=<value>] pre-defines a macro\n"
767 " -U<macro> undefines a macro\n"
768 " -X<format> specifies error reporting format (gnu or vc)\n"
H. Peter Anvinb030c922007-11-13 11:31:15 -0800769 " -w+foo enables warning foo (equiv. -Wfoo)\n"
770 " -w-foo disable warning foo (equiv. -Wno-foo)\n"
771 "Warnings:\n");
772 for (i = 0; i <= ERR_WARN_MAX; i++)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000773 printf(" %-23s %s (default %s)\n",
774 suppressed_names[i], suppressed_what[i],
Victor van den Elzen819703a2008-07-16 15:20:56 +0200775 suppressed_global[i] ? "off" : "on");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000776 printf
777 ("\nresponse files should contain command line parameters"
778 ", one per line.\n");
779 if (p[2] == 'f') {
780 printf("\nvalid output formats for -f are"
781 " (`*' denotes default):\n");
782 ofmt_list(ofmt, stdout);
783 } else {
784 printf("\nFor a list of valid output formats, use -hf.\n");
785 printf("For a list of debug formats, use -f <form> -y.\n");
786 }
787 exit(0); /* never need usage message here */
788 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800789
H. Peter Anvine2c80182005-01-15 22:15:51 +0000790 case 'y':
791 printf("\nvalid debug formats for '%s' output format are"
792 " ('*' denotes default):\n", ofmt->shortname);
793 dfmt_list(ofmt, stdout);
794 exit(0);
795 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800796
H. Peter Anvine2c80182005-01-15 22:15:51 +0000797 case 't':
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700798 tasm_compatible_mode = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000799 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800800
H. Peter Anvine2c80182005-01-15 22:15:51 +0000801 case 'v':
802 {
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000803 const char *nasm_version_string =
H. Peter Anvine2c80182005-01-15 22:15:51 +0000804 "NASM version " NASM_VER " compiled on " __DATE__
H. Peter Anvineba20a72002-04-30 20:53:55 +0000805#ifdef DEBUG
H. Peter Anvine2c80182005-01-15 22:15:51 +0000806 " with -DDEBUG"
H. Peter Anvineba20a72002-04-30 20:53:55 +0000807#endif
H. Peter Anvine2c80182005-01-15 22:15:51 +0000808 ;
809 puts(nasm_version_string);
810 exit(0); /* never need usage message here */
811 }
812 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800813
H. Peter Anvine2c80182005-01-15 22:15:51 +0000814 case 'e': /* preprocess only */
H. Peter Anvin413fb902007-09-26 15:19:28 -0700815 case 'E':
H. Peter Anvine2c80182005-01-15 22:15:51 +0000816 operating_mode = op_preprocess;
817 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800818
H. Peter Anvine2c80182005-01-15 22:15:51 +0000819 case 'a': /* assemble only - don't preprocess */
820 preproc = &no_pp;
821 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800822
H. Peter Anvinb030c922007-11-13 11:31:15 -0800823 case 'W':
H. Peter Anvin423e3812007-11-15 17:12:29 -0800824 if (param[0] == 'n' && param[1] == 'o' && param[2] == '-') {
H. Peter Anvinb030c922007-11-13 11:31:15 -0800825 suppress = true;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800826 param += 3;
H. Peter Anvinb030c922007-11-13 11:31:15 -0800827 } else {
828 suppress = false;
H. Peter Anvinb030c922007-11-13 11:31:15 -0800829 }
830 goto set_warning;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800831
H. Peter Anvine2c80182005-01-15 22:15:51 +0000832 case 'w':
H. Peter Anvin423e3812007-11-15 17:12:29 -0800833 if (param[0] != '+' && param[0] != '-') {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000834 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
835 "invalid option to `-w'");
H. Peter Anvinb030c922007-11-13 11:31:15 -0800836 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000837 }
H. Peter Anvin423e3812007-11-15 17:12:29 -0800838 suppress = (param[0] == '-');
839 param++;
H. Peter Anvinb030c922007-11-13 11:31:15 -0800840 goto set_warning;
841 set_warning:
842 for (i = 0; i <= ERR_WARN_MAX; i++)
H. Peter Anvin423e3812007-11-15 17:12:29 -0800843 if (!nasm_stricmp(param, suppressed_names[i]))
H. Peter Anvinb030c922007-11-13 11:31:15 -0800844 break;
845 if (i <= ERR_WARN_MAX)
Victor van den Elzen819703a2008-07-16 15:20:56 +0200846 suppressed_global[i] = suppress;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800847 else if (!nasm_stricmp(param, "all"))
H. Peter Anvinb030c922007-11-13 11:31:15 -0800848 for (i = 1; i <= ERR_WARN_MAX; i++)
Victor van den Elzen819703a2008-07-16 15:20:56 +0200849 suppressed_global[i] = suppress;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800850 else if (!nasm_stricmp(param, "none"))
851 for (i = 1; i <= ERR_WARN_MAX; i++)
Victor van den Elzen819703a2008-07-16 15:20:56 +0200852 suppressed_global[i] = !suppress;
H. Peter Anvinb030c922007-11-13 11:31:15 -0800853 else
854 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
H. Peter Anvin423e3812007-11-15 17:12:29 -0800855 "invalid warning `%s'", param);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000856 break;
H. Peter Anvin423e3812007-11-15 17:12:29 -0800857
H. Peter Anvine2c80182005-01-15 22:15:51 +0000858 case 'M':
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700859 switch (p[2]) {
860 case 0:
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700861 operating_mode = op_depend;
862 break;
863 case 'G':
864 operating_mode = op_depend;
865 depend_missing_ok = true;
866 break;
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700867 case 'P':
868 depend_emit_phony = true;
869 break;
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -0700870 case 'D':
871 depend_file = q;
872 advance = true;
873 break;
874 case 'T':
875 depend_target = q;
876 advance = true;
877 break;
878 case 'Q':
879 depend_target = quote_for_make(q);
880 advance = true;
881 break;
882 default:
883 report_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
884 "unknown dependency option `-M%c'", p[2]);
885 break;
886 }
887 if (advance && (!q || !q[0])) {
888 report_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
889 "option `-M%c' requires a parameter", p[2]);
890 break;
891 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000892 break;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000893
H. Peter Anvine2c80182005-01-15 22:15:51 +0000894 case '-':
895 {
896 int s;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000897
H. Peter Anvine2c80182005-01-15 22:15:51 +0000898 if (p[2] == 0) { /* -- => stop processing options */
899 stopoptions = 1;
900 break;
901 }
902 for (s = 0; textopts[s].label; s++) {
903 if (!nasm_stricmp(p + 2, textopts[s].label)) {
904 break;
905 }
906 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000907
H. Peter Anvine2c80182005-01-15 22:15:51 +0000908 switch (s) {
909
910 case OPT_PREFIX:
911 case OPT_POSTFIX:
912 {
913 if (!q) {
914 report_error(ERR_NONFATAL | ERR_NOFILE |
915 ERR_USAGE,
916 "option `--%s' requires an argument",
917 p + 2);
918 break;
919 } else {
920 advance = 1, param = q;
921 }
922
923 if (s == OPT_PREFIX) {
924 strncpy(lprefix, param, PREFIX_MAX - 1);
925 lprefix[PREFIX_MAX - 1] = 0;
926 break;
927 }
928 if (s == OPT_POSTFIX) {
929 strncpy(lpostfix, param, POSTFIX_MAX - 1);
930 lpostfix[POSTFIX_MAX - 1] = 0;
931 break;
932 }
933 break;
934 }
935 default:
936 {
937 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
938 "unrecognised option `--%s'", p + 2);
939 break;
940 }
941 }
942 break;
943 }
944
945 default:
946 if (!ofmt->setinfo(GI_SWITCH, &p))
947 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
948 "unrecognised option `-%c'", p[1]);
949 break;
950 }
951 } else {
952 if (*inname) {
953 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
954 "more than one input file specified");
H. Peter Anvindc242712007-11-18 11:55:10 -0800955 } else {
956 copy_filename(inname, p);
957 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000958 }
959
960 return advance;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000961}
962
H. Peter Anvineba20a72002-04-30 20:53:55 +0000963#define ARG_BUF_DELTA 128
964
H. Peter Anvine2c80182005-01-15 22:15:51 +0000965static void process_respfile(FILE * rfile)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000966{
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000967 char *buffer, *p, *q, *prevarg;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000968 int bufsize, prevargsize;
969
970 bufsize = prevargsize = ARG_BUF_DELTA;
971 buffer = nasm_malloc(ARG_BUF_DELTA);
972 prevarg = nasm_malloc(ARG_BUF_DELTA);
973 prevarg[0] = '\0';
974
H. Peter Anvine2c80182005-01-15 22:15:51 +0000975 while (1) { /* Loop to handle all lines in file */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000976 p = buffer;
977 while (1) { /* Loop to handle long lines */
978 q = fgets(p, bufsize - (p - buffer), rfile);
979 if (!q)
980 break;
981 p += strlen(p);
982 if (p > buffer && p[-1] == '\n')
983 break;
984 if (p - buffer > bufsize - 10) {
985 int offset;
986 offset = p - buffer;
987 bufsize += ARG_BUF_DELTA;
988 buffer = nasm_realloc(buffer, bufsize);
989 p = buffer + offset;
990 }
991 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000992
H. Peter Anvine2c80182005-01-15 22:15:51 +0000993 if (!q && p == buffer) {
994 if (prevarg[0])
995 process_arg(prevarg, NULL);
996 nasm_free(buffer);
997 nasm_free(prevarg);
998 return;
999 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001000
H. Peter Anvine2c80182005-01-15 22:15:51 +00001001 /*
1002 * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
1003 * them are present at the end of the line.
1004 */
1005 *(p = &buffer[strcspn(buffer, "\r\n\032")]) = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +00001006
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001007 while (p > buffer && nasm_isspace(p[-1]))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001008 *--p = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +00001009
H. Peter Anvine2c80182005-01-15 22:15:51 +00001010 p = buffer;
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001011 while (nasm_isspace(*p))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001012 p++;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001013
H. Peter Anvine2c80182005-01-15 22:15:51 +00001014 if (process_arg(prevarg, p))
1015 *p = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +00001016
Charles Crayne192d5b52007-10-18 19:02:42 -07001017 if ((int) strlen(p) > prevargsize - 10) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001018 prevargsize += ARG_BUF_DELTA;
1019 prevarg = nasm_realloc(prevarg, prevargsize);
1020 }
H. Peter Anvindc242712007-11-18 11:55:10 -08001021 strncpy(prevarg, p, prevargsize);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001022 }
1023}
1024
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001025/* Function to process args from a string of args, rather than the
1026 * argv array. Used by the environment variable and response file
1027 * processing.
1028 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001029static void process_args(char *args)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001030{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001031 char *p, *q, *arg, *prevarg;
1032 char separator = ' ';
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001033
1034 p = args;
1035 if (*p && *p != '-')
H. Peter Anvine2c80182005-01-15 22:15:51 +00001036 separator = *p++;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001037 arg = NULL;
1038 while (*p) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001039 q = p;
1040 while (*p && *p != separator)
1041 p++;
1042 while (*p == separator)
1043 *p++ = '\0';
1044 prevarg = arg;
1045 arg = q;
1046 if (process_arg(prevarg, arg))
1047 arg = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001048 }
1049 if (arg)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001050 process_arg(arg, NULL);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001051}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001052
H. Peter Anvinbe2678c2008-01-21 16:23:59 -08001053static void process_response_file(const char *file)
1054{
1055 char str[2048];
1056 FILE *f = fopen(file, "r");
1057 if (!f) {
1058 perror(file);
1059 exit(-1);
1060 }
1061 while (fgets(str, sizeof str, f)) {
1062 process_args(str);
1063 }
1064 fclose(f);
1065}
1066
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001067static void parse_cmdline(int argc, char **argv)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001068{
1069 FILE *rfile;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001070 char *envreal, *envcopy = NULL, *p, *arg;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001071
Charles Craynefcce07f2007-09-30 22:15:36 -07001072 *inname = *outname = *listname = *errname = '\0';
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001073
1074 /*
H. Peter Anvinff7ccc02002-05-06 19:41:57 +00001075 * First, process the NASMENV environment variable.
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001076 */
H. Peter Anvinff7ccc02002-05-06 19:41:57 +00001077 envreal = getenv("NASMENV");
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001078 arg = NULL;
1079 if (envreal) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001080 envcopy = nasm_strdup(envreal);
1081 process_args(envcopy);
1082 nasm_free(envcopy);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001083 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001084
1085 /*
1086 * Now process the actual command line.
1087 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001088 while (--argc) {
H. Peter Anvin423e3812007-11-15 17:12:29 -08001089 bool advance;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001090 argv++;
1091 if (argv[0][0] == '@') {
1092 /* We have a response file, so process this as a set of
1093 * arguments like the environment variable. This allows us
1094 * to have multiple arguments on a single line, which is
1095 * different to the -@resp file processing below for regular
1096 * NASM.
1097 */
H. Peter Anvinbe2678c2008-01-21 16:23:59 -08001098 process_response_file(argv[0]+1);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001099 argc--;
1100 argv++;
1101 }
1102 if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
H. Peter Anvin423e3812007-11-15 17:12:29 -08001103 p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &advance);
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001104 if (p) {
1105 rfile = fopen(p, "r");
1106 if (rfile) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001107 process_respfile(rfile);
1108 fclose(rfile);
1109 } else
1110 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
1111 "unable to open response file `%s'", p);
1112 }
1113 } else
H. Peter Anvin423e3812007-11-15 17:12:29 -08001114 advance = process_arg(argv[0], argc > 1 ? argv[1] : NULL);
1115 argv += advance, argc -= advance;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001116 }
1117
H. Peter Anvin70c0bf22007-11-19 11:45:40 -08001118 /* Look for basic command line typos. This definitely doesn't
1119 catch all errors, but it might help cases of fumbled fingers. */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001120 if (!*inname)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001121 report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
1122 "no input file specified");
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001123 else if (!strcmp(inname, errname) ||
1124 !strcmp(inname, outname) ||
1125 !strcmp(inname, listname) ||
1126 (depend_file && !strcmp(inname, depend_file)))
H. Peter Anvin59ddd262007-10-01 11:26:31 -07001127 report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
1128 "file `%s' is both input and output file",
1129 inname);
H. Peter Anvin59ddd262007-10-01 11:26:31 -07001130
H. Peter Anvin70653092007-10-19 14:42:29 -07001131 if (*errname) {
H. Peter Anvin59ddd262007-10-01 11:26:31 -07001132 error_file = fopen(errname, "w");
1133 if (!error_file) {
1134 error_file = stderr; /* Revert to default! */
1135 report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
1136 "cannot open file `%s' for error messages",
1137 errname);
1138 }
Charles Craynefcce07f2007-09-30 22:15:36 -07001139 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001140}
1141
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001142/* List of directives */
H. Peter Anvin70055962007-10-11 00:05:31 -07001143enum directives {
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001144 D_NONE, D_ABSOLUTE, D_BITS, D_COMMON, D_CPU, D_DEBUG, D_DEFAULT,
H. Peter Anvinf6c9e652007-10-16 14:40:27 -07001145 D_EXTERN, D_FLOAT, D_GLOBAL, D_LIST, D_SECTION, D_SEGMENT, D_WARNING
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001146};
1147static const char *directives[] = {
1148 "", "absolute", "bits", "common", "cpu", "debug", "default",
H. Peter Anvinf6c9e652007-10-16 14:40:27 -07001149 "extern", "float", "global", "list", "section", "segment", "warning"
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001150};
H. Peter Anvin70055962007-10-11 00:05:31 -07001151static enum directives getkw(char **directive, char **value);
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001152
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001153static void assemble_file(char *fname, StrList **depend_ptr)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001154{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001155 char *directive, *value, *p, *q, *special, *line, debugid[80];
H. Peter Anvine2c80182005-01-15 22:15:51 +00001156 insn output_ins;
H. Peter Anvin70055962007-10-11 00:05:31 -07001157 int i, validid;
1158 bool rn_error;
Charles Crayne5fbbc8c2007-11-07 19:03:46 -08001159 int32_t seg;
1160 int64_t offs;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001161 struct tokenval tokval;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001162 expr *e;
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001163 int pass_max;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001164
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001165 if (cmd_sb == 32 && cmd_cpu < IF_386)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001166 report_error(ERR_FATAL, "command line: "
1167 "32-bit segment size requires a higher cpu");
H. Peter Anvineba20a72002-04-30 20:53:55 +00001168
Charles Crayne2581c862008-09-10 19:21:52 -07001169 pass_max = (INT_MAX >> 1) + 2; /* Almost unlimited */
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001170 for (passn = 1; pass0 <= 2; passn++) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001171 int pass1, pass2;
1172 ldfunc def_label;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001173
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001174 pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */
1175 pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */
1176 /* pass0 0, 0, 0, ..., 1, 2 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001177
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001178 def_label = passn > 1 ? redefine_label : define_label;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001179
Keith Kaniosb7a89542007-04-12 02:40:54 +00001180 globalbits = sb = cmd_sb; /* set 'bits' to command line default */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001181 cpu = cmd_cpu;
1182 if (pass0 == 2) {
1183 if (*listname)
1184 nasmlist.init(listname, report_error);
1185 }
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001186 in_abs_seg = false;
1187 global_offset_changed = false; /* set by redefine_label */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001188 location.segment = ofmt->section(NULL, pass2, &sb);
Keith Kaniosb7a89542007-04-12 02:40:54 +00001189 globalbits = sb;
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001190 if (passn > 1) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001191 saa_rewind(forwrefs);
1192 forwref = saa_rstruct(forwrefs);
1193 raa_free(offsets);
1194 offsets = raa_init();
1195 }
H. Peter Anvin07b7b9e2008-05-29 19:09:11 -07001196 preproc->reset(fname, pass1, report_error, evaluate, &nasmlist,
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001197 pass1 == 2 ? depend_ptr : NULL);
Victor van den Elzen819703a2008-07-16 15:20:56 +02001198 memcpy(suppressed, suppressed_global, (ERR_WARN_MAX+1) * sizeof(bool));
1199
H. Peter Anvine2c80182005-01-15 22:15:51 +00001200 globallineno = 0;
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001201 if (passn == 1)
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001202 location.known = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001203 location.offset = offs = GET_CURR_OFFS;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001204
H. Peter Anvine2c80182005-01-15 22:15:51 +00001205 while ((line = preproc->getline())) {
H. Peter Anvin70055962007-10-11 00:05:31 -07001206 enum directives d;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001207 globallineno++;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001208
H. Peter Anvine2c80182005-01-15 22:15:51 +00001209 /* here we parse our directives; this is not handled by the 'real'
1210 * parser. */
1211 directive = line;
H. Peter Anvin70055962007-10-11 00:05:31 -07001212 d = getkw(&directive, &value);
1213 if (d) {
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001214 int err = 0;
1215
H. Peter Anvin70055962007-10-11 00:05:31 -07001216 switch (d) {
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001217 case D_SEGMENT: /* [SEGMENT n] */
1218 case D_SECTION:
H. Peter Anvine2c80182005-01-15 22:15:51 +00001219 seg = ofmt->section(value, pass2, &sb);
1220 if (seg == NO_SEG) {
1221 report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
Keith Kaniosb7a89542007-04-12 02:40:54 +00001222 "segment name `%s' not recognized",
H. Peter Anvine2c80182005-01-15 22:15:51 +00001223 value);
1224 } else {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001225 in_abs_seg = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001226 location.segment = seg;
1227 }
1228 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001229 case D_EXTERN: /* [EXTERN label:special] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001230 if (*value == '$')
1231 value++; /* skip initial $ if present */
1232 if (pass0 == 2) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001233 q = value;
1234 while (*q && *q != ':')
H. Peter Anvine2c80182005-01-15 22:15:51 +00001235 q++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001236 if (*q == ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001237 *q++ = '\0';
1238 ofmt->symdef(value, 0L, 0L, 3, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001239 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001240 } else if (passn == 1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001241 q = value;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001242 validid = true;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001243 if (!isidstart(*q))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001244 validid = false;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001245 while (*q && *q != ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001246 if (!isidchar(*q))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001247 validid = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001248 q++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001249 }
1250 if (!validid) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001251 report_error(ERR_NONFATAL,
1252 "identifier expected after EXTERN");
1253 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001254 }
1255 if (*q == ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001256 *q++ = '\0';
1257 special = q;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001258 } else
H. Peter Anvine2c80182005-01-15 22:15:51 +00001259 special = NULL;
1260 if (!is_extern(value)) { /* allow re-EXTERN to be ignored */
1261 int temp = pass0;
1262 pass0 = 1; /* fake pass 1 in labels.c */
1263 declare_as_global(value, special,
1264 report_error);
1265 define_label(value, seg_alloc(), 0L, NULL,
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001266 false, true, ofmt, report_error);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001267 pass0 = temp;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001268 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001269 } /* else pass0 == 1 */
1270 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001271 case D_BITS: /* [BITS bits] */
Keith Kaniosb7a89542007-04-12 02:40:54 +00001272 globalbits = sb = get_bits(value);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001273 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001274 case D_GLOBAL: /* [GLOBAL symbol:special] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001275 if (*value == '$')
1276 value++; /* skip initial $ if present */
1277 if (pass0 == 2) { /* pass 2 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001278 q = value;
1279 while (*q && *q != ':')
H. Peter Anvine2c80182005-01-15 22:15:51 +00001280 q++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001281 if (*q == ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001282 *q++ = '\0';
1283 ofmt->symdef(value, 0L, 0L, 3, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001284 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001285 } else if (pass2 == 1) { /* pass == 1 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001286 q = value;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001287 validid = true;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001288 if (!isidstart(*q))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001289 validid = false;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001290 while (*q && *q != ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001291 if (!isidchar(*q))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001292 validid = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001293 q++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001294 }
1295 if (!validid) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001296 report_error(ERR_NONFATAL,
1297 "identifier expected after GLOBAL");
1298 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001299 }
1300 if (*q == ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001301 *q++ = '\0';
1302 special = q;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001303 } else
H. Peter Anvine2c80182005-01-15 22:15:51 +00001304 special = NULL;
1305 declare_as_global(value, special, report_error);
1306 } /* pass == 1 */
1307 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001308 case D_COMMON: /* [COMMON symbol size:special] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001309 if (*value == '$')
1310 value++; /* skip initial $ if present */
1311 if (pass0 == 1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001312 p = value;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001313 validid = true;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001314 if (!isidstart(*p))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001315 validid = false;
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001316 while (*p && !nasm_isspace(*p)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001317 if (!isidchar(*p))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001318 validid = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001319 p++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001320 }
1321 if (!validid) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001322 report_error(ERR_NONFATAL,
1323 "identifier expected after COMMON");
1324 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001325 }
1326 if (*p) {
Keith Kaniosb7a89542007-04-12 02:40:54 +00001327 int64_t size;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001328
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001329 while (*p && nasm_isspace(*p))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001330 *p++ = '\0';
1331 q = p;
1332 while (*q && *q != ':')
1333 q++;
1334 if (*q == ':') {
1335 *q++ = '\0';
1336 special = q;
1337 } else
1338 special = NULL;
1339 size = readnum(p, &rn_error);
1340 if (rn_error)
1341 report_error(ERR_NONFATAL,
1342 "invalid size specified"
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001343 " in COMMON declaration");
H. Peter Anvine2c80182005-01-15 22:15:51 +00001344 else
1345 define_common(value, seg_alloc(), size,
1346 special, ofmt, report_error);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001347 } else
H. Peter Anvine2c80182005-01-15 22:15:51 +00001348 report_error(ERR_NONFATAL,
1349 "no size specified in"
1350 " COMMON declaration");
1351 } else if (pass0 == 2) { /* pass == 2 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001352 q = value;
1353 while (*q && *q != ':') {
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001354 if (nasm_isspace(*q))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001355 *q = '\0';
1356 q++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001357 }
1358 if (*q == ':') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001359 *q++ = '\0';
1360 ofmt->symdef(value, 0L, 0L, 3, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001361 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001362 }
1363 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001364 case D_ABSOLUTE: /* [ABSOLUTE address] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001365 stdscan_reset();
1366 stdscan_bufptr = value;
1367 tokval.t_type = TOKEN_INVALID;
1368 e = evaluate(stdscan, NULL, &tokval, NULL, pass2,
1369 report_error, NULL);
1370 if (e) {
1371 if (!is_reloc(e))
1372 report_error(pass0 ==
1373 1 ? ERR_NONFATAL : ERR_PANIC,
1374 "cannot use non-relocatable expression as "
1375 "ABSOLUTE address");
1376 else {
1377 abs_seg = reloc_seg(e);
1378 abs_offset = reloc_value(e);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001379 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001380 } else if (passn == 1)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001381 abs_offset = 0x100; /* don't go near zero in case of / */
1382 else
1383 report_error(ERR_PANIC, "invalid ABSOLUTE address "
1384 "in pass two");
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001385 in_abs_seg = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001386 location.segment = NO_SEG;
1387 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001388 case D_DEBUG: /* [DEBUG] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001389 p = value;
1390 q = debugid;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001391 validid = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001392 if (!isidstart(*p))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001393 validid = false;
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001394 while (*p && !nasm_isspace(*p)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001395 if (!isidchar(*p))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001396 validid = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001397 *q++ = *p++;
1398 }
1399 *q++ = 0;
1400 if (!validid) {
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001401 report_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001402 "identifier expected after DEBUG");
1403 break;
1404 }
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001405 while (*p && nasm_isspace(*p))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001406 p++;
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001407 if (pass0 == 2)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001408 ofmt->current_dfmt->debug_directive(debugid, p);
1409 break;
Victor van den Elzen819703a2008-07-16 15:20:56 +02001410 case D_WARNING: /* [WARNING {+|-|*}warn-name] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001411 if (pass1 == 1) {
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001412 while (*value && nasm_isspace(*value))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001413 value++;
1414
Victor van den Elzen819703a2008-07-16 15:20:56 +02001415 switch(*value) {
1416 case '-': validid = 0; value++; break;
1417 case '+': validid = 1; value++; break;
1418 case '*': validid = 2; value++; break;
1419 default: /*
1420 * Should this error out?
1421 * I'll keep it so nothing breaks.
1422 */
1423 validid = 1; break;
1424 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001425
1426 for (i = 1; i <= ERR_WARN_MAX; i++)
1427 if (!nasm_stricmp(value, suppressed_names[i]))
1428 break;
Victor van den Elzen819703a2008-07-16 15:20:56 +02001429 if (i <= ERR_WARN_MAX) {
1430 switch(validid) {
1431 case 0: suppressed[i] = true; break;
1432 case 1: suppressed[i] = false; break;
1433 case 2: suppressed[i] = suppressed_global[i];
1434 break;
1435 }
1436 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001437 else
1438 report_error(ERR_NONFATAL,
1439 "invalid warning id in WARNING directive");
1440 }
1441 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001442 case D_CPU: /* [CPU] */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001443 cpu = get_cpu(value);
1444 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001445 case D_LIST: /* [LIST {+|-}] */
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001446 while (*value && nasm_isspace(*value))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001447 value++;
1448
1449 if (*value == '+') {
1450 user_nolist = 0;
1451 } else {
1452 if (*value == '-') {
1453 user_nolist = 1;
1454 } else {
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001455 err = 1;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001456 }
1457 }
1458 break;
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001459 case D_DEFAULT: /* [DEFAULT] */
1460 stdscan_reset();
1461 stdscan_bufptr = value;
1462 tokval.t_type = TOKEN_INVALID;
1463 if (stdscan(NULL, &tokval) == TOKEN_SPECIAL) {
1464 switch ((int)tokval.t_integer) {
1465 case S_REL:
1466 globalrel = 1;
1467 break;
1468 case S_ABS:
1469 globalrel = 0;
1470 break;
1471 default:
1472 err = 1;
1473 break;
1474 }
1475 } else {
1476 err = 1;
1477 }
1478 break;
H. Peter Anvinf6c9e652007-10-16 14:40:27 -07001479 case D_FLOAT:
1480 if (float_option(value)) {
1481 report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
1482 "unknown 'float' directive: %s",
1483 value);
1484 }
1485 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001486 default:
1487 if (!ofmt->directive(directive, value, pass2))
1488 report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
1489 "unrecognised directive [%s]",
1490 directive);
1491 }
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001492 if (err) {
1493 report_error(ERR_NONFATAL,
1494 "invalid parameter to [%s] directive",
1495 directive);
1496 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001497 } else { /* it isn't a directive */
1498
1499 parse_line(pass1, line, &output_ins,
1500 report_error, evaluate, def_label);
1501
Charles Crayne2581c862008-09-10 19:21:52 -07001502 if (optimizing > 0) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001503 if (forwref != NULL && globallineno == forwref->lineno) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001504 output_ins.forw_ref = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001505 do {
1506 output_ins.oprs[forwref->operand].opflags |=
1507 OPFLAG_FORWARD;
1508 forwref = saa_rstruct(forwrefs);
1509 } while (forwref != NULL
1510 && forwref->lineno == globallineno);
1511 } else
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001512 output_ins.forw_ref = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001513 }
1514
Charles Crayne2581c862008-09-10 19:21:52 -07001515 if (optimizing > 0) {
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001516 if (passn == 1) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001517 for (i = 0; i < output_ins.operands; i++) {
1518 if (output_ins.oprs[i].
1519 opflags & OPFLAG_FORWARD) {
1520 struct forwrefinfo *fwinf =
1521 (struct forwrefinfo *)
1522 saa_wstruct(forwrefs);
1523 fwinf->lineno = globallineno;
1524 fwinf->operand = i;
1525 }
1526 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001527 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001528 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001529
H. Peter Anvine2c80182005-01-15 22:15:51 +00001530 /* forw_ref */
1531 if (output_ins.opcode == I_EQU) {
1532 if (pass1 == 1) {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001533 /*
H. Peter Anvine2c80182005-01-15 22:15:51 +00001534 * Special `..' EQUs get processed in pass two,
1535 * except `..@' macro-processor EQUs which are done
1536 * in the normal place.
1537 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001538 if (!output_ins.label)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001539 report_error(ERR_NONFATAL,
1540 "EQU not preceded by label");
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001541
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001542 else if (output_ins.label[0] != '.' ||
1543 output_ins.label[1] != '.' ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001544 output_ins.label[2] == '@') {
1545 if (output_ins.operands == 1 &&
1546 (output_ins.oprs[0].type & IMMEDIATE) &&
1547 output_ins.oprs[0].wrt == NO_SEG) {
1548 int isext =
1549 output_ins.oprs[0].
1550 opflags & OPFLAG_EXTERN;
1551 def_label(output_ins.label,
1552 output_ins.oprs[0].segment,
1553 output_ins.oprs[0].offset, NULL,
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001554 false, isext, ofmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001555 report_error);
1556 } else if (output_ins.operands == 2
1557 && (output_ins.oprs[0].
1558 type & IMMEDIATE)
1559 && (output_ins.oprs[0].type & COLON)
1560 && output_ins.oprs[0].segment ==
1561 NO_SEG
1562 && output_ins.oprs[0].wrt == NO_SEG
1563 && (output_ins.oprs[1].
1564 type & IMMEDIATE)
1565 && output_ins.oprs[1].segment ==
1566 NO_SEG
1567 && output_ins.oprs[1].wrt ==
1568 NO_SEG) {
1569 def_label(output_ins.label,
1570 output_ins.oprs[0].
1571 offset | SEG_ABS,
1572 output_ins.oprs[1].offset, NULL,
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001573 false, false, ofmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001574 report_error);
1575 } else
1576 report_error(ERR_NONFATAL,
1577 "bad syntax for EQU");
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001578 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001579 } else {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001580 /*
H. Peter Anvine2c80182005-01-15 22:15:51 +00001581 * Special `..' EQUs get processed here, except
1582 * `..@' macro processor EQUs which are done above.
1583 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001584 if (output_ins.label[0] == '.' &&
H. Peter Anvine2c80182005-01-15 22:15:51 +00001585 output_ins.label[1] == '.' &&
1586 output_ins.label[2] != '@') {
1587 if (output_ins.operands == 1 &&
1588 (output_ins.oprs[0].type & IMMEDIATE)) {
1589 define_label(output_ins.label,
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001590 output_ins.oprs[0].segment,
1591 output_ins.oprs[0].offset,
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001592 NULL, false, false, ofmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001593 report_error);
1594 } else if (output_ins.operands == 2
1595 && (output_ins.oprs[0].
1596 type & IMMEDIATE)
1597 && (output_ins.oprs[0].type & COLON)
1598 && output_ins.oprs[0].segment ==
1599 NO_SEG
1600 && (output_ins.oprs[1].
1601 type & IMMEDIATE)
1602 && output_ins.oprs[1].segment ==
1603 NO_SEG) {
1604 define_label(output_ins.label,
1605 output_ins.oprs[0].
1606 offset | SEG_ABS,
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001607 output_ins.oprs[1].offset,
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001608 NULL, false, false, ofmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001609 report_error);
1610 } else
1611 report_error(ERR_NONFATAL,
1612 "bad syntax for EQU");
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001613 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001614 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001615 } else { /* instruction isn't an EQU */
H. Peter Anvineba20a72002-04-30 20:53:55 +00001616
H. Peter Anvine2c80182005-01-15 22:15:51 +00001617 if (pass1 == 1) {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001618
Charles Crayne5fbbc8c2007-11-07 19:03:46 -08001619 int64_t l = insn_size(location.segment, offs, sb, cpu,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001620 &output_ins, report_error);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001621
H. Peter Anvine2c80182005-01-15 22:15:51 +00001622 /* if (using_debug_info) && output_ins.opcode != -1) */
1623 if (using_debug_info)
1624 { /* fbk 03/25/01 */
1625 /* this is done here so we can do debug type info */
Keith Kaniosb7a89542007-04-12 02:40:54 +00001626 int32_t typeinfo =
H. Peter Anvine2c80182005-01-15 22:15:51 +00001627 TYS_ELEMENTS(output_ins.operands);
1628 switch (output_ins.opcode) {
1629 case I_RESB:
1630 typeinfo =
1631 TYS_ELEMENTS(output_ins.oprs[0].
1632 offset) | TY_BYTE;
1633 break;
1634 case I_RESW:
1635 typeinfo =
1636 TYS_ELEMENTS(output_ins.oprs[0].
1637 offset) | TY_WORD;
1638 break;
1639 case I_RESD:
1640 typeinfo =
1641 TYS_ELEMENTS(output_ins.oprs[0].
1642 offset) | TY_DWORD;
1643 break;
1644 case I_RESQ:
1645 typeinfo =
1646 TYS_ELEMENTS(output_ins.oprs[0].
1647 offset) | TY_QWORD;
1648 break;
1649 case I_REST:
1650 typeinfo =
1651 TYS_ELEMENTS(output_ins.oprs[0].
1652 offset) | TY_TBYTE;
1653 break;
H. Peter Anvindfb91802008-05-20 11:43:53 -07001654 case I_RESO:
1655 typeinfo =
1656 TYS_ELEMENTS(output_ins.oprs[0].
1657 offset) | TY_OWORD;
1658 break;
1659 case I_RESY:
1660 typeinfo =
1661 TYS_ELEMENTS(output_ins.oprs[0].
1662 offset) | TY_YWORD;
1663 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001664 case I_DB:
1665 typeinfo |= TY_BYTE;
1666 break;
1667 case I_DW:
1668 typeinfo |= TY_WORD;
1669 break;
1670 case I_DD:
1671 if (output_ins.eops_float)
1672 typeinfo |= TY_FLOAT;
1673 else
1674 typeinfo |= TY_DWORD;
1675 break;
1676 case I_DQ:
1677 typeinfo |= TY_QWORD;
1678 break;
1679 case I_DT:
1680 typeinfo |= TY_TBYTE;
1681 break;
H. Peter Anvin4408b622007-09-22 21:29:41 -07001682 case I_DO:
1683 typeinfo |= TY_OWORD;
1684 break;
H. Peter Anvindfb91802008-05-20 11:43:53 -07001685 case I_DY:
1686 typeinfo |= TY_YWORD;
1687 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001688 default:
1689 typeinfo = TY_LABEL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001690
H. Peter Anvine2c80182005-01-15 22:15:51 +00001691 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001692
H. Peter Anvine2c80182005-01-15 22:15:51 +00001693 ofmt->current_dfmt->debug_typevalue(typeinfo);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001694
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001695 }
1696 if (l != -1) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001697 offs += l;
1698 SET_CURR_OFFS(offs);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001699 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001700 /*
H. Peter Anvine2c80182005-01-15 22:15:51 +00001701 * else l == -1 => invalid instruction, which will be
1702 * flagged as an error on pass 2
1703 */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001704
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001705 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001706 offs += assemble(location.segment, offs, sb, cpu,
1707 &output_ins, ofmt, report_error,
1708 &nasmlist);
1709 SET_CURR_OFFS(offs);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001710
H. Peter Anvine2c80182005-01-15 22:15:51 +00001711 }
1712 } /* not an EQU */
1713 cleanup_insn(&output_ins);
1714 }
1715 nasm_free(line);
1716 location.offset = offs = GET_CURR_OFFS;
1717 } /* end while (line = preproc->getline... */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001718
H. Peter Anvine2c80182005-01-15 22:15:51 +00001719 if (pass1 == 2 && global_offset_changed)
1720 report_error(ERR_NONFATAL,
1721 "phase error detected at end of assembly.");
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001722
H. Peter Anvine2c80182005-01-15 22:15:51 +00001723 if (pass1 == 1)
1724 preproc->cleanup(1);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001725
H. Peter Anvine2c80182005-01-15 22:15:51 +00001726 if (pass1 == 1 && terminate_after_phase) {
1727 fclose(ofile);
1728 remove(outname);
1729 if (want_usage)
1730 usage();
1731 exit(1);
1732 }
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001733 if (passn >= pass_max - 2 ||
1734 (passn > 1 && !global_offset_changed))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001735 pass0++;
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001736 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001737
H. Peter Anvine2c80182005-01-15 22:15:51 +00001738 preproc->cleanup(0);
1739 nasmlist.cleanup();
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001740#if 1
Charles Crayne2581c862008-09-10 19:21:52 -07001741 if (opt_verbose_info) /* -On and -Ov switches */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001742 fprintf(stdout,
H. Peter Anvin00835fe2008-01-08 23:03:57 -08001743 "info:: assembly required 1+%d+1 passes\n", passn-3);
H. Peter Anvin734b1882002-04-30 21:01:08 +00001744#endif
H. Peter Anvine2c80182005-01-15 22:15:51 +00001745} /* exit from assemble_file (...) */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001746
H. Peter Anvin70055962007-10-11 00:05:31 -07001747static enum directives getkw(char **directive, char **value)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001748{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001749 char *p, *q, *buf;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001750
Michael K. Ter Louw1d392362003-08-15 22:25:53 +00001751 buf = *directive;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001752
H. Peter Anvincaa82a12002-04-30 21:03:11 +00001753 /* allow leading spaces or tabs */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001754 while (*buf == ' ' || *buf == '\t')
1755 buf++;
H. Peter Anvincaa82a12002-04-30 21:03:11 +00001756
H. Peter Anvine2c80182005-01-15 22:15:51 +00001757 if (*buf != '[')
1758 return 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001759
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001760 p = buf;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001761
H. Peter Anvine2c80182005-01-15 22:15:51 +00001762 while (*p && *p != ']')
1763 p++;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001764
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001765 if (!*p)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001766 return 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001767
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001768 q = p++;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001769
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001770 while (*p && *p != ';') {
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001771 if (!nasm_isspace(*p))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001772 return 0;
1773 p++;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001774 }
1775 q[1] = '\0';
1776
H. Peter Anvine2c80182005-01-15 22:15:51 +00001777 *directive = p = buf + 1;
1778 while (*buf && *buf != ' ' && *buf != ']' && *buf != '\t')
1779 buf++;
1780 if (*buf == ']') {
1781 *buf = '\0';
1782 *value = buf;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001783 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001784 *buf++ = '\0';
H. Peter Anvinbda7a6e2008-06-21 10:23:17 -07001785 while (nasm_isspace(*buf))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001786 buf++; /* beppu - skip leading whitespace */
1787 *value = buf;
1788 while (*buf != ']')
1789 buf++;
1790 *buf++ = '\0';
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001791 }
H. Peter Anvin62b24d72007-08-29 16:38:05 +00001792
1793 return bsii(*directive, directives, elements(directives));
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001794}
1795
Ed Berosetfa771012002-06-09 20:56:40 +00001796/**
1797 * gnu style error reporting
1798 * This function prints an error message to error_file in the
1799 * style used by GNU. An example would be:
1800 * file.asm:50: error: blah blah blah
H. Peter Anvin70653092007-10-19 14:42:29 -07001801 * where file.asm is the name of the file, 50 is the line number on
Ed Berosetfa771012002-06-09 20:56:40 +00001802 * which the error occurs (or is detected) and "error:" is one of
1803 * the possible optional diagnostics -- it can be "error" or "warning"
H. Peter Anvin70653092007-10-19 14:42:29 -07001804 * or something else. Finally the line terminates with the actual
Ed Berosetfa771012002-06-09 20:56:40 +00001805 * error message.
H. Peter Anvin70653092007-10-19 14:42:29 -07001806 *
1807 * @param severity the severity of the warning or error
Ed Berosetfa771012002-06-09 20:56:40 +00001808 * @param fmt the printf style format string
1809 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001810static void report_error_gnu(int severity, const char *fmt, ...)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001811{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001812 va_list ap;
1813
Ed Berosetfa771012002-06-09 20:56:40 +00001814 if (is_suppressed_warning(severity))
H. Peter Anvine2c80182005-01-15 22:15:51 +00001815 return;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001816
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001817 if (severity & ERR_NOFILE)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001818 fputs("nasm: ", error_file);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001819 else {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001820 char *currentfile = NULL;
Keith Kaniosb7a89542007-04-12 02:40:54 +00001821 int32_t lineno = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001822 src_get(&lineno, &currentfile);
Keith Kanios93f2e9a2007-04-14 00:10:59 +00001823 fprintf(error_file, "%s:%"PRId32": ", currentfile, lineno);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001824 nasm_free(currentfile);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001825 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001826 va_start(ap, fmt);
1827 report_error_common(severity, fmt, ap);
1828 va_end(ap);
Ed Berosetfa771012002-06-09 20:56:40 +00001829}
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001830
Ed Berosetfa771012002-06-09 20:56:40 +00001831/**
1832 * MS style error reporting
1833 * This function prints an error message to error_file in the
H. Peter Anvin70653092007-10-19 14:42:29 -07001834 * style used by Visual C and some other Microsoft tools. An example
Ed Berosetfa771012002-06-09 20:56:40 +00001835 * would be:
Ed Beroset6e61d0d2002-06-11 03:29:36 +00001836 * file.asm(50) : error: blah blah blah
H. Peter Anvin70653092007-10-19 14:42:29 -07001837 * where file.asm is the name of the file, 50 is the line number on
Ed Beroset6e61d0d2002-06-11 03:29:36 +00001838 * which the error occurs (or is detected) and "error:" is one of
1839 * the possible optional diagnostics -- it can be "error" or "warning"
H. Peter Anvin70653092007-10-19 14:42:29 -07001840 * or something else. Finally the line terminates with the actual
Ed Beroset6e61d0d2002-06-11 03:29:36 +00001841 * error message.
H. Peter Anvin70653092007-10-19 14:42:29 -07001842 *
1843 * @param severity the severity of the warning or error
Ed Berosetfa771012002-06-09 20:56:40 +00001844 * @param fmt the printf style format string
1845 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001846static void report_error_vc(int severity, const char *fmt, ...)
Ed Berosetfa771012002-06-09 20:56:40 +00001847{
1848 va_list ap;
1849
H. Peter Anvine2c80182005-01-15 22:15:51 +00001850 if (is_suppressed_warning(severity))
1851 return;
Ed Berosetfa771012002-06-09 20:56:40 +00001852
1853 if (severity & ERR_NOFILE)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001854 fputs("nasm: ", error_file);
Ed Berosetfa771012002-06-09 20:56:40 +00001855 else {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001856 char *currentfile = NULL;
Keith Kaniosb7a89542007-04-12 02:40:54 +00001857 int32_t lineno = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001858 src_get(&lineno, &currentfile);
Keith Kanios93f2e9a2007-04-14 00:10:59 +00001859 fprintf(error_file, "%s(%"PRId32") : ", currentfile, lineno);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001860 nasm_free(currentfile);
Ed Berosetfa771012002-06-09 20:56:40 +00001861 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001862 va_start(ap, fmt);
1863 report_error_common(severity, fmt, ap);
1864 va_end(ap);
Ed Berosetfa771012002-06-09 20:56:40 +00001865}
1866
1867/**
1868 * check for supressed warning
H. Peter Anvin70653092007-10-19 14:42:29 -07001869 * checks for suppressed warning or pass one only warning and we're
Ed Berosetfa771012002-06-09 20:56:40 +00001870 * not in pass 1
1871 *
1872 * @param severity the severity of the warning or error
1873 * @return true if we should abort error/warning printing
1874 */
H. Peter Anvin2b046cf2008-01-22 14:08:36 -08001875static bool is_suppressed_warning(int severity)
Ed Berosetfa771012002-06-09 20:56:40 +00001876{
1877 /*
1878 * See if it's a suppressed warning.
1879 */
H. Peter Anvin2b046cf2008-01-22 14:08:36 -08001880 return (severity & ERR_MASK) == ERR_WARNING &&
1881 (((severity & ERR_WARN_MASK) != 0 &&
1882 suppressed[(severity & ERR_WARN_MASK) >> ERR_WARN_SHR]) ||
1883 /* See if it's a pass-one only warning and we're not in pass one. */
1884 ((severity & ERR_PASS1) && pass0 != 1));
Ed Berosetfa771012002-06-09 20:56:40 +00001885}
1886
1887/**
1888 * common error reporting
1889 * This is the common back end of the error reporting schemes currently
H. Peter Anvin70653092007-10-19 14:42:29 -07001890 * implemented. It prints the nature of the warning and then the
Ed Berosetfa771012002-06-09 20:56:40 +00001891 * specific error message to error_file and may or may not return. It
1892 * doesn't return if the error severity is a "panic" or "debug" type.
H. Peter Anvin70653092007-10-19 14:42:29 -07001893 *
1894 * @param severity the severity of the warning or error
Ed Berosetfa771012002-06-09 20:56:40 +00001895 * @param fmt the printf style format string
1896 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001897static void report_error_common(int severity, const char *fmt,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001898 va_list args)
Ed Berosetfa771012002-06-09 20:56:40 +00001899{
H. Peter Anvin7df04172008-06-10 18:27:38 -07001900 switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001901 case ERR_WARNING:
1902 fputs("warning: ", error_file);
1903 break;
1904 case ERR_NONFATAL:
1905 fputs("error: ", error_file);
1906 break;
1907 case ERR_FATAL:
1908 fputs("fatal: ", error_file);
1909 break;
1910 case ERR_PANIC:
1911 fputs("panic: ", error_file);
1912 break;
1913 case ERR_DEBUG:
1914 fputs("debug: ", error_file);
1915 break;
H. Peter Anvin7df04172008-06-10 18:27:38 -07001916 default:
1917 break;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001918 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001919
H. Peter Anvine2c80182005-01-15 22:15:51 +00001920 vfprintf(error_file, fmt, args);
H. Peter Anvind1fb15c2007-11-13 09:37:59 -08001921 putc('\n', error_file);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001922
1923 if (severity & ERR_USAGE)
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001924 want_usage = true;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001925
1926 switch (severity & ERR_MASK) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001927 case ERR_DEBUG:
1928 /* no further action, by definition */
1929 break;
H. Peter Anvinb030c922007-11-13 11:31:15 -08001930 case ERR_WARNING:
1931 if (!suppressed[0]) /* Treat warnings as errors */
1932 terminate_after_phase = true;
1933 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001934 case ERR_NONFATAL:
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001935 terminate_after_phase = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001936 break;
1937 case ERR_FATAL:
1938 if (ofile) {
1939 fclose(ofile);
1940 remove(outname);
1941 }
1942 if (want_usage)
1943 usage();
1944 exit(1); /* instantly die */
1945 break; /* placate silly compilers */
1946 case ERR_PANIC:
1947 fflush(NULL);
1948 /* abort(); *//* halt, catch fire, and dump core */
1949 exit(3);
1950 break;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001951 }
1952}
1953
H. Peter Anvin734b1882002-04-30 21:01:08 +00001954static void usage(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001955{
H. Peter Anvin620515a2002-04-30 20:57:38 +00001956 fputs("type `nasm -h' for help\n", error_file);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001957}
1958
H. Peter Anvin734b1882002-04-30 21:01:08 +00001959static void register_output_formats(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001960{
H. Peter Anvine2c80182005-01-15 22:15:51 +00001961 ofmt = ofmt_register(report_error);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001962}
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001963
1964#define BUF_DELTA 512
1965
1966static FILE *no_pp_fp;
1967static efunc no_pp_err;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001968static ListGen *no_pp_list;
Keith Kaniosb7a89542007-04-12 02:40:54 +00001969static int32_t no_pp_lineinc;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001970
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001971static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval,
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001972 ListGen * listgen, StrList **deplist)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001973{
1974 src_set_fname(nasm_strdup(file));
1975 src_set_linnum(0);
1976 no_pp_lineinc = 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001977 no_pp_err = error;
1978 no_pp_fp = fopen(file, "r");
1979 if (!no_pp_fp)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001980 no_pp_err(ERR_FATAL | ERR_NOFILE,
1981 "unable to open input file `%s'", file);
H. Peter Anvin76690a12002-04-30 20:52:49 +00001982 no_pp_list = listgen;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001983 (void)pass; /* placate compilers */
1984 (void)eval; /* placate compilers */
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001985
1986 if (deplist) {
1987 StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
1988 sl->next = NULL;
1989 strcpy(sl->str, file);
1990 *deplist = sl;
1991 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001992}
1993
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001994static char *no_pp_getline(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001995{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001996 char *buffer, *p, *q;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001997 int bufsize;
1998
1999 bufsize = BUF_DELTA;
2000 buffer = nasm_malloc(BUF_DELTA);
H. Peter Anvineba20a72002-04-30 20:53:55 +00002001 src_set_linnum(src_get_linnum() + no_pp_lineinc);
2002
H. Peter Anvine2c80182005-01-15 22:15:51 +00002003 while (1) { /* Loop to handle %line */
H. Peter Anvineba20a72002-04-30 20:53:55 +00002004
H. Peter Anvine2c80182005-01-15 22:15:51 +00002005 p = buffer;
2006 while (1) { /* Loop to handle long lines */
2007 q = fgets(p, bufsize - (p - buffer), no_pp_fp);
2008 if (!q)
2009 break;
2010 p += strlen(p);
2011 if (p > buffer && p[-1] == '\n')
2012 break;
2013 if (p - buffer > bufsize - 10) {
2014 int offset;
2015 offset = p - buffer;
2016 bufsize += BUF_DELTA;
2017 buffer = nasm_realloc(buffer, bufsize);
2018 p = buffer + offset;
2019 }
2020 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00002021
H. Peter Anvine2c80182005-01-15 22:15:51 +00002022 if (!q && p == buffer) {
2023 nasm_free(buffer);
2024 return NULL;
2025 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00002026
H. Peter Anvine2c80182005-01-15 22:15:51 +00002027 /*
2028 * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
2029 * them are present at the end of the line.
2030 */
2031 buffer[strcspn(buffer, "\r\n\032")] = '\0';
H. Peter Anvineba20a72002-04-30 20:53:55 +00002032
H. Peter Anvin0a98f602007-10-03 21:22:16 -07002033 if (!nasm_strnicmp(buffer, "%line", 5)) {
Keith Kaniosb7a89542007-04-12 02:40:54 +00002034 int32_t ln;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002035 int li;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00002036 char *nm = nasm_malloc(strlen(buffer));
Keith Kanios93f2e9a2007-04-14 00:10:59 +00002037 if (sscanf(buffer + 5, "%"PRId32"+%d %s", &ln, &li, nm) == 3) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002038 nasm_free(src_set_fname(nm));
2039 src_set_linnum(ln);
2040 no_pp_lineinc = li;
2041 continue;
2042 }
2043 nasm_free(nm);
2044 }
2045 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002046 }
2047
H. Peter Anvine2c80182005-01-15 22:15:51 +00002048 no_pp_list->line(LIST_READ, buffer);
H. Peter Anvin76690a12002-04-30 20:52:49 +00002049
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002050 return buffer;
2051}
2052
H. Peter Anvine2c80182005-01-15 22:15:51 +00002053static void no_pp_cleanup(int pass)
H. Peter Anvineba20a72002-04-30 20:53:55 +00002054{
Keith Kaniosc7ae18d2007-04-14 00:46:25 +00002055 (void)pass; /* placate GCC */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002056 fclose(no_pp_fp);
2057}
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002058
Keith Kaniosa6dfa782007-04-13 16:47:53 +00002059static uint32_t get_cpu(char *value)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002060{
H. Peter Anvine2c80182005-01-15 22:15:51 +00002061 if (!strcmp(value, "8086"))
2062 return IF_8086;
2063 if (!strcmp(value, "186"))
2064 return IF_186;
2065 if (!strcmp(value, "286"))
2066 return IF_286;
2067 if (!strcmp(value, "386"))
2068 return IF_386;
2069 if (!strcmp(value, "486"))
2070 return IF_486;
2071 if (!strcmp(value, "586") || !nasm_stricmp(value, "pentium"))
2072 return IF_PENT;
2073 if (!strcmp(value, "686") ||
2074 !nasm_stricmp(value, "ppro") ||
2075 !nasm_stricmp(value, "pentiumpro") || !nasm_stricmp(value, "p2"))
2076 return IF_P6;
2077 if (!nasm_stricmp(value, "p3") || !nasm_stricmp(value, "katmai"))
2078 return IF_KATMAI;
2079 if (!nasm_stricmp(value, "p4") || /* is this right? -- jrc */
2080 !nasm_stricmp(value, "willamette"))
2081 return IF_WILLAMETTE;
2082 if (!nasm_stricmp(value, "prescott"))
2083 return IF_PRESCOTT;
Keith Kaniosb7a89542007-04-12 02:40:54 +00002084 if (!nasm_stricmp(value, "x64") ||
2085 !nasm_stricmp(value, "x86-64"))
H. Peter Anvin0db11e22007-04-17 20:23:11 +00002086 return IF_X86_64;
H. Peter Anvin3ab8de62002-05-28 01:25:06 +00002087 if (!nasm_stricmp(value, "ia64") ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00002088 !nasm_stricmp(value, "ia-64") ||
2089 !nasm_stricmp(value, "itanium") ||
2090 !nasm_stricmp(value, "itanic") || !nasm_stricmp(value, "merced"))
2091 return IF_IA64;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002092
H. Peter Anvine2c80182005-01-15 22:15:51 +00002093 report_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL,
2094 "unknown 'cpu' type");
H. Peter Anvin734b1882002-04-30 21:01:08 +00002095
H. Peter Anvine2c80182005-01-15 22:15:51 +00002096 return IF_PLEVEL; /* the maximum level */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002097}
2098
Keith Kaniosa6dfa782007-04-13 16:47:53 +00002099static int get_bits(char *value)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002100{
2101 int i;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002102
H. Peter Anvine2c80182005-01-15 22:15:51 +00002103 if ((i = atoi(value)) == 16)
2104 return i; /* set for a 16-bit segment */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002105 else if (i == 32) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002106 if (cpu < IF_386) {
2107 report_error(ERR_NONFATAL,
2108 "cannot specify 32-bit segment on processor below a 386");
2109 i = 16;
2110 }
Keith Kaniosb7a89542007-04-12 02:40:54 +00002111 } else if (i == 64) {
H. Peter Anvin0db11e22007-04-17 20:23:11 +00002112 if (cpu < IF_X86_64) {
Keith Kaniosb7a89542007-04-12 02:40:54 +00002113 report_error(ERR_NONFATAL,
2114 "cannot specify 64-bit segment on processor below an x86-64");
2115 i = 16;
2116 }
2117 if (i != maxbits) {
2118 report_error(ERR_NONFATAL,
2119 "%s output format does not support 64-bit code",
2120 ofmt->shortname);
2121 i = 16;
2122 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002123 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002124 report_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL,
Keith Kaniosb7a89542007-04-12 02:40:54 +00002125 "`%s' is not a valid segment size; must be 16, 32 or 64",
H. Peter Anvine2c80182005-01-15 22:15:51 +00002126 value);
2127 i = 16;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00002128 }
2129 return i;
2130}
2131
2132/* end of nasm.c */