diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2018-12-18 11:12:46 -0800 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2018-12-18 11:14:59 -0800 |
commit | e55d03dd47c221f631fe518c623cdd8a703076b2 (patch) | |
tree | a8dad51972e4dd49b401afcc0f08ce4b53b331f1 | |
parent | 8c17bb2fc4d61675b6775e78fbb37b48f19379d3 (diff) | |
download | nasm-e55d03dd47c221f631fe518c623cdd8a703076b2.tar.gz |
Clean up the handling of various passes
The use of pass0, pass1, pass2, and "pass" passed as an argument is
really confusing and already caused a severe bug in the 2.14.01
release cycle. Clean them up and be far more explicit about what
various passes mean.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r-- | asm/directiv.c | 55 | ||||
-rw-r--r-- | asm/eval.c | 28 | ||||
-rw-r--r-- | asm/eval.h | 2 | ||||
-rw-r--r-- | asm/labels.c | 17 | ||||
-rw-r--r-- | asm/nasm.c | 177 | ||||
-rw-r--r-- | asm/parser.c | 12 | ||||
-rw-r--r-- | asm/parser.h | 2 | ||||
-rw-r--r-- | asm/preproc-nop.c | 17 | ||||
-rw-r--r-- | asm/preproc.c | 71 | ||||
-rw-r--r-- | include/nasm.h | 89 | ||||
-rw-r--r-- | output/nullout.c | 3 | ||||
-rw-r--r-- | output/outaout.c | 5 | ||||
-rw-r--r-- | output/outas86.c | 5 | ||||
-rw-r--r-- | output/outbin.c | 15 | ||||
-rw-r--r-- | output/outcoff.c | 23 | ||||
-rw-r--r-- | output/outdbg.c | 23 | ||||
-rw-r--r-- | output/outelf.c | 24 | ||||
-rw-r--r-- | output/outieee.c | 20 | ||||
-rw-r--r-- | output/outlib.h | 2 | ||||
-rw-r--r-- | output/outmacho.c | 24 | ||||
-rw-r--r-- | output/outobj.c | 28 | ||||
-rw-r--r-- | output/outrdf2.c | 10 |
22 files changed, 353 insertions, 299 deletions
diff --git a/asm/directiv.c b/asm/directiv.c index 66901530..46079b48 100644 --- a/asm/directiv.c +++ b/asm/directiv.c @@ -106,10 +106,8 @@ static iflag_t get_cpu(const char *value) break; } - if (!cpu->name) { - nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL, - "unknown 'cpu' type '%s'", value); - } + if (!cpu->name) + nasm_nonfatal("unknown 'cpu' type '%s'", value); iflag_set_cpu(&r, cpu->level); return r; @@ -135,9 +133,8 @@ static int get_bits(const char *value) } break; default: - nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL, - "`%s' is not a valid segment size; must be 16, 32 or 64", - value); + nasm_nonfatal("`%s' is not a valid segment size; must be 16, 32 or 64", + value); i = 16; break; } @@ -206,7 +203,6 @@ bool process_directives(char *directive) char *value, *p, *q, *special; struct tokenval tokval; bool bad_param = false; - int pass2 = passn > 1 ? 2 : 1; enum label_type type; d = parse_directive_line(&directive, &value); @@ -220,7 +216,7 @@ bool process_directives(char *directive) break; default: /* It's a backend-specific directive */ - switch (ofmt->directive(d, value, pass2)) { + switch (ofmt->directive(d, value)) { case DIRR_UNKNOWN: goto unknown; case DIRR_OK: @@ -236,19 +232,17 @@ bool process_directives(char *directive) case D_unknown: unknown: - nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, - "unrecognised directive [%s]", directive); + nasm_nonfatal("unrecognized directive [%s]", directive); break; case D_SEGMENT: /* [SEGMENT n] */ case D_SECTION: { int sb = globalbits; - int32_t seg = ofmt->section(value, pass2, &sb); + int32_t seg = ofmt->section(value, &sb); if (seg == NO_SEG) { - nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, - "segment name `%s' not recognized", value); + nasm_nonfatal("segment name `%s' not recognized", value); } else { globalbits = sb; switch_segment(seg); @@ -264,7 +258,7 @@ bool process_directives(char *directive) stdscan_reset(); stdscan_set(value); tokval.t_type = TOKEN_INVALID; - e = evaluate(stdscan, NULL, &tokval, NULL, pass2, NULL); + e = evaluate(stdscan, NULL, &tokval, NULL, true, NULL); if (e) { uint64_t align = e->value; @@ -374,22 +368,20 @@ bool process_directives(char *directive) stdscan_reset(); stdscan_set(value); tokval.t_type = TOKEN_INVALID; - e = evaluate(stdscan, NULL, &tokval, NULL, pass2, NULL); + e = evaluate(stdscan, NULL, &tokval, NULL, true, NULL); if (e) { - if (!is_reloc(e)) - nasm_error(pass0 == - 1 ? ERR_NONFATAL : ERR_PANIC, - "cannot use non-relocatable expression as " - "ABSOLUTE address"); - else { + if (!is_reloc(e)) { + nasm_nonfatal("cannot use non-relocatable expression as " + "ABSOLUTE address"); + } else { absolute.segment = reloc_seg(e); absolute.offset = reloc_value(e); } - } else if (passn == 1) + } else if (pass_first()) { absolute.offset = 0x100; /* don't go near zero in case of / */ - else - nasm_panic("invalid ABSOLUTE address " - "in pass two"); + } else { + nasm_nonfatal("invalid ABSOLUTE address"); + } in_absolute = true; location.segment = NO_SEG; location.offset = absolute.offset; @@ -419,17 +411,15 @@ bool process_directives(char *directive) *q = 0; } if (badid) { - nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC, - "identifier expected after DEBUG"); + nasm_nonfatal("identifier expected after DEBUG"); break; } if (overlong) { - nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC, - "DEBUG identifier too long"); + nasm_nonfatal("DEBUG identifier too long"); break; } p = nasm_skip_spaces(p); - if (pass0 == 2) + if (pass_final()) dfmt->debug_directive(debugid, p); break; } @@ -484,8 +474,7 @@ bool process_directives(char *directive) case D_FLOAT: if (float_option(value)) { - nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, - "unknown 'float' directive: %s", value); + nasm_nonfatal("unknown 'float' directive: %s", value); } break; @@ -69,7 +69,7 @@ static int tempexpr_size; static struct tokenval *tokval; /* The current token */ static int tt; /* The t_type of tokval */ -static int critical; +static bool critical; static int *opflags; static struct eval_hints *hint; @@ -978,21 +978,17 @@ static expr *expr6(void) } else { if (!lookup_label(tokval->t_charptr, &label_seg, &label_ofs)) { scope = local_scope(tokval->t_charptr); - if (critical == 2) { - nasm_nonfatal("symbol `%s%s' undefined", - scope,tokval->t_charptr); + if (critical) { + nasm_nonfatal("symbol `%s%s' not defined%s", + scope,tokval->t_charptr, + pass_first() ? " before use" : ""); return NULL; - } else if (critical == 1) { - nasm_nonfatal("symbol `%s%s' not defined before use", - scope,tokval->t_charptr); - return NULL; - } else { - if (opflags) - *opflags |= OPFLAG_FORWARD; - type = EXPR_UNKNOWN; - label_seg = NO_SEG; - label_ofs = 1; } + if (opflags) + *opflags |= OPFLAG_FORWARD; + type = EXPR_UNKNOWN; + label_seg = NO_SEG; + label_ofs = 1; } if (opflags && is_extern(tokval->t_charptr)) *opflags |= OPFLAG_EXTERN; @@ -1015,7 +1011,7 @@ static expr *expr6(void) } expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, - int *fwref, int crit, struct eval_hints *hints) + int *fwref, bool crit, struct eval_hints *hints) { expr *e; expr *f = NULL; @@ -1026,7 +1022,7 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, if (hint) hint->type = EAH_NOHINT; - critical = crit & ~CRITICAL; + critical = crit; scanfunc = sc; scpriv = scprivate; tokval = tv; @@ -42,7 +42,7 @@ * The evaluator itself. */ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, - int *fwref, int critical, struct eval_hints *hints); + int *fwref, bool critical, struct eval_hints *hints); void eval_cleanup(void); diff --git a/asm/labels.c b/asm/labels.c index 3cbded11..93eaa2de 100644 --- a/asm/labels.c +++ b/asm/labels.c @@ -156,7 +156,7 @@ static void out_symdef(union label *lptr) int64_t backend_offset; /* Backend-defined special segments are passed to symdef immediately */ - if (pass0 == 2) { + if (pass_final()) { /* Emit special fixups for globals and commons */ switch (lptr->defn.type) { case LBL_GLOBAL: @@ -171,7 +171,7 @@ static void out_symdef(union label *lptr) return; } - if (pass0 != 1 && lptr->defn.type != LBL_BACKEND) + if (pass_type() != PASS_STAB && lptr->defn.type != LBL_BACKEND) return; /* Clean up this hack... */ @@ -383,7 +383,7 @@ static bool declare_label_lptr(union label *lptr, special = NULL; if (lptr->defn.type == type || - (pass0 == 0 && lptr->defn.type == LBL_LOCAL)) { + (!pass_stable() && lptr->defn.type == LBL_LOCAL)) { lptr->defn.type = type; if (special) { if (!lptr->defn.special) @@ -435,13 +435,14 @@ void define_label(const char *label, int32_t segment, union label *lptr; bool created, changed; int64_t size; - int64_t lastdef; + int64_t lpass, lastdef; /* - * The backend may invoke this before pass 1, so treat that as - * a special "pass". + * The backend may invoke this during initialization, at which + * pass_count() is zero, so add one so we never have a zero value + * for a defined variable. */ - const int64_t lpass = passn + 1; + lpass = pass_count() + 1; /* * Phase errors here can be one of two types: a new label appears, @@ -521,7 +522,7 @@ void define_label(const char *label, int32_t segment, nasm_error(noteflags, "label `%s' originally defined", lptr->defn.label); src_set(saved_line, saved_fname); - } else if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) { + } else if (changed && pass_final() && lptr->defn.type != LBL_SPECIAL) { /*! *!label-redef-late [err] label (re)defined during code generation *! the value of a label changed during the final, code-generation @@ -102,9 +102,12 @@ static bool abort_on_panic = ABORT_ON_PANIC; static bool keep_all; bool tasm_compatible_mode = false; -int pass0; -int64_t passn; -static int pass1, pass2; /* XXX: Get rid of these, they are redundant */ +enum pass_type _pass_type; +const char * const _pass_types[] = +{ + "init", "first", "optimize", "stabilize", "final" +}; +int64_t _passn; int globalrel = 0; int globalbnd = 0; @@ -117,7 +120,6 @@ static const char *errname; static int64_t globallineno; /* for forward-reference tracking */ -/* static int pass = 0; */ const struct ofmt *ofmt = &OF_DEFAULT; const struct ofmt_alias *ofmt_alias = NULL; const struct dfmt *dfmt; @@ -201,7 +203,7 @@ nasm_set_limit(const char *limit, const char *valstr) break; } if (i > LIMIT_MAX) { - if (passn == 0) + if (not_started()) errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE; else errlevel = ERR_WARNING|ERR_PASS1|WARN_UNKNOWN_PRAGMA; @@ -214,7 +216,7 @@ nasm_set_limit(const char *limit, const char *valstr) } else { val = readnum(valstr, &rn_error); if (rn_error || val < 0) { - if (passn == 0) + if (not_started()) errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE; else errlevel = ERR_WARNING|ERR_PASS1|WARN_BAD_PRAGMA; @@ -460,7 +462,9 @@ int main(int argc, char **argv) include_path = strlist_alloc(true); - pass0 = 0; + _pass_type = PASS_INIT; + _passn = 0; + want_usage = terminate_after_phase = false; nasm_set_verror(nasm_verror_asm); @@ -546,11 +550,11 @@ int main(int argc, char **argv) if (depend_missing_ok) preproc->include_path(NULL); /* "assume generated" */ - preproc->reset(inname, 0, depend_list); + preproc->reset(inname, PP_DEPS, depend_list); ofile = NULL; while ((line = preproc->getline())) nasm_free(line); - preproc->cleanup(0); + preproc->cleanup_pass(); } else if (operating_mode & OP_PREPROCESS) { char *line; const char *file_name = NULL; @@ -566,8 +570,8 @@ int main(int argc, char **argv) location.known = false; - /* pass = 1; */ - preproc->reset(inname, 3, depend_list); + _pass_type = PASS_FIRST; /* We emulate this assembly pass */ + preproc->reset(inname, PP_PREPROC, depend_list); /* Revert all warnings to the default state */ memcpy(warning_state, warning_state_init, sizeof warning_state); @@ -592,7 +596,7 @@ int main(int argc, char **argv) nasm_fputs(line, ofile); nasm_free(line); } - preproc->cleanup(0); + preproc->cleanup_pass(); if (ofile) fclose(ofile); if (ofile && terminate_after_phase && !keep_all) @@ -626,6 +630,8 @@ int main(int argc, char **argv) } } + preproc->cleanup_session(); + if (depend_list && !terminate_after_phase) emit_dependencies(depend_list); @@ -1428,35 +1434,38 @@ static void assemble_file(const char *fname, struct strlist *depend_list) break; } - prev_offset_changed = nasm_limit[LIMIT_PASSES]; - for (passn = 1; pass0 <= 2; passn++) { - pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */ - pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */ - /* pass0 0, 0, 0, ..., 1, 2 */ + prev_offset_changed = INT64_MAX; - /* - * Create a warning buffer list unless we are in pass 2 (everything will be - * emitted immediately in pass 2.) - */ - if (warn_list) { - if (warn_list->nstr || pass0 == 2) + if (listname && !keep_all) { + /* Remove the list file in case we die before the output pass */ + remove(listname); + } + + while (!terminate_after_phase && !pass_final()) { + _passn++; + if (pass_type() != PASS_OPT || !global_offset_changed) + _pass_type++; + global_offset_changed = 0; + + /* + * Create a warning buffer list unless we are in + * pass 2 (everything will be emitted immediately in pass 2.) + */ + if (warn_list) { + if (warn_list->nstr || pass_final()) strlist_free(&warn_list); } - if (pass0 < 2 && !warn_list) + if (!pass_final() && !warn_list) warn_list = strlist_alloc(false); globalbits = cmd_sb; /* set 'bits' to command line default */ cpu = cmd_cpu; - if (pass0 == 2) { - lfmt->init(listname); - } else if (passn == 1 && listname && !keep_all) { - /* Remove the list file in case we die before the output pass */ - remove(listname); - } + if (pass_final()) + lfmt->init(listname); + in_absolute = false; - global_offset_changed = 0; /* set by redefine_label */ - if (passn > 1) { + if (!pass_first()) { saa_rewind(forwrefs); forwref = saa_rstruct(forwrefs); raa_free(offsets); @@ -1464,11 +1473,11 @@ static void assemble_file(const char *fname, struct strlist *depend_list) } location.segment = NO_SEG; location.offset = 0; - if (passn == 1) + if (pass_first()) location.known = true; ofmt->reset(); - switch_segment(ofmt->section(NULL, pass2, &globalbits)); - preproc->reset(fname, pass1, pass1 == 2 ? depend_list : NULL); + switch_segment(ofmt->section(NULL, &globalbits)); + preproc->reset(fname, PP_NORMAL, pass_final() ? depend_list : NULL); /* Revert all warnings to the default state */ memcpy(warning_state, warning_state_init, sizeof warning_state); @@ -1488,7 +1497,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list) goto end_of_line; /* Just do final cleanup */ /* Not a directive, or even something that starts with [ */ - parse_line(pass1, line, &output_ins); + parse_line(line, &output_ins); if (optimizing.level > 0) { if (forwref != NULL && globallineno == forwref->lineno) { @@ -1502,7 +1511,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list) output_ins.forw_ref = false; if (output_ins.forw_ref) { - if (passn == 1) { + if (pass_first()) { for (i = 0; i < output_ins.operands; i++) { if (output_ins.oprs[i].opflags & OPFLAG_FORWARD) { struct forwrefinfo *fwinf = (struct forwrefinfo *)saa_wstruct(forwrefs); @@ -1544,7 +1553,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list) nasm_assert(output_ins.times >= 0); for (n = 1; n <= output_ins.times; n++) { - if (pass1 == 1) { + if (!pass_final()) { int64_t l = insn_size(location.segment, location.offset, globalbits, &output_ins); @@ -1653,9 +1662,38 @@ static void assemble_file(const char *fname, struct strlist *depend_list) nasm_free(line); } /* end while (line = preproc->getline... */ - if (global_offset_changed && !terminate_after_phase) { - switch (pass0) { - case 1: + preproc->cleanup_pass(); + + /* Don't output further messages if we are dead anyway */ + if (terminate_after_phase) + break; + + if (global_offset_changed) { + switch (pass_type()) { + case PASS_OPT: + /* + * This is the only pass type that can be executed more + * than once, and therefore has the ability to stall. + */ + if (global_offset_changed < prev_offset_changed) { + prev_offset_changed = global_offset_changed; + stall_count = 0; + } else { + stall_count++; + } + + if (stall_count > nasm_limit[LIMIT_STALLED] || + pass_count() >= nasm_limit[LIMIT_PASSES]) { + /* No convergence, almost certainly dead */ + nasm_nonfatal("unable to find valid values for all labels " + "after %"PRId64" passes; " + "stalled for %"PRId64", giving up.", + pass_count(), stall_count); + nasm_note("Possible causes: recursive EQUs, macro abuse."); + } + break; + + case PASS_STAB: /*! *!phase [off] phase error during stabilization *! warns about symbols having changed values during @@ -1663,10 +1701,10 @@ static void assemble_file(const char *fname, struct strlist *depend_list) *! inherently fatal, but may be a source of bugs. */ nasm_warn(WARN_PHASE, "phase error during stabilization " - "pass, hoping for the best"); + "pass, hoping for the best"); break; - case 2: + case PASS_FINAL: nasm_nonfatal("phase error during code generation pass"); break; @@ -1675,51 +1713,16 @@ static void assemble_file(const char *fname, struct strlist *depend_list) break; } } + } - if (pass1 == 1) - preproc->cleanup(1); - - /* - * Always run at least two optimization passes (pass0 == 0); - * things like subsections will fail miserably without that. - * Once we commit to a stabilization pass (pass0 == 1), we can't - * go back, and if something goes bad, we can only hope - * that we don't end up with a phase error at the end. - */ - if ((passn > 1 && !global_offset_changed) || pass0 > 0) { - pass0++; - } else if (global_offset_changed && - global_offset_changed < prev_offset_changed) { - prev_offset_changed = global_offset_changed; - stall_count = 0; - } else { - stall_count++; - } - - if (terminate_after_phase) - break; - - if ((stall_count > nasm_limit[LIMIT_STALLED]) || - (passn >= nasm_limit[LIMIT_PASSES])) { - /* We get here if the labels don't converge - * Example: FOO equ FOO + 1 - */ - nasm_nonfatal("Can't find valid values for all labels " - "after %"PRId64" passes, giving up.", passn); - nasm_note("Possible causes: recursive EQUs, macro abuse."); - break; - } + if (opt_verbose_info && pass_final()) { + /* -On and -Ov switches */ + nasm_note("info: assembly required 1+%"PRId64"+2 passes\n", + pass_count()-3); } strlist_free(&warn_list); - preproc->cleanup(0); lfmt->cleanup(); - - if (!terminate_after_phase && opt_verbose_info) { - /* -On and -Ov switches */ - fprintf(stdout, "info: assembly required 1+%"PRId64"+1 passes\n", - passn-3); - } } /** @@ -1752,12 +1755,10 @@ static bool skip_this_pass(errflags severity) return false; /* - * passn is 1 on the very first pass only. - * pass0 is 2 on the code-generation (final) pass only. - * These are the passes we care about in this case. + * Let's get rid of these flags when and if we can... */ - return (((severity & ERR_PASS1) && passn != 1) && - ((severity & ERR_PASS2) && pass0 != 2)); + return ((severity & ERR_PASS1) && !pass_first()) || + ((severity & ERR_PASS2) && !pass_final()); } /** diff --git a/asm/parser.c b/asm/parser.c index 74ea77c9..9c96732d 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -415,12 +415,12 @@ static int value_to_extop(expr * vect, extop *eop, int32_t myseg) return 0; } -insn *parse_line(int pass, char *buffer, insn *result) +insn *parse_line(char *buffer, insn *result) { bool insn_is_label = false; struct eval_hints hints; int opnum; - int critical; + bool critical; bool first; bool recover; int i; @@ -501,7 +501,7 @@ restart_parse: expr *value; i = stdscan(NULL, &tokval); - value = evaluate(stdscan, NULL, &tokval, NULL, pass0, NULL); + value = evaluate(stdscan, NULL, &tokval, NULL, pass_stable(), NULL); i = tokval.t_type; if (!value) /* Error in evaluator */ goto fail; @@ -566,11 +566,7 @@ restart_parse: * `critical' flag on calling evaluate(), so that it will bomb * out on undefined symbols. */ - if (result->opcode == I_INCBIN) { - critical = (pass0 < 2 ? 1 : 2); - - } else - critical = (pass == 2 ? 2 : 0); + critical = pass_final() || (result->opcode == I_INCBIN); if (opcode_is_db(result->opcode) || result->opcode == I_INCBIN) { extop *eop, **tail = &result->eops, **fixptr; diff --git a/asm/parser.h b/asm/parser.h index cd2d1362..15298cb0 100644 --- a/asm/parser.h +++ b/asm/parser.h @@ -39,7 +39,7 @@ #ifndef NASM_PARSER_H #define NASM_PARSER_H -insn *parse_line(int pass, char *buffer, insn *result); +insn *parse_line(char *buffer, insn *result); void cleanup_insn(insn *instruction); #endif diff --git a/asm/preproc-nop.c b/asm/preproc-nop.c index 4aba059c..3d77dd52 100644 --- a/asm/preproc-nop.c +++ b/asm/preproc-nop.c @@ -63,15 +63,17 @@ static void nop_init(void) /* Nothing to do */ } -static void nop_reset(const char *file, int pass, struct strlist *deplist) +static void nop_reset(const char *file, enum preproc_mode mode, + struct strlist *deplist) { + (void)mode; /* placate compilers */ + src_set(0, file); nop_lineinc = 1; nop_fp = nasm_open_read(file, NF_TEXT); if (!nop_fp) nasm_fatalf(ERR_NOFILE, "unable to open input file `%s'", file); - (void)pass; /* placate compilers */ strlist_add(deplist, file); } @@ -136,15 +138,19 @@ static char *nop_getline(void) return buffer; } -static void nop_cleanup(int pass) +static void nop_cleanup_pass(void) { - (void)pass; /* placate GCC */ if (nop_fp) { fclose(nop_fp); nop_fp = NULL; } } +static void nop_cleanup_session(void) +{ + /* Nothing we need to do */ +} + static void nop_extra_stdmac(macros_t *macros) { (void)macros; @@ -185,7 +191,8 @@ const struct preproc_ops preproc_nop = { nop_init, nop_reset, nop_getline, - nop_cleanup, + nop_cleanup_pass, + nop_cleanup_session, nop_extra_stdmac, nop_pre_define, nop_pre_undefine, diff --git a/asm/preproc.c b/asm/preproc.c index ff3a567b..9e1d2f44 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -388,13 +388,13 @@ static Context *cstk; static Include *istk; static const struct strlist *ipath_list; -static int pass; /* HACK: pass 0 = generate dependencies only */ static struct strlist *deplist; static uint64_t unique; /* unique identifier numbers */ static Line *predef = NULL; static bool do_predef; +static enum preproc_mode pp_mode; /* * The current set of multi-line macros we have defined. @@ -1966,8 +1966,7 @@ iftype: t = tline = expand_smacro(tline); tptr = &t; tokval.t_type = TOKEN_INVALID; - evalresult = evaluate(ppscan, tptr, &tokval, - NULL, pass | CRITICAL, NULL); + evalresult = evaluate(ppscan, tptr, &tokval, NULL, true, NULL); if (!evalresult) return -1; if (tokval.t_type) @@ -2559,7 +2558,8 @@ static int do_directive(Token *tline, char **output) inc->conds = NULL; found_path = NULL; inc->fp = inc_fopen(p, deplist, &found_path, - pass == 0 ? INC_OPTIONAL : INC_NEEDED, NF_TEXT); + (pp_mode == PP_DEPS) + ? INC_OPTIONAL : INC_NEEDED, NF_TEXT); if (!inc->fp) { /* -MG given but file not found */ nasm_free(inc); @@ -2672,7 +2672,7 @@ static int do_directive(Token *tline, char **output) issue_error: { /* Only error out if this is the final pass */ - if (pass != 2 && i != PP_FATAL) + if (pass_final() && i != PP_FATAL) return DIRECTIVE_FOUND; tline->next = expand_smacro(tline->next); @@ -2913,7 +2913,7 @@ issue_error: tptr = &t; tokval.t_type = TOKEN_INVALID; evalresult = - evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + evaluate(ppscan, tptr, &tokval, NULL, true, NULL); free_tlist(tline); if (!evalresult) return DIRECTIVE_FOUND; @@ -2960,7 +2960,7 @@ issue_error: tptr = &t; tokval.t_type = TOKEN_INVALID; evalresult = - evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + evaluate(ppscan, tptr, &tokval, NULL, true, NULL); if (!evalresult) { free_tlist(origline); return DIRECTIVE_FOUND; @@ -3461,7 +3461,7 @@ issue_error: tt = t->next; tptr = &tt; tokval.t_type = TOKEN_INVALID; - evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + evalresult = evaluate(ppscan, tptr, &tokval, NULL, true, NULL); if (!evalresult) { free_tlist(tline); free_tlist(origline); @@ -3480,7 +3480,7 @@ issue_error: count = 1; /* Backwards compatibility: one character */ } else { tokval.t_type = TOKEN_INVALID; - evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + evalresult = evaluate(ppscan, tptr, &tokval, NULL, true, NULL); if (!evalresult) { free_tlist(tline); free_tlist(origline); @@ -3546,7 +3546,7 @@ issue_error: t = tline; tptr = &t; tokval.t_type = TOKEN_INVALID; - evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + evalresult = evaluate(ppscan, tptr, &tokval, NULL, true, NULL); free_tlist(tline); if (!evalresult) { free_tlist(origline); @@ -4896,9 +4896,10 @@ static void pp_verror(errflags severity, const char *fmt, va_list arg) } static void -pp_reset(const char *file, int apass, struct strlist *dep_list) +pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list) { Token *t; + int apass; cstk = NULL; istk = nasm_malloc(sizeof(Include)); @@ -4918,6 +4919,7 @@ pp_reset(const char *file, int apass, struct strlist *dep_list) init_macros(); unique = 0; deplist = dep_list; + pp_mode = mode; if (tasm_compatible_mode) pp_add_stdmac(nasm_stdmac_tasm); @@ -4933,20 +4935,32 @@ pp_reset(const char *file, int apass, struct strlist *dep_list) do_predef = true; - /* - * 0 for dependencies, 1 for preparatory passes, 2 for final pass. - * The caller, however, will also pass in 3 for preprocess-only so - * we can set __PASS__ accordingly. - */ - pass = apass > 2 ? 2 : apass; - strlist_add(deplist, file); /* * Define the __PASS__ macro. This is defined here unlike * all the other builtins, because it is special -- it varies between * passes. + * + * 0 = dependencies only + * 1 = preparatory passes + * 2 = final pass + * 3 = preproces only */ + switch (mode) { + case PP_NORMAL: + apass = pass_final() ? 2 : 1; + break; + case PP_DEPS: + apass = 0; + break; + case PP_PREPROC: + apass = 3; + break; + default: + panic(); + } + t = nasm_malloc(sizeof(*t)); t->next = NULL; make_tok_num(t, apass); @@ -5187,7 +5201,7 @@ done: return line; } -static void pp_cleanup(int pass) +static void pp_cleanup_pass(void) { real_verror = nasm_set_verror(pp_verror); @@ -5217,13 +5231,15 @@ static void pp_cleanup(int pass) while (cstk) ctx_pop(); src_set_fname(NULL); - if (pass == 0) { - free_llist(predef); - predef = NULL; - delete_Blocks(); - freeTokens = NULL; - ipath_list = NULL; - } +} + +static void pp_cleanup_session(void) +{ + free_llist(predef); + predef = NULL; + delete_Blocks(); + freeTokens = NULL; + ipath_list = NULL; } static void pp_include_path(struct strlist *list) @@ -5373,7 +5389,8 @@ const struct preproc_ops nasmpp = { pp_init, pp_reset, pp_getline, - pp_cleanup, + pp_cleanup_pass, + pp_cleanup_session, pp_extra_stdmac, pp_pre_define, pp_pre_undefine, diff --git a/include/nasm.h b/include/nasm.h index ba015aec..eb376b16 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -330,6 +330,13 @@ typedef expr *(*evalfunc)(scanner sc, void *scprivate, /* * preprocessors ought to look like this: */ + +enum preproc_mode { + PP_NORMAL, /* Assembly */ + PP_DEPS, /* Dependencies only */ + PP_PREPROC /* Preprocessing only */ +}; + struct preproc_ops { /* * Called once at the very start of assembly. @@ -341,7 +348,8 @@ struct preproc_ops { * of the pass, an error reporting function, an evaluator * function, and a listing generator to talk to. */ - void (*reset)(const char *file, int pass, struct strlist *deplist); + void (*reset)(const char *file, enum preproc_mode mode, + struct strlist *deplist); /* * Called to fetch a line of preprocessed source. The line @@ -350,8 +358,15 @@ struct preproc_ops { */ char *(*getline)(void); - /* Called at the end of a pass */ - void (*cleanup)(int pass); + /* Called at the end of each pass. */ + void (*cleanup_pass)(void); + + /* + * Called at the end of the assembly session, + * after cleanup_pass() has been called for the + * last pass. + */ + void (*cleanup_session)(void); /* Additional macros specific to output format */ void (*extra_stdmac)(macros_t *macros); @@ -874,7 +889,7 @@ struct ofmt { * the segment, by setting `*bits' to 16 or 32. Or, if it * doesn't wish to define a default, it can leave `bits' alone. */ - int32_t (*section)(char *name, int pass, int *bits); + int32_t (*section)(char *name, int *bits); /* * This function is called when a label is defined @@ -919,8 +934,7 @@ struct ofmt { * This procedure is called to allow the output driver to * process its own specific directives. When called, it has the * directive word in `directive' and the parameter string in - * `value'. It is called in both assembly passes, and `pass' - * will be either 1 or 2. + * `value'. * * The following values are (currently) possible for * directive_result: @@ -932,7 +946,7 @@ struct ofmt { * "invalid parameter to [*] directive" */ enum directive_result - (*directive)(enum directive directive, char *value, int pass); + (*directive)(enum directive directive, char *value); /* * This procedure is called after assembly finishes, to allow @@ -1214,14 +1228,6 @@ enum decorator_tokens { * Global modes */ -/* - * This declaration passes the "pass" number to all other modules - * "pass0" assumes the values: 0, 0, ..., 0, 1, 2 - * where 0 = optimizing pass - * 1 = pass 1 - * 2 = pass 2 - */ - /* * flag to disable optimizations selectively * this is useful to turn-off certain optimizations @@ -1236,8 +1242,57 @@ struct optimization { int flag; }; -extern int pass0; -extern int64_t passn; /* Actual pass number */ +/* + * Various types of compiler passes we may execute. + */ +enum pass_type { + PASS_INIT, /* Initialization, not doing anything yet */ + PASS_FIRST, /* The very first pass over the code */ + PASS_OPT, /* Optimization pass */ + PASS_STAB, /* Stabilization pass (original pass 1) */ + PASS_FINAL /* Code generation pass (original pass 2) */ +}; +extern const char * const _pass_types[]; +extern enum pass_type _pass_type; +static inline enum pass_type pass_type(void) +{ + return _pass_type; +} +static inline const char *pass_type_name(void) +{ + return _pass_types[_pass_type]; +} +/* True during initialization, no code read yet */ +static inline bool not_started(void) +{ + return pass_type() == PASS_INIT; +} +/* True for the initial pass and setup (old "pass2 < 2") */ +static inline bool pass_first(void) +{ + return pass_type() <= PASS_FIRST; +} +/* At this point we better have stable definitions */ +static inline bool pass_stable(void) +{ + return pass_type() >= PASS_STAB; +} +/* True for the code generation pass only, (old "pass1 >= 2") */ +static inline bool pass_final(void) +{ + return pass_type() >= PASS_FINAL; +} + +/* + * The actual pass number. 0 is used during initialization, the very + * first pass is 1, and then it is simply increasing numbers until we are + * done. + */ +extern int64_t _passn; /* Actual pass number */ +static inline int64_t pass_count(void) +{ + return _passn; +} extern struct optimization optimizing; extern int globalbits; /* 16, 32 or 64-bit mode */ diff --git a/output/nullout.c b/output/nullout.c index ad451e8b..121fe70b 100644 --- a/output/nullout.c +++ b/output/nullout.c @@ -36,11 +36,10 @@ #include "outlib.h" enum directive_result -null_directive(enum directive directive, char *value, int pass) +null_directive(enum directive directive, char *value) { (void)directive; (void)value; - (void)pass; return DIRR_UNKNOWN; } diff --git a/output/outaout.c b/output/outaout.c index 4eca36db..61f21119 100644 --- a/output/outaout.c +++ b/output/outaout.c @@ -236,11 +236,8 @@ static void aout_cleanup(void) saa_free(strs); } -static int32_t aout_section_names(char *name, int pass, int *bits) +static int32_t aout_section_names(char *name, int *bits) { - - (void)pass; - /* * Default to 32 bits. */ diff --git a/output/outas86.c b/output/outas86.c index 4d2a92ab..eed0396d 100644 --- a/output/outas86.c +++ b/output/outas86.c @@ -159,11 +159,8 @@ static void as86_cleanup(void) saa_free(strs); } -static int32_t as86_section_names(char *name, int pass, int *bits) +static int32_t as86_section_names(char *name, int *bits) { - - (void)pass; - /* * Default is 16 bits. */ diff --git a/output/outbin.c b/output/outbin.c index 5e0dbdbc..4bf13fa4 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -1202,7 +1202,7 @@ static void bin_define_section_labels(void) labels_defined = 1; } -static int32_t bin_secname(char *name, int pass, int *bits) +static int32_t bin_secname(char *name, int *bits) { char *p; struct Section *sec; @@ -1211,14 +1211,15 @@ static int32_t bin_secname(char *name, int pass, int *bits) * pass. Use this opportunity to establish the default section * (default is BITS-16 ".text" segment). */ - if (!name) { /* Reset ORG and section attributes at the start of each pass. */ + if (!name) { + /* Reset ORG and section attributes at the start of each pass. */ origin_defined = 0; list_for_each(sec, sections) sec->flags &= ~(START_DEFINED | VSTART_DEFINED | ALIGN_DEFINED | VALIGN_DEFINED); /* Define section start and vstart labels. */ - if (pass != 1) + if (!pass_first()) bin_define_section_labels(); /* Establish the default (.text) section. */ @@ -1247,14 +1248,14 @@ static int32_t bin_secname(char *name, int pass, int *bits) } /* Handle attribute assignments. */ - if (pass != 1) + if (!pass_first()) bin_assign_attributes(sec, p); #ifndef ABIN_SMART_ADAPT /* The following line disables smart adaptation of * PROGBITS/NOBITS section types (it forces sections to * default to PROGBITS). */ - if ((pass != 1) && !(sec->flags & TYPE_DEFINED)) + if (!pass_first() && !(sec->flags & TYPE_DEFINED)) sec->flags |= TYPE_DEFINED | TYPE_PROGBITS; #endif @@ -1262,7 +1263,7 @@ static int32_t bin_secname(char *name, int pass, int *bits) } static enum directive_result -bin_directive(enum directive directive, char *args, int pass) +bin_directive(enum directive directive, char *args) { switch (directive) { case D_ORG: @@ -1300,7 +1301,7 @@ bin_directive(enum directive directive, char *args, int pass) * and symbol information to stdout, stderr, or to a file. */ char *p; - if (pass != 1) + if (!pass_first()) return DIRR_OK; args += strspn(args, " \t"); while (*args) { diff --git a/output/outcoff.c b/output/outcoff.c index 3979d93f..a90e355e 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -291,7 +291,7 @@ static inline int32_t coff_sectalign_flags(unsigned int align) return (ilog2_32(align) + 1) << 20; } -static int32_t coff_section_names(char *name, int pass, int *bits) +static int32_t coff_section_names(char *name, int *bits) { char *p; uint32_t flags, align_and = ~0L, align_or = 0L; @@ -402,7 +402,7 @@ static int32_t coff_section_names(char *name, int pass, int *bits) coff_sects[i]->flags = flags; coff_sects[i]->flags &= align_and; coff_sects[i]->flags |= align_or; - } else if (pass == 1) { + } else if (pass_first()) { /* Check if any flags are specified */ if (flags) { unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK; @@ -566,7 +566,7 @@ static void coff_out(int32_t segto, const void *data, } if (!s) { int tempint; /* ignored */ - if (segto != coff_section_names(".text", 2, &tempint)) + if (segto != coff_section_names(".text", &tempint)) nasm_panic("strange segment conditions in COFF driver"); else s = coff_sects[coff_nsects - 1]; @@ -751,14 +751,21 @@ static void BuildExportTable(STRING **rvp) } static enum directive_result -coff_directives(enum directive directive, char *value, int pass) +coff_directives(enum directive directive, char *value) { switch (directive) { case D_EXPORT: { char *q, *name; - if (pass == 2) + /* + * XXX: pass_first() is really wrong here, but AddExport() + * needs to be modified to handle duplicate calls for the + * same value in order to change that. The right thing to do + * is probably to mark a label as an export in the label + * structure, in case the label doesn't actually exist. + */ + if (!pass_first()) return DIRR_OK; /* ignore in pass two */ name = q = value; while (*q && !nasm_isspace(*q)) @@ -798,10 +805,10 @@ coff_directives(enum directive directive, char *value, int pass) sxseg = i; } /* - * pass0 == 2 is the only time when the full set of symbols are - * guaranteed to be present; it is the final output pass. + * pass_final() is the only time when the full set of symbols are + * guaranteed to be present as it is the final output pass. */ - if (pass0 == 2) { + if (pass_final()) { uint32_t n; saa_rewind(coff_syms); for (n = 0; n < coff_nsyms; n++) { diff --git a/output/outdbg.c b/output/outdbg.c index b5496b98..e5f15ef7 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -75,8 +75,8 @@ static void dbg_init(void) static void dbg_reset(void) { - fprintf(ofile, "*** pass reset: pass0 = %d, passn = %"PRId64"\n", - pass0, passn); + fprintf(ofile, "*** pass reset: pass = %"PRId64" (%s)\n", + pass_count(), pass_type_name()); } static void dbg_cleanup(void) @@ -90,8 +90,7 @@ static void dbg_cleanup(void) } } -static int32_t dbg_add_section(char *name, int pass, int *bits, - const char *whatwecallit) +static int32_t dbg_add_section(char *name, int *bits, const char *whatwecallit) { int seg; @@ -121,8 +120,8 @@ static int32_t dbg_add_section(char *name, int pass, int *bits, s->number = seg = seg_alloc(); s->next = dbgsect; dbgsect = s; - fprintf(ofile, "%s %s (%s) pass %d: returning %d\n", - whatwecallit, name, tail, pass, seg); + fprintf(ofile, "%s %s (%s) pass %"PRId64" (%s) : returning %d\n", + whatwecallit, name, tail, pass_count(), pass_type_name(), seg); if (section_labels) backend_label(s->name, s->number + 1, 0); @@ -131,9 +130,9 @@ static int32_t dbg_add_section(char *name, int pass, int *bits, return seg; } -static int32_t dbg_section_names(char *name, int pass, int *bits) +static int32_t dbg_section_names(char *name, int *bits) { - return dbg_add_section(name, pass, bits, "section_names"); + return dbg_add_section(name, bits, "section_names"); } static int32_t dbg_herelabel(const char *name, enum label_type type, @@ -323,7 +322,7 @@ static void dbg_sectalign(int32_t seg, unsigned int value) } static enum directive_result -dbg_directive(enum directive directive, char *value, int pass) +dbg_directive(enum directive directive, char *value) { switch (directive) { /* @@ -334,7 +333,7 @@ dbg_directive(enum directive directive, char *value, int pass) case D_GROUP: { int dummy; - dbg_add_section(value, pass, &dummy, "directive:group"); + dbg_add_section(value, &dummy, "directive:group"); break; } @@ -342,8 +341,8 @@ dbg_directive(enum directive directive, char *value, int pass) break; } - fprintf(ofile, "directive [%s] value [%s] (pass %d)\n", - directive_dname(directive), value, pass); + fprintf(ofile, "directive [%s] value [%s] pass %"PRId64" (%s)\n", + directive_dname(directive), value, pass_count(), pass_type_name()); return DIRR_OK; } diff --git a/output/outelf.c b/output/outelf.c index 2f609c83..cd77901f 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -209,7 +209,7 @@ const struct elf_known_section elf_known_sections[] = { }; /* parse section attributes */ -static void elf_section_attrib(char *name, char *attr, int pass, +static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint32_t *flags_or, uint64_t *align, int *type) { @@ -258,7 +258,7 @@ static void elf_section_attrib(char *name, char *attr, int pass, *type = SHT_PROGBITS; } else if (!nasm_stricmp(opt, "nobits")) { *type = SHT_NOBITS; - } else if (pass == 1) { + } else if (pass_first()) { nasm_warn(WARN_OTHER, "Unknown section attribute '%s' ignored on" " declaration of section `%s'", opt, name); } @@ -267,7 +267,7 @@ static void elf_section_attrib(char *name, char *attr, int pass, } static enum directive_result -elf_directive(enum directive directive, char *value, int pass) +elf_directive(enum directive directive, char *value) { int64_t n; bool err; @@ -275,8 +275,8 @@ elf_directive(enum directive directive, char *value, int pass) switch (directive) { case D_OSABI: - if (pass == 2) - return DIRR_OK; /* ignore in pass 2 */ + if (!pass_first()) /* XXX: Why? */ + return DIRR_OK; n = readnum(value, &err); if (err) { @@ -413,7 +413,7 @@ static int elf_make_section(char *name, int type, int flags, int align) return nsects - 1; } -static int32_t elf_section_names(char *name, int pass, int *bits) +static int32_t elf_section_names(char *name, int *bits) { char *p; uint32_t flags, flags_and, flags_or; @@ -430,7 +430,7 @@ static int32_t elf_section_names(char *name, int pass, int *bits) *p++ = '\0'; flags_and = flags_or = type = align = 0; - elf_section_attrib(name, p, pass, &flags_and, + elf_section_attrib(name, p, &flags_and, &flags_or, &align, &type); if (!strcmp(name, ".shstrtab") || @@ -458,7 +458,7 @@ static int32_t elf_section_names(char *name, int pass, int *bits) flags = (ks->flags & ~flags_and) | flags_or; i = elf_make_section(name, type, flags, align); - } else if (pass == 1) { + } else if (pass_first()) { if ((type && sects[i]->type != type) || (align && sects[i]->align != align) || (flags_and && ((sects[i]->flags & flags_and) != flags_or))) @@ -549,7 +549,7 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, if (segment == def_seg) { /* we have to be sure at least text section is there */ int tempint; - if (segment != elf_section_names(".text", 2, &tempint)) + if (segment != elf_section_names(".text", &tempint)) nasm_panic("strange segment conditions in ELF driver"); } for (i = 0; i < nsects; i++) { @@ -803,7 +803,7 @@ static void elf32_out(int32_t segto, const void *data, } if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) + if (segto != elf_section_names(".text", &tempint)) nasm_panic("strange segment conditions in ELF driver"); else { s = sects[nsects - 1]; @@ -1014,7 +1014,7 @@ static void elf64_out(int32_t segto, const void *data, } if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) + if (segto != elf_section_names(".text", &tempint)) nasm_panic("strange segment conditions in ELF driver"); else { s = sects[nsects - 1]; @@ -1292,7 +1292,7 @@ static void elfx32_out(int32_t segto, const void *data, } if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) + if (segto != elf_section_names(".text", &tempint)) nasm_panic("strange segment conditions in ELF driver"); else { s = sects[nsects - 1]; diff --git a/output/outieee.c b/output/outieee.c index 0078fa90..1247077e 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -146,7 +146,7 @@ static struct ieeeSection { struct ieeeObjData *data, *datacurr; struct ieeeFixupp *fptr, *flptr; int32_t index; /* the NASM segment id */ - int32_t ieee_index; /* the OBJ-file segment index */ + int32_t ieee_index; /* the IEEE-file segment index */ int32_t currentpos; int32_t align; /* can be SEG_ABS + absolute addr */ int32_t startpos; @@ -193,7 +193,7 @@ static void ieee_data_new(struct ieeeSection *); static void ieee_write_fixup(int32_t, int32_t, struct ieeeSection *, int, uint64_t, int32_t); static void ieee_install_fixup(struct ieeeSection *, struct ieeeFixupp *); -static int32_t ieee_segment(char *, int, int *); +static int32_t ieee_segment(char *, int *); static void ieee_write_file(void); static void ieee_write_byte(struct ieeeSection *, int); static void ieee_write_word(struct ieeeSection *, int); @@ -403,7 +403,7 @@ static void ieee_out(int32_t segto, const void *data, */ if (!any_segs) { int tempint; /* ignored */ - if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint)) + if (segto != ieee_segment("__NASMDEFSEG", &tempint)) nasm_panic("strange segment conditions in IEEE driver"); } @@ -655,7 +655,7 @@ static void ieee_install_fixup(struct ieeeSection *seg, /* * segment registry */ -static int32_t ieee_segment(char *name, int pass, int *bits) +static int32_t ieee_segment(char *name, int *bits) { /* * We call the label manager here to define a name for the new @@ -705,7 +705,7 @@ static int32_t ieee_segment(char *name, int pass, int *bits) for (seg = seghead; seg; seg = seg->next) { ieee_idx++; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass == 1) + if (attrs > 0 && pass_first()) nasm_warn(WARN_OTHER, "segment attributes specified on" " redeclaration of segment: ignoring"); if (seg->use32) @@ -807,11 +807,9 @@ static int32_t ieee_segment(char *name, int pass, int *bits) * directives supported */ static enum directive_result -ieee_directive(enum directive directive, char *value, int pass) +ieee_directive(enum directive directive, char *value) { - (void)value; - (void)pass; switch (directive) { case D_UPPERCASE: @@ -1275,7 +1273,7 @@ static void dbgls_init(void) arrindex = ARRAY_BOT; arrhead = NULL; arrtail = &arrhead; - ieee_segment("??LINE", 2, &tempint); + ieee_segment("??LINE", &tempint); any_segs = false; } static void dbgls_cleanup(void) @@ -1323,8 +1321,8 @@ static void dbgls_linnum(const char *lnfname, int32_t lineno, int32_t segto) */ if (!any_segs) { int tempint; /* ignored */ - if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic("strange segment conditions in OBJ driver"); + if (segto != ieee_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in IEEE driver"); } /* diff --git a/output/outlib.h b/output/outlib.h index 6dc7bdad..30f2c0b2 100644 --- a/output/outlib.h +++ b/output/outlib.h @@ -41,7 +41,7 @@ uint64_t realsize(enum out_type type, uint64_t size); /* Do-nothing versions of some output routines */ enum directive_result -null_directive(enum directive directive, char *value, int pass); +null_directive(enum directive directive, char *value); void null_sectalign(int32_t seg, unsigned int value); void null_reset(void); int32_t null_segbase(int32_t seg); diff --git a/output/outmacho.c b/output/outmacho.c index 820136f6..6482be09 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -788,7 +788,7 @@ lookup_known_section(const char *name, bool by_sectname) return NULL; } -static int32_t macho_section(char *name, int pass, int *bits) +static int32_t macho_section(char *name, int *bits) { const struct macho_known_section *known_section; const struct macho_known_section_attr *sa; @@ -801,8 +801,6 @@ static int32_t macho_section(char *name, int pass, int *bits) bool new_seg; - (void)pass; - /* Default to the appropriate number of bits. */ if (!name) { *bits = fmt.ptrsize << 3; @@ -986,8 +984,9 @@ static void macho_symdef(char *name, int32_t section, int64_t offset, #if defined(DEBUG) && DEBUG>2 nasm_error(ERR_DEBUG, - " macho_symdef: %s, pass0=%d, passn=%"PRId64", sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", - name, pass0, passn, section, offset, is_global, special); + " macho_symdef: %s, pass=%"PRId64" type %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", + name, pass_count(), pass_types[pass_type()], + section, offset, is_global, special); #endif if (is_global == 3) { @@ -1767,7 +1766,6 @@ static enum directive_result macho_no_dead_strip(const char *labels) char *s, *p, *ep; char ec; enum directive_result rv = DIRR_ERROR; - bool real = passn > 1; p = s = nasm_strdup(labels); while (*p) { @@ -1782,7 +1780,7 @@ static enum directive_result macho_no_dead_strip(const char *labels) goto err; } *ep = '\0'; - if (real) { + if (!pass_first()) { if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP)) rv = DIRR_ERROR; } @@ -1805,14 +1803,12 @@ err: static enum directive_result macho_pragma(const struct pragma *pragma) { - bool real = passn > 1; - switch (pragma->opcode) { case D_SUBSECTIONS_VIA_SYMBOLS: if (*pragma->tail) return DIRR_BADPARAM; - if (real) + if (!pass_first()) head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS; /* Jmp-match optimization conflicts */ @@ -1844,10 +1840,10 @@ static void macho_dbg_generate(void) /* debug section defines */ { int bits = 0; - macho_section(".debug_abbrev", 0, &bits); - macho_section(".debug_info", 0, &bits); - macho_section(".debug_line", 0, &bits); - macho_section(".debug_str", 0, &bits); + macho_section(".debug_abbrev", &bits); + macho_section(".debug_info", &bits); + macho_section(".debug_line", &bits); + macho_section(".debug_str", &bits); } /* dw section walk to find high_addr and total_len */ diff --git a/output/outobj.c b/output/outobj.c index 9fd4ddca..e861754e 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -634,9 +634,9 @@ static const struct dfmt borland_debug_form; /* The current segment */ static struct Segment *current_seg; -static int32_t obj_segment(char *, int, int *); +static int32_t obj_segment(char *, int *); static void obj_write_file(void); -static enum directive_result obj_directive(enum directive, char *, int); +static enum directive_result obj_directive(enum directive, char *); static void obj_init(void) { @@ -837,7 +837,7 @@ static void obj_deflabel(char *name, int32_t segment, */ if (!any_segs && segment == first_seg) { int tempint; /* ignored */ - if (segment != obj_segment("__NASMDEFSEG", 2, &tempint)) + if (segment != obj_segment("__NASMDEFSEG", &tempint)) nasm_panic("strange segment conditions in OBJ driver"); } @@ -1029,7 +1029,7 @@ static void obj_out(int32_t segto, const void *data, */ if (!any_segs) { int tempint; /* ignored */ - if (segto != obj_segment("__NASMDEFSEG", 2, &tempint)) + if (segto != obj_segment("__NASMDEFSEG", &tempint)) nasm_panic("strange segment conditions in OBJ driver"); } @@ -1323,7 +1323,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, obj_commit(forp); } -static int32_t obj_segment(char *name, int pass, int *bits) +static int32_t obj_segment(char *name, int *bits) { /* * We call the label manager here to define a name for the new @@ -1379,7 +1379,7 @@ static int32_t obj_segment(char *name, int pass, int *bits) break; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass == 1) + if (attrs > 0 && pass_first()) nasm_warn(WARN_OTHER, "segment attributes specified on" " redeclaration of segment: ignoring"); if (seg->use32) @@ -1455,7 +1455,7 @@ static int32_t obj_segment(char *name, int pass, int *bits) if (!strcmp(grp->name, "FLAT")) break; if (!grp) { - obj_directive(D_GROUP, "FLAT", 1); + obj_directive(D_GROUP, "FLAT"); for (grp = grphead; grp; grp = grp->next) if (!strcmp(grp->name, "FLAT")) break; @@ -1570,13 +1570,13 @@ static int32_t obj_segment(char *name, int pass, int *bits) } static enum directive_result -obj_directive(enum directive directive, char *value, int pass) +obj_directive(enum directive directive, char *value) { switch (directive) { case D_GROUP: { char *p, *q, *v; - if (pass == 1) { + if (pass_first()) { /* XXX */ struct Group *grp; struct Segment *seg; struct External **extp; @@ -1690,8 +1690,8 @@ obj_directive(enum directive directive, char *value, int pass) { char *q, *extname, *libname, *impname; - if (pass == 2) - return 1; /* ignore in pass two */ + if (!pass_first()) /* XXX */ + return DIRR_OK; extname = q = value; while (*q && !nasm_isspace(*q)) q++; @@ -1740,7 +1740,7 @@ obj_directive(enum directive directive, char *value, int pass) int flags = 0; unsigned int ordinal = 0; - if (pass == 2) + if (!pass_first()) return DIRR_OK; /* ignore in pass two */ intname = q = value; while (*q && !nasm_isspace(*q)) @@ -1887,7 +1887,7 @@ static int32_t obj_segbase(int32_t segment) e = eb->exts[i]; if (!e) { /* Not available yet, probably a forward reference */ - nasm_assert(pass0 < 2); /* Convergence failure */ + nasm_assert(!pass_final()); return NO_SEG; } @@ -2502,7 +2502,7 @@ static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto) */ if (!any_segs) { int tempint; /* ignored */ - if (segto != obj_segment("__NASMDEFSEG", 2, &tempint)) + if (segto != obj_segment("__NASMDEFSEG", &tempint)) nasm_panic("strange segment conditions in OBJ driver"); } diff --git a/output/outrdf2.c b/output/outrdf2.c index 456d1bdf..c649a5a6 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -151,7 +151,7 @@ static void rdf2_init(void) headerlength = 0; } -static int32_t rdf2_section_names(char *name, int pass, int *bits) +static int32_t rdf2_section_names(char *name, int *bits) { int i; bool err; @@ -159,8 +159,6 @@ static int32_t rdf2_section_names(char *name, int pass, int *bits) int code = -1; int reserved = 0; - (void)pass; - /* * Default is 32 bits, in the text segment. */ @@ -705,7 +703,7 @@ static void rdf2_cleanup(void) * Handle RDOFF2 specific directives */ static enum directive_result -rdf2_directive(enum directive directive, char *value, int pass) +rdf2_directive(enum directive directive, char *value) { size_t n; @@ -716,7 +714,7 @@ rdf2_directive(enum directive directive, char *value, int pass) nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); return DIRR_ERROR; } - if (pass == 1) { + if (pass_first()) { /* XXX */ struct DLLRec r; r.type = RDFREC_DLL; r.reclen = n + 1; @@ -730,7 +728,7 @@ rdf2_directive(enum directive directive, char *value, int pass) nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); return DIRR_ERROR; } - if (pass == 1) { + if (pass_first()) { /* XXX */ struct ModRec r; r.type = RDFREC_MODNAME; r.reclen = n + 1; |