0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-10-10 00:25:06 -04:00

labels: make the prefix/suffix options and pragmas consistent

Make the spellings for the label-mangling options and pragmas
consistent, and implement the directive forms which were documented
but never implemented.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin (Intel)
2025-10-07 18:46:39 -07:00
parent c08b4edca1
commit ae9335a0b9
11 changed files with 116 additions and 50 deletions

View File

@@ -86,7 +86,7 @@ NDISASM = disasm\ndisasm.obj
PROGOBJ = $(NASM) $(NDISASM) PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X) PROGS = nasm$(X) ndisasm$(X)
# Files dependent on extracted warnings # Files dependent on warnings.dat
WARNOBJ = asm\warnings.obj WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src

View File

@@ -71,7 +71,7 @@ NDISASM = disasm\ndisasm.obj
PROGOBJ = $(NASM) $(NDISASM) PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X) PROGS = nasm$(X) ndisasm$(X)
# Files dependent on extracted warnings # Files dependent on warnings.dat
WARNOBJ = asm\warnings.obj WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src

View File

@@ -603,6 +603,18 @@ bool process_directives(char *directive)
case D_PRAGMA: case D_PRAGMA:
process_pragma(value); process_pragma(value);
break; break;
case D_PREFIX:
case D_GPREFIX:
case D_SUFFIX:
case D_GSUFFIX:
case D_POSTFIX:
case D_GPOSTFIX:
case D_LPREFIX:
case D_LSUFFIX:
case D_LPOSTFIX:
set_label_mangle(d, value);
break;
} }

View File

@@ -87,18 +87,23 @@ uppercase ; outieee, outobj
#special pragma_tokens #special pragma_tokens
; --- Assembler pragmas ; --- Assembler pragmas
prefix
suffix
gprefix
gsuffix
lprefix
lsuffix
limit limit
; --- Listing pragmas ; --- Listing pragmas
options options
; --- Backend pragmas ; --- Common output pragmas
prefix
suffix
postfix
gprefix
gsuffix
gpostfix
lprefix
lsuffix
lpostfix
; --- Backend-specific pragmas
subsections_via_symbols ; macho subsections_via_symbols ; macho
no_dead_strip ; macho no_dead_strip ; macho
maxdump ; dbg maxdump ; dbg

View File

@@ -262,14 +262,45 @@ static inline bool is_global(enum label_type type)
return type == LBL_GLOBAL || type == LBL_COMMON; return type == LBL_GLOBAL || type == LBL_COMMON;
} }
enum mangle_index {
LM_LPREFIX, /* Local variable prefix */
LM_LSUFFIX, /* Local variable suffix */
LM_GPREFIX, /* Global variable prefix */
LM_GSUFFIX /* GLobal variable suffix */
};
static const char *mangle_strings[] = {"", "", "", ""}; static const char *mangle_strings[] = {"", "", "", ""};
static bool mangle_string_set[ARRAY_SIZE(mangle_strings)]; static bool mangle_string_set[ARRAY_SIZE(mangle_strings)];
/* /*
* Set a prefix or suffix * Set a prefix or suffix
*/ */
void set_label_mangle(enum mangle_index which, const char *what) void set_label_mangle(enum directive how, const char *what)
{ {
enum mangle_index which;
switch (how) {
case D_PREFIX:
case D_GPREFIX:
which = LM_GPREFIX;
break;
case D_SUFFIX:
case D_GSUFFIX:
case D_POSTFIX:
case D_GPOSTFIX:
which = LM_GSUFFIX;
break;
case D_LPREFIX:
which = LM_LPREFIX;
break;
case D_LSUFFIX:
case D_LPOSTFIX:
which = LM_LSUFFIX;
break;
default:
return;
}
if (mangle_string_set[which]) if (mangle_string_set[which])
return; /* Once set, do not change */ return; /* Once set, do not change */

View File

@@ -932,15 +932,15 @@ static const struct textargs textopts[] = {
{"version", OPT_VERSION, ARG_NO, 0}, {"version", OPT_VERSION, ARG_NO, 0},
{"help", OPT_HELP, ARG_MAYBE, 0}, {"help", OPT_HELP, ARG_MAYBE, 0},
{"abort-on-panic", OPT_ABORT_ON_PANIC, ARG_NO, 0}, {"abort-on-panic", OPT_ABORT_ON_PANIC, ARG_NO, 0},
{"prefix", OPT_MANGLE, ARG_YES, LM_GPREFIX}, {"prefix", OPT_MANGLE, ARG_YES, D_PREFIX},
{"postfix", OPT_MANGLE, ARG_YES, LM_GSUFFIX}, {"postfix", OPT_MANGLE, ARG_YES, D_POSTFIX},
{"suffix", OPT_MANGLE, ARG_YES, LM_GSUFFIX}, {"suffix", OPT_MANGLE, ARG_YES, D_SUFFIX},
{"gprefix", OPT_MANGLE, ARG_YES, LM_GPREFIX}, {"gprefix", OPT_MANGLE, ARG_YES, D_GPREFIX},
{"gpostfix", OPT_MANGLE, ARG_YES, LM_GSUFFIX}, {"gpostfix", OPT_MANGLE, ARG_YES, D_GPOSTFIX},
{"gsuffix", OPT_MANGLE, ARG_YES, LM_GSUFFIX}, {"gsuffix", OPT_MANGLE, ARG_YES, D_GSUFFIX},
{"lprefix", OPT_MANGLE, ARG_YES, LM_LPREFIX}, {"lprefix", OPT_MANGLE, ARG_YES, D_LPREFIX},
{"lpostfix", OPT_MANGLE, ARG_YES, LM_LSUFFIX}, {"lpostfix", OPT_MANGLE, ARG_YES, D_LPOSTFIX},
{"lsuffix", OPT_MANGLE, ARG_YES, LM_LSUFFIX}, {"lsuffix", OPT_MANGLE, ARG_YES, D_LSUFFIX},
{"include", OPT_INCLUDE, ARG_YES, 0}, {"include", OPT_INCLUDE, ARG_YES, 0},
{"pragma", OPT_PRAGMA, ARG_YES, 0}, {"pragma", OPT_PRAGMA, ARG_YES, 0},
{"before", OPT_BEFORE, ARG_YES, 0}, {"before", OPT_BEFORE, ARG_YES, 0},

View File

@@ -287,17 +287,14 @@ static enum directive_result output_pragma_common(const struct pragma *pragma)
switch (pragma->opcode) { switch (pragma->opcode) {
case D_PREFIX: case D_PREFIX:
case D_GPREFIX: case D_GPREFIX:
set_label_mangle(LM_GPREFIX, pragma->tail);
return DIRR_OK;
case D_SUFFIX: case D_SUFFIX:
case D_GSUFFIX: case D_GSUFFIX:
set_label_mangle(LM_GSUFFIX, pragma->tail); case D_POSTFIX:
return DIRR_OK; case D_GPOSTFIX:
case D_LPREFIX: case D_LPREFIX:
set_label_mangle(LM_LPREFIX, pragma->tail);
return DIRR_OK;
case D_LSUFFIX: case D_LSUFFIX:
set_label_mangle(LM_LSUFFIX, pragma->tail); case D_LPOSTFIX:
set_label_mangle(pragma->opcode, pragma->tail);
return DIRR_OK; return DIRR_OK;
default: default:
return DIRR_UNKNOWN; return DIRR_UNKNOWN;

View File

@@ -36,8 +36,14 @@ It is the production version of NASM since 2025.
\b A new \c{--bits} option as convenience shorthand for \c{--before \b A new \c{--bits} option as convenience shorthand for \c{--before
"BITS ..."}. See \k{opt-bits}. "BITS ..."}. See \k{opt-bits}.
\b Add aliases \c{--suffix}, \c{--gsuffix} and \c{--lsuffix} for the \b The options and pragmas for configuring external label mangling
corresponding \c{postfix} options. See \k{opt-pfix}. were inconsistent, the former using the spelling \c{postfix} and
the latter \c{suffix}. Furthermore, these were also documented as
\e{directives} in addition to pragmas. Implement the already
documented directives (bracketed forms only) and allow both
\c{postfix} and \c{suffix} in all cases.
See \k{opt-pfix} and \k{mangling}.
\b Define additional permissive patterns and fix some opcode bugs. \b Define additional permissive patterns and fix some opcode bugs.

View File

@@ -402,26 +402,38 @@ global variables).
Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept
private extensions mentioned in \k{global}. private extensions mentioned in \k{global}.
\H{mangling} \i\c{(G|L)PREFIX}, \i\c{(G|L)POSTFIX}: Mangling Symbols \IR{PREFIX} \c{[PREFIX]}
\IC{PREFIX}{GPREFIX} \c{[GPREFIX]}
\IC{PREFIX}{LPREFIX} \c{[LPREFIX]}
\IC{PREFIX}{SUFFIX} \c{[SUFFIX]}
\IC{PREFIX}{GSUFFIX} \c{[GSUFFIX]}
\IC{PREFIX}{LSUFFIX} \c{[LSUFFIX]}
\IC{PREFIX}{POSTFIX} \c{[POSTFIX]}
\IC{PREFIX}{GPOSTFIX} \c{[GPOSTFIX]}
\IC{PREFIX}{LPOSTFIX} \c{[LPOSTFIX]}
\c{PREFIX}, \c{GPREFIX}, \c{LPREFIX}, \c{POSTFIX}, \c{GPOSTFIX}, and \H{mangling} \I{PREFIX}\c{[GL]PREFIX}, \c{[GL]SUFFIX}: Mangling Symbols
\c{LPOSTFIX} directives can prepend or append a string to a certain
\c{[PREFIX}, \c{[GPREFIX}, \c{[LPREFIX}, \c{[SUFFIX}, \c{[GSUFFIX}, and
\c{[LSUFFIX} directives can prepend or append a string to a certain
type of symbols, normally to fit specific ABI conventions type of symbols, normally to fit specific ABI conventions
\b\c{PREFIX}|\c{GPREFIX}: Prepend the argument to all \c{EXTERN}, \b\c{[PREFIX}, \c{[GPREFIX}: Prepend the argument to all \c{EXTERN},
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols. \c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
\b\c{LPREFIX}: Prepend the argument to all other symbols \b\c{[LPREFIX}: Prepend the argument to all other symbols
such as local labels and backend defined symbols. such as local labels and backend defined symbols.
\b\c{POSTFIX}|\c{GPOSTFIX}: Append the argument to all \c{EXTERN}, \b\c{[SUFFIX]}, \c{[GSUFFIX]}, \c{[POSTFIX]}, \c{[GPOSTFIX]}: Append
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols. the argument to all \c{EXTERN}, \c{COMMON}, \c{STATIC}, and
\c{GLOBAL} symbols.
\b\c{LPOSTFIX}: Append the argument to all other symbols \b\c{[LSUFFIX]}, \c{[LPOSTFIX]}: Append the argument to all other symbols
such as local labels and backend defined symbols. such as local labels and backend defined symbols.
These are macros implemented as pragmas, and using \c{%pragma} syntax These directives are also implemented as pragmas, and using
can be restricted to specific backends (see \k{pragma}): \c{%pragma} syntax can be restricted to specific backends (see
\k{pragma}):
\c %pragma macho lprefix L_ \c %pragma macho lprefix L_
@@ -443,13 +455,19 @@ naming scheme to chunk up sections into smaller subsections, each of
which may be eliminated. When the \c{subsections_via_symbols} which may be eliminated. When the \c{subsections_via_symbols}
directive (\k{macho-ssvs}) is declared, each symbol is the start of a directive (\k{macho-ssvs}) is declared, each symbol is the start of a
separate block. The subsection is, then, defined to include sections separate block. The subsection is, then, defined to include sections
before the one that starts with a 'L'. \c{LPREFIX} is useful here to before the one that starts with a 'L'. \c{[LPREFIX]} is useful here to
mark all local symbols with the 'L' prefix to be excluded to the meta mark all local symbols with the 'L' prefix to be excluded to the meta
section. It converts local symbols compatible with the particular section. It converts local symbols compatible with the particular
toolchain. Note that local symbols declared with \c{STATIC} toolchain. Note that local symbols declared with \c{STATIC}
(\k{static}) are excluded from the symbol mangling and also not marked (\k{static}) are excluded from the symbol mangling and also not marked
as global. as global.
Earlier versions of NASM called the pragmas \i\c{suffix} and the
options \i\c{--postfix}, and did not implement directives at all
despite being so documented. Since NASM 3.01, the directive forms are
implemented, and directives, pragmas and options all support all
spellings.
\H{CPU} \i\c{CPU}: Defining CPU Dependencies \H{CPU} \i\c{CPU}: Defining CPU Dependencies

View File

@@ -557,9 +557,13 @@ system calling conventions.
\c{--prefix} is an alias for \c{--gprefix}. \c{--prefix} is an alias for \c{--gprefix}.
Starting with NASM 3.01, \c{--suffix}, \c{--gsuffix}, and See \k{mangling} for the equivalent directives and pragmas.
\c{--lsuffix} are accepted as aliases for the corresponding
\c{postfix} options. Earlier versions of NASM called the pragmas \i\c{suffix} and the
options \i\c{--postfix}, and did not implement directives at all
despite being so documented. Since NASM 3.01, the directive forms are
implemented, and directives, pragmas and options all support all
spellings.
\IR{--pragma} \c{--pragma} option \IR{--pragma} \c{--pragma} option

View File

@@ -10,13 +10,6 @@
#include "compiler.h" #include "compiler.h"
enum mangle_index {
LM_LPREFIX, /* Local variable prefix */
LM_LSUFFIX, /* Local variable suffix */
LM_GPREFIX, /* Global variable prefix */
LM_GSUFFIX /* GLobal variable suffix */
};
enum label_type { enum label_type {
LBL_none = -1, /* No label */ LBL_none = -1, /* No label */
LBL_LOCAL = 0, /* Must be zero */ LBL_LOCAL = 0, /* Must be zero */
@@ -39,7 +32,7 @@ void define_label(const char *label, int32_t segment, int64_t offset,
void backend_label(const char *label, int32_t segment, int64_t offset); void backend_label(const char *label, int32_t segment, int64_t offset);
bool declare_label(const char *label, enum label_type type, bool declare_label(const char *label, enum label_type type,
const char *special); const char *special);
void set_label_mangle(enum mangle_index which, const char *what); void set_label_mangle(enum directive which, const char *what);
int init_labels(void); int init_labels(void);
void cleanup_labels(void); void cleanup_labels(void);
const char *local_scope(const char *label); const char *local_scope(const char *label);