1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 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(char *fname, efunc error)
131 listfp = fopen(fname, "w");
133 error(ERR_NONFATAL, "unable to open listing file `%s'",
144 mistack = nasm_malloc(sizeof(MacroInhibit));
145 mistack->next = NULL;
147 mistack->inhibiting = true;
150 static void list_cleanup(void)
156 MacroInhibit *temp = mistack;
157 mistack = temp->next;
165 static void list_out(int32_t offset, char *str)
167 if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
168 strcat(listdata, "-");
173 strcat(listdata, str);
176 static void list_address(int32_t offset, const char *brackets,
177 int64_t addr, int size)
182 nasm_assert(size <= 8);
195 static void list_output(int32_t offset, const void *data,
196 enum out_type type, uint64_t size)
200 if (!listp || suppress || user_nolist) /* fbk - 9/2/00 */
206 uint8_t const *p = data;
208 if (size == 0 && !listdata[0])
213 list_out(offset++, q);
219 list_address(offset, "[]", *(int64_t *)data, size);
222 list_address(offset, "()", *(int64_t *)data, 1);
225 list_address(offset, "()", *(int64_t *)data, 2);
228 list_address(offset, "()", *(int64_t *)data, 4);
231 list_address(offset, "()", *(int64_t *)data, 8);
235 snprintf(q, sizeof(q), "<res %08"PRIX64">", size);
242 static void list_line(int type, char *line)
246 if (user_nolist) { /* fbk - 9/2/00 */
251 if (mistack && mistack->inhibiting) {
252 if (type == LIST_MACRO)
254 else { /* pop the m i stack */
255 MacroInhibit *temp = mistack;
256 mistack = temp->next;
262 strncpy(listline, line, LIST_MAX_LEN - 1);
263 listline[LIST_MAX_LEN - 1] = '\0';
264 listlevel_e = listlevel;
267 static void list_uplevel(int type)
271 if (type == LIST_INCBIN || type == LIST_TIMES) {
272 suppress |= (type == LIST_INCBIN ? 1 : 2);
273 list_out(listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
279 if (mistack && mistack->inhibiting && type == LIST_INCLUDE) {
280 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
281 temp->next = mistack;
282 temp->level = listlevel;
283 temp->inhibiting = false;
285 } else if (type == LIST_MACRO_NOLIST) {
286 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
287 temp->next = mistack;
288 temp->level = listlevel;
289 temp->inhibiting = true;
294 static void list_downlevel(int type)
299 if (type == LIST_INCBIN || type == LIST_TIMES) {
300 suppress &= ~(type == LIST_INCBIN ? 1 : 2);
305 while (mistack && mistack->level > listlevel) {
306 MacroInhibit *temp = mistack;
307 mistack = temp->next;
312 static void list_error(int severity, const char *pfx, const char *msg)
317 snprintf(listerror, sizeof listerror, "%s%s", pfx, msg);
319 if ((severity & ERR_MASK) >= ERR_FATAL)