Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug prefix map #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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 @@ -104,7 +104,7 @@ PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)

LIBOBJ_NW = 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) nasmlib/errfile.$(O) \
Expand Down
26 changes: 25 additions & 1 deletion asm/nasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,8 @@ enum text_options {
OPT_KEEP_ALL,
OPT_NO_LINE,
OPT_DEBUG,
OPT_REPRODUCIBLE
OPT_REPRODUCIBLE,
OPT_DEBUG_PREFIX_MAP
};
enum need_arg {
ARG_NO,
Expand Down Expand Up @@ -975,6 +976,7 @@ static const struct textargs textopts[] = {
{"no-line", OPT_NO_LINE, ARG_NO, 0},
{"debug", OPT_DEBUG, ARG_MAYBE, 0},
{"reproducible", OPT_REPRODUCIBLE, ARG_NO, 0},
{"debug-prefix-map", OPT_DEBUG_PREFIX_MAP, ARG_YES, 0},
{NULL, OPT_BOGUS, ARG_NO, 0}
};

Expand Down Expand Up @@ -1338,6 +1340,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:
help(stdout);
exit(0);
Expand Down Expand Up @@ -2296,6 +2318,8 @@ static void help(FILE *out)
" --lpostfix str append the given string to local symbols\n"
"\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"
"\n"
" -w+x enable warning x (also -Wx)\n"
" -w-x disable warning x (also -Wno-x)\n"
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,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 _stati64])
Expand All @@ -253,6 +254,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_UINTPTR_T
Expand Down
4 changes: 4 additions & 0 deletions include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ size_t strlcpy(char *, const char *, size_t);
char *strrchrnul(const char *, int);
#endif

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

#ifndef __cplusplus /* C++ has false, true, bool as keywords */
# ifdef HAVE_STDBOOL_H
# include <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 @@ -250,10 +250,19 @@ int64_t readstrnum(char *str, int length, bool *warn);
*/
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 @@ -39,6 +39,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 @@ -61,3 +63,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;
}
4 changes: 3 additions & 1 deletion output/outas86.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ static void as86_sect_write(struct Section *, const uint8_t *,

static void as86_init(void)
{
char filename[FILENAME_MAX];
Copy link
Contributor

@mvanotti mvanotti May 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this out of the stack?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving this out of the stack would be an excellent thing. Depending on MAX_PATH, FILENAME_MAX et al is highly discouraged, too (I would like to make that the empty set.)


stext.data = saa_init(1L);
stext.datalen = 0L;
stext.head = stext.last = NULL;
Expand All @@ -131,7 +133,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
4 changes: 2 additions & 2 deletions output/outcoff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1072,14 +1072,14 @@ static void coff_symbol(char *name, int32_t strpos, int32_t value,

static void coff_write_symbols(void)
{
char filename[18];
char filename[19];
uint32_t i;

/*
* The `.file' record, and the file name auxiliary record.
*/
coff_symbol(".file", 0L, 0L, -2, 0, 0x67, 1);
strncpy(filename, inname, 18);
filename_debug_remap(filename, inname, 19);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sizeof(filename) ?

nasm_write(filename, 18, ofile);

/*
Expand Down
2 changes: 1 addition & 1 deletion output/outelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ static void elf_init(void)
};
const char * const *p;

strlcpy(elf_module, inname, sizeof(elf_module));
filename_debug_remap(elf_module, inname, sizeof(elf_module));
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 @@ -207,7 +207,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 @@ -644,7 +644,7 @@ static enum directive_result obj_directive(enum directive, char *);

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 @@ -402,6 +402,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
2 changes: 1 addition & 1 deletion travis/test/_version.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
NASM version 2.16rc0 compiled on Jul 3 2020
NASM version 2.16rc0 compiled on Apr 29 2021
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.