Commit graph

742 commits

Author SHA1 Message Date
H. Peter Anvin (Intel)
9248a85f97 asm/error.c: handle -w* during command line parsing
During command line parsing, warning_state_init is NULL as the warning
stack is naturally not set up yet. Furthermore, -w* would mean return
to command-line default, which isn't even defined yet.

Rather than ignoring it or returning an error, do something useful by
allowing -w* to reset to the *compile time* default when specified on
the command line.

Reported-by: <momo-trip@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/155
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-07 15:43:40 -07:00
H. Peter Anvin (Intel)
18c778c590 files: formalize storing "mapped" file names in the filenames system
Formalize the mechanism for storing mapped (non-filesystem) filenames
in the filenames array. These are not compared against input or output
files for overwrite checks.

Add the infrastructure for comparing more than one input filename
(future proofing.)

Move the Makefile dependency target name to the filenames system.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 17:08:01 -07:00
Joshua Watt
851460a10b Add --debug-prefix-map option
Adds an option to remap file prefixes in output object files. This is
analogous to the "-fdebug-prefix-map" option in GCC, and allows files to
be built in a reproducible manner regardless of the build directory.

[ hpa: this still needs to be documented in doc/running.src. ]

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:22:48 -07:00
H. Peter Anvin (Intel)
dad1d8ca42 outbin: register the mapfile; check for input clobber; remove on fail
- Register the map file with the filename system.
- Check to see if the mapfile is clobbering the input.
- Remove the map file if the output file is also removed.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 18:22:39 -07:00
H. Peter Anvin (Intel)
720a32672c Refactor the handling of primary input/output files
Replace the direct setting of variables for input and output variables
with accessors. This allows for properly tracking the lifetimes of the
data and allows for things like checking of the overwrite of the
primary input file to be centralized.

It isn't possible *in the general case* to check for overwrite of
*any* of the input files, although in the particularly important case
of the assembler proper it ought to be possible to do a bit better:

it should be able to guard for overwrites of non-primary input files
except for the error file or the list file if and only if -Lp is used.

That is, however, a latter project.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 18:22:26 -07:00
H. Peter Anvin (Intel)
27500eee7f preproc.c: check do_delete_Token() actually has a token
It seems pretty clear from the API that [do_]delete_Token() always was
intended to allow for a NULL option; the test for "if (tp)" is
somewhat pointless when invoking the delete_Token() macro which does a
do_delete_Token(&(t)).

Add in the null check to *tp as well.

Fixes: https://github.com/netwide-assembler/nasm/issues/176
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:18:43 -07:00
H. Peter Anvin (Intel)
9969b34454 listing: add __?LIST_OPTIONS?__ and __?LIST_OPTIONS_DEFAULT?__ macros
Add macros to query the current state of the listing options, add
appropriate documentation.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:13:30 -07:00
H. Peter Anvin (Intel)
06f9a1855e listing.[ch]: allow ! to be used in %pragma and * to reset to cmdline
Do allow the ! as a wildcard for all options to be used in %pragma as
well as on the command line.

Keep track of the command-line default to allow the * modifier (like
warnings) to reset to the command-line default.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:04:25 -07:00
H. Peter Anvin (Intel)
640c7e0f5b preproc: fix memory leak: long tokens never freed
When tokens exceeded INLINE_TEXT, free_Token() had managed to miss
freeing the allocated token buffer.

This is different from the pull request merely in forward-porting the
change to the current code base.

Reported-by: <sorokin@github.com>
Fixes: https://github.com/netwide-assembler/nasm/pull/70
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 18:55:25 -07:00
H. Peter Anvin (Intel)
4d18bdd318 listing: allow the user to suppress abbreviation of TIMES and INCBIN
Allow the user to suppress the abbreviation of the output from TIMES
(and therefore ALIGN) and INCBIN.

Sync the documentation with the help text, too.

Fixes: https://github.com/netwide-assembler/nasm/issues/211
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 18:11:40 -07:00
H. Peter Anvin (Intel)
6051380c34 nasm.c: in preprocessor mode (-E) free the line data after printing
pp_getline() returns a string in heap storage, it needs to be freed.
This is done correctly in the other modes, but in preprocessor mode,
the freeing was missed.

This also replaces nasm_free() ... assignment with the nasm_strto()
idiom.

Reported-by: <for-just-we@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/254
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 16:35:31 -07:00
H. Peter Anvin (Intel)
7bc82e7daf asm/nasm.c: fix use-after-free for -M* options in -@ files
-M* options in response files would hold on to a pointer to the new
value, but in response files that is not a persistent buffer. Make
sure to make a copy instead.

This uses the new nasm_str[dup]to() helpers.

(Note that calling nasm_free() on a NULL pointer is guaranteed safe.)

Reported-by: <BreakingBad6@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/222
Fixes: CVE-2026-6068
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 17:35:33 -07:00
H. Peter Anvin (Intel)
414ea824d9 directiv.c: correct the parsing of $-symbols in directives, again
1fc631a173 [directiv.c: $-hex requires nasm_isnumstart, not just nasm_isnumchar]

... was accidentally a commit of a wrong, broken version of the fix
(SIGMY: My fault (core dumped)).

Both the nasm_isidchar() and !nasm_isnumstart() checks need to be
applied to the *same* character, the one immediately after '$'.

Huge special thanks to ecm-pushbx for the quick testing and timely bug
report!

Reported-by: <ecm-pushbx@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/252
Fixes: 1fc631a173
Fixes: 178a1b7443
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:11:19 -07:00
alexvoste
cfcfe9e701 asm/labels: fix memory leak in local label structures
Travis CI testing with AddressSanitizer (ASan) triggered a severe memory
leak in the assembler label tracking. Local label structures were not
properly freed during cleanup stages. This fix adds proper verification
and destruction of tracking labels, resolving the ASan memory leak.

Signed-off-by: alexvoste <alexvostedev@proton.me>
[ hpa: fixed indentation style and removed unnecessary { } ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 15:13:47 -07:00
alexvoste
3a33d83610 parser: fix invalid segment override on EQU FAR pointers
The parser incorrectly treated colons as memory segment overrides inside
EQU directives because of an inverted far_jmp_ok check. This regression
was introduced in commit 8981724. Removing the incorrect negation
restores proper parsing of FAR pointer constants.

Fixes #242

Signed-off-by: alexvoste <alexvostedev@proton.me>
2026-06-25 15:11:05 -07:00
H. Peter Anvin (Intel)
2b37c0ad75 directiv.c: include leading $ in a token if missing an identifier
When complaining about a valid token where an identifier was expected,
do include the leading $ if at all applicable to avoid confusing the
user.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 14:59:33 -07:00
H. Peter Anvin (Intel)
1fc631a173 directiv.c: $-hex requires nasm_isnumstart, not just nasm_isnumchar
For identifier-escapes beginning with $a-f to work, the $ hexadecimal
prefix cannot be used, nor could it ever be used, with A-F immediately
after the $. This is the main reason the $-hex has been deprecated.

When adding the non-dollarhex mode, this got accidentally promoted to
nasm_isnumchar() instead of nasm_isnumstart(), which broke using
$-escaped identifiers in directives.

To fix this properly, it would be a good thing to add a central
identifier-skipping function.

Fixes: https://github.com/netwide-assembler/nasm/issues/223
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 14:58:22 -07:00
H. Peter Anvin (Intel)
6f830c1c74 labels: handle the sequence EXTERN, GLOBAL, defined
The sequence EXTERN, GLOBAL, definition would fail, because the EXTERN
would create a pseudo-segment and consider it a definition, whereas
GLOBAL would set change it to a global definition, but leaving the
definition existing, which is not the normal case for a GLOBAL symbol
(define_label would not be called.)

Therefore, explicitly "undefine" the symbol by setting defn.defined to
0, as it would be after a GLOBAL statement, as as it is when an EXTERN
statement is followed by a definition (causing it to be implicitly
promoted to GLOBAL.)

Reported-by: E. C. Masloch <ecm-pushbx@github.com>
Reported-by: <roel-z@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/224
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 15:08:27 -07:00
H. Peter Anvin (Intel)
0c9baa8f3a preproc: ensure forward process in %clear loop
The %clear loop was missing advancing to the next token. Also allow
the list to be comma-separated, like most other cases in NASM.
Reported-by: <magicelk235@gmail.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/227
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:40:01 -07:00
H. Peter Anvin (Intel)
9052efaa63 preproc: warn if the user tries to use %rmacro
Unfortunately, the %rmacro and %irmacro directives were not disabled
when recursive macros were removed due to the implementation did not
work. Make them issue a warning and document that they might change in
the future.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:29:41 -07:00
H. Peter Anvin (Intel)
d832776ccb Revert "parser: fix invalid segment override on EQU FAR pointers"
This reverts commit 35ffac3ea0.

This commit caused a regression, causing segment overrides to get
lost. Multiple travis tests failed as a result.

Revert this until a proper solution exists.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:54:47 -07:00
xmoezzz
d2541cb884 nasm.c: response file (-@) option parsing UAF affecting debug format selection (-F / -g)
Fixes: https://github.com/netwide-assembler/nasm/pull/189
[ hpa: added necessary cast to nasm_free() ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:21:09 -07:00
alexvoste
35ffac3ea0 parser: fix invalid segment override on EQU FAR pointers
The parser incorrectly treated colons as memory segment overrides inside
EQU directives because of an inverted far_jmp_ok check. This regression
was introduced in commit 8981724. Removing the incorrect negation restores
proper parsing of FAR pointer constants.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 18:21:39 -07:00
H. Peter Anvin (Intel)
de7a94e884 asm/preproc.c: remove unused variable bad_bracket
This variable was assigned but never used.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:52:15 -07:00
H. Peter Anvin (Intel)
0114c92101 asm/assemble.c: remove unused variable this_good
This variable was assigned but never used.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:51:49 -07:00
Yongjie2017
b5235c49f0 asm/preproc.c: fix https://nvd.nist.gov/vuln/detail/CVE-2025-8842
When there is an ill formed assembly (e.g. a macro without a correct
ending), the assembly processing will end with a defining->refcnt
in non-zero value that further causes a nasm_assert in free_mmacro,
the nasm_assert causes a panic.

Force the defining->refcnt to zero in pp_clean_pass as a bailout.

Signed-off-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
2026-04-17 06:35:57 +08:00
Yongjie2017
8c3f3fbe36 asm/preproc.c: fix https://nvd.nist.gov/vuln/detail/CVE-2025-8844
When there is an invalid radix specifier, the parse_smacro_template
set the current char pointer (cp) to NULL, but the tailing processing
of the for loop increases the cp so its value is 0x1 that deceives
the for loop condition check.

Add a NULL pointer checking on the cp after the switch statement
to quit the for loop because of the invalid radix specifier.

Signed-off-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
2026-04-17 06:33:06 +08:00
H. Peter Anvin (Intel)
3cb6231581 asm/preproc.c: remove git merge crap in comment
A comment accidentally was left with a merge resolution
annotation. This was of course harmless, being in a comment, but it
shouldn't be there.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:21:41 -07:00
H. Peter Anvin (Intel)
e1e03770f7 asm/preproc.c: remove dead code, improve comment
ppscan() had a break; statement followed immediately by a return
statement. The latter was left over from code restructuring and is
dead code.

Remove it.

Fix a nearby comment indicating that we should not need to strip a
const from a string pointer. Probably Token::t_charptr should be
const, but it might need additional work.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:10:16 -07:00
H. Peter Anvin (Intel)
c8ea2d906d asm/preproc.c: fix NULL pointer on %exitrep outside %rep
When %exitrep incorrectly occurs outside a %rep block, do_exit_macro()
returns NULL, but the %exitrep code would try to set m->in_progress =
1 anyway, causing a NULL pointer dereference and crashing NASM.

Add a NULL pointer guard around this assignment; an error has already
been issued.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:06:34 -07:00
H. Peter Anvin (Intel)
d7c7de072f asm/preproc.c: correct the parameter string size calculation
In list_smacro_def(), the number of characters required for the
parameter string description was off by one; fix.

Improve the comment to explain the exact calculation, and make it more
explicit by specifying the calculation as (5+3+1) instead of just 9.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:03:51 -07:00
H. Peter Anvin (Intel)
d1e9ce5ab0 asm/preproc.c: merge end-of-input code
Normally, end of included files or special inputs should be handled by
pp_tokline(), but under some conditions it might be handled by
pp_cleanup_pass(). The latter case would assume the input was from a
file, which would cause a crash if istk->fp is NULL.

Although this should never happen, this is a good reason to merge
these two pieces of code, which ought to be doing the same thing
anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 12:55:55 -07:00
H. Peter Anvin (Intel)
00fe1077dc Add \^ escape sequences for Ctrl characters
It is fairly common to want to represent characters like
Ctrl-Z. Instead of having to use character codes, allow these to be
coded as `\^z` or `\^Z` instead.

`\^?` is DEL.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:08:21 -07:00
H. Peter Anvin (Intel)
fe5235ffc9 limits: allow querying limits, and reset limits for each pass
Allow limits to be queried via a %limit() preprocessor function and a
__?NASM_LIMITS?__ macro.

Reset limits at the top of each pass. Note that the pass number limits
are checked at the *end* of the pass, so a %pragma limit will be
properly honored anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 17:00:49 -07:00
H. Peter Anvin (Intel)
444ef5a122 asm/preproc.c: remove (void) on variable which is actually used
stdmac_env() actually uses nparams, so don't (void) it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 16:54:47 -07:00
H. Peter Anvin (Intel)
4afd70f404 assemble_file(): make stall_count static
This function is invoked separately for each pass; therefore the stall
count would never get incremented. Make it a static variable to make
sure it does get incremented correctly.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 16:51:52 -07:00
H. Peter Anvin (Intel)
a8d44ce956 limits: revamp the limit processor, change params limit to dynamic
Revamp the limit processor to allow a limit to have an absolute
maximum other than LIMIT_MAX_VAL.

Use LIMIT_MAX as a final enum parameter == parameter count == final
actual value + 1, which is the more usual construct and doesn't need
manual updating.

Allow setting a limit to the default value by setting it to "0" or
"default".

Accept "max" or "maximum" instead of "unlimited", specifically to
better handle the case of a fixed maximum < LIMIT_MAX_VAL.

Change the mmacro limit parameter to a dynamic limit, in case someone
needs it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 15:12:19 -07:00
H. Peter Anvin (Intel)
e856c2e1dd asm/preproc.c: limit the mmacro parameter count to 16383
There is no conceivable way that a *specified* mmacro parameter count
of anywhere near that much would make sense, and as such almost
certainly represents an error.

Note that the code will still support varadic macros with an excessive
number of parameters.

Use int64_t to make (reasonably) sure that we actually catch
overflows.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 14:48:46 -07:00
H. Peter Anvin (Intel)
ab0cb6afcb asm/preproc.c: set MAX_TEXT to INT_MAX >> 2
There are still places in the code where "int" are used as
length. Reduce MAX_TEXT to INT_MAX >> 2 so that even adding two
lengths together should make a valid "int".

A token shouldn't be 512GB anyway...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 13:52:13 -07:00
H. Peter Anvin (Intel)
b41191e29d warnings.dat: fix a missing "is"
Another editorial change.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 02:21:20 -07:00
H. Peter Anvin (Intel)
6f8dc8116f warnings.dat: correct regative -> negative spelling
Correct a typo.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 02:17:50 -07:00
H. Peter Anvin (Intel)
55e064dccb preproc: %env() function
Add an %env() function for expanding environment variables as a more
flexible and robust alternative to %! (the variable name can be
computed without doing weird things like %tok(%strcat("%!",...)) and a
fallback value can be specified by the user.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 01:14:17 -07:00
H. Peter Anvin (Intel)
2ac469c93e preproc: for a parameter of type =x/ub, the topmost bit was lost
The buffer size passed in did not account for the terminating zero,
even though space was allocated for it. Explicitly use the size of the
buffer minus two bytes for the radix prefix instead of 64 (which is
the maximum possible number of digits, not the length of the string
buffer.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-07 23:49:00 -07:00
H. Peter Anvin (Intel)
c8fa17205b Add support for C2y-style \o and braced escapes, and \d for decimal
C2y adds \o for octal byte escapes, and allows \x, \o, or \u escape
sequences to be enclosed in braces to indicate their termination.

Add a \d sequence as a NASM extension to allow decimal bytes to be
specified.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-06 17:59:28 -08:00
H. Peter Anvin (Intel)
b1909cf39b listing: move LIST_* enums to listing.h
The LIST_* enums belongs in listing.h, move them there and actually
use them in listing.c.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-04 14:14:02 -08:00
H. Peter Anvin (Intel)
89e1d6203a assemble: for -LX emit specific template number as well
When using -LX to debug template selection, emit the specific template
number (as per insnsa.c) as well as the xda line number.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-04 14:12:55 -08:00
H. Peter Anvin (Intel)
5606bdb335 listing: move the setting of options to one function
Disentangle the list option setting from the list option
checking. This makes the code simpler for the compiler to grok, and
centralizing code is usually a good idea.

The option setting is hardly performance critical anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 15:26:56 -08:00
H. Peter Anvin (Intel)
fe9586f201 listing: separate "user" and "debug" flag, add matching debug option
Adding information about the NASM internal state to the list file can
be useful for debugging purposes. Separate the list of options that
are "user" options and those that are "debugging" options. The latter
are not implied by -L+ and are intended for NASM developer use.

Introduce -LX, which lists which instruction patterns are matched by
each instruction.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 14:12:48 -08:00
H. Peter Anvin (Intel)
2aab21b3fb Fix the handling of the "rel" and "iwd" byte codes with oXX prefixes
The "rel" and "iwd" byte codes are supposed to be sensitive to the
operand size of the instruction, but inadvertently were only sensitive
to the CPU mode or an explicit size override for the operand.

"rel" affects direct near jumps, calls, and XBEGIN; "iwd" direct far
jumps and calls. No other instructions use these opcodes.

Fix this, so that e.g. "o32 jmp foo" is treated the same as "jmp dword
foo".

Correct the golden copies of the jmpxx travis tests (which were always
wrong.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 09:57:44 -08:00
Maciej Wieczor-Retman
3910b58e96 parser.c: Fix issue #181 - redundancy needed to avoid NEAR optimized out
To assemble a JMP in the NEAR form the STRICT keyword is needed. This
change introduced recently reportedly breaks building boot sectors and
is non-intuitive since other JMP versions don't behave this way.

Disable optimizing the JMP size if the NEAR keyword is used.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-04 17:18:44 +01:00