Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ ZLIBOBJ = \
# Common library objects
LIBOBJ_COM = \
stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) \
stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) stdlib/strlcat.$(O) \
\
nasmlib/ver.$(O) \
nasmlib/alloc.$(O) nasmlib/asprintf.$(O) \
Expand Down
26 changes: 25 additions & 1 deletion asm/nasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,8 @@ enum text_options {
OPT_DEBUG,
OPT_INFO,
OPT_REPRODUCIBLE,
OPT_BITS
OPT_BITS,
OPT_DEBUG_PREFIX_MAP
};
enum need_arg {
ARG_NO,
Expand Down Expand Up @@ -925,6 +926,7 @@ static const struct textargs textopts[] = {
{"debug", OPT_DEBUG, ARG_MAYBE, 0},
{"reproducible", OPT_REPRODUCIBLE, ARG_NO, 0},
{"bits", OPT_BITS, ARG_YES, 0},
{"debug-prefix-map", OPT_DEBUG_PREFIX_MAP, ARG_YES, 0},
{NULL, OPT_BOGUS, ARG_NO, 0}
};

Expand Down Expand Up @@ -1305,6 +1307,26 @@ static bool process_arg(char *p, char *q, int pass)
case OPT_REPRODUCIBLE:
reproducible = true;
break;
case OPT_DEBUG_PREFIX_MAP: {
struct debug_prefix_list *d;
char *c;
c = strchr(param, '=');

if (!c) {
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
"option `--%s' must be of the form `BASE=DEST'", p);
break;
}

*c = '\0';
d = nasm_malloc(sizeof(*d));
d->next = debug_prefixes;
d->base = nasm_strdup(param);
d->dest = nasm_strdup(c + 1);
debug_prefixes = d;
*c = '=';
}
break;
case OPT_HELP:
/* Allow --help topic without *requiring* topic */
if (!param)
Expand Down Expand Up @@ -2031,6 +2053,8 @@ static void help(FILE *out, const char *what)
" --lprefix str prepend the given string to local symbols\n"
" --lpostfix str append the given string to local symbols\n"
" --reproducible attempt to produce run-to-run identical output\n"
" --debug-prefix-map base=dest\n"
" remap paths starting with 'base' to 'dest' in output files\n"
, out);
}
if (help_optor(with, HW_LIMIT)) {
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ PA_FUNC_SNPRINTF
PA_FUNC_VSNPRINTF
AC_CHECK_FUNCS([strlcpy])
AC_CHECK_FUNCS([strrchrnul])
AC_CHECK_FUNCS([strlcat])

dnl These types are POSIX-specific, and Windows does it differently...
AC_CHECK_TYPES([struct stat], [AC_CHECK_FUNCS([stat fstat])])
Expand All @@ -247,6 +248,7 @@ AC_CHECK_DECLS(strsep)
AC_CHECK_DECLS(strlcpy)
AC_CHECK_DECLS(strnlen)
AC_CHECK_DECLS(strrchrnul)
AC_CHECK_DECLS(strlcat)

dnl Check for missing types
AC_TYPE_UINTMAX_T
Expand Down
4 changes: 4 additions & 0 deletions include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ size_t strlcpy(char *, const char *, size_t);
char * pure_func strrchrnul(const char *, int);
#endif

#if !defined(HAVE_STRLCAT) || !HAVE_DECL_STRLCAT
size_t strlcat(char *, const char *, size_t);
#endif

/* C++ and C23 have bool, false, and true as proper keywords */
#if !defined(__cplusplus) && (__STDC_VERSION__ < 202311L)
# ifdef HAVE_STDBOOL_H
Expand Down
9 changes: 9 additions & 0 deletions include/nasmlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,19 @@ static inline const char *nasm_digit_chars(bool ucase)
*/
int32_t seg_alloc(void);

struct debug_prefix_list {
struct debug_prefix_list *next;
char *base;
char *dest;
};

extern struct debug_prefix_list *debug_prefixes;

/*
* Add/replace or remove an extension to the end of a filename
*/
const char *filename_set_extension(const char *inname, const char *extension);
char *filename_debug_remap(char *dest, char const *inname, size_t len);

/*
* Utility macros...
Expand Down
4 changes: 4 additions & 0 deletions nasm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ OPTIONS
Prepend or append (respectively) the given argument to all global or
extern variables.

--debug-prefix-map 'BASE=DEST'::
Map file names beginning with 'BASE' to 'DEST' when encoding them in
output object files.

SYNTAX
------
This man page does not fully describe the syntax of *nasm*'s assembly language,
Expand Down
20 changes: 20 additions & 0 deletions nasmlib/filename.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "nasmlib.h"
#include "error.h"

struct debug_prefix_list *debug_prefixes = NULL;

/*
* Add/modify a filename extension, assumed to be a period-delimited
* field at the very end of the filename. Returns a newly allocated
Expand All @@ -31,3 +33,21 @@ const char *filename_set_extension(const char *inname, const char *extension)

return p;
}

char *filename_debug_remap(char *dest, char const *in, size_t len)
{
struct debug_prefix_list *d;
size_t n;

for (d = debug_prefixes; d != NULL; d = d->next) {
n = strlen(d->base);
if (strncmp(in, d->base, n) == 0) {
strlcpy(dest, d->dest, len);
strlcat(dest, &in[n], len);
return dest;
}
}

strlcpy(dest, in, len);
return dest;
}
3 changes: 2 additions & 1 deletion output/outas86.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static struct SAA *strs;
static size_t strslen;

static int as86_reloc_size;
static char filename[FILENAME_MAX];

static void as86_write(void);
static void as86_write_section(struct Section *, int);
Expand Down Expand Up @@ -101,7 +102,7 @@ static void as86_init(void)
strslen = 0;

/* as86 module name = input file minus extension */
as86_add_string(filename_set_extension(inname, ""));
as86_add_string(filename_debug_remap(filename, filename_set_extension(inname, ""), sizeof(filename)));
}

static void as86_cleanup(void)
Expand Down
6 changes: 3 additions & 3 deletions output/outcoff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1239,10 +1239,10 @@ static void coff_write_symbols(void)
*/
coff_symbol(".file", 0L, 0L, -2, 0, 0x67, 1);
if (reproducible)
memset(filename, 0, 18);
memset(filename, 0, sizeof(filename));
else
strncpy(filename, inname, 18);
nasm_write(filename, 18, ofile);
filename_debug_remap(filename, inname, sizeof(filename));
nasm_write(filename, sizeof(filename), ofile);

/*
* The section records, with their auxiliaries.
Expand Down
4 changes: 2 additions & 2 deletions output/outelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,8 @@ static void elf_init(void)
const char * const *p;
const char * cur_path = nasm_realpath(inname);

strlcpy(elf_module, inname, sizeof(elf_module));
strlcpy(elf_dir, nasm_dirname(cur_path), sizeof(elf_dir));
filename_debug_remap(elf_module, inname, sizeof(elf_module));
filename_debug_remap(elf_dir, nasm_dirname(cur_path), sizeof(elf_dir));
sects = NULL;
nsects = sectlen = 0;
syms = saa_init((int32_t)sizeof(struct elf_symbol));
Expand Down
2 changes: 1 addition & 1 deletion output/outieee.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ static void ieee_unqualified_name(char *, char *);
*/
static void ieee_init(void)
{
strlcpy(ieee_infile, inname, sizeof(ieee_infile));
filename_debug_remap(ieee_infile, inname, sizeof(ieee_infile));
any_segs = false;
fpubhead = NULL;
fpubtail = &fpubhead;
Expand Down
2 changes: 1 addition & 1 deletion output/outobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ static const char *get_default_class(const char *segment)

static void obj_init(void)
{
strlcpy(obj_infile, inname, sizeof(obj_infile));
filename_debug_remap(obj_infile, inname, sizeof(obj_infile));
first_seg = seg_alloc();
any_segs = false;
fpubhead = NULL;
Expand Down
43 changes: 43 additions & 0 deletions stdlib/strlcat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2019 Garmin Ltd. or its subsidiaries
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "compiler.h"

/*
* Concatenate src string to dest of size size. The destination buffer will
* have no more than size-1 character when the operation finishes. Always NUL
* terminates, unless size == 0 or dest has no NUL terminator. Returns
* strlen(initial dest) + strlen(src); if retval >= size, truncation occurred.
*/
#ifndef HAVE_STRLCAT

size_t strlcat(char *dest, const char *src, size_t size)
{
size_t n;

/* find the NULL terminator in dest */
for (n = 0; n < size && dest[n] != '\0'; n++)
;

/* destination was not NULL terminated. Return the initial size */
if (n == size)
return size;

return strlcpy(&dest[n], src, size - n) + n;
}

#endif

6 changes: 6 additions & 0 deletions test/elfdebugprefix.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
;Testname=unoptimized; Arguments=-O0 --debug-prefix-map elf=ELF -felf -oelfdebugprefix.o; Files=stdout stderr elfdebugprefix.o; Validate=readelf --wide --symbols elfdebugprefix.o | grep 'FILE.*ELFdebugprefix.asm'

SECTION .text
test: ; [1]
ret

12 changes: 10 additions & 2 deletions test/performtest.pl
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,22 @@ sub perform {
TEST:
while(<TESTFILE>) {
#See if there is a test case
last unless /Testname=(.*);\s*Arguments=(.*);\s*Files=(.*)/;
my ($subname, $arguments, $files) = ($1, $2, $3);
last unless /Testname=(.*);\s*Arguments=(.*);\s*Files=([^;]*)(?:;\s*Validate=(.*))?/;
my ($subname, $arguments, $files, $validate) = ($1, $2, $3, $4);
chomp $files;
debugprint("$subname | $arguments | $files");

#Call nasm with this test case
system("$nasm $arguments $testpath > $stdoutfile 2> $stderrfile");
debugprint("$nasm $arguments $testpath > $stdoutfile 2> $stderrfile ----> $?");

if($validate) {
if(system("$validate >> $stdoutfile 2>> $stderrfile") != 0) {
print "Test $testname/$subname validation failed\n";
$globalresult = 1;
}
}

#Move the output to the test dir
mkpath("$outputdir/$testname/$subname");
foreach(split / /,$files) {
Expand Down
6 changes: 6 additions & 0 deletions travis/nasm-t.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,12 @@ def test_run(desc):
if filecmp.cmp(match, output) == False:
show_diff(desc['_test-name'], match, output)
return test_fail(desc['_test-name'], match + " and " + output + " files are different")
if 'validate' in t:
pvalidate = subprocess.run(t['validate'].format(output=output), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if pvalidate.returncode != 0:
return test_fail(desc['_test-name'], "Validation failed with %d:\nSTDOUT: %s\nSTDERR: %s" % (pvalidate.returncode, pvalidate.stdout, pvalidate.stderr))

elif 'stdout' in t:
print("\tComparing stdout")
match = desc['_base-dir'] + os.sep + t['stdout']
Expand Down
16 changes: 16 additions & 0 deletions travis/test/efldebugprefix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[
{
"description": "Test debug-prefix-map on ELF files",
"id": "elfdebugprefix",
"format": "elf",
"source": "elfdebugprefix.asm",
"option": "-O0 --debug-prefix-map ./travis/test/elf=ELF",
"target": [
{
"output": "elfdebugprefix.o",
"validate": "readelf --wide --symbols {output} | grep 'FILE.*ELFdebugprefix.asm'"
}
]
}
]

4 changes: 4 additions & 0 deletions travis/test/elfdebugprefix.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SECTION .text
test: ; [1]
ret

Binary file added travis/test/elfdebugprefix.o.t
Binary file not shown.