preproc: command-line preproc directive after system-generated

BR 3392527: make sure that all command-line specified preprocessing
directives are processed after the system-generated ones. In
particular __OUTPUT_FORMAT__ was generated after command line pass 2,
at which point -p, -d, -u, --pragma and --before had already been
processed.

There is no reason to split up defined_macros() anymore: the right
place to execute it is simply between command line passes 1 and 2. We
can also set dfmt here, which lets us define a __DEBUG_FORMAT__ macro
as well.

Finally move some options that have no business being processed in
pass 2 to pass 1.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2018-11-11 13:25:16 -08:00
parent 9a1216a1ef
commit bf6230baa9
3 changed files with 84 additions and 39 deletions

View file

@ -134,6 +134,7 @@ static struct SAA *forwrefs; /* keep track of forward references */
static const struct forwrefinfo *forwref;
static const struct preproc_ops *preproc;
static StrList *include_path;
#define OP_NORMAL (1u << 0)
#define OP_PREPROCESS (1u << 1)
@ -258,7 +259,11 @@ static void nasm_fputs(const char *line, FILE * outfile)
puts(line);
}
static void define_macros_early(void)
/*
* Define system-defined macros that are not part of
* macros/standard.mac.
*/
static void define_macros(void)
{
const struct compile_time * const oct = &official_compile_time;
char temp[128];
@ -289,11 +294,6 @@ static void define_macros_early(void)
snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, oct->posix);
preproc->pre_define(temp);
}
}
static void define_macros_late(void)
{
char temp[128];
/*
* In case if output format is defined by alias
@ -303,6 +303,41 @@ static void define_macros_late(void)
snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s",
ofmt_alias ? ofmt_alias->shortname : ofmt->shortname);
preproc->pre_define(temp);
/*
* Output-format specific macros.
*/
if (ofmt->stdmac)
preproc->extra_stdmac(ofmt->stdmac);
/*
* Debug format, if any
*/
if (dfmt != &null_debug_form) {
snprintf(temp, sizeof(temp), "__DEBUG_FORMAT__=%s", dfmt->shortname);
preproc->pre_define(temp);
}
}
/*
* Initialize the preprocessor, set up the include path, and define
* the system-included macros. This is called between passes 1 and 2
* of parsing the command options; ofmt and dfmt are defined at this
* point.
*
* Command-line specified preprocessor directives (-p, -d, -u,
* --pragma, --before) are processed after this function.
*/
static void preproc_init(void)
{
StrList *ip, *iptmp;
preproc->init();
define_macros();
list_for_each_safe(ip, iptmp, include_path) {
preproc->include_path(ip->str);
nasm_free(ip);
}
}
static void emit_dependencies(StrList *list)
@ -445,23 +480,7 @@ int main(int argc, char **argv)
return 1;
}
/*
* Define some macros dependent on the runtime, but not
* on the command line (as those are scanned in cmdline pass 2.)
*/
preproc->init();
define_macros_early();
parse_cmdline(argc, argv, 2);
if (terminate_after_phase) {
if (want_usage)
usage();
return 1;
}
/* Save away the default state of warnings */
memcpy(warning_state_init, warning_state, sizeof warning_state);
/* At this point we have ofmt and the name of the desired debug format */
if (!using_debug_info) {
/* No debug info, redirect to the null backend (empty stubs) */
dfmt = &null_debug_form;
@ -478,8 +497,17 @@ int main(int argc, char **argv)
}
}
if (ofmt->stdmac)
preproc->extra_stdmac(ofmt->stdmac);
preproc_init();
parse_cmdline(argc, argv, 2);
if (terminate_after_phase) {
if (want_usage)
usage();
return 1;
}
/* Save away the default state of warnings */
memcpy(warning_state_init, warning_state, sizeof warning_state);
/*
* If no output file name provided and this
@ -491,10 +519,8 @@ int main(int argc, char **argv)
outname = filename_set_extension(inname, ofmt->extension);
}
/* define some macros dependent of command-line */
define_macros_late();
depend_ptr = (depend_file || (operating_mode & OP_DEPEND)) ? &depend_list : NULL;
depend_ptr = (depend_file || (operating_mode & OP_DEPEND))
? &depend_list : NULL;
if (!depend_target)
depend_target = quote_for_make(outname);
@ -869,7 +895,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'O': /* Optimization level */
if (pass == 2) {
if (pass == 1) {
int opt;
if (!*param) {
@ -934,8 +960,8 @@ static bool process_arg(char *p, char *q, int pass)
case 'i': /* include search path */
case 'I':
if (pass == 2)
preproc->include_path(param);
if (pass == 1)
nasm_add_string_to_strlist(&include_path, param);
break;
case 'l': /* listing file */
@ -949,7 +975,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'F': /* specify debug format */
if (pass == 2) {
if (pass == 1) {
using_debug_info = true;
debug_format = param;
}
@ -969,7 +995,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'g':
if (pass == 2) {
if (pass == 1) {
using_debug_info = true;
if (p[2])
debug_format = nasm_skip_spaces(p + 2);
@ -1163,7 +1189,7 @@ static bool process_arg(char *p, char *q, int pass)
preproc->pre_command(NULL, param);
break;
case OPT_LIMIT:
if (pass == 2)
if (pass == 1)
nasm_set_limit(p+olen, param);
break;
case OPT_KEEP_ALL:

View file

@ -7,9 +7,19 @@
The NASM 2 series supports x86-64, and is the production version of NASM
since 2007.
\S{cl-2.14.01} Version 2.14.01
\b Create all system-defined macros defore processing command-line
given preprocessing directives (\c{-p}, \c{-d}, \c{-u}, \c{--pragma},
\c{--before}).
\b If debugging is enabled, define a \c{__DEBUG_FORMAT__} predefined
macro. See \k{dfmtm}.
\S{cl-2.14} Version 2.14
\b Changed \c{-I} option semantics by adding a trailing path separator unconditionally.
\b Changed \c{-I} option semantics by adding a trailing path separator
unconditionally.
\b Fixed null dereference in corrupted invalid single line macros.

View file

@ -3898,9 +3898,9 @@ mode-dependent macros.
\S{ofmtm} \i\c{__OUTPUT_FORMAT__}: Current Output Format
The \c{__OUTPUT_FORMAT__} standard macro holds the current Output Format,
as given by the \c{-f} option or NASM's default. Type \c{nasm -hf} for a
list.
The \c{__OUTPUT_FORMAT__} standard macro holds the current output
format name, as given by the \c{-f} option or NASM's default. Type
\c{nasm -hf} for a list.
\c %ifidn __OUTPUT_FORMAT__, win32
\c %define NEWLINE 13, 10
@ -3908,6 +3908,15 @@ list.
\c %define NEWLINE 10
\c %endif
\S{dfmtm} \i\c{__DEBUG_FORMAT__}: Current Debug Format
If debugging information generation is enabled, The
\c{__DEBUG_FORMAT__} standard macro holds the current debug format
name as specified by the \c{-F} or \c{-g} option or the output format
default. Type \c{nasm -f} \e{output} \c{y} for a list.
\c{__DEBUG_FORMAT__} is not defined if debugging is not enabled, or if
the debug format specified is \c{null}.
\S{datetime} Assembly Date and Time Macros