mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-25 18:10:23 +08:00
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>
This commit is contained in:
parent
21da8ae8e5
commit
5df6ca712d
@ -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;
|
||||
|
@ -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:
|
||||
|
22
asm/nasm.c
22
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);
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
} 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) {
|
||||
nasm_warn(WARN_OTHER, "section attributes ignored on"
|
||||
" redeclaration of section `%s'", name);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user