Skip to content

Commit

Permalink
preproc: standard macros now C-safe, %aliases off, fix %? recursion
Browse files Browse the repository at this point in the history
Enough users expect the namespace starting with underscore to be safe
for symbols. Change our private namespace from __foo__ to
__?foo?__. Use %defalias to provide backwards compatiblity (by using
%defalias instead of %define, we handle the case properly where the
user changes the value.)

Add a preprocessor directive:

%aliases off

... to disable all smacro aliases and thereby making the namespace
clean.

Finally, fix infinite recursion when seeing %? or %?? due to
paste_tokens(). If we don't paste anything, the expansion is done.

Signed-off-by: H. Peter Anvin <[email protected]>
  • Loading branch information
H. Peter Anvin committed Aug 27, 2019
1 parent eaef851 commit d235408
Show file tree
Hide file tree
Showing 25 changed files with 519 additions and 351 deletions.
10 changes: 5 additions & 5 deletions asm/float.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,18 +737,18 @@ static int to_float(const char *str, int s, uint8_t *result,
if (str[0] == '_') {
/* Special tokens */

switch (str[2]) {
case 'n': /* __nan__ */
switch (str[3]) {
case 'n': /* __?nan?__ */
case 'N':
case 'q': /* __qnan__ */
case 'q': /* __?qnan?__ */
case 'Q':
type = FL_QNAN;
break;
case 's': /* __snan__ */
case 's': /* __?snan?__ */
case 'S':
type = FL_SNAN;
break;
case 'i': /* __infinity__ */
case 'i': /* __?infinity?__ */
case 'I':
type = FL_INFINITY;
break;
Expand Down
22 changes: 11 additions & 11 deletions asm/nasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,29 +299,29 @@ static void define_macros(void)
char temp[128];

if (oct->have_local) {
strftime(temp, sizeof temp, "__DATE__=\"%Y-%m-%d\"", &oct->local);
strftime(temp, sizeof temp, "__?DATE?__=\"%Y-%m-%d\"", &oct->local);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__DATE_NUM__=%Y%m%d", &oct->local);
strftime(temp, sizeof temp, "__?DATE_NUM?__=%Y%m%d", &oct->local);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__TIME__=\"%H:%M:%S\"", &oct->local);
strftime(temp, sizeof temp, "__?TIME?__=\"%H:%M:%S\"", &oct->local);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__TIME_NUM__=%H%M%S", &oct->local);
strftime(temp, sizeof temp, "__?TIME_NUM?__=%H%M%S", &oct->local);
preproc->pre_define(temp);
}

if (oct->have_gm) {
strftime(temp, sizeof temp, "__UTC_DATE__=\"%Y-%m-%d\"", &oct->gm);
strftime(temp, sizeof temp, "__?UTC_DATE?__=\"%Y-%m-%d\"", &oct->gm);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__UTC_DATE_NUM__=%Y%m%d", &oct->gm);
strftime(temp, sizeof temp, "__?UTC_DATE_NUM?__=%Y%m%d", &oct->gm);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__UTC_TIME__=\"%H:%M:%S\"", &oct->gm);
strftime(temp, sizeof temp, "__?UTC_TIME?__=\"%H:%M:%S\"", &oct->gm);
preproc->pre_define(temp);
strftime(temp, sizeof temp, "__UTC_TIME_NUM__=%H%M%S", &oct->gm);
strftime(temp, sizeof temp, "__?UTC_TIME_NUM?__=%H%M%S", &oct->gm);
preproc->pre_define(temp);
}

if (oct->have_posix) {
snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, oct->posix);
snprintf(temp, sizeof temp, "__?POSIX_TIME?__=%"PRId64, oct->posix);
preproc->pre_define(temp);
}

Expand All @@ -330,7 +330,7 @@ static void define_macros(void)
* we have to put shortname of the alias itself here
* otherwise ABI backward compatibility gets broken.
*/
snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s",
snprintf(temp, sizeof(temp), "__?OUTPUT_FORMAT?__=%s",
ofmt_alias ? ofmt_alias->shortname : ofmt->shortname);
preproc->pre_define(temp);

Expand All @@ -344,7 +344,7 @@ static void define_macros(void)
* Debug format, if any
*/
if (dfmt != &null_debug_form) {
snprintf(temp, sizeof(temp), "__DEBUG_FORMAT__=%s", dfmt->shortname);
snprintf(temp, sizeof(temp), "__?DEBUG_FORMAT?__=%s", dfmt->shortname);
preproc->pre_define(temp);
}
}
Expand Down
1 change: 1 addition & 0 deletions asm/pptok.dat
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
%un!macro

# Other directives
%aliases
%arg
%clear
%depend
Expand Down
99 changes: 86 additions & 13 deletions asm/preproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ static int LocalOffset = 0;
static Context *cstk;
static Include *istk;
static const struct strlist *ipath_list;
static bool do_aliases;

static struct strlist *deplist;

Expand Down Expand Up @@ -1602,6 +1603,55 @@ static int ppscan(void *private_data, struct tokenval *tokval)
return tokval->t_type = tline->text[0];
}

/*
* 1. An expression (true if nonzero 0)
* 2. The keywords true, on, yes for true
* 3. The keywords false, off, no for false
* 4. An empty line, for true
*
* On error, return defval (usually the previous value)
*/
static bool pp_get_boolean_option(Token *tline, bool defval)
{
static const char * const noyes[] = {
"no", "yes",
"false", "true",
"off", "on"
};
struct ppscan pps;
struct tokenval tokval;
expr *evalresult;

skip_white_(tline);
if (!tline || !tline->type)
return true;

if (tline->type == TOK_ID) {
size_t i;
for (i = 0; i < ARRAY_SIZE(noyes); i++)
if (!nasm_stricmp(tline->text, noyes[i]))
return i & 1;
}

pps.tptr = NULL;
pps.tptr = tline;
pps.ntokens = -1;
tokval.t_type = TOKEN_INVALID;
evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL);

if (!evalresult)
return true;

if (tokval.t_type)
nasm_warn(WARN_OTHER, "trailing garbage after expression ignored");
if (!is_really_simple(evalresult)) {
nasm_nonfatal("boolean flag expression must be a constant");
return defval;
}

return reloc_value(evalresult) != 0;
}

/*
* Compare a string to the name of an existing macro; this is a
* simple wrapper which calls either strcmp or nasm_stricmp
Expand Down Expand Up @@ -1801,7 +1851,7 @@ FILE *pp_input_fopen(const char *filename, enum file_flags mode)
*/
static bool
smacro_defined(Context * ctx, const char *name, int nparam, SMacro ** defn,
bool nocase)
bool nocase, bool find_alias)
{
struct hash_table *smtbl;
SMacro *m;
Expand All @@ -1817,12 +1867,22 @@ smacro_defined(Context * ctx, const char *name, int nparam, SMacro ** defn,
} else {
smtbl = &smacros;
}

restart:
m = (SMacro *) hash_findix(smtbl, name);

while (m) {
if (!mstrcmp(m->name, name, m->casesense && nocase) &&
(nparam <= 0 || m->nparam == 0 || nparam == m->nparam ||
(m->greedy && nparam >= m->nparam-1))) {
if (m->alias && !find_alias) {
if (do_aliases) {
name = m->name;
goto restart;
} else {
continue;
}
}
if (defn) {
*defn = (nparam == m->nparam || nparam == -1) ? m : NULL;
}
Expand Down Expand Up @@ -1963,7 +2023,7 @@ static enum cond_state if_condition(Token * tline, enum preproc_token ct)
dname);
goto fail;
}
if (smacro_defined(NULL, tline->text, 0, NULL, true))
if (smacro_defined(NULL, tline->text, 0, NULL, true, false))
j = true;
tline = tline->next;
}
Expand Down Expand Up @@ -2460,7 +2520,7 @@ static SMacro *define_smacro(const char *mname, bool casesense,
while (1) {
ctx = get_ctx(mname, &mname);

if (!smacro_defined(ctx, mname, nparam, &smac, casesense)) {
if (!smacro_defined(ctx, mname, nparam, &smac, casesense, true)) {
/* Create a new macro */
smtbl = ctx ? &ctx->localmac : &smacros;
smhead = (SMacro **) hash_findi_add(smtbl, mname);
Expand All @@ -2476,7 +2536,7 @@ static SMacro *define_smacro(const char *mname, bool casesense,
* some others didn't. What is the right thing to do here?
*/
goto fail;
} else if (!smac->alias || defining_alias) {
} else if (!smac->alias || !do_aliases || defining_alias) {
/*
* We're redefining, so we have to take over an
* existing SMacro structure. This means freeing
Expand Down Expand Up @@ -2545,6 +2605,8 @@ static void undef_smacro(const char *mname, bool undefalias)
while ((s = *sp) != NULL) {
if (!mstrcmp(s->name, mname, s->casesense)) {
if (s->alias && !undefalias) {
if (!do_aliases)
continue;
if (s->in_progress) {
nasm_nonfatal("macro alias loop");
} else {
Expand Down Expand Up @@ -3916,6 +3978,12 @@ static int do_directive(Token *tline, Token **output)
define_smacro(mname, casesense, macro_start, NULL);
break;

case PP_ALIASES:
tline = tline->next;
tline = expand_smacro(tline);
do_aliases = pp_get_boolean_option(tline, do_aliases);
break;

case PP_LINE:
/*
* Syntax is `%line nnn[+mmm] [filename]'
Expand Down Expand Up @@ -4371,7 +4439,7 @@ static Token *expand_mmac_params(Token * tline)
cc = find_cc(tt);
if (cc == -1) {
nasm_nonfatal("macro parameter `%s' is not a condition code",
text);
t->text);
text = NULL;
break;
}
Expand Down Expand Up @@ -4534,6 +4602,8 @@ static SMacro *expand_one_smacro(Token ***tpp)
* checking for parameters if necessary.
*/
list_for_each(m, head) {
if (unlikely(m->alias && !do_aliases))
continue;
if (!mstrcmp(m->name, mname, m->casesense))
break;
}
Expand Down Expand Up @@ -4986,8 +5056,10 @@ static Token *expand_smacro_noreset(Token * tline)
* Also we look for %+ tokens and concatenate the tokens
* before and after them (without white spaces in between).
*/
paste_tokens(&thead, tmatch, ARRAY_SIZE(tmatch), true);

if (!paste_tokens(&thead, tmatch, ARRAY_SIZE(tmatch), true)) {
tline = thead;
break;
}
expanded = false;
}

Expand Down Expand Up @@ -5578,10 +5650,10 @@ struct magic_macros {
};
static const struct magic_macros magic_macros[] =
{
{ "__FILE__", 0, stdmac_file },
{ "__LINE__", 0, stdmac_line },
{ "__BITS__", 0, stdmac_bits },
{ "__PTR__", 0, stdmac_ptr },
{ "__?FILE?__", 0, stdmac_file },
{ "__?LINE?__", 0, stdmac_line },
{ "__?BITS?__", 0, stdmac_bits },
{ "__?PTR?__", 0, stdmac_ptr },
{ NULL, 0, NULL }
};

Expand Down Expand Up @@ -5613,6 +5685,7 @@ pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list)
unique = 0;
deplist = dep_list;
pp_mode = mode;
do_aliases = true;

if (!use_loaded)
use_loaded = nasm_malloc(use_package_count * sizeof(bool));
Expand Down Expand Up @@ -5656,7 +5729,7 @@ pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list)
do_predef = true;

/*
* Define the __PASS__ macro. This is defined here unlike all the
* Define the __?PASS?__ macro. This is defined here unlike all the
* other builtins, because it is special -- it varies between
* passes -- but there is really no particular reason to make it
* magic.
Expand All @@ -5680,7 +5753,7 @@ pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list)
panic();
}

define_smacro("__PASS__", true, make_tok_num(apass), NULL);
define_smacro("__?PASS?__", true, make_tok_num(apass), NULL);
}

static void pp_init(void)
Expand Down
62 changes: 31 additions & 31 deletions asm/tokens.dat
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,42 @@ to
ptr

% TOKEN_FLOAT, 0, 0, 0
__infinity__
__nan__
__qnan__
__snan__

% TOKEN_FLOATIZE, 0, 0, FLOAT_{__float*__}
__float8__
__float16__
__float32__
__float64__
__float80m__
__float80e__
__float128l__
__float128h__

% TOKEN_STRFUNC, 0, 0, STRFUNC_{__*__}
__utf16__
__utf16le__
__utf16be__
__utf32__
__utf32le__
__utf32be__

% TOKEN_IFUNC, 0, 0, IFUNC_{__*__}
__ilog2e__
__ilog2w__
__ilog2f__
__ilog2c__
__?infinity?__
__?nan?__
__?qnan?__
__?snan?__

% TOKEN_FLOATIZE, 0, 0, FLOAT_{__?float*?__}
__?float8?__
__?float16?__
__?float32?__
__?float64?__
__?float80m?__
__?float80e?__
__?float128l?__
__?float128h?__

% TOKEN_STRFUNC, 0, 0, STRFUNC_{__?*?__}
__?utf16?__
__?utf16le?__
__?utf16be?__
__?utf32?__
__?utf32le?__
__?utf32be?__

% TOKEN_IFUNC, 0, 0, IFUNC_{__?*?__}
__?ilog2e?__
__?ilog2w?__
__?ilog2f?__
__?ilog2c?__

% TOKEN_*, 0, 0, 0
seg
wrt

% TOKEN_{__*__}, 0, 0, 0
__masm_ptr__
__masm_flat__
% TOKEN_{__?*?__}, 0, 0, 0
__?masm_ptr?__
__?masm_flat?__

% TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO{1to*}
1to2
Expand Down
Loading

0 comments on commit d235408

Please sign in to comment.