summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 12:25:11 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 12:25:11 -0800
commit5df6ca712df59a7f83b27ebd382bfb6ee851fff8 (patch)
treed926fa961f5a91c71317ac34c2867246f8d229eb
parent21da8ae8e5163aa6dd2042d70a7530d7d6accab7 (diff)
downloadnasm-5df6ca712df59a7f83b27ebd382bfb6ee851fff8.tar.gz
With buffered warnings, change the handling of error passes
With buffered warnings, most warnings *must* be issued on every pass, so ERR_PASS1 is simply wrong in most cases. ERR_PASS1 now means "force this warning to be output even in pass_first(). This is to be used for the case where the warning is only executed in pass_first() code; this is highly discouraged as it means the warnings will not appear in the list file and subsequent passes may make the warning suddenly vanish. ERR_PASS2 just as before suppresses an error or warning unless we are in pass_final(). Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r--asm/assemble.c4
-rw-r--r--asm/eval.c4
-rw-r--r--asm/nasm.c22
-rw-r--r--asm/parser.c8
-rw-r--r--asm/preproc.c53
-rw-r--r--asm/stdscan.c2
-rw-r--r--include/error.h4
-rw-r--r--nasmlib/readnum.c2
-rw-r--r--output/outbin.c4
-rw-r--r--output/outcoff.c68
-rw-r--r--output/outelf.c9
-rw-r--r--output/outelf.h1
-rw-r--r--output/outieee.c5
-rw-r--r--output/outobj.c4
-rw-r--r--output/pecoff.h1
15 files changed, 102 insertions, 89 deletions
diff --git a/asm/assemble.c b/asm/assemble.c
index c5d3f65c..d5706820 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -1205,7 +1205,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
nasm_nonfatal("attempt to reserve non-constant"
" quantity of BSS space");
else if (ins->oprs[0].opflags & OPFLAG_FORWARD)
- nasm_warn(WARN_OTHER|ERR_PASS1, "forward reference in RESx "
+ nasm_warn(WARN_OTHER, "forward reference in RESx "
"can have unpredictable results");
else
length += ins->oprs[0].offset;
@@ -2528,7 +2528,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
if (eaflags & EAF_BYTEOFFS ||
(eaflags & EAF_WORDOFFS &&
input->disp_size != (addrbits != 16 ? 32 : 16)))
- nasm_warn(WARN_OTHER|ERR_PASS1, "displacement size ignored on absolute address");
+ nasm_warn(WARN_OTHER, "displacement size ignored on absolute address");
if (bits == 64 && (~input->type & IP_REL)) {
output->sib_present = true;
diff --git a/asm/eval.c b/asm/eval.c
index 9179c0bf..28db3276 100644
--- a/asm/eval.c
+++ b/asm/eval.c
@@ -784,7 +784,7 @@ static expr *eval_strfunc(enum strfunc type)
}
if (rn_warn)
- nasm_warn(WARN_OTHER|ERR_PASS1, "character constant too long");
+ nasm_warn(WARN_OTHER, "character constant too long");
begintemp();
addtotemp(EXPR_SIMPLE, val);
@@ -942,7 +942,7 @@ static expr *expr6(void)
case TOKEN_STR:
tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn);
if (rn_warn)
- nasm_warn(WARN_OTHER|ERR_PASS1, "character constant too long");
+ nasm_warn(WARN_OTHER, "character constant too long");
addtotemp(EXPR_SIMPLE, tmpval);
break;
case TOKEN_REG:
diff --git a/asm/nasm.c b/asm/nasm.c
index 6800a5b6..e0c23af3 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -206,7 +206,7 @@ nasm_set_limit(const char *limit, const char *valstr)
if (not_started())
errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE;
else
- errlevel = ERR_WARNING|ERR_PASS1|WARN_UNKNOWN_PRAGMA;
+ errlevel = ERR_WARNING|WARN_UNKNOWN_PRAGMA;
nasm_error(errlevel, "unknown limit: `%s'", limit);
return DIRR_ERROR;
}
@@ -219,7 +219,7 @@ nasm_set_limit(const char *limit, const char *valstr)
if (not_started())
errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE;
else
- errlevel = ERR_WARNING|ERR_PASS1|WARN_BAD_PRAGMA;
+ errlevel = ERR_WARNING|WARN_BAD_PRAGMA;
nasm_error(errlevel, "invalid limit value: `%s'", limit);
return DIRR_ERROR;
}
@@ -1754,11 +1754,8 @@ static bool skip_this_pass(errflags severity)
if ((severity & ERR_MASK) >= ERR_FATAL)
return false;
- /*
- * Let's get rid of these flags when and if we can...
- */
- return ((severity & ERR_PASS1) && !pass_first()) ||
- ((severity & ERR_PASS2) && !pass_final());
+ /* This message not applicable unless pass_final */
+ return (severity & ERR_PASS2) && !pass_final();
}
/**
@@ -1869,7 +1866,9 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
const char *file = currentfile ? currentfile : "nasm";
const char *here = (severity & ERR_HERE) ? " here" : "";
- if (warn_list && true_type < ERR_NONFATAL) {
+ if (warn_list && true_type < ERR_NONFATAL &&
+ !(pass_first() && (severity & ERR_PASS1)))
+ {
/*
* Buffer up warnings until we either get an error
* or we are on the code-generation pass.
@@ -1878,8 +1877,11 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
file, linestr, errfmt->beforemsg,
pfx, msg, here, warnsuf);
} else {
- /* If we have buffered warnings, output them now. */
- if (warn_list) {
+ /*
+ * If we have buffered warnings, and this is a non-warning,
+ * output them now.
+ */
+ if (true_type >= ERR_NONFATAL && warn_list) {
strlist_write(warn_list, "\n", error_file);
strlist_free(&warn_list);
}
diff --git a/asm/parser.c b/asm/parser.c
index 9c96732d..abc1ea40 100644
--- a/asm/parser.c
+++ b/asm/parser.c
@@ -469,7 +469,7 @@ restart_parse:
*! a label without a trailing colon. This is most likely indicative
*! of a typo, but is technically correct NASM syntax (see \k{syntax}.)
*/
- nasm_warn(WARN_ORPHAN_LABELS | ERR_PASS1,
+ nasm_warn(WARN_ORPHAN_LABELS ,
"label alone on a line without a colon might be in error");
}
if (i != TOKEN_INSN || tokval.t_integer != I_EQU) {
@@ -519,7 +519,7 @@ restart_parse:
int slot = prefix_slot(tokval.t_integer);
if (result->prefixes[slot]) {
if (result->prefixes[slot] == tokval.t_integer)
- nasm_warn(WARN_OTHER|ERR_PASS1, "instruction has redundant prefixes");
+ nasm_warn(WARN_OTHER, "instruction has redundant prefixes");
else
nasm_nonfatal("instruction has conflicting prefixes");
}
@@ -732,7 +732,7 @@ is_expression:
*/
goto fail;
} else /* DB ... */ if (oper_num == 0)
- nasm_warn(WARN_OTHER|ERR_PASS1, "no operand for data declaration");
+ nasm_warn(WARN_OTHER, "no operand for data declaration");
else
result->operands = oper_num;
@@ -1126,7 +1126,7 @@ is_expression:
op->basereg = value->type;
if (rs && (op->type & SIZE_MASK) != rs)
- nasm_warn(WARN_OTHER|ERR_PASS1, "register size specification ignored");
+ nasm_warn(WARN_OTHER, "register size specification ignored");
}
}
diff --git a/asm/preproc.c b/asm/preproc.c
index 9e1d2f44..93dcd263 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -909,7 +909,7 @@ static Token *tokenize(char *line)
p++;
}
if (*p != '}')
- nasm_warn(WARN_OTHER|ERR_PASS1, "unterminated %%{ construct");
+ nasm_warn(WARN_OTHER, "unterminated %%{ construct");
p[-1] = '\0';
if (*p)
p++;
@@ -997,7 +997,7 @@ static Token *tokenize(char *line)
if (*p) {
p++;
} else {
- nasm_warn(WARN_OTHER|ERR_PASS1, "unterminated string");
+ nasm_warn(WARN_OTHER, "unterminated string");
/* Handling unterminated strings by UNV */
/* type = -1; */
}
@@ -1911,7 +1911,7 @@ static bool if_condition(Token * tline, enum preproc_token ct)
mmac = mmac->next;
}
if (tline && tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after %%ifmacro ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after %%ifmacro ignored");
nasm_free(searching.name);
j = found;
break;
@@ -1970,7 +1970,7 @@ iftype:
if (!evalresult)
return -1;
if (tokval.t_type)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after expression ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
if (!is_simple(evalresult)) {
nasm_nonfatal("non-constant value given to `%s'",
pp_directives[ct]);
@@ -2004,7 +2004,7 @@ static bool define_smacro(Context *ctx, const char *mname, bool casesense,
if (smacro_defined(ctx, mname, nparam, &smac, casesense)) {
if (!smac) {
- nasm_warn(WARN_OTHER|ERR_PASS1, "single-line macro `%s' defined both with and"
+ nasm_warn(WARN_OTHER, "single-line macro `%s' defined both with and"
" without parameters", mname);
/*
* Some instances of the old code considered this a failure,
@@ -2137,7 +2137,7 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
*! warns when a macro has more default parameters than optional parameters.
*! See \k{mlmacdef} for why might want to disable this warning.
*/
- nasm_warn(ERR_PASS1|WARN_MACRO_DEFAULTS,
+ nasm_warn(WARN_MACRO_DEFAULTS,
"too many default macro parameters in macro `%s'", def->name);
}
@@ -2514,7 +2514,7 @@ static int do_directive(Token *tline, char **output)
case PP_CLEAR:
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%%clear' ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after `%%clear' ignored");
free_macros();
init_macros();
free_tlist(origline);
@@ -2530,7 +2530,7 @@ static int do_directive(Token *tline, char **output)
return DIRECTIVE_FOUND; /* but we did _something_ */
}
if (t->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%%depend' ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after `%%depend' ignored");
p = t->text;
if (t->type != TOK_INTERNAL_STRING)
nasm_unquote_cstr(p, i);
@@ -2549,7 +2549,7 @@ static int do_directive(Token *tline, char **output)
return DIRECTIVE_FOUND; /* but we did _something_ */
}
if (t->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%%include' ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after `%%include' ignored");
p = t->text;
if (t->type != TOK_INTERNAL_STRING)
nasm_unquote_cstr(p, i);
@@ -2592,7 +2592,7 @@ static int do_directive(Token *tline, char **output)
return DIRECTIVE_FOUND; /* but we did _something_ */
}
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%%use' ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after `%%use' ignored");
if (tline->type == TOK_STRING)
nasm_unquote_cstr(tline->text, i);
use_pkg = nasm_stdmac_find_package(tline->text);
@@ -2621,7 +2621,7 @@ static int do_directive(Token *tline, char **output)
return DIRECTIVE_FOUND; /* but we did _something_ */
}
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%s' ignored",
+ nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored",
pp_directives[i]);
p = nasm_strdup(tline->text);
} else {
@@ -2659,22 +2659,19 @@ static int do_directive(Token *tline, char **output)
severity = ERR_FATAL;
goto issue_error;
case PP_ERROR:
- severity = ERR_NONFATAL;
+ severity = ERR_NONFATAL|ERR_PASS2;
goto issue_error;
case PP_WARNING:
/*!
*!user [on] %warning directives
*! controls output of \c{%warning} directives (see \k{pperror}).
*/
- severity = ERR_WARNING|WARN_USER;
+ severity = ERR_WARNING|WARN_USER|ERR_PASS2;
goto issue_error;
issue_error:
{
/* Only error out if this is the final pass */
- if (pass_final() && i != PP_FATAL)
- return DIRECTIVE_FOUND;
-
tline->next = expand_smacro(tline->next);
tline = tline->next;
skip_white_(tline);
@@ -2726,7 +2723,7 @@ issue_error:
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
- nasm_warn(WARN_OTHER|ERR_PASS1|ERR_PP_PRECOND,
+ nasm_warn(WARN_OTHER|ERR_PP_PRECOND,
"`%%elif' after `%%else' ignored");
istk->conds->state = COND_NEVER;
break;
@@ -2751,7 +2748,7 @@ issue_error:
case PP_ELSE:
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1|ERR_PP_PRECOND,
+ nasm_warn(WARN_OTHER|ERR_PP_PRECOND,
"trailing garbage after `%%else' ignored");
if (!istk->conds)
nasm_fatal("`%%else: no matching `%%if'");
@@ -2770,7 +2767,7 @@ issue_error:
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
- nasm_warn(WARN_OTHER|ERR_PASS1|ERR_PP_PRECOND,
+ nasm_warn(WARN_OTHER|ERR_PP_PRECOND,
"`%%else' after `%%else' ignored.");
istk->conds->state = COND_NEVER;
break;
@@ -2780,7 +2777,7 @@ issue_error:
case PP_ENDIF:
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1|ERR_PP_PRECOND,
+ nasm_warn(WARN_OTHER|ERR_PP_PRECOND,
"trailing garbage after `%%endif' ignored");
if (!istk->conds)
nasm_fatal("`%%endif': no matching `%%if'");
@@ -2820,7 +2817,7 @@ issue_error:
|| defining->plus)
&& (defining->nparam_min <= mmac->nparam_max
|| mmac->plus)) {
- nasm_warn(WARN_OTHER|ERR_PASS1, "redefining multi-line macro `%s'",
+ nasm_warn(WARN_OTHER, "redefining multi-line macro `%s'",
defining->name);
return DIRECTIVE_FOUND;
}
@@ -2918,7 +2915,7 @@ issue_error:
if (!evalresult)
return DIRECTIVE_FOUND;
if (tokval.t_type)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after expression ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
if (!is_simple(evalresult)) {
nasm_nonfatal("non-constant value given to `%%rotate'");
return DIRECTIVE_FOUND;
@@ -2966,7 +2963,7 @@ issue_error:
return DIRECTIVE_FOUND;
}
if (tokval.t_type)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after expression ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
if (!is_simple(evalresult)) {
nasm_nonfatal("non-constant value given to `%%rep'");
return DIRECTIVE_FOUND;
@@ -3163,7 +3160,7 @@ issue_error:
return DIRECTIVE_FOUND;
}
if (tline->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after macro name ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after macro name ignored");
/* Find the context that symbol belongs to */
ctx = get_ctx(tline->text, &mname);
@@ -3295,7 +3292,7 @@ issue_error:
return DIRECTIVE_FOUND; /* but we did _something_ */
}
if (t->next)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after `%%pathsearch' ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after `%%pathsearch' ignored");
p = t->text;
if (t->type != TOK_INTERNAL_STRING)
nasm_unquote(p, NULL);
@@ -3554,7 +3551,7 @@ issue_error:
}
if (tokval.t_type)
- nasm_warn(WARN_OTHER|ERR_PASS1, "trailing garbage after expression ignored");
+ nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
if (!is_simple(evalresult)) {
nasm_nonfatal("non-constant value given to `%%%sassign'",
@@ -4311,7 +4308,7 @@ again:
*! with the wrong number of parameters. See \k{mlmacover} for an
*! example of why you might want to disable this warning.
*/
- nasm_warn(ERR_PASS1|WARN_MACRO_PARAMS,
+ nasm_warn(WARN_MACRO_PARAMS,
"macro `%s' exists, "
"but not taking %d parameters",
mstart->text, nparam);
@@ -4612,7 +4609,7 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
* After all that, we didn't find one with the right number of
* parameters. Issue a warning, and fail to expand the macro.
*/
- nasm_warn(ERR_PASS1|WARN_MACRO_PARAMS,
+ nasm_warn(WARN_MACRO_PARAMS,
"macro `%s' exists, but not taking %d parameters",
tline->text, nparam);
nasm_free(params);
diff --git a/asm/stdscan.c b/asm/stdscan.c
index dbe0fd54..4f256fc6 100644
--- a/asm/stdscan.c
+++ b/asm/stdscan.c
@@ -173,7 +173,7 @@ int stdscan(void *private_data, struct tokenval *tv)
*! indicate a mistake in the source code. Currently only the MASM
*! \c{PTR} keyword is recognized.
*/
- nasm_warn(ERR_PASS1|WARN_PTR, "`%s' is not a NASM keyword",
+ nasm_warn(WARN_PTR, "`%s' is not a NASM keyword",
tv->t_charptr);
}
diff --git a/include/error.h b/include/error.h
index 9c935214..03a220ec 100644
--- a/include/error.h
+++ b/include/error.h
@@ -93,8 +93,8 @@ static inline vefunc nasm_set_verror(vefunc ve)
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
#define ERR_HERE 0x00000020 /* point to a specific source location */
#define ERR_USAGE 0x00000040 /* print a usage message */
-#define ERR_PASS1 0x00000080 /* only print this error on pass one */
-#define ERR_PASS2 0x00000100 /* only print this error on pass one */
+#define ERR_PASS1 0x00000080 /* message on pass_first */
+#define ERR_PASS2 0x00000100 /* ignore unless on pass_final */
#define ERR_NO_SEVERITY 0x00000200 /* suppress printing severity */
#define ERR_PP_PRECOND 0x00000400 /* for preprocessor use */
diff --git a/nasmlib/readnum.c b/nasmlib/readnum.c
index 4e73c1a1..3ed6b3f2 100644
--- a/nasmlib/readnum.c
+++ b/nasmlib/readnum.c
@@ -169,7 +169,7 @@ int64_t readnum(const char *str, bool *error)
*! covers warnings about numeric constants which
*! don't fit in 64 bits.
*/
- nasm_error(ERR_WARNING | ERR_PASS1 | WARN_NUMBER_OVERFLOW,
+ nasm_error(ERR_WARNING | WARN_NUMBER_OVERFLOW,
"numeric constant %s does not fit in 64 bits",
str);
}
diff --git a/output/outbin.c b/output/outbin.c
index 4bf13fa4..73a4d8a7 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -1328,13 +1328,13 @@ bin_directive(enum directive directive, char *args)
else { /* Must be a filename. */
rf = nasm_open_write(p, NF_TEXT);
if (!rf) {
- nasm_warn(WARN_OTHER, "unable to open map file `%s'", p);
+ nasm_warn(WARN_OTHER|ERR_PASS1, "unable to open map file `%s'", p);
map_control = 0;
return DIRR_OK;
}
}
} else
- nasm_warn(WARN_OTHER, "map file already specified");
+ nasm_warn(WARN_OTHER|ERR_PASS1, "map file already specified");
}
if (map_control == 0)
map_control |= MAP_ORIGIN | MAP_SUMMARY;
diff --git a/output/outcoff.c b/output/outcoff.c
index a90e355e..2c8520f1 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -402,45 +402,51 @@ static int32_t coff_section_names(char *name, int *bits)
coff_sects[i]->flags = flags;
coff_sects[i]->flags &= align_and;
coff_sects[i]->flags |= align_or;
- } else if (pass_first()) {
- /* Check if any flags are specified */
- if (flags) {
- unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK;
-
- /* Warn if non-alignment flags differ */
- if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) {
- nasm_warn(WARN_OTHER, "section attributes ignored on"
- " redeclaration of section `%s'", name);
+ } else if (flags) {
+ /* Check if any flags are respecified */
+ unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK;
+
+ /* Warn if non-alignment flags differ */
+ if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK &&
+ coff_sects[i]->pass_last_seen == pass_count()) {
+ nasm_warn(WARN_OTHER, "section attributes changed on"
+ " redeclaration of section `%s'", name);
+ }
+ /* Check if alignment might be needed */
+ if (align_flags > IMAGE_SCN_ALIGN_1BYTES) {
+ unsigned int sect_align_flags = coff_sects[i]->flags & IMAGE_SCN_ALIGN_MASK;
+
+ /* Compute the actual alignment */
+ unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20);
+
+ /* Update section header as needed */
+ if (align_flags > sect_align_flags) {
+ coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags;
}
- /* Check if alignment might be needed */
- if (align_flags > IMAGE_SCN_ALIGN_1BYTES) {
- unsigned int sect_align_flags = coff_sects[i]->flags & IMAGE_SCN_ALIGN_MASK;
+ /* Check if not already aligned */
+ if (coff_sects[i]->len % align) {
+ unsigned int padding = (align - coff_sects[i]->len) % align;
+ /* We need to write at most 8095 bytes */
+ char buffer[8095];
- /* Compute the actual alignment */
- unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20);
+ nasm_assert(padding <= sizeof buffer);
- /* Update section header as needed */
- if (align_flags > sect_align_flags) {
- coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags;
- }
- /* Check if not already aligned */
- if (coff_sects[i]->len % align) {
- unsigned int padding = (align - coff_sects[i]->len) % align;
- /* We need to write at most 8095 bytes */
- char buffer[8095];
- if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) {
- /* Fill with INT 3 instructions */
- memset(buffer, 0xCC, padding);
- } else {
- memset(buffer, 0x00, padding);
- }
- saa_wbytes(coff_sects[i]->data, buffer, padding);
- coff_sects[i]->len += padding;
+ if (pass_final())
+ nasm_nonfatal("section alignment changed during code generation");
+
+ if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) {
+ /* Fill with INT 3 instructions */
+ memset(buffer, 0xCC, padding);
+ } else {
+ memset(buffer, 0x00, padding);
}
+ saa_wbytes(coff_sects[i]->data, buffer, padding);
+ coff_sects[i]->len += padding;
}
}
}
+ coff_sects[i]->pass_last_seen = pass_count();
return coff_sects[i]->index;
}
diff --git a/output/outelf.c b/output/outelf.c
index cd77901f..366e52de 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -258,8 +258,8 @@ static void elf_section_attrib(char *name, char *attr,
*type = SHT_PROGBITS;
} else if (!nasm_stricmp(opt, "nobits")) {
*type = SHT_NOBITS;
- } else if (pass_first()) {
- nasm_warn(WARN_OTHER, "Unknown section attribute '%s' ignored on"
+ } else {
+ nasm_warn(WARN_OTHER, "unknown section attribute '%s' ignored on"
" declaration of section `%s'", opt, name);
}
opt = next;
@@ -458,14 +458,15 @@ static int32_t elf_section_names(char *name, int *bits)
flags = (ks->flags & ~flags_and) | flags_or;
i = elf_make_section(name, type, flags, align);
- } else if (pass_first()) {
+ } else if (sects[i]->pass_last_seen == pass_count()) {
if ((type && sects[i]->type != type)
|| (align && sects[i]->align != align)
|| (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
- nasm_warn(WARN_OTHER, "incompatible section attributes ignored on"
+ nasm_warn(WARN_OTHER|ERR_PASS1, "incompatible section attributes ignored on"
" redeclaration of section `%s'", name);
}
+ sects[i]->pass_last_seen = pass_count();
return sects[i]->index;
}
diff --git a/output/outelf.h b/output/outelf.h
index 8eef73ae..0801eaf8 100644
--- a/output/outelf.h
+++ b/output/outelf.h
@@ -141,6 +141,7 @@ struct elf_section {
int type; /* SHT_PROGBITS or SHT_NOBITS */
uint64_t align; /* alignment: power of two */
uint64_t flags; /* section flags */
+ int64_t pass_last_seen;
char *name;
struct SAA *rel;
uint64_t rellen;
diff --git a/output/outieee.c b/output/outieee.c
index 1247077e..f2f598ee 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -151,6 +151,7 @@ static struct ieeeSection {
int32_t align; /* can be SEG_ABS + absolute addr */
int32_t startpos;
int32_t use32; /* is this segment 32-bit? */
+ int64_t pass_last_seen;
struct ieeePublic *pubhead, **pubtail, *lochead, **loctail;
enum {
CMB_PRIVATE = 0,
@@ -705,13 +706,15 @@ static int32_t ieee_segment(char *name, int *bits)
for (seg = seghead; seg; seg = seg->next) {
ieee_idx++;
if (!strcmp(seg->name, name)) {
- if (attrs > 0 && pass_first())
+ if (attrs > 0 && seg->pass_last_seen == pass_count())
nasm_warn(WARN_OTHER, "segment attributes specified on"
" redeclaration of segment: ignoring");
if (seg->use32)
*bits = 32;
else
*bits = 16;
+
+ seg->pass_last_seen = pass_count();
return seg->index;
}
}
diff --git a/output/outobj.c b/output/outobj.c
index e861754e..c7407cf9 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -580,6 +580,7 @@ static struct Segment {
struct Group *grp; /* the group it beint32_ts to */
uint32_t currentpos;
int32_t align; /* can be SEG_ABS + absolute addr */
+ int64_t pass_last_seen;
struct Public *pubhead, **pubtail, *lochead, **loctail;
char *segclass, *overlay; /* `class' is a C++ keyword :-) */
ObjRecord *orp;
@@ -1379,7 +1380,7 @@ static int32_t obj_segment(char *name, int *bits)
break;
if (!strcmp(seg->name, name)) {
- if (attrs > 0 && pass_first())
+ if (attrs > 0 && seg->pass_last_seen == pass_count())
nasm_warn(WARN_OTHER, "segment attributes specified on"
" redeclaration of segment: ignoring");
if (seg->use32)
@@ -1387,6 +1388,7 @@ static int32_t obj_segment(char *name, int *bits)
else
*bits = 16;
current_seg = seg;
+ seg->pass_last_seen = pass_count();
return seg->index;
}
}
diff --git a/output/pecoff.h b/output/pecoff.h
index 8b57d6b2..7b6f46c2 100644
--- a/output/pecoff.h
+++ b/output/pecoff.h
@@ -484,6 +484,7 @@ struct coff_Section {
char *name;
int32_t namepos; /* Offset of name into the strings table */
int32_t pos, relpos;
+ int64_t pass_last_seen;
};
struct coff_Reloc {