summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/nasm/nasm/0002-Add-debug-prefix-map-option.patch
blob: bbfae2e8a50b87765b49ed46c328f4a9917c1640 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
From fa677c1caf6b8192971920cf5c1aa8cb33c74605 Mon Sep 17 00:00:00 2001
From: Joshua Watt <JPEWhacker@gmail.com>
Date: Tue, 19 Nov 2019 13:12:17 -0600
Subject: [PATCH 2/2] 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.

Upstream-Status: Submitted [https://bugzilla.nasm.us/show_bug.cgi?id=3392635]
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 asm/nasm.c              | 28 ++++++++++++++++++++++++++--
 include/nasmlib.h       |  9 +++++++++
 nasm.txt                |  4 ++++
 nasmlib/filename.c      | 20 ++++++++++++++++++++
 output/outas86.c        |  4 +++-
 output/outcoff.c        |  4 ++--
 output/outelf.c         |  8 ++++----
 output/outieee.c        |  2 +-
 output/outobj.c         |  2 +-
 stdlib/strlcat.c        |  2 +-
 test/elfdebugprefix.asm |  6 ++++++
 test/performtest.pl     | 12 ++++++++++--
 12 files changed, 87 insertions(+), 14 deletions(-)
 create mode 100644 test/elfdebugprefix.asm

diff --git a/asm/nasm.c b/asm/nasm.c
index 1c5a5fc5..5d45103c 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -841,7 +841,8 @@ enum text_options {
     OPT_BEFORE,
     OPT_LIMIT,
     OPT_KEEP_ALL,
-    OPT_NO_LINE
+    OPT_NO_LINE,
+    OPT_DEBUG_PREFIX_MAP
 };
 struct textargs {
     const char *label;
@@ -866,6 +867,7 @@ static const struct textargs textopts[] = {
     {"limit-",   OPT_LIMIT,   true, 0},
     {"keep-all", OPT_KEEP_ALL, false, 0},
     {"no-line",  OPT_NO_LINE, false, 0},
+    {"debug-prefix-map", OPT_DEBUG_PREFIX_MAP, true, 0},
     {NULL, OPT_BOGUS, false, 0}
 };
 
@@ -1217,6 +1219,26 @@ static bool process_arg(char *p, char *q, int pass)
                 case OPT_NO_LINE:
                     pp_noline = 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(0);
                     exit(0);
@@ -2010,7 +2032,9 @@ static void help(const char xopt)
          "   --lpostfix str append the given string to all other symbols\n"
          "   --keep-all     output files will not be removed even if an error happens\n"
          "   --no-line      ignore %%line directives in input\n"
-         "   --limit-X val  set execution limit X\n");
+         "   --limit-X val  set execution limit X\n"
+         "   --debug-prefix-map base=dest\n"
+         "                  remap paths starting with 'base' to 'dest' in output files\n");
 
     for (i = 0; i <= LIMIT_MAX; i++) {
         printf("                     %-15s %s (default ",
diff --git a/include/nasmlib.h b/include/nasmlib.h
index e57d0e6d..cf921547 100644
--- a/include/nasmlib.h
+++ b/include/nasmlib.h
@@ -195,10 +195,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...
diff --git a/nasm.txt b/nasm.txt
index a28202f9..443c06b2 100644
--- a/nasm.txt
+++ b/nasm.txt
@@ -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,
diff --git a/nasmlib/filename.c b/nasmlib/filename.c
index 172ae0bc..fda2be41 100644
--- a/nasmlib/filename.c
+++ b/nasmlib/filename.c
@@ -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
@@ -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;
+}
diff --git a/output/outas86.c b/output/outas86.c
index 3f9867b9..d5f4f966 100644
--- a/output/outas86.c
+++ b/output/outas86.c
@@ -113,6 +113,8 @@ static void as86_sect_write(struct Section *, const uint8_t *,
 
 static void as86_init(void)
 {
+    char filename[FILENAME_MAX];
+
     stext.data = saa_init(1L);
     stext.datalen = 0L;
     stext.head = stext.last = NULL;
@@ -134,7 +136,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)
diff --git a/output/outcoff.c b/output/outcoff.c
index a2fd302c..bcf576fb 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -1070,14 +1070,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);
     nasm_write(filename, 18, ofile);
 
     /*
diff --git a/output/outelf.c b/output/outelf.c
index de99d076..203b5dc0 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------- *
- *   
+ *
  *   Copyright 1996-2017 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
@@ -14,7 +14,7 @@
  *     copyright notice, this list of conditions and the following
  *     disclaimer in the documentation and/or other materials provided
  *     with the distribution.
- *     
+ *
  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -315,7 +315,7 @@ elf_directive(enum directive directive, char *value, int pass)
 
 static void elf_init(void)
 {
-    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));
@@ -868,7 +868,7 @@ static void elf32_out(int32_t segto, const void *data,
                       " segment base references");
             } else {
                 if (wrt == NO_SEG) {
-                    /* 
+                    /*
                      * The if() is a hack to deal with compilers which
                      * don't handle switch() statements with 64-bit
                      * expressions.
diff --git a/output/outieee.c b/output/outieee.c
index 3a28942d..f61824e4 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -209,7 +209,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;
diff --git a/output/outobj.c b/output/outobj.c
index b4f2c499..55bba4a1 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -640,7 +640,7 @@ static enum directive_result obj_directive(enum directive, char *, int);
 
 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;
diff --git a/stdlib/strlcat.c b/stdlib/strlcat.c
index 7084d460..ee93dea3 100644
--- a/stdlib/strlcat.c
+++ b/stdlib/strlcat.c
@@ -29,7 +29,7 @@ size_t strlcat(char *dest, const char *src, size_t size)
     size_t n;
 
     /* find the NULL terminator in dest */
-    for (n = 0; i < size && dest[n] != '\0'; n++)
+    for (n = 0; n < size && dest[n] != '\0'; n++)
         ;
 
     /* destination was not NULL terminated. Return the initial size */
diff --git a/test/elfdebugprefix.asm b/test/elfdebugprefix.asm
new file mode 100644
index 00000000..a67ba29c
--- /dev/null
+++ b/test/elfdebugprefix.asm
@@ -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
+
diff --git a/test/performtest.pl b/test/performtest.pl
index f7865b39..096f9604 100755
--- a/test/performtest.pl
+++ b/test/performtest.pl
@@ -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) {
-- 
2.23.0