Skip to content

Commit 851460a

Browse files
JPEWdevH. Peter Anvin (Intel)
authored andcommitted
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>
1 parent c577f35 commit 851460a

18 files changed

Lines changed: 123 additions & 19 deletions

File tree

asm/nasm.c

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,17 @@ struct forwrefinfo { /* info held on forward refs. */
4242
int operand;
4343
};
4444

45+
struct debug_prefix_list {
46+
struct debug_prefix_list *next;
47+
char *base;
48+
char *dest;
49+
};
50+
4551
const char *_progname;
4652

4753
static void open_and_process_respfile(char *, int);
4854
static void parse_cmdline(int, char **, int);
49-
static void assemble_file(const char *, struct strlist *);
55+
static void assemble_file(const char *, char const *, struct strlist *);
5056
static void help(FILE *out, const char *what);
5157

5258
static bool using_debug_info;
@@ -81,6 +87,8 @@ FILE *ofile = NULL;
8187
enum optimization optimizing = OPTIM_DEFAULT;
8288
static int cmd_sb = 16; /* by default */
8389

90+
static struct debug_prefix_list *debug_prefixes = NULL;
91+
8492
iflag_t cpu, cmd_cpu;
8593

8694
struct location location;
@@ -721,7 +729,7 @@ int main(int argc, char **argv)
721729
if (depend_missing_ok)
722730
pp_include_path(NULL); /* "assume generated" */
723731

724-
pp_reset(get_filename(FN_INFILE), PP_DEPS, depend_list);
732+
pp_reset(get_filename(FN_INFILE), get_filename(FN_MAPPED_INFILE), PP_DEPS, depend_list);
725733
ofile = NULL;
726734
while ((line = pp_getline()))
727735
nasm_free(line);
@@ -747,7 +755,7 @@ int main(int argc, char **argv)
747755
location.known = false;
748756

749757
_pass_type = PASS_PREPROC;
750-
pp_reset(get_filename(FN_INFILE), PP_PREPROC, depend_list);
758+
pp_reset(get_filename(FN_INFILE), get_filename(FN_MAPPED_INFILE), PP_PREPROC, depend_list);
751759
error_pass_start(true);
752760

753761
while ((line = pp_getline())) {
@@ -808,7 +816,7 @@ int main(int argc, char **argv)
808816
ofmt->init();
809817
dfmt->init();
810818

811-
assemble_file(get_filename(FN_INFILE), depend_list);
819+
assemble_file(get_filename(FN_INFILE), get_filename(FN_MAPPED_INFILE), depend_list);
812820

813821
if (!terminate_after_phase()) {
814822
ofmt->cleanup();
@@ -864,6 +872,30 @@ static char *get_param(char *p, char *q, bool *advance)
864872
return r;
865873
}
866874

875+
/*
876+
* Apply debug prefix mappings to a path buffer
877+
*/
878+
static char *debug_prefix_remap(char const* path)
879+
{
880+
struct debug_prefix_list *d;
881+
size_t n;
882+
883+
for (d = debug_prefixes; d != NULL; d = d->next) {
884+
n = strlen(d->base);
885+
if (strncmp(path, d->base, n) == 0) {
886+
size_t prefix_len = strlen(d->dest);
887+
size_t suffix_len = strlen(path) - n;
888+
size_t len = prefix_len + suffix_len + 1;
889+
char* out = nasm_malloc(len);
890+
strlcpy(out, d->dest, len);
891+
strlcpy(&out[prefix_len], &path[n], len - prefix_len);
892+
return out;
893+
}
894+
}
895+
896+
return nasm_strdup(path);
897+
}
898+
867899
/*
868900
* Convert a string to a POSIX make-safe form; returns a newly allocated
869901
* string.
@@ -1030,7 +1062,8 @@ enum text_options {
10301062
OPT_DEBUG,
10311063
OPT_INFO,
10321064
OPT_REPRODUCIBLE,
1033-
OPT_BITS
1065+
OPT_BITS,
1066+
OPT_DEBUG_PREFIX_MAP
10341067
};
10351068
enum need_arg {
10361069
ARG_NO,
@@ -1069,6 +1102,7 @@ static const struct textargs textopts[] = {
10691102
{"debug", OPT_DEBUG, ARG_MAYBE, 0},
10701103
{"reproducible", OPT_REPRODUCIBLE, ARG_NO, 0},
10711104
{"bits", OPT_BITS, ARG_YES, 0},
1105+
{"debug-prefix-map", OPT_DEBUG_PREFIX_MAP, ARG_YES, 0},
10721106
{NULL, OPT_BOGUS, ARG_NO, 0}
10731107
};
10741108

@@ -1455,6 +1489,26 @@ static bool process_arg(char *p, char *q, int pass)
14551489
case OPT_REPRODUCIBLE:
14561490
reproducible = true;
14571491
break;
1492+
case OPT_DEBUG_PREFIX_MAP: {
1493+
struct debug_prefix_list *d;
1494+
char *c;
1495+
c = strchr(param, '=');
1496+
1497+
if (!c) {
1498+
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
1499+
"option `--%s' must be of the form `BASE=DEST'", p);
1500+
break;
1501+
}
1502+
1503+
*c = '\0';
1504+
d = nasm_malloc(sizeof(*d));
1505+
d->next = debug_prefixes;
1506+
d->base = nasm_strdup(param);
1507+
d->dest = nasm_strdup(c + 1);
1508+
debug_prefixes = d;
1509+
*c = '=';
1510+
}
1511+
break;
14581512
case OPT_HELP:
14591513
/* Allow --help topic without *requiring* topic */
14601514
if (!param)
@@ -1672,6 +1726,8 @@ static void parse_cmdline(int argc, char **argv, int pass)
16721726
if (!get_filename(FN_INFILE))
16731727
nasm_fatalf(ERR_USAGE, "no input file specified");
16741728

1729+
set_filename(FN_MAPPED_INFILE, debug_prefix_remap(get_filename(FN_INFILE)));
1730+
16751731
check_overwrite_files();
16761732

16771733
open_errfile(get_filename(FN_ERRFILE));
@@ -1724,7 +1780,7 @@ void print_final_report(bool failure)
17241780
}
17251781
}
17261782

1727-
static void assemble_file(const char *fname, struct strlist *depend_list)
1783+
static void assemble_file(const char *fname, char const* mapped_fname, struct strlist *depend_list)
17281784
{
17291785
static int64_t stall_count = 0; /* Make sure we make forward progress... */
17301786
char *line;
@@ -1814,7 +1870,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
18141870
location.known = true;
18151871
ofmt->reset();
18161872
switch_segment(ofmt->section(NULL, &globl.bits));
1817-
pp_reset(fname, PP_NORMAL, depend_list);
1873+
pp_reset(fname, mapped_fname, PP_NORMAL, depend_list);
18181874

18191875
globallineno = 0;
18201876

@@ -2205,6 +2261,8 @@ static void help(FILE *out, const char *what)
22052261
" --lprefix str prepend the given string to local symbols\n"
22062262
" --lpostfix str append the given string to local symbols\n"
22072263
" --reproducible attempt to produce run-to-run identical output\n"
2264+
" --debug-prefix-map base=dest\n"
2265+
" remap paths starting with 'base' to 'dest' in output files\n"
22082266
, out);
22092267
}
22102268
if (help_is(with, HW_LIMIT)) {

asm/preproc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8638,7 +8638,7 @@ static void pp_reset_stdmac(enum preproc_mode mode)
86388638
define_smacro("__?PASS?__", true, make_tok_num(NULL, apass), NULL);
86398639
}
86408640

8641-
void pp_reset(const char *file, enum preproc_mode mode,
8641+
void pp_reset(const char *file, char const* mapped_fname, enum preproc_mode mode,
86428642
struct strlist *dep_list)
86438643
{
86448644
cstk = NULL;
@@ -8677,7 +8677,7 @@ void pp_reset(const char *file, enum preproc_mode mode,
86778677
nasm_fatalf(ERR_NOFILE, "unable to open input file `%s'%s%s",
86788678
file, errno ? " " : "", errno ? strerror(errno) : "");
86798679
}
8680-
src_set(0, file);
8680+
src_set(0, mapped_fname);
86818681
istk->where = src_where();
86828682
istk->lineinc = 1;
86838683

common/files.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
static const char * const filename_names[FN_NFILES] = {
99
"input",
10+
"mapped-input",
1011
"output",
1112
"error",
1213
"list",
@@ -44,7 +45,7 @@ void check_overwrite_files(void)
4445
if (!inname)
4546
return;
4647

47-
for (fn = FN_INFILE+1; fn < FN_NFILES; fn++) {
48+
for (fn = FN_INFILE+2; fn < FN_NFILES; fn++) {
4849
const char *outname = get_filename(fn);
4950
if (outname && !strcmp(inname, outname)) {
5051
nasm_fatal("%s file would overwrite input file",

include/files.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
enum filenames {
1515
/* These two entries must be first, in this order */
1616
FN_INFILE, /* Primary input file */
17+
FN_MAPPED_INFILE, /* Debug mapped input file */
1718
FN_OUTFILE, /* Primary output file */
1819

1920
FN_ERRFILE, /* Error message file */

include/nasm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ void pp_init(enum preproc_opt opt);
458458
* of the pass, an error reporting function, an evaluator
459459
* function, and a listing generator to talk to.
460460
*/
461-
void pp_reset(const char *file, enum preproc_mode mode,
461+
void pp_reset(const char *file, const char* mapped_fname, enum preproc_mode mode,
462462
struct strlist *deplist);
463463

464464
/*

nasm.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ OPTIONS
147147
Prepend or append (respectively) the given argument to all global or
148148
extern variables.
149149

150+
--debug-prefix-map 'BASE=DEST'::
151+
Map file names beginning with 'BASE' to 'DEST' when encoding them in
152+
output object files.
153+
150154
SYNTAX
151155
------
152156
This man page does not fully describe the syntax of *nasm*'s assembly language,

output/outas86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static void as86_init(void)
104104
strslen = 0;
105105

106106
/* as86 module name = input file minus extension */
107-
module_name = filename_set_extension(get_filename(FN_INFILE), "");
107+
module_name = filename_set_extension(get_filename(FN_MAPPED_INFILE), "");
108108
as86_add_string(module_name);
109109
nasm_free(module_name);
110110
}

output/outcoff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,7 @@ static void coff_write_symbols(void)
13421342
if (reproducible)
13431343
memset(filename, 0, 18);
13441344
else
1345-
strncpy(filename, get_filename(FN_INFILE), 18);
1345+
strncpy(filename, get_filename(FN_MAPPED_INFILE), 18);
13461346
nasm_write(filename, 18, ofile);
13471347

13481348
/*

output/outelf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static void elf64_init(void)
511511

512512
static void elf_populate_dirs(void)
513513
{
514-
const char * const infile = get_filename(FN_INFILE);
514+
const char * const infile = get_filename(FN_MAPPED_INFILE);
515515
char *cur_path = nasm_realpath(infile);
516516
char *dir_name = nasm_dirname(cur_path);
517517

output/outieee.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ static void ieee_unqualified_name(char *, char *);
179179
*/
180180
static void ieee_init(void)
181181
{
182-
strlcpy(ieee_infile, get_filename(FN_INFILE), sizeof(ieee_infile));
182+
strlcpy(ieee_infile, get_filename(FN_MAPPED_INFILE), sizeof(ieee_infile));
183183
any_segs = false;
184184
fpubhead = NULL;
185185
fpubtail = &fpubhead;

0 commit comments

Comments
 (0)