summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 11:12:46 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 11:14:59 -0800
commite55d03dd47c221f631fe518c623cdd8a703076b2 (patch)
treea8dad51972e4dd49b401afcc0f08ce4b53b331f1
parent8c17bb2fc4d61675b6775e78fbb37b48f19379d3 (diff)
downloadnasm-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.c55
-rw-r--r--asm/eval.c28
-rw-r--r--asm/eval.h2
-rw-r--r--asm/labels.c17
-rw-r--r--asm/nasm.c177
-rw-r--r--asm/parser.c12
-rw-r--r--asm/parser.h2
-rw-r--r--asm/preproc-nop.c17
-rw-r--r--asm/preproc.c71
-rw-r--r--include/nasm.h89
-rw-r--r--output/nullout.c3
-rw-r--r--output/outaout.c5
-rw-r--r--output/outas86.c5
-rw-r--r--output/outbin.c15
-rw-r--r--output/outcoff.c23
-rw-r--r--output/outdbg.c23
-rw-r--r--output/outelf.c24
-rw-r--r--output/outieee.c20
-rw-r--r--output/outlib.h2
-rw-r--r--output/outmacho.c24
-rw-r--r--output/outobj.c28
-rw-r--r--output/outrdf2.c10
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;
diff --git a/asm/eval.c b/asm/eval.c
index f9380e9b..9179c0bf 100644
--- a/asm/eval.c
+++ b/asm/eval.c
@@ -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;
diff --git a/asm/eval.h b/asm/eval.h
index 7af17eb8..ba471a22 100644
--- a/asm/eval.h
+++ b/asm/eval.h
@@ -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
diff --git a/asm/nasm.c b/asm/nasm.c
index ec6a959d..6800a5b6 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -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;