1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2019 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * listing.c listing file generator for the Netwide Assembler
48 #define LIST_MAX_LEN 1024 /* something sensible */
49 #define LIST_INDENT 40
50 #define LIST_HEXBIT 18
52 typedef struct MacroInhibit MacroInhibit
;
54 static struct MacroInhibit
{
60 static const char xdigit
[] = "0123456789ABCDEF";
62 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
64 uint64_t list_options
, active_list_options
;
66 static char listline
[LIST_MAX_LEN
];
67 static bool listlinep
;
69 static struct strlist
*list_errors
;
71 static char listdata
[2 * LIST_INDENT
]; /* we need less than that actually */
72 static int32_t listoffset
;
74 static int32_t listlineno
;
76 static int suppress
; /* for INCBIN & TIMES special cases */
78 static int listlevel
, listlevel_e
;
82 static void list_emit(void)
85 const struct strlist_entry
*e
;
87 if (listlinep
|| *listdata
) {
88 fprintf(listfp
, "%6"PRId32
" ", listlineno
);
91 fprintf(listfp
, "%08"PRIX32
" %-*s", listoffset
, LIST_HEXBIT
+ 1,
94 fprintf(listfp
, "%*s", LIST_HEXBIT
+ 10, "");
97 fprintf(listfp
, "%s<%d>", (listlevel
< 10 ? " " : ""),
100 fprintf(listfp
, " ");
103 fprintf(listfp
, " %s", listline
);
111 static const char fillchars
[] = " --***XX";
114 strlist_for_each(e
, list_errors
) {
115 fprintf(listfp
, "%6"PRId32
" ", listlineno
);
116 fillchar
= fillchars
[e
->pvt
.u
& ERR_MASK
];
117 for (i
= 0; i
< LIST_HEXBIT
; i
++)
118 putc(fillchar
, listfp
);
121 fprintf(listfp
, " %s<%d>", (listlevel
< 10 ? " " : ""),
124 fprintf(listfp
, " ");
126 fprintf(listfp
, " %s\n", e
->str
);
129 strlist_free(&list_errors
);
133 static void list_cleanup(void)
139 MacroInhibit
*temp
= mistack
;
140 mistack
= temp
->next
;
149 static void list_init(const char *fname
)
154 if (!fname
|| fname
[0] == '\0') {
159 listfp
= nasm_open_write(fname
, NF_TEXT
);
161 nasm_nonfatal("unable to open listing file `%s'", fname
);
171 mistack
->next
= NULL
;
173 mistack
->inhibiting
= true;
176 static void list_out(int64_t offset
, char *str
)
178 if (strlen(listdata
) + strlen(str
) > LIST_HEXBIT
) {
179 strcat(listdata
, "-");
184 strcat(listdata
, str
);
187 static void list_address(int64_t offset
, const char *brackets
,
188 int64_t addr
, int size
)
193 nasm_assert(size
<= 8);
206 static void list_size(int64_t offset
, const char *tag
, uint64_t size
)
211 if (list_option('d'))
212 fmt
= "<%s %"PRIu64
">";
214 fmt
= "<%s %"PRIX64
"h>";
216 snprintf(buf
, sizeof buf
, fmt
, tag
, size
);
217 list_out(offset
, buf
);
220 static void list_output(const struct out_data
*data
)
223 uint64_t size
= data
->size
;
224 uint64_t offset
= data
->offset
;
225 const uint8_t *p
= data
->data
;
228 if (!listfp
|| suppress
|| user_nolist
)
231 switch (data
->type
) {
234 list_size(offset
, "zero", size
);
244 listoffset
= data
->offset
;
249 list_out(offset
++, q
);
253 /* Used for listing on non-code generation passes with -Lp */
254 list_size(offset
, "len", size
);
259 list_address(offset
, "[]", data
->toffset
, size
);
263 memset(q
+1, 's', size
<< 1);
264 q
[(size
<< 1)+1] = ']';
265 q
[(size
<< 1)+2] = '\0';
270 list_address(offset
, "()", data
->toffset
, size
);
275 list_size(offset
, "res", size
);
283 static void list_line(int type
, int32_t lineno
, const char *line
)
291 if (mistack
&& mistack
->inhibiting
) {
292 if (type
== LIST_MACRO
)
294 else { /* pop the m i stack */
295 MacroInhibit
*temp
= mistack
;
296 mistack
= temp
->next
;
304 strlcpy(listline
, line
, LIST_MAX_LEN
-3);
305 memcpy(listline
+ LIST_MAX_LEN
-4, "...", 4);
306 listlevel_e
= listlevel
;
309 static void mistack_push(bool inhibiting
)
311 MacroInhibit
*temp
= nasm_malloc(sizeof(MacroInhibit
));
312 temp
->next
= mistack
;
313 temp
->level
= listlevel
;
314 temp
->inhibiting
= inhibiting
;
318 static void list_uplevel(int type
, int64_t size
)
326 list_size(listoffset
, "bin", size
);
331 list_size(listoffset
, "rep", size
);
336 if (mistack
&& mistack
->inhibiting
)
340 case LIST_MACRO_NOLIST
:
351 static void list_downlevel(int type
)
367 while (mistack
&& mistack
->level
> listlevel
) {
368 MacroInhibit
*temp
= mistack
;
369 mistack
= temp
->next
;
376 static void list_error(errflags severity
, const char *fmt
, ...)
384 list_errors
= strlist_alloc(false);
387 strlist_vprintf(list_errors
, fmt
, ap
);
389 strlist_tail(list_errors
)->pvt
.u
= severity
;
391 if ((severity
& ERR_MASK
) >= ERR_FATAL
)
395 static void list_set_offset(uint64_t offset
)
400 static void list_update_options(const char *str
)
406 while ((c
= *str
++)) {
415 mask
= list_option_mask(c
);
417 list_options
|= mask
;
419 list_options
&= ~mask
;
425 enum directive_result
list_pragma(const struct pragma
*pragma
)
427 switch (pragma
->opcode
) {
429 list_update_options(pragma
->tail
);
437 static const struct lfmt nasm_list
= {
448 const struct lfmt
*lfmt
= &nasm_list
;