nasm.c 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2018 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. /*
  34. * The Netwide Assembler main program module
  35. */
  36. #include "compiler.h"
  37. #include <stdio.h>
  38. #include <stdarg.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <ctype.h>
  42. #include <limits.h>
  43. #include "nasm.h"
  44. #include "nasmlib.h"
  45. #include "error.h"
  46. #include "saa.h"
  47. #include "raa.h"
  48. #include "float.h"
  49. #include "stdscan.h"
  50. #include "insns.h"
  51. #include "preproc.h"
  52. #include "parser.h"
  53. #include "eval.h"
  54. #include "assemble.h"
  55. #include "labels.h"
  56. #include "outform.h"
  57. #include "listing.h"
  58. #include "iflag.h"
  59. #include "ver.h"
  60. /*
  61. * This is the maximum number of optimization passes to do. If we ever
  62. * find a case where the optimizer doesn't naturally converge, we might
  63. * have to drop this value so the assembler doesn't appear to just hang.
  64. */
  65. #define MAX_OPTIMIZE (INT_MAX >> 1)
  66. struct forwrefinfo { /* info held on forward refs. */
  67. int lineno;
  68. int operand;
  69. };
  70. static void parse_cmdline(int, char **, int);
  71. static void assemble_file(const char *, StrList **);
  72. static bool skip_this_pass(int severity);
  73. static void nasm_verror_asm(int severity, const char *fmt, va_list args);
  74. static void usage(void);
  75. static void help(char xopt);
  76. struct error_format {
  77. const char *beforeline; /* Before line number, if present */
  78. const char *afterline; /* After line number, if present */
  79. const char *beforemsg; /* Before actual message */
  80. };
  81. static const struct error_format errfmt_gnu = { ":", "", ": " };
  82. static const struct error_format errfmt_msvc = { "(", ")", " : " };
  83. static const struct error_format *errfmt = &errfmt_gnu;
  84. static bool using_debug_info, opt_verbose_info;
  85. static const char *debug_format;
  86. #ifndef ABORT_ON_PANIC
  87. # define ABORT_ON_PANIC 0
  88. #endif
  89. static bool abort_on_panic = ABORT_ON_PANIC;
  90. static bool keep_all;
  91. bool tasm_compatible_mode = false;
  92. int pass0;
  93. int64_t passn;
  94. static int pass1, pass2; /* XXX: Get rid of these, they are redundant */
  95. int globalrel = 0;
  96. int globalbnd = 0;
  97. struct compile_time official_compile_time;
  98. const char *inname;
  99. const char *outname;
  100. static const char *listname;
  101. static const char *errname;
  102. static int64_t globallineno; /* for forward-reference tracking */
  103. /* static int pass = 0; */
  104. const struct ofmt *ofmt = &OF_DEFAULT;
  105. const struct ofmt_alias *ofmt_alias = NULL;
  106. const struct dfmt *dfmt;
  107. FILE *error_file; /* Where to write error messages */
  108. FILE *ofile = NULL;
  109. struct optimization optimizing =
  110. { MAX_OPTIMIZE, OPTIM_ALL_ENABLED }; /* number of optimization passes to take */
  111. static int cmd_sb = 16; /* by default */
  112. iflag_t cpu;
  113. static iflag_t cmd_cpu;
  114. struct location location;
  115. bool in_absolute; /* Flag we are in ABSOLUTE seg */
  116. struct location absolute; /* Segment/offset inside ABSOLUTE */
  117. static struct RAA *offsets;
  118. static struct SAA *forwrefs; /* keep track of forward references */
  119. static const struct forwrefinfo *forwref;
  120. static const struct preproc_ops *preproc;
  121. static StrList *include_path;
  122. bool pp_noline; /* Ignore %line directives */
  123. #define OP_NORMAL (1U << 0)
  124. #define OP_PREPROCESS (1U << 1)
  125. #define OP_DEPEND (1U << 2)
  126. static unsigned int operating_mode;
  127. /* Dependency flags */
  128. static bool depend_emit_phony = false;
  129. static bool depend_missing_ok = false;
  130. static const char *depend_target = NULL;
  131. static const char *depend_file = NULL;
  132. StrList *depend_list;
  133. static bool want_usage;
  134. static bool terminate_after_phase;
  135. bool user_nolist = false;
  136. static char *quote_for_pmake(const char *str);
  137. static char *quote_for_wmake(const char *str);
  138. static char *(*quote_for_make)(const char *) = quote_for_pmake;
  139. /*
  140. * Execution limits that can be set via a command-line option or %pragma
  141. */
  142. #define LIMIT_MAX_VAL (INT64_MAX >> 1) /* Effectively unlimited */
  143. int64_t nasm_limit[LIMIT_MAX+1] =
  144. { LIMIT_MAX_VAL, 1000, 1000000, 1000000, 1000000, 2000000000 };
  145. struct limit_info {
  146. const char *name;
  147. const char *help;
  148. };
  149. static const struct limit_info limit_info[LIMIT_MAX+1] = {
  150. { "passes", "total number of passes" },
  151. { "stalled-passes", "number of passes without forward progress" },
  152. { "macro-levels", "levels of macro expansion"},
  153. { "rep", "%rep count" },
  154. { "eval", "expression evaluation descent"},
  155. { "lines", "total source lines processed"}
  156. };
  157. enum directive_result
  158. nasm_set_limit(const char *limit, const char *valstr)
  159. {
  160. int i;
  161. int64_t val;
  162. bool rn_error;
  163. int errlevel;
  164. for (i = 0; i <= LIMIT_MAX; i++) {
  165. if (!nasm_stricmp(limit, limit_info[i].name))
  166. break;
  167. }
  168. if (i > LIMIT_MAX) {
  169. if (passn == 0)
  170. errlevel = ERR_WARNING|ERR_NOFILE|ERR_USAGE;
  171. else
  172. errlevel = ERR_WARNING|ERR_PASS1|WARN_UNKNOWN_PRAGMA;
  173. nasm_error(errlevel, "unknown limit: `%s'", limit);
  174. return DIRR_ERROR;
  175. }
  176. if (!nasm_stricmp(valstr, "unlimited")) {
  177. val = LIMIT_MAX_VAL;
  178. } else {
  179. val = readnum(valstr, &rn_error);
  180. if (rn_error || val < 0) {
  181. if (passn == 0)
  182. errlevel = ERR_WARNING|ERR_NOFILE|ERR_USAGE;
  183. else
  184. errlevel = ERR_WARNING|ERR_PASS1|WARN_BAD_PRAGMA;
  185. nasm_error(errlevel, "invalid limit value: `%s'", limit);
  186. return DIRR_ERROR;
  187. }
  188. if (val > LIMIT_MAX_VAL)
  189. val = LIMIT_MAX_VAL;
  190. }
  191. nasm_limit[i] = val;
  192. return DIRR_OK;
  193. }
  194. int64_t switch_segment(int32_t segment)
  195. {
  196. location.segment = segment;
  197. if (segment == NO_SEG) {
  198. location.offset = absolute.offset;
  199. in_absolute = true;
  200. } else {
  201. location.offset = raa_read(offsets, segment);
  202. in_absolute = false;
  203. }
  204. return location.offset;
  205. }
  206. static void set_curr_offs(int64_t l_off)
  207. {
  208. if (in_absolute)
  209. absolute.offset = l_off;
  210. else
  211. offsets = raa_write(offsets, location.segment, l_off);
  212. }
  213. static void increment_offset(int64_t delta)
  214. {
  215. if (unlikely(delta == 0))
  216. return;
  217. location.offset += delta;
  218. set_curr_offs(location.offset);
  219. }
  220. static void nasm_fputs(const char *line, FILE * outfile)
  221. {
  222. if (outfile) {
  223. fputs(line, outfile);
  224. putc('\n', outfile);
  225. } else
  226. puts(line);
  227. }
  228. /*
  229. * Define system-defined macros that are not part of
  230. * macros/standard.mac.
  231. */
  232. static void define_macros(void)
  233. {
  234. const struct compile_time * const oct = &official_compile_time;
  235. char temp[128];
  236. if (oct->have_local) {
  237. strftime(temp, sizeof temp, "__DATE__=\"%Y-%m-%d\"", &oct->local);
  238. preproc->pre_define(temp);
  239. strftime(temp, sizeof temp, "__DATE_NUM__=%Y%m%d", &oct->local);
  240. preproc->pre_define(temp);
  241. strftime(temp, sizeof temp, "__TIME__=\"%H:%M:%S\"", &oct->local);
  242. preproc->pre_define(temp);
  243. strftime(temp, sizeof temp, "__TIME_NUM__=%H%M%S", &oct->local);
  244. preproc->pre_define(temp);
  245. }
  246. if (oct->have_gm) {
  247. strftime(temp, sizeof temp, "__UTC_DATE__=\"%Y-%m-%d\"", &oct->gm);
  248. preproc->pre_define(temp);
  249. strftime(temp, sizeof temp, "__UTC_DATE_NUM__=%Y%m%d", &oct->gm);
  250. preproc->pre_define(temp);
  251. strftime(temp, sizeof temp, "__UTC_TIME__=\"%H:%M:%S\"", &oct->gm);
  252. preproc->pre_define(temp);
  253. strftime(temp, sizeof temp, "__UTC_TIME_NUM__=%H%M%S", &oct->gm);
  254. preproc->pre_define(temp);
  255. }
  256. if (oct->have_posix) {
  257. snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, oct->posix);
  258. preproc->pre_define(temp);
  259. }
  260. /*
  261. * In case if output format is defined by alias
  262. * we have to put shortname of the alias itself here
  263. * otherwise ABI backward compatibility gets broken.
  264. */
  265. snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s",
  266. ofmt_alias ? ofmt_alias->shortname : ofmt->shortname);
  267. preproc->pre_define(temp);
  268. /*
  269. * Output-format specific macros.
  270. */
  271. if (ofmt->stdmac)
  272. preproc->extra_stdmac(ofmt->stdmac);
  273. /*
  274. * Debug format, if any
  275. */
  276. if (dfmt != &null_debug_form) {
  277. snprintf(temp, sizeof(temp), "__DEBUG_FORMAT__=%s", dfmt->shortname);
  278. preproc->pre_define(temp);
  279. }
  280. }
  281. /*
  282. * Initialize the preprocessor, set up the include path, and define
  283. * the system-included macros. This is called between passes 1 and 2
  284. * of parsing the command options; ofmt and dfmt are defined at this
  285. * point.
  286. *
  287. * Command-line specified preprocessor directives (-p, -d, -u,
  288. * --pragma, --before) are processed after this function.
  289. */
  290. static void preproc_init(void)
  291. {
  292. StrList *ip, *iptmp;
  293. preproc->init();
  294. define_macros();
  295. list_for_each_safe(ip, iptmp, include_path) {
  296. preproc->include_path(ip->str);
  297. nasm_free(ip);
  298. }
  299. }
  300. static void emit_dependencies(StrList *list)
  301. {
  302. FILE *deps;
  303. int linepos, len;
  304. StrList *l, *nl;
  305. bool wmake = (quote_for_make == quote_for_wmake);
  306. const char *wrapstr, *nulltarget;
  307. wrapstr = wmake ? " &\n " : " \\\n ";
  308. nulltarget = wmake ? "\t%null\n" : "";
  309. if (depend_file && strcmp(depend_file, "-")) {
  310. deps = nasm_open_write(depend_file, NF_TEXT);
  311. if (!deps) {
  312. nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
  313. "unable to write dependency file `%s'", depend_file);
  314. return;
  315. }
  316. } else {
  317. deps = stdout;
  318. }
  319. linepos = fprintf(deps, "%s :", depend_target);
  320. list_for_each(l, list) {
  321. char *file = quote_for_make(l->str);
  322. len = strlen(file);
  323. if (linepos + len > 62 && linepos > 1) {
  324. fputs(wrapstr, deps);
  325. linepos = 1;
  326. }
  327. fprintf(deps, " %s", file);
  328. linepos += len+1;
  329. nasm_free(file);
  330. }
  331. fprintf(deps, "\n\n");
  332. list_for_each_safe(l, nl, list) {
  333. if (depend_emit_phony) {
  334. char *file = quote_for_make(l->str);
  335. fprintf(deps, "%s :\n%s\n", file, nulltarget);
  336. nasm_free(file);
  337. }
  338. nasm_free(l);
  339. }
  340. if (deps != stdout)
  341. fclose(deps);
  342. }
  343. /* Convert a struct tm to a POSIX-style time constant */
  344. static int64_t make_posix_time(const struct tm *tm)
  345. {
  346. int64_t t;
  347. int64_t y = tm->tm_year;
  348. /* See IEEE 1003.1:2004, section 4.14 */
  349. t = (y-70)*365 + (y-69)/4 - (y-1)/100 + (y+299)/400;
  350. t += tm->tm_yday;
  351. t *= 24;
  352. t += tm->tm_hour;
  353. t *= 60;
  354. t += tm->tm_min;
  355. t *= 60;
  356. t += tm->tm_sec;
  357. return t;
  358. }
  359. static void timestamp(void)
  360. {
  361. struct compile_time * const oct = &official_compile_time;
  362. const struct tm *tp, *best_gm;
  363. time(&oct->t);
  364. best_gm = NULL;
  365. tp = localtime(&oct->t);
  366. if (tp) {
  367. oct->local = *tp;
  368. best_gm = &oct->local;
  369. oct->have_local = true;
  370. }
  371. tp = gmtime(&oct->t);
  372. if (tp) {
  373. oct->gm = *tp;
  374. best_gm = &oct->gm;
  375. oct->have_gm = true;
  376. if (!oct->have_local)
  377. oct->local = oct->gm;
  378. } else {
  379. oct->gm = oct->local;
  380. }
  381. if (best_gm) {
  382. oct->posix = make_posix_time(best_gm);
  383. oct->have_posix = true;
  384. }
  385. }
  386. int main(int argc, char **argv)
  387. {
  388. StrList **depend_ptr;
  389. timestamp();
  390. error_file = stderr;
  391. iflag_set_default_cpu(&cpu);
  392. iflag_set_default_cpu(&cmd_cpu);
  393. pass0 = 0;
  394. want_usage = terminate_after_phase = false;
  395. nasm_set_verror(nasm_verror_asm);
  396. tolower_init();
  397. src_init();
  398. /*
  399. * We must call init_labels() before the command line parsing,
  400. * because we may be setting prefixes/suffixes from the command
  401. * line.
  402. */
  403. init_labels();
  404. offsets = raa_init();
  405. forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo));
  406. preproc = &nasmpp;
  407. operating_mode = OP_NORMAL;
  408. parse_cmdline(argc, argv, 1);
  409. if (terminate_after_phase) {
  410. if (want_usage)
  411. usage();
  412. return 1;
  413. }
  414. /* At this point we have ofmt and the name of the desired debug format */
  415. if (!using_debug_info) {
  416. /* No debug info, redirect to the null backend (empty stubs) */
  417. dfmt = &null_debug_form;
  418. } else if (!debug_format) {
  419. /* Default debug format for this backend */
  420. dfmt = ofmt->default_dfmt;
  421. } else {
  422. dfmt = dfmt_find(ofmt, debug_format);
  423. if (!dfmt) {
  424. nasm_fatal(ERR_USAGE,
  425. "unrecognized debug format `%s' for"
  426. " output format `%s'",
  427. debug_format, ofmt->shortname);
  428. }
  429. }
  430. preproc_init();
  431. parse_cmdline(argc, argv, 2);
  432. if (terminate_after_phase) {
  433. if (want_usage)
  434. usage();
  435. return 1;
  436. }
  437. /* Save away the default state of warnings */
  438. memcpy(warning_state_init, warning_state, sizeof warning_state);
  439. /* Dependency filename if we are also doing other things */
  440. if (!depend_file && (operating_mode & ~OP_DEPEND)) {
  441. if (outname)
  442. depend_file = nasm_strcat(outname, ".d");
  443. else
  444. depend_file = filename_set_extension(inname, ".d");
  445. }
  446. /*
  447. * If no output file name provided and this
  448. * is preprocess mode, we're perfectly
  449. * fine to output into stdout.
  450. */
  451. if (!outname && !(operating_mode & OP_PREPROCESS)) {
  452. outname = filename_set_extension(inname, ofmt->extension);
  453. if (!strcmp(outname, inname)) {
  454. outname = "nasm.out";
  455. nasm_error(ERR_WARNING,
  456. "default output file same as input, using `%s' for output\n",
  457. outname);
  458. }
  459. }
  460. depend_ptr = (operating_mode & OP_DEPEND) ? &depend_list : NULL;
  461. if (!depend_target)
  462. depend_target = quote_for_make(outname);
  463. if (!(operating_mode & (OP_PREPROCESS|OP_NORMAL))) {
  464. char *line;
  465. if (depend_missing_ok)
  466. preproc->include_path(NULL); /* "assume generated" */
  467. preproc->reset(inname, 0, depend_ptr);
  468. ofile = NULL;
  469. while ((line = preproc->getline()))
  470. nasm_free(line);
  471. preproc->cleanup(0);
  472. } else if (operating_mode & OP_PREPROCESS) {
  473. char *line;
  474. const char *file_name = NULL;
  475. int32_t prior_linnum = 0;
  476. int lineinc = 0;
  477. if (outname) {
  478. ofile = nasm_open_write(outname, NF_TEXT);
  479. if (!ofile)
  480. nasm_fatal(0, "unable to open output file `%s'", outname);
  481. } else
  482. ofile = NULL;
  483. location.known = false;
  484. /* pass = 1; */
  485. preproc->reset(inname, 3, depend_ptr);
  486. /* Revert all warnings to the default state */
  487. memcpy(warning_state, warning_state_init, sizeof warning_state);
  488. while ((line = preproc->getline())) {
  489. /*
  490. * We generate %line directives if needed for later programs
  491. */
  492. int32_t linnum = prior_linnum += lineinc;
  493. int altline = src_get(&linnum, &file_name);
  494. if (altline) {
  495. if (altline == 1 && lineinc == 1)
  496. nasm_fputs("", ofile);
  497. else {
  498. lineinc = (altline != -1 || lineinc != 1);
  499. fprintf(ofile ? ofile : stdout,
  500. "%%line %"PRId32"+%d %s\n", linnum, lineinc,
  501. file_name);
  502. }
  503. prior_linnum = linnum;
  504. }
  505. nasm_fputs(line, ofile);
  506. nasm_free(line);
  507. }
  508. preproc->cleanup(0);
  509. if (ofile)
  510. fclose(ofile);
  511. if (ofile && terminate_after_phase && !keep_all)
  512. remove(outname);
  513. ofile = NULL;
  514. }
  515. if (operating_mode & OP_NORMAL) {
  516. ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY);
  517. if (!ofile)
  518. nasm_fatal(ERR_NOFILE,
  519. "unable to open output file `%s'", outname);
  520. ofmt->init();
  521. dfmt->init();
  522. assemble_file(inname, depend_ptr);
  523. if (!terminate_after_phase) {
  524. ofmt->cleanup();
  525. cleanup_labels();
  526. fflush(ofile);
  527. if (ferror(ofile)) {
  528. nasm_error(ERR_NONFATAL|ERR_NOFILE,
  529. "write error on output file `%s'", outname);
  530. terminate_after_phase = true;
  531. }
  532. }
  533. if (ofile) {
  534. fclose(ofile);
  535. if (terminate_after_phase && !keep_all)
  536. remove(outname);
  537. ofile = NULL;
  538. }
  539. }
  540. if (depend_list && !terminate_after_phase)
  541. emit_dependencies(depend_list);
  542. if (want_usage)
  543. usage();
  544. raa_free(offsets);
  545. saa_free(forwrefs);
  546. eval_cleanup();
  547. stdscan_cleanup();
  548. src_free();
  549. return terminate_after_phase;
  550. }
  551. /*
  552. * Get a parameter for a command line option.
  553. * First arg must be in the form of e.g. -f...
  554. */
  555. static char *get_param(char *p, char *q, bool *advance)
  556. {
  557. *advance = false;
  558. if (p[2]) /* the parameter's in the option */
  559. return nasm_skip_spaces(p + 2);
  560. if (q && q[0]) {
  561. *advance = true;
  562. return q;
  563. }
  564. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  565. "option `-%c' requires an argument", p[1]);
  566. return NULL;
  567. }
  568. /*
  569. * Copy a filename
  570. */
  571. static void copy_filename(const char **dst, const char *src, const char *what)
  572. {
  573. if (*dst)
  574. nasm_fatal(0, "more than one %s file specified: %s\n", what, src);
  575. *dst = nasm_strdup(src);
  576. }
  577. /*
  578. * Convert a string to a POSIX make-safe form
  579. */
  580. static char *quote_for_pmake(const char *str)
  581. {
  582. const char *p;
  583. char *os, *q;
  584. size_t n = 1; /* Terminating zero */
  585. size_t nbs = 0;
  586. if (!str)
  587. return NULL;
  588. for (p = str; *p; p++) {
  589. switch (*p) {
  590. case ' ':
  591. case '\t':
  592. /* Convert N backslashes + ws -> 2N+1 backslashes + ws */
  593. n += nbs + 2;
  594. nbs = 0;
  595. break;
  596. case '$':
  597. case '#':
  598. nbs = 0;
  599. n += 2;
  600. break;
  601. case '\\':
  602. nbs++;
  603. n++;
  604. break;
  605. default:
  606. nbs = 0;
  607. n++;
  608. break;
  609. }
  610. }
  611. /* Convert N backslashes at the end of filename to 2N backslashes */
  612. if (nbs)
  613. n += nbs;
  614. os = q = nasm_malloc(n);
  615. nbs = 0;
  616. for (p = str; *p; p++) {
  617. switch (*p) {
  618. case ' ':
  619. case '\t':
  620. while (nbs--)
  621. *q++ = '\\';
  622. *q++ = '\\';
  623. *q++ = *p;
  624. break;
  625. case '$':
  626. *q++ = *p;
  627. *q++ = *p;
  628. nbs = 0;
  629. break;
  630. case '#':
  631. *q++ = '\\';
  632. *q++ = *p;
  633. nbs = 0;
  634. break;
  635. case '\\':
  636. *q++ = *p;
  637. nbs++;
  638. break;
  639. default:
  640. *q++ = *p;
  641. nbs = 0;
  642. break;
  643. }
  644. }
  645. while (nbs--)
  646. *q++ = '\\';
  647. *q = '\0';
  648. return os;
  649. }
  650. /*
  651. * Convert a string to a Watcom make-safe form
  652. */
  653. static char *quote_for_wmake(const char *str)
  654. {
  655. const char *p;
  656. char *os, *q;
  657. bool quote = false;
  658. size_t n = 1; /* Terminating zero */
  659. if (!str)
  660. return NULL;
  661. for (p = str; *p; p++) {
  662. switch (*p) {
  663. case ' ':
  664. case '\t':
  665. case '&':
  666. quote = true;
  667. n++;
  668. break;
  669. case '\"':
  670. quote = true;
  671. n += 2;
  672. break;
  673. case '$':
  674. case '#':
  675. n += 2;
  676. break;
  677. default:
  678. n++;
  679. break;
  680. }
  681. }
  682. if (quote)
  683. n += 2;
  684. os = q = nasm_malloc(n);
  685. if (quote)
  686. *q++ = '\"';
  687. for (p = str; *p; p++) {
  688. switch (*p) {
  689. case '$':
  690. case '#':
  691. *q++ = '$';
  692. *q++ = *p;
  693. break;
  694. case '\"':
  695. *q++ = *p;
  696. *q++ = *p;
  697. break;
  698. default:
  699. *q++ = *p;
  700. break;
  701. }
  702. }
  703. if (quote)
  704. *q++ = '\"';
  705. *q = '\0';
  706. return os;
  707. }
  708. enum text_options {
  709. OPT_BOGUS,
  710. OPT_VERSION,
  711. OPT_HELP,
  712. OPT_ABORT_ON_PANIC,
  713. OPT_MANGLE,
  714. OPT_INCLUDE,
  715. OPT_PRAGMA,
  716. OPT_BEFORE,
  717. OPT_LIMIT,
  718. OPT_KEEP_ALL,
  719. OPT_NO_LINE
  720. };
  721. struct textargs {
  722. const char *label;
  723. enum text_options opt;
  724. bool need_arg;
  725. int pvt;
  726. };
  727. static const struct textargs textopts[] = {
  728. {"v", OPT_VERSION, false, 0},
  729. {"version", OPT_VERSION, false, 0},
  730. {"help", OPT_HELP, false, 0},
  731. {"abort-on-panic", OPT_ABORT_ON_PANIC, false, 0},
  732. {"prefix", OPT_MANGLE, true, LM_GPREFIX},
  733. {"postfix", OPT_MANGLE, true, LM_GSUFFIX},
  734. {"gprefix", OPT_MANGLE, true, LM_GPREFIX},
  735. {"gpostfix", OPT_MANGLE, true, LM_GSUFFIX},
  736. {"lprefix", OPT_MANGLE, true, LM_LPREFIX},
  737. {"lpostfix", OPT_MANGLE, true, LM_LSUFFIX},
  738. {"include", OPT_INCLUDE, true, 0},
  739. {"pragma", OPT_PRAGMA, true, 0},
  740. {"before", OPT_BEFORE, true, 0},
  741. {"limit-", OPT_LIMIT, true, 0},
  742. {"keep-all", OPT_KEEP_ALL, false, 0},
  743. {"no-line", OPT_NO_LINE, false, 0},
  744. {NULL, OPT_BOGUS, false, 0}
  745. };
  746. static void show_version(void)
  747. {
  748. printf("NASM version %s compiled on %s%s\n",
  749. nasm_version, nasm_date, nasm_compile_options);
  750. exit(0);
  751. }
  752. static bool stopoptions = false;
  753. static bool process_arg(char *p, char *q, int pass)
  754. {
  755. char *param;
  756. bool advance = false;
  757. if (!p || !p[0])
  758. return false;
  759. if (p[0] == '-' && !stopoptions) {
  760. if (strchr("oOfpPdDiIlFXuUZwW", p[1])) {
  761. /* These parameters take values */
  762. if (!(param = get_param(p, q, &advance)))
  763. return advance;
  764. }
  765. switch (p[1]) {
  766. case 's':
  767. if (pass == 1)
  768. error_file = stdout;
  769. break;
  770. case 'o': /* output file */
  771. if (pass == 2)
  772. copy_filename(&outname, param, "output");
  773. break;
  774. case 'f': /* output format */
  775. if (pass == 1) {
  776. ofmt = ofmt_find(param, &ofmt_alias);
  777. if (!ofmt) {
  778. nasm_fatal(ERR_USAGE, "unrecognised output format `%s' - use -hf for a list", param);
  779. }
  780. }
  781. break;
  782. case 'O': /* Optimization level */
  783. if (pass == 1) {
  784. int opt;
  785. if (!*param) {
  786. /* Naked -O == -Ox */
  787. optimizing.level = MAX_OPTIMIZE;
  788. } else {
  789. while (*param) {
  790. switch (*param) {
  791. case '0': case '1': case '2': case '3': case '4':
  792. case '5': case '6': case '7': case '8': case '9':
  793. opt = strtoul(param, &param, 10);
  794. /* -O0 -> optimizing.level == -1, 0.98 behaviour */
  795. /* -O1 -> optimizing.level == 0, 0.98.09 behaviour */
  796. if (opt < 2)
  797. optimizing.level = opt - 1;
  798. else
  799. optimizing.level = opt;
  800. break;
  801. case 'v':
  802. case '+':
  803. param++;
  804. opt_verbose_info = true;
  805. break;
  806. case 'x':
  807. param++;
  808. optimizing.level = MAX_OPTIMIZE;
  809. break;
  810. default:
  811. nasm_fatal(0,
  812. "unknown optimization option -O%c\n",
  813. *param);
  814. break;
  815. }
  816. }
  817. if (optimizing.level > MAX_OPTIMIZE)
  818. optimizing.level = MAX_OPTIMIZE;
  819. }
  820. }
  821. break;
  822. case 'p': /* pre-include */
  823. case 'P':
  824. if (pass == 2)
  825. preproc->pre_include(param);
  826. break;
  827. case 'd': /* pre-define */
  828. case 'D':
  829. if (pass == 2)
  830. preproc->pre_define(param);
  831. break;
  832. case 'u': /* un-define */
  833. case 'U':
  834. if (pass == 2)
  835. preproc->pre_undefine(param);
  836. break;
  837. case 'i': /* include search path */
  838. case 'I':
  839. if (pass == 1)
  840. nasm_add_string_to_strlist(&include_path, param);
  841. break;
  842. case 'l': /* listing file */
  843. if (pass == 2)
  844. copy_filename(&listname, param, "listing");
  845. break;
  846. case 'Z': /* error messages file */
  847. if (pass == 1)
  848. copy_filename(&errname, param, "error");
  849. break;
  850. case 'F': /* specify debug format */
  851. if (pass == 1) {
  852. using_debug_info = true;
  853. debug_format = param;
  854. }
  855. break;
  856. case 'X': /* specify error reporting format */
  857. if (pass == 1) {
  858. if (!nasm_stricmp("vc", param) || !nasm_stricmp("msvc", param) || !nasm_stricmp("ms", param))
  859. errfmt = &errfmt_msvc;
  860. else if (!nasm_stricmp("gnu", param) || !nasm_stricmp("gcc", param))
  861. errfmt = &errfmt_gnu;
  862. else
  863. nasm_fatal(ERR_USAGE, "unrecognized error reporting format `%s'", param);
  864. }
  865. break;
  866. case 'g':
  867. if (pass == 1) {
  868. using_debug_info = true;
  869. if (p[2])
  870. debug_format = nasm_skip_spaces(p + 2);
  871. }
  872. break;
  873. case 'h':
  874. help(p[2]);
  875. exit(0); /* never need usage message here */
  876. break;
  877. case 'y':
  878. printf("\nvalid debug formats for '%s' output format are"
  879. " ('*' denotes default):\n", ofmt->shortname);
  880. dfmt_list(ofmt, stdout);
  881. exit(0);
  882. break;
  883. case 't':
  884. if (pass == 2)
  885. tasm_compatible_mode = true;
  886. break;
  887. case 'v':
  888. show_version();
  889. break;
  890. case 'e': /* preprocess only */
  891. case 'E':
  892. if (pass == 1)
  893. operating_mode = OP_PREPROCESS;
  894. break;
  895. case 'a': /* assemble only - don't preprocess */
  896. if (pass == 1)
  897. preproc = &preproc_nop;
  898. break;
  899. case 'w':
  900. case 'W':
  901. if (pass == 2) {
  902. if (!set_warning_status(param)) {
  903. nasm_error(ERR_WARNING|ERR_NOFILE|WARN_UNK_WARNING,
  904. "unknown warning option: %s", param);
  905. }
  906. }
  907. break;
  908. case 'M':
  909. if (pass == 1) {
  910. switch (p[2]) {
  911. case 'W':
  912. quote_for_make = quote_for_wmake;
  913. break;
  914. case 'D':
  915. case 'F':
  916. case 'T':
  917. case 'Q':
  918. advance = true;
  919. break;
  920. default:
  921. break;
  922. }
  923. } else {
  924. switch (p[2]) {
  925. case 0:
  926. operating_mode = OP_DEPEND;
  927. break;
  928. case 'G':
  929. operating_mode = OP_DEPEND;
  930. depend_missing_ok = true;
  931. break;
  932. case 'P':
  933. depend_emit_phony = true;
  934. break;
  935. case 'D':
  936. operating_mode |= OP_DEPEND;
  937. if (q && (q[0] != '-' || q[1] == '\0')) {
  938. depend_file = q;
  939. advance = true;
  940. }
  941. break;
  942. case 'F':
  943. depend_file = q;
  944. advance = true;
  945. break;
  946. case 'T':
  947. depend_target = q;
  948. advance = true;
  949. break;
  950. case 'Q':
  951. depend_target = quote_for_make(q);
  952. advance = true;
  953. break;
  954. case 'W':
  955. /* handled in pass 1 */
  956. break;
  957. default:
  958. nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
  959. "unknown dependency option `-M%c'", p[2]);
  960. break;
  961. }
  962. }
  963. if (advance && (!q || !q[0])) {
  964. nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
  965. "option `-M%c' requires a parameter", p[2]);
  966. break;
  967. }
  968. break;
  969. case '-':
  970. {
  971. const struct textargs *tx;
  972. size_t olen, plen;
  973. char *eqsave;
  974. p += 2;
  975. if (!*p) { /* -- => stop processing options */
  976. stopoptions = true;
  977. break;
  978. }
  979. olen = 0; /* Placate gcc at lower optimization levels */
  980. plen = strlen(p);
  981. for (tx = textopts; tx->label; tx++) {
  982. olen = strlen(tx->label);
  983. if (olen > plen)
  984. continue;
  985. if (nasm_memicmp(p, tx->label, olen))
  986. continue;
  987. if (tx->label[olen-1] == '-')
  988. break; /* Incomplete option */
  989. if (!p[olen] || p[olen] == '=')
  990. break; /* Complete option */
  991. }
  992. if (!tx->label) {
  993. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  994. "unrecognized option `--%s'", p);
  995. }
  996. eqsave = param = strchr(p+olen, '=');
  997. if (param)
  998. *param++ = '\0';
  999. if (tx->need_arg) {
  1000. if (!param) {
  1001. param = q;
  1002. advance = true;
  1003. }
  1004. /* Note: a null string is a valid parameter */
  1005. if (!param) {
  1006. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  1007. "option `--%s' requires an argument",
  1008. p);
  1009. break;
  1010. }
  1011. } else {
  1012. if (param) {
  1013. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  1014. "option `--%s' does not take an argument",
  1015. p);
  1016. }
  1017. }
  1018. switch (tx->opt) {
  1019. case OPT_VERSION:
  1020. show_version();
  1021. break;
  1022. case OPT_ABORT_ON_PANIC:
  1023. abort_on_panic = true;
  1024. break;
  1025. case OPT_MANGLE:
  1026. if (pass == 2)
  1027. set_label_mangle(tx->pvt, param);
  1028. break;
  1029. case OPT_INCLUDE:
  1030. if (pass == 2)
  1031. preproc->pre_include(q);
  1032. break;
  1033. case OPT_PRAGMA:
  1034. if (pass == 2)
  1035. preproc->pre_command("pragma", param);
  1036. break;
  1037. case OPT_BEFORE:
  1038. if (pass == 2)
  1039. preproc->pre_command(NULL, param);
  1040. break;
  1041. case OPT_LIMIT:
  1042. if (pass == 1)
  1043. nasm_set_limit(p+olen, param);
  1044. break;
  1045. case OPT_KEEP_ALL:
  1046. keep_all = true;
  1047. break;
  1048. case OPT_NO_LINE:
  1049. pp_noline = true;
  1050. break;
  1051. case OPT_HELP:
  1052. help(0);
  1053. exit(0);
  1054. default:
  1055. panic();
  1056. }
  1057. if (eqsave)
  1058. *eqsave = '='; /* Restore = argument separator */
  1059. break;
  1060. }
  1061. default:
  1062. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  1063. "unrecognised option `-%c'", p[1]);
  1064. break;
  1065. }
  1066. } else if (pass == 2) {
  1067. /* In theory we could allow multiple input files... */
  1068. copy_filename(&inname, p, "input");
  1069. }
  1070. return advance;
  1071. }
  1072. #define ARG_BUF_DELTA 128
  1073. static void process_respfile(FILE * rfile, int pass)
  1074. {
  1075. char *buffer, *p, *q, *prevarg;
  1076. int bufsize, prevargsize;
  1077. bufsize = prevargsize = ARG_BUF_DELTA;
  1078. buffer = nasm_malloc(ARG_BUF_DELTA);
  1079. prevarg = nasm_malloc(ARG_BUF_DELTA);
  1080. prevarg[0] = '\0';
  1081. while (1) { /* Loop to handle all lines in file */
  1082. p = buffer;
  1083. while (1) { /* Loop to handle long lines */
  1084. q = fgets(p, bufsize - (p - buffer), rfile);
  1085. if (!q)
  1086. break;
  1087. p += strlen(p);
  1088. if (p > buffer && p[-1] == '\n')
  1089. break;
  1090. if (p - buffer > bufsize - 10) {
  1091. int offset;
  1092. offset = p - buffer;
  1093. bufsize += ARG_BUF_DELTA;
  1094. buffer = nasm_realloc(buffer, bufsize);
  1095. p = buffer + offset;
  1096. }
  1097. }
  1098. if (!q && p == buffer) {
  1099. if (prevarg[0])
  1100. process_arg(prevarg, NULL, pass);
  1101. nasm_free(buffer);
  1102. nasm_free(prevarg);
  1103. return;
  1104. }
  1105. /*
  1106. * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
  1107. * them are present at the end of the line.
  1108. */
  1109. *(p = &buffer[strcspn(buffer, "\r\n\032")]) = '\0';
  1110. while (p > buffer && nasm_isspace(p[-1]))
  1111. *--p = '\0';
  1112. p = nasm_skip_spaces(buffer);
  1113. if (process_arg(prevarg, p, pass))
  1114. *p = '\0';
  1115. if ((int) strlen(p) > prevargsize - 10) {
  1116. prevargsize += ARG_BUF_DELTA;
  1117. prevarg = nasm_realloc(prevarg, prevargsize);
  1118. }
  1119. strncpy(prevarg, p, prevargsize);
  1120. }
  1121. }
  1122. /* Function to process args from a string of args, rather than the
  1123. * argv array. Used by the environment variable and response file
  1124. * processing.
  1125. */
  1126. static void process_args(char *args, int pass)
  1127. {
  1128. char *p, *q, *arg, *prevarg;
  1129. char separator = ' ';
  1130. p = args;
  1131. if (*p && *p != '-')
  1132. separator = *p++;
  1133. arg = NULL;
  1134. while (*p) {
  1135. q = p;
  1136. while (*p && *p != separator)
  1137. p++;
  1138. while (*p == separator)
  1139. *p++ = '\0';
  1140. prevarg = arg;
  1141. arg = q;
  1142. if (process_arg(prevarg, arg, pass))
  1143. arg = NULL;
  1144. }
  1145. if (arg)
  1146. process_arg(arg, NULL, pass);
  1147. }
  1148. static void process_response_file(const char *file, int pass)
  1149. {
  1150. char str[2048];
  1151. FILE *f = nasm_open_read(file, NF_TEXT);
  1152. if (!f) {
  1153. perror(file);
  1154. exit(-1);
  1155. }
  1156. while (fgets(str, sizeof str, f)) {
  1157. process_args(str, pass);
  1158. }
  1159. fclose(f);
  1160. }
  1161. static void parse_cmdline(int argc, char **argv, int pass)
  1162. {
  1163. FILE *rfile;
  1164. char *envreal, *envcopy = NULL, *p;
  1165. int i;
  1166. /*
  1167. * Initialize all the warnings to their default state, including
  1168. * warning index 0 used for "always on".
  1169. */
  1170. for (i = 0; i < WARN_ALL; i++)
  1171. warning_state_init[i] = warning_state[i] = warnings[i].state;
  1172. /*
  1173. * First, process the NASMENV environment variable.
  1174. */
  1175. envreal = getenv("NASMENV");
  1176. if (envreal) {
  1177. envcopy = nasm_strdup(envreal);
  1178. process_args(envcopy, pass);
  1179. nasm_free(envcopy);
  1180. }
  1181. /*
  1182. * Now process the actual command line.
  1183. */
  1184. while (--argc) {
  1185. bool advance;
  1186. argv++;
  1187. if (argv[0][0] == '@') {
  1188. /*
  1189. * We have a response file, so process this as a set of
  1190. * arguments like the environment variable. This allows us
  1191. * to have multiple arguments on a single line, which is
  1192. * different to the -@resp file processing below for regular
  1193. * NASM.
  1194. */
  1195. process_response_file(argv[0]+1, pass);
  1196. argc--;
  1197. argv++;
  1198. }
  1199. if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
  1200. p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &advance);
  1201. if (p) {
  1202. rfile = nasm_open_read(p, NF_TEXT);
  1203. if (rfile) {
  1204. process_respfile(rfile, pass);
  1205. fclose(rfile);
  1206. } else
  1207. nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
  1208. "unable to open response file `%s'", p);
  1209. }
  1210. } else
  1211. advance = process_arg(argv[0], argc > 1 ? argv[1] : NULL, pass);
  1212. argv += advance, argc -= advance;
  1213. }
  1214. /*
  1215. * Look for basic command line typos. This definitely doesn't
  1216. * catch all errors, but it might help cases of fumbled fingers.
  1217. */
  1218. if (pass != 2)
  1219. return;
  1220. if (!inname)
  1221. nasm_fatal(ERR_USAGE, "no input file specified");
  1222. else if ((errname && !strcmp(inname, errname)) ||
  1223. (outname && !strcmp(inname, outname)) ||
  1224. (listname && !strcmp(inname, listname)) ||
  1225. (depend_file && !strcmp(inname, depend_file)))
  1226. nasm_fatal(ERR_USAGE, "will not overwrite input file");
  1227. if (errname) {
  1228. error_file = nasm_open_write(errname, NF_TEXT);
  1229. if (!error_file) {
  1230. error_file = stderr; /* Revert to default! */
  1231. nasm_fatal(ERR_USAGE, "cannot open file `%s' for error messages", errname);
  1232. }
  1233. }
  1234. }
  1235. static void assemble_file(const char *fname, StrList **depend_ptr)
  1236. {
  1237. char *line;
  1238. insn output_ins;
  1239. int i;
  1240. uint64_t prev_offset_changed;
  1241. int64_t stall_count = 0; /* Make sure we make forward progress... */
  1242. switch (cmd_sb) {
  1243. case 16:
  1244. break;
  1245. case 32:
  1246. if (!iflag_cpu_level_ok(&cmd_cpu, IF_386))
  1247. nasm_fatal(0, "command line: 32-bit segment size requires a higher cpu");
  1248. break;
  1249. case 64:
  1250. if (!iflag_cpu_level_ok(&cmd_cpu, IF_X86_64))
  1251. nasm_fatal(0, "command line: 64-bit segment size requires a higher cpu");
  1252. break;
  1253. default:
  1254. panic();
  1255. break;
  1256. }
  1257. prev_offset_changed = nasm_limit[LIMIT_PASSES];
  1258. for (passn = 1; pass0 <= 2; passn++) {
  1259. pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */
  1260. pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */
  1261. /* pass0 0, 0, 0, ..., 1, 2 */
  1262. globalbits = cmd_sb; /* set 'bits' to command line default */
  1263. cpu = cmd_cpu;
  1264. if (pass0 == 2) {
  1265. lfmt->init(listname);
  1266. } else if (passn == 1 && listname && !keep_all) {
  1267. /* Remove the list file in case we die before the output pass */
  1268. remove(listname);
  1269. }
  1270. in_absolute = false;
  1271. global_offset_changed = 0; /* set by redefine_label */
  1272. if (passn > 1) {
  1273. saa_rewind(forwrefs);
  1274. forwref = saa_rstruct(forwrefs);
  1275. raa_free(offsets);
  1276. offsets = raa_init();
  1277. }
  1278. location.segment = NO_SEG;
  1279. location.offset = 0;
  1280. if (passn == 1)
  1281. location.known = true;
  1282. ofmt->reset();
  1283. switch_segment(ofmt->section(NULL, pass2, &globalbits));
  1284. preproc->reset(fname, pass1, pass1 == 2 ? depend_ptr : NULL);
  1285. /* Revert all warnings to the default state */
  1286. memcpy(warning_state, warning_state_init, sizeof warning_state);
  1287. globallineno = 0;
  1288. while ((line = preproc->getline())) {
  1289. if (++globallineno > nasm_limit[LIMIT_LINES])
  1290. nasm_fatal(0,
  1291. "overall line count exceeds the maximum %"PRId64"\n",
  1292. nasm_limit[LIMIT_LINES]);
  1293. /*
  1294. * Here we parse our directives; this is not handled by the
  1295. * main parser.
  1296. */
  1297. if (process_directives(line))
  1298. goto end_of_line; /* Just do final cleanup */
  1299. /* Not a directive, or even something that starts with [ */
  1300. parse_line(pass1, line, &output_ins);
  1301. if (optimizing.level > 0) {
  1302. if (forwref != NULL && globallineno == forwref->lineno) {
  1303. output_ins.forw_ref = true;
  1304. do {
  1305. output_ins.oprs[forwref->operand].opflags |= OPFLAG_FORWARD;
  1306. forwref = saa_rstruct(forwrefs);
  1307. } while (forwref != NULL
  1308. && forwref->lineno == globallineno);
  1309. } else
  1310. output_ins.forw_ref = false;
  1311. if (output_ins.forw_ref) {
  1312. if (passn == 1) {
  1313. for (i = 0; i < output_ins.operands; i++) {
  1314. if (output_ins.oprs[i].opflags & OPFLAG_FORWARD) {
  1315. struct forwrefinfo *fwinf = (struct forwrefinfo *)saa_wstruct(forwrefs);
  1316. fwinf->lineno = globallineno;
  1317. fwinf->operand = i;
  1318. }
  1319. }
  1320. }
  1321. }
  1322. }
  1323. /* forw_ref */
  1324. if (output_ins.opcode == I_EQU) {
  1325. if (!output_ins.label) {
  1326. nasm_error(ERR_NONFATAL, "EQU not preceded by label");
  1327. } else if (output_ins.operands == 1 &&
  1328. (output_ins.oprs[0].type & IMMEDIATE) &&
  1329. output_ins.oprs[0].wrt == NO_SEG) {
  1330. define_label(output_ins.label,
  1331. output_ins.oprs[0].segment,
  1332. output_ins.oprs[0].offset, false);
  1333. } else if (output_ins.operands == 2
  1334. && (output_ins.oprs[0].type & IMMEDIATE)
  1335. && (output_ins.oprs[0].type & COLON)
  1336. && output_ins.oprs[0].segment == NO_SEG
  1337. && output_ins.oprs[0].wrt == NO_SEG
  1338. && (output_ins.oprs[1].type & IMMEDIATE)
  1339. && output_ins.oprs[1].segment == NO_SEG
  1340. && output_ins.oprs[1].wrt == NO_SEG) {
  1341. define_label(output_ins.label,
  1342. output_ins.oprs[0].offset | SEG_ABS,
  1343. output_ins.oprs[1].offset, false);
  1344. } else {
  1345. nasm_error(ERR_NONFATAL, "bad syntax for EQU");
  1346. }
  1347. } else { /* instruction isn't an EQU */
  1348. int32_t n;
  1349. nasm_assert(output_ins.times >= 0);
  1350. for (n = 1; n <= output_ins.times; n++) {
  1351. if (pass1 == 1) {
  1352. int64_t l = insn_size(location.segment,
  1353. location.offset,
  1354. globalbits, &output_ins);
  1355. /* if (using_debug_info) && output_ins.opcode != -1) */
  1356. if (using_debug_info)
  1357. { /* fbk 03/25/01 */
  1358. /* this is done here so we can do debug type info */
  1359. int32_t typeinfo =
  1360. TYS_ELEMENTS(output_ins.operands);
  1361. switch (output_ins.opcode) {
  1362. case I_RESB:
  1363. typeinfo =
  1364. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;
  1365. break;
  1366. case I_RESW:
  1367. typeinfo =
  1368. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;
  1369. break;
  1370. case I_RESD:
  1371. typeinfo =
  1372. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;
  1373. break;
  1374. case I_RESQ:
  1375. typeinfo =
  1376. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;
  1377. break;
  1378. case I_REST:
  1379. typeinfo =
  1380. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;
  1381. break;
  1382. case I_RESO:
  1383. typeinfo =
  1384. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_OWORD;
  1385. break;
  1386. case I_RESY:
  1387. typeinfo =
  1388. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_YWORD;
  1389. break;
  1390. case I_RESZ:
  1391. typeinfo =
  1392. TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_ZWORD;
  1393. break;
  1394. case I_DB:
  1395. typeinfo |= TY_BYTE;
  1396. break;
  1397. case I_DW:
  1398. typeinfo |= TY_WORD;
  1399. break;
  1400. case I_DD:
  1401. if (output_ins.eops_float)
  1402. typeinfo |= TY_FLOAT;
  1403. else
  1404. typeinfo |= TY_DWORD;
  1405. break;
  1406. case I_DQ:
  1407. typeinfo |= TY_QWORD;
  1408. break;
  1409. case I_DT:
  1410. typeinfo |= TY_TBYTE;
  1411. break;
  1412. case I_DO:
  1413. typeinfo |= TY_OWORD;
  1414. break;
  1415. case I_DY:
  1416. typeinfo |= TY_YWORD;
  1417. break;
  1418. case I_DZ:
  1419. typeinfo |= TY_ZWORD;
  1420. break;
  1421. default:
  1422. typeinfo = TY_LABEL;
  1423. break;
  1424. }
  1425. dfmt->debug_typevalue(typeinfo);
  1426. }
  1427. /*
  1428. * For INCBIN, let the code in assemble
  1429. * handle TIMES, so we don't have to read the
  1430. * input file over and over.
  1431. */
  1432. if (l != -1) {
  1433. increment_offset(l);
  1434. }
  1435. /*
  1436. * else l == -1 => invalid instruction, which will be
  1437. * flagged as an error on pass 2
  1438. */
  1439. } else {
  1440. if (n == 2)
  1441. lfmt->uplevel(LIST_TIMES);
  1442. increment_offset(assemble(location.segment,
  1443. location.offset,
  1444. globalbits, &output_ins));
  1445. }
  1446. } /* not an EQU */
  1447. }
  1448. if (output_ins.times > 1)
  1449. lfmt->downlevel(LIST_TIMES);
  1450. cleanup_insn(&output_ins);
  1451. end_of_line:
  1452. nasm_free(line);
  1453. } /* end while (line = preproc->getline... */
  1454. if (global_offset_changed && !terminate_after_phase) {
  1455. switch (pass0) {
  1456. case 1:
  1457. nasm_error(ERR_WARNING|WARN_PHASE,
  1458. "phase error during stabilization pass, hoping for the best");
  1459. break;
  1460. case 2:
  1461. nasm_error(ERR_NONFATAL,
  1462. "phase error during code generation pass");
  1463. break;
  1464. default:
  1465. /* This is normal, we'll keep going... */
  1466. break;
  1467. }
  1468. }
  1469. if (pass1 == 1)
  1470. preproc->cleanup(1);
  1471. /*
  1472. * Always run at least two optimization passes (pass0 == 0);
  1473. * things like subsections will fail miserably without that.
  1474. * Once we commit to a stabilization pass (pass0 == 1), we can't
  1475. * go back, and if something goes bad, we can only hope
  1476. * that we don't end up with a phase error at the end.
  1477. */
  1478. if ((passn > 1 && !global_offset_changed) || pass0 > 0) {
  1479. pass0++;
  1480. } else if (global_offset_changed &&
  1481. global_offset_changed < prev_offset_changed) {
  1482. prev_offset_changed = global_offset_changed;
  1483. stall_count = 0;
  1484. } else {
  1485. stall_count++;
  1486. }
  1487. if (terminate_after_phase)
  1488. break;
  1489. if ((stall_count > nasm_limit[LIMIT_STALLED]) ||
  1490. (passn >= nasm_limit[LIMIT_PASSES])) {
  1491. /* We get here if the labels don't converge
  1492. * Example: FOO equ FOO + 1
  1493. */
  1494. nasm_error(ERR_NONFATAL,
  1495. "Can't find valid values for all labels "
  1496. "after %"PRId64" passes, giving up.", passn);
  1497. nasm_error(ERR_NONFATAL,
  1498. "Possible causes: recursive EQUs, macro abuse.");
  1499. break;
  1500. }
  1501. }
  1502. preproc->cleanup(0);
  1503. lfmt->cleanup();
  1504. if (!terminate_after_phase && opt_verbose_info) {
  1505. /* -On and -Ov switches */
  1506. fprintf(stdout, "info: assembly required 1+%"PRId64"+1 passes\n",
  1507. passn-3);
  1508. }
  1509. }
  1510. /**
  1511. * get warning index; 0 if this is non-suppressible.
  1512. */
  1513. static size_t warn_index(int severity)
  1514. {
  1515. size_t index;
  1516. if ((severity & ERR_MASK) >= ERR_FATAL)
  1517. return 0; /* Fatal errors are never suppressible */
  1518. /* If this is a warning and no index is provided, it is WARN_OTHER */
  1519. if ((severity & (ERR_MASK|WARN_MASK)) == ERR_WARNING)
  1520. severity |= WARN_OTHER;
  1521. index = WARN_IDX(severity);
  1522. nasm_assert(index < WARN_ALL);
  1523. return index;
  1524. }
  1525. static bool skip_this_pass(int severity)
  1526. {
  1527. /*
  1528. * See if it's a pass-specific error or warning which should be skipped.
  1529. * We can never skip fatal errors as by definition they cannot be
  1530. * resumed from.
  1531. */
  1532. if ((severity & ERR_MASK) >= ERR_FATAL)
  1533. return false;
  1534. /*
  1535. * passn is 1 on the very first pass only.
  1536. * pass0 is 2 on the code-generation (final) pass only.
  1537. * These are the passes we care about in this case.
  1538. */
  1539. return (((severity & ERR_PASS1) && passn != 1) ||
  1540. ((severity & ERR_PASS2) && pass0 != 2));
  1541. }
  1542. /**
  1543. * check for suppressed message (usually warnings or notes)
  1544. *
  1545. * @param severity the severity of the warning or error
  1546. * @return true if we should abort error/warning printing
  1547. */
  1548. static bool is_suppressed(int severity)
  1549. {
  1550. if ((severity & ERR_MASK) >= ERR_FATAL)
  1551. return false; /* Fatal errors can never be suppressed */
  1552. return !(warning_state[warn_index(severity)] & WARN_ST_ENABLED);
  1553. }
  1554. /**
  1555. * Return the true error type (the ERR_MASK part) of the given
  1556. * severity, accounting for warnings that may need to be promoted to
  1557. * error.
  1558. *
  1559. * @param severity the severity of the warning or error
  1560. * @return true if we should error out
  1561. */
  1562. static int true_error_type(int severity)
  1563. {
  1564. const uint8_t warn_is_err = WARN_ST_ENABLED|WARN_ST_ERROR;
  1565. int type;
  1566. type = severity & ERR_MASK;
  1567. /* Promote warning to error? */
  1568. if (type == ERR_WARNING) {
  1569. uint8_t state = warning_state[warn_index(severity)];
  1570. if ((state & warn_is_err) == warn_is_err)
  1571. type = ERR_NONFATAL;
  1572. }
  1573. return type;
  1574. }
  1575. /**
  1576. * common error reporting
  1577. * This is the common back end of the error reporting schemes currently
  1578. * implemented. It prints the nature of the warning and then the
  1579. * specific error message to error_file and may or may not return. It
  1580. * doesn't return if the error severity is a "panic" or "debug" type.
  1581. *
  1582. * @param severity the severity of the warning or error
  1583. * @param fmt the printf style format string
  1584. */
  1585. static void nasm_verror_asm(int severity, const char *fmt, va_list args)
  1586. {
  1587. char msg[1024];
  1588. char warnsuf[64];
  1589. char linestr[64];
  1590. const char *pfx;
  1591. int spec_type = severity & ERR_MASK; /* type originally specified */
  1592. int true_type = true_error_type(severity);
  1593. const char *currentfile = NULL;
  1594. int32_t lineno = 0;
  1595. static const char * const pfx_table[ERR_MASK+1] = {
  1596. "debug: ", "note: ", "warning: ", "error: ",
  1597. "", "", "fatal: ", "panic: "
  1598. };
  1599. if (is_suppressed(severity))
  1600. return;
  1601. if (!(severity & ERR_NOFILE)) {
  1602. src_get(&lineno, &currentfile);
  1603. if (!currentfile) {
  1604. currentfile = currentfile ? currentfile :
  1605. inname && inname[0] ? inname :
  1606. outname && outname[0] ? outname :
  1607. NULL;
  1608. lineno = 0;
  1609. }
  1610. }
  1611. /*
  1612. * For a debug/warning/note event, if ERR_HERE is set don't
  1613. * output anything if there is no current filename available
  1614. */
  1615. if (!currentfile && (severity & ERR_HERE) && true_type <= ERR_WARNING)
  1616. return;
  1617. if (severity & ERR_NO_SEVERITY)
  1618. pfx = "";
  1619. else
  1620. pfx = pfx_table[true_type];
  1621. vsnprintf(msg, sizeof msg, fmt, args);
  1622. *warnsuf = 0;
  1623. if (spec_type == ERR_WARNING) {
  1624. snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
  1625. (true_type >= ERR_NONFATAL) ? "error=" : "",
  1626. warnings[warn_index(severity)].name);
  1627. }
  1628. *linestr = 0;
  1629. if (lineno) {
  1630. snprintf(linestr, sizeof linestr, "%s%"PRId32"%s",
  1631. errfmt->beforeline, lineno, errfmt->afterline);
  1632. }
  1633. if (!skip_this_pass(severity)) {
  1634. fprintf(error_file, "%s%s%s%s%s%s%s\n",
  1635. currentfile ? currentfile : "nasm",
  1636. linestr, errfmt->beforemsg, pfx, msg,
  1637. (severity & ERR_HERE) ? " here" : "", warnsuf);
  1638. }
  1639. /* Are we recursing from error_list_macros? */
  1640. if (severity & ERR_PP_LISTMACRO)
  1641. return;
  1642. /*
  1643. * Don't suppress this with skip_this_pass(), or we don't get
  1644. * pass1 or preprocessor warnings in the list file
  1645. */
  1646. if (severity & ERR_HERE) {
  1647. if (lineno)
  1648. lfmt->error(severity, "%s%s at %s:%"PRId32"%s",
  1649. pfx, msg, currentfile, lineno, warnsuf);
  1650. else if (currentfile)
  1651. lfmt->error(severity, "%s%s in file %s%s",
  1652. pfx, msg, currentfile, warnsuf);
  1653. else
  1654. lfmt->error(severity, "%s%s in unknown location%s",
  1655. pfx, msg, warnsuf);
  1656. } else {
  1657. lfmt->error(severity, "%s%s%s", pfx, msg, warnsuf);
  1658. }
  1659. if (skip_this_pass(severity))
  1660. return;
  1661. if (severity & ERR_USAGE)
  1662. want_usage = true;
  1663. preproc->error_list_macros(severity);
  1664. switch (true_type) {
  1665. case ERR_NOTE:
  1666. case ERR_DEBUG:
  1667. case ERR_WARNING:
  1668. /* no further action, by definition */
  1669. break;
  1670. case ERR_NONFATAL:
  1671. terminate_after_phase = true;
  1672. break;
  1673. case ERR_FATAL:
  1674. if (ofile) {
  1675. fclose(ofile);
  1676. if (!keep_all)
  1677. remove(outname);
  1678. ofile = NULL;
  1679. }
  1680. if (want_usage)
  1681. usage();
  1682. exit(1); /* instantly die */
  1683. break; /* placate silly compilers */
  1684. case ERR_PANIC:
  1685. fflush(NULL);
  1686. if (abort_on_panic)
  1687. abort(); /* halt, catch fire, dump core/stop debugger */
  1688. if (ofile) {
  1689. fclose(ofile);
  1690. if (!keep_all)
  1691. remove(outname);
  1692. ofile = NULL;
  1693. }
  1694. exit(3);
  1695. break;
  1696. default:
  1697. break; /* ??? */
  1698. }
  1699. }
  1700. static void usage(void)
  1701. {
  1702. fputs("type `nasm -h' for help\n", error_file);
  1703. }
  1704. static void help(const char xopt)
  1705. {
  1706. int i;
  1707. printf
  1708. ("usage: nasm [-@ response file] [-o outfile] [-f format] "
  1709. "[-l listfile]\n"
  1710. " [options...] [--] filename\n"
  1711. " or nasm -v (or --v) for version info\n\n"
  1712. "\n"
  1713. "Response files should contain command line parameters,\n"
  1714. "one per line.\n"
  1715. "\n"
  1716. " -t assemble in SciTech TASM compatible mode\n");
  1717. printf
  1718. (" -E (or -e) preprocess only (writes output to stdout by default)\n"
  1719. " -a don't preprocess (assemble only)\n"
  1720. " -M generate Makefile dependencies on stdout\n"
  1721. " -MG d:o, missing files assumed generated\n"
  1722. " -MF file set Makefile dependency file\n"
  1723. " -MD file assemble and generate dependencies\n"
  1724. " -MT file dependency target name\n"
  1725. " -MQ file dependency target name (quoted)\n"
  1726. " -MP emit phony target\n\n"
  1727. " -Zfile redirect error messages to file\n"
  1728. " -s redirect error messages to stdout\n\n"
  1729. " -g generate debugging information\n\n"
  1730. " -F format select a debugging format\n\n"
  1731. " -gformat same as -g -F format\n\n"
  1732. " -o outfile write output to an outfile\n\n"
  1733. " -f format select an output format\n\n"
  1734. " -l listfile write listing to a listfile\n\n"
  1735. " -Ipath add a pathname to the include file path\n");
  1736. printf
  1737. (" -Oflags... optimize opcodes, immediates and branch offsets\n"
  1738. " -O0 no optimization\n"
  1739. " -O1 minimal optimization\n"
  1740. " -Ox multipass optimization (default)\n"
  1741. " -Ov display the number of passes executed at the end\n"
  1742. " -Pfile pre-include a file (also --include)\n"
  1743. " -Dmacro[=str] pre-define a macro\n"
  1744. " -Umacro undefine a macro\n"
  1745. " -Xformat specifiy error reporting format (gnu or vc)\n"
  1746. " -w+foo enable warning foo (equiv. -Wfoo)\n"
  1747. " -w-foo disable warning foo (equiv. -Wno-foo)\n"
  1748. " -w[+-]error[=foo]\n"
  1749. " promote [specific] warnings to errors\n"
  1750. " -h show invocation summary and exit (also --help)\n\n"
  1751. " --pragma str pre-executes a specific %%pragma\n"
  1752. " --before str add line (usually a preprocessor statement) before the input\n"
  1753. " --prefix str prepend the given string to all the given string\n"
  1754. " to all extern, common and global symbols (also --gprefix)\n"
  1755. " --postfix str append the given string to all the given string\n"
  1756. " to all extern, common and global symbols (also --gpostfix)\n"
  1757. " --lprefix str prepend the given string to all other symbols\n"
  1758. " --lpostfix str append the given string to all other symbols\n"
  1759. " --keep-all output files will not be removed even if an error happens\n"
  1760. " --no-line ignore %%line directives in input\n"
  1761. " --limit-X val set execution limit X\n");
  1762. for (i = 0; i <= LIMIT_MAX; i++) {
  1763. printf(" %-15s %s (default ",
  1764. limit_info[i].name, limit_info[i].help);
  1765. if (nasm_limit[i] < LIMIT_MAX_VAL) {
  1766. printf("%"PRId64")\n", nasm_limit[i]);
  1767. } else {
  1768. printf("unlimited)\n");
  1769. }
  1770. }
  1771. printf("\nWarnings for the -W/-w options: (default in brackets)\n");
  1772. for (i = 1; i <= WARN_ALL; i++)
  1773. printf(" %-23s %s%s\n",
  1774. warnings[i].name, warnings[i].help,
  1775. i == WARN_ALL ? "\n" :
  1776. (warnings[i].state & WARN_ST_ERROR) ? " [error]" :
  1777. (warnings[i].state & WARN_ST_ENABLED) ? " [on]" : " [off]");
  1778. if (xopt == 'f') {
  1779. printf("valid output formats for -f are"
  1780. " (`*' denotes default):\n");
  1781. ofmt_list(ofmt, stdout);
  1782. } else {
  1783. printf("For a list of valid output formats, use -hf.\n");
  1784. printf("For a list of debug formats, use -f <format> -y.\n");
  1785. }
  1786. }