out: Elf -- Fix typo in section name
[nasm.git] / listing.c
blob27d16ed1abb26561f4944f422d17a9230be8dee8
1 /* ----------------------------------------------------------------------- *
2 *
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
9 * conditions are met:
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
38 #include "compiler.h"
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <stddef.h>
43 #include <string.h>
44 #include <ctype.h>
46 #include "nasm.h"
47 #include "nasmlib.h"
48 #include "listing.h"
50 #define LIST_MAX_LEN 216 /* something sensible */
51 #define LIST_INDENT 40
52 #define LIST_HEXBIT 18
54 typedef struct MacroInhibit MacroInhibit;
56 static struct MacroInhibit {
57 MacroInhibit *next;
58 int level;
59 int inhibiting;
60 } *mistack;
62 static char xdigit[] = "0123456789ABCDEF";
64 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
66 static char listline[LIST_MAX_LEN];
67 static bool listlinep;
69 static char listerror[LIST_MAX_LEN];
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 int32_t listp;
78 static int suppress; /* for INCBIN & TIMES special cases */
80 static int listlevel, listlevel_e;
82 static FILE *listfp;
84 static void list_emit(void)
86 int i;
88 if (!listlinep && !listdata[0])
89 return;
91 fprintf(listfp, "%6"PRId32" ", listlineno);
93 if (listdata[0])
94 fprintf(listfp, "%08"PRIX32" %-*s", listoffset, LIST_HEXBIT + 1,
95 listdata);
96 else
97 fprintf(listfp, "%*s", LIST_HEXBIT + 10, "");
99 if (listlevel_e)
100 fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""),
101 listlevel_e);
102 else if (listlinep)
103 fprintf(listfp, " ");
105 if (listlinep)
106 fprintf(listfp, " %s", listline);
108 putc('\n', listfp);
109 listlinep = false;
110 listdata[0] = '\0';
112 if (listerror[0]) {
113 fprintf(listfp, "%6"PRId32" ", listlineno);
114 for (i = 0; i < LIST_HEXBIT; i++)
115 putc('*', listfp);
117 if (listlevel_e)
118 fprintf(listfp, " %s<%d>", (listlevel < 10 ? " " : ""),
119 listlevel_e);
120 else
121 fprintf(listfp, " ");
123 fprintf(listfp, " %s\n", listerror);
124 listerror[0] = '\0';
128 static void list_init(const char *fname)
130 if (!fname || fname[0] == '\0') {
131 listfp = NULL;
132 return;
135 listfp = fopen(fname, "w");
136 if (!listfp) {
137 nasm_error(ERR_NONFATAL, "unable to open listing file `%s'",
138 fname);
139 return;
142 *listline = '\0';
143 listlineno = 0;
144 *listerror = '\0';
145 listp = true;
146 listlevel = 0;
147 suppress = 0;
148 mistack = nasm_malloc(sizeof(MacroInhibit));
149 mistack->next = NULL;
150 mistack->level = 0;
151 mistack->inhibiting = true;
154 static void list_cleanup(void)
156 if (!listp)
157 return;
159 while (mistack) {
160 MacroInhibit *temp = mistack;
161 mistack = temp->next;
162 nasm_free(temp);
165 list_emit();
166 fclose(listfp);
169 static void list_out(int32_t offset, char *str)
171 if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
172 strcat(listdata, "-");
173 list_emit();
175 if (!listdata[0])
176 listoffset = offset;
177 strcat(listdata, str);
180 static void list_address(int32_t offset, const char *brackets,
181 int64_t addr, int size)
183 char q[20];
184 char *r = q;
186 nasm_assert(size <= 8);
188 *r++ = brackets[0];
189 while (size--) {
190 HEX(r, addr);
191 addr >>= 8;
192 r += 2;
194 *r++ = brackets[1];
195 *r = '\0';
196 list_out(offset, q);
199 static void list_output(int32_t offset, const void *data,
200 enum out_type type, uint64_t size)
202 char q[20];
204 if (!listp || suppress || user_nolist)
205 return;
207 switch (type) {
208 case OUT_RAWDATA:
210 uint8_t const *p = data;
212 if (size == 0 && !listdata[0])
213 listoffset = offset;
214 while (size--) {
215 HEX(q, *p);
216 q[2] = '\0';
217 list_out(offset++, q);
218 p++;
220 break;
222 case OUT_ADDRESS:
223 list_address(offset, "[]", *(int64_t *)data, abs((int)size));
224 break;
225 case OUT_REL1ADR:
226 list_address(offset, "()", *(int64_t *)data, 1);
227 break;
228 case OUT_REL2ADR:
229 list_address(offset, "()", *(int64_t *)data, 2);
230 break;
231 case OUT_REL4ADR:
232 list_address(offset, "()", *(int64_t *)data, 4);
233 break;
234 case OUT_REL8ADR:
235 list_address(offset, "()", *(int64_t *)data, 8);
236 break;
237 case OUT_RESERVE:
239 snprintf(q, sizeof(q), "<res %08"PRIX64">", size);
240 list_out(offset, q);
241 break;
246 static void list_line(int type, char *line)
248 if (!listp)
249 return;
251 if (user_nolist)
252 return;
254 if (mistack && mistack->inhibiting) {
255 if (type == LIST_MACRO)
256 return;
257 else { /* pop the m i stack */
258 MacroInhibit *temp = mistack;
259 mistack = temp->next;
260 nasm_free(temp);
263 list_emit();
264 listlineno = src_get_linnum();
265 listlinep = true;
266 strncpy(listline, line, LIST_MAX_LEN - 1);
267 listline[LIST_MAX_LEN - 1] = '\0';
268 listlevel_e = listlevel;
271 static void list_uplevel(int type)
273 if (!listp)
274 return;
275 if (type == LIST_INCBIN || type == LIST_TIMES) {
276 suppress |= (type == LIST_INCBIN ? 1 : 2);
277 list_out(listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
278 return;
281 listlevel++;
283 if (mistack && mistack->inhibiting && type == LIST_INCLUDE) {
284 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
285 temp->next = mistack;
286 temp->level = listlevel;
287 temp->inhibiting = false;
288 mistack = temp;
289 } else if (type == LIST_MACRO_NOLIST) {
290 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
291 temp->next = mistack;
292 temp->level = listlevel;
293 temp->inhibiting = true;
294 mistack = temp;
298 static void list_downlevel(int type)
300 if (!listp)
301 return;
303 if (type == LIST_INCBIN || type == LIST_TIMES) {
304 suppress &= ~(type == LIST_INCBIN ? 1 : 2);
305 return;
308 listlevel--;
309 while (mistack && mistack->level > listlevel) {
310 MacroInhibit *temp = mistack;
311 mistack = temp->next;
312 nasm_free(temp);
316 static void list_error(int severity, const char *pfx, const char *msg)
318 if (!listfp)
319 return;
321 snprintf(listerror, sizeof listerror, "%s%s", pfx, msg);
323 if ((severity & ERR_MASK) >= ERR_FATAL)
324 list_emit();
328 static const struct lfmt nasm_list = {
329 list_init,
330 list_cleanup,
331 list_output,
332 list_line,
333 list_uplevel,
334 list_downlevel,
335 list_error
338 const struct lfmt *lfmt = &nasm_list;