1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2016 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
51 #define LIST_MAX_LEN 216 /* something sensible */
52 #define LIST_INDENT 40
53 #define LIST_HEXBIT 18
55 typedef struct MacroInhibit MacroInhibit
;
57 static struct MacroInhibit
{
63 static char xdigit
[] = "0123456789ABCDEF";
65 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
67 static char listline
[LIST_MAX_LEN
];
68 static bool listlinep
;
70 static char listerror
[LIST_MAX_LEN
];
72 static char listdata
[2 * LIST_INDENT
]; /* we need less than that actually */
73 static int32_t listoffset
;
75 static int32_t listlineno
;
79 static int suppress
; /* for INCBIN & TIMES special cases */
81 static int listlevel
, listlevel_e
;
85 static void list_emit(void)
89 if (!listlinep
&& !listdata
[0])
92 fprintf(listfp
, "%6"PRId32
" ", listlineno
);
95 fprintf(listfp
, "%08"PRIX32
" %-*s", listoffset
, LIST_HEXBIT
+ 1,
98 fprintf(listfp
, "%*s", LIST_HEXBIT
+ 10, "");
101 fprintf(listfp
, "%s<%d>", (listlevel
< 10 ? " " : ""),
104 fprintf(listfp
, " ");
107 fprintf(listfp
, " %s", listline
);
114 fprintf(listfp
, "%6"PRId32
" ", listlineno
);
115 for (i
= 0; i
< LIST_HEXBIT
; i
++)
119 fprintf(listfp
, " %s<%d>", (listlevel
< 10 ? " " : ""),
122 fprintf(listfp
, " ");
124 fprintf(listfp
, " %s\n", listerror
);
129 static void list_init(const char *fname
)
131 if (!fname
|| fname
[0] == '\0') {
136 listfp
= fopen(fname
, "w");
138 nasm_error(ERR_NONFATAL
, "unable to open listing file `%s'",
149 mistack
= nasm_malloc(sizeof(MacroInhibit
));
150 mistack
->next
= NULL
;
152 mistack
->inhibiting
= true;
155 static void list_cleanup(void)
161 MacroInhibit
*temp
= mistack
;
162 mistack
= temp
->next
;
170 static void list_out(int32_t offset
, char *str
)
172 if (strlen(listdata
) + strlen(str
) > LIST_HEXBIT
) {
173 strcat(listdata
, "-");
178 strcat(listdata
, str
);
181 static void list_address(int32_t offset
, const char *brackets
,
182 int64_t addr
, int size
)
187 nasm_assert(size
<= 8);
200 static void list_output(int32_t offset
, const void *data
,
201 enum out_type type
, uint64_t size
)
205 if (!listp
|| suppress
|| user_nolist
)
211 uint8_t const *p
= data
;
213 if (size
== 0 && !listdata
[0])
218 list_out(offset
++, q
);
224 list_address(offset
, "[]", *(int64_t *)data
, abs((int)size
));
227 list_address(offset
, "()", *(int64_t *)data
, 1);
230 list_address(offset
, "()", *(int64_t *)data
, 2);
233 list_address(offset
, "()", *(int64_t *)data
, 4);
236 list_address(offset
, "()", *(int64_t *)data
, 8);
240 snprintf(q
, sizeof(q
), "<res %08"PRIX64
">", size
);
247 static void list_line(int type
, char *line
)
255 if (mistack
&& mistack
->inhibiting
) {
256 if (type
== LIST_MACRO
)
258 else { /* pop the m i stack */
259 MacroInhibit
*temp
= mistack
;
260 mistack
= temp
->next
;
265 listlineno
= src_get_linnum();
267 strncpy(listline
, line
, LIST_MAX_LEN
- 1);
268 listline
[LIST_MAX_LEN
- 1] = '\0';
269 listlevel_e
= listlevel
;
272 static void list_uplevel(int type
)
276 if (type
== LIST_INCBIN
|| type
== LIST_TIMES
) {
277 suppress
|= (type
== LIST_INCBIN
? 1 : 2);
278 list_out(listoffset
, type
== LIST_INCBIN
? "<incbin>" : "<rept>");
284 if (mistack
&& mistack
->inhibiting
&& type
== LIST_INCLUDE
) {
285 MacroInhibit
*temp
= nasm_malloc(sizeof(MacroInhibit
));
286 temp
->next
= mistack
;
287 temp
->level
= listlevel
;
288 temp
->inhibiting
= false;
290 } else if (type
== LIST_MACRO_NOLIST
) {
291 MacroInhibit
*temp
= nasm_malloc(sizeof(MacroInhibit
));
292 temp
->next
= mistack
;
293 temp
->level
= listlevel
;
294 temp
->inhibiting
= true;
299 static void list_downlevel(int type
)
304 if (type
== LIST_INCBIN
|| type
== LIST_TIMES
) {
305 suppress
&= ~(type
== LIST_INCBIN
? 1 : 2);
310 while (mistack
&& mistack
->level
> listlevel
) {
311 MacroInhibit
*temp
= mistack
;
312 mistack
= temp
->next
;
317 static void list_error(int severity
, const char *pfx
, const char *msg
)
322 snprintf(listerror
, sizeof listerror
, "%s%s", pfx
, msg
);
324 if ((severity
& ERR_MASK
) >= ERR_FATAL
)
329 static const struct lfmt nasm_list
= {
339 const struct lfmt
*lfmt
= &nasm_list
;