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>
This commit is contained in:
H. Peter Anvin (Intel) 2018-12-18 11:12:46 -08:00
parent 8c17bb2fc4
commit e55d03dd47
22 changed files with 353 additions and 299 deletions

@ -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);

@ -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());
}
/**

@ -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;

@ -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

@ -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,

@ -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,

@ -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 */

@ -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;
}

@ -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.
*/

@ -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.
*/

@ -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) {

@ -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++) {

@ -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;
}

@ -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];

@ -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");
}
/*

@ -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);

@ -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 */

@ -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");
}

@ -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;