]> git.saurik.com Git - apple/boot.git/blob - i386/nasm/listing.c
boot-111.tar.gz
[apple/boot.git] / i386 / nasm / listing.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* listing.c listing file generator for the Netwide Assembler
26 *
27 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
28 * Julian Hall. All rights reserved. The software is
29 * redistributable under the licence given in the file "Licence"
30 * distributed in the NASM archive.
31 *
32 * initial version 2/vii/97 by Simon Tatham
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stddef.h>
38 #include <string.h>
39 #include <ctype.h>
40
41 #include "nasm.h"
42 #include "nasmlib.h"
43 #include "listing.h"
44
45 #define LIST_MAX_LEN 216 /* something sensible */
46 #define LIST_INDENT 40
47 #define LIST_HEXBIT 18
48
49 typedef struct MacroInhibit MacroInhibit;
50
51 static struct MacroInhibit {
52 MacroInhibit *next;
53 int level;
54 int inhibiting;
55 } *mistack;
56
57 static char xdigit[] = "0123456789ABCDEF";
58
59 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
60
61 static char listline[LIST_MAX_LEN];
62 static int listlinep;
63
64 static char listdata[2*LIST_INDENT]; /* we need less than that actually */
65 static long listoffset;
66
67 static long listlineno;
68
69 static long listp;
70
71 static int suppress; /* for INCBIN & TIMES special cases */
72
73 static int listlevel, listlevel_e;
74
75 static FILE *listfp;
76
77 static void list_emit (void) {
78 if (!listlinep && !listdata[0])
79 return;
80 fprintf(listfp, "%6ld ", ++listlineno);
81 if (listdata[0])
82 fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
83 else
84 fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
85 if (listlevel_e)
86 fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
87 else if (listlinep)
88 fprintf(listfp, " ");
89 if (listlinep)
90 fprintf(listfp, " %s", listline);
91 fputc('\n', listfp);
92 listlinep = FALSE;
93 listdata[0] = '\0';
94 }
95
96 static void list_init (char *fname, efunc error) {
97 listfp = fopen (fname, "w");
98 if (!listfp) {
99 error (ERR_NONFATAL, "unable to open listing file `%s'", fname);
100 return;
101 }
102 *listline = '\0';
103 listlineno = 0;
104 listp = TRUE;
105 listlevel = 0;
106 suppress = 0;
107 mistack = nasm_malloc(sizeof(MacroInhibit));
108 mistack->next = NULL;
109 mistack->level = 0;
110 mistack->inhibiting = TRUE;
111 }
112
113 static void list_cleanup (void) {
114 if (!listp)
115 return;
116 while (mistack) {
117 MacroInhibit *temp = mistack;
118 mistack = temp->next;
119 nasm_free (temp);
120 }
121 list_emit();
122 fclose (listfp);
123 }
124
125 static void list_out (long offset, char *str) {
126 if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
127 strcat(listdata, "-");
128 list_emit();
129 }
130 if (!listdata[0])
131 listoffset = offset;
132 strcat(listdata, str);
133 }
134
135 static void list_output (long offset, void *data, unsigned long type) {
136 long typ, size;
137
138 if (!listp || suppress)
139 return;
140
141 typ = type & OUT_TYPMASK;
142 size = type & OUT_SIZMASK;
143
144 if (typ == OUT_RAWDATA) {
145 unsigned char *p = data;
146 char q[3];
147 while (size--) {
148 HEX (q, *p);
149 q[2] = '\0';
150 list_out (offset++, q);
151 p++;
152 }
153 } else if (typ == OUT_ADDRESS) {
154 unsigned long d = *(long *)data;
155 char q[11];
156 unsigned char p[4], *r = p;
157 if (size == 4) {
158 q[0] = '['; q[9] = ']'; q[10] = '\0';
159 WRITELONG (r, d);
160 HEX (q+1, p[0]);
161 HEX (q+3, p[1]);
162 HEX (q+5, p[2]);
163 HEX (q+7, p[3]);
164 list_out (offset, q);
165 } else {
166 q[0] = '['; q[5] = ']'; q[6] = '\0';
167 WRITESHORT (r, d);
168 HEX (q+1, p[0]);
169 HEX (q+3, p[1]);
170 list_out (offset, q);
171 }
172 } else if (typ == OUT_REL2ADR) {
173 unsigned long d = *(long *)data;
174 char q[11];
175 unsigned char p[4], *r = p;
176 q[0] = '('; q[5] = ')'; q[6] = '\0';
177 WRITESHORT (r, d);
178 HEX (q+1, p[0]);
179 HEX (q+3, p[1]);
180 list_out (offset, q);
181 } else if (typ == OUT_REL4ADR) {
182 unsigned long d = *(long *)data;
183 char q[11];
184 unsigned char p[4], *r = p;
185 q[0] = '('; q[9] = ')'; q[10] = '\0';
186 WRITELONG (r, d);
187 HEX (q+1, p[0]);
188 HEX (q+3, p[1]);
189 HEX (q+5, p[2]);
190 HEX (q+7, p[3]);
191 list_out (offset, q);
192 } else if (typ == OUT_RESERVE) {
193 char q[20];
194 sprintf(q, "<res %08lX>", size);
195 list_out (offset, q);
196 }
197 }
198
199 static void list_line (int type, char *line) {
200 if (!listp)
201 return;
202 if (mistack && mistack->inhibiting) {
203 if (type == LIST_MACRO)
204 return;
205 else { /* pop the m i stack */
206 MacroInhibit *temp = mistack;
207 mistack = temp->next;
208 nasm_free (temp);
209 }
210 }
211 list_emit();
212 listlinep = TRUE;
213 strncpy (listline, line, LIST_MAX_LEN-1);
214 listline[LIST_MAX_LEN-1] = '\0';
215 listlevel_e = listlevel;
216 }
217
218 static void list_uplevel (int type) {
219 if (!listp)
220 return;
221 if (type == LIST_INCBIN || type == LIST_TIMES) {
222 suppress |= (type == LIST_INCBIN ? 1 : 2);
223 list_out (listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
224 return;
225 }
226 listlevel++;
227 if (mistack && mistack->inhibiting && type == LIST_INCLUDE) {
228 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
229 temp->next = mistack;
230 temp->level = listlevel;
231 temp->inhibiting = FALSE;
232 mistack = temp;
233 } else if (type == LIST_MACRO_NOLIST) {
234 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
235 temp->next = mistack;
236 temp->level = listlevel;
237 temp->inhibiting = TRUE;
238 mistack = temp;
239 }
240 }
241
242 static void list_downlevel (int type) {
243 if (!listp)
244 return;
245 if (type == LIST_INCBIN || type == LIST_TIMES) {
246 suppress &= ~(type == LIST_INCBIN ? 1 : 2);
247 return;
248 }
249 listlevel--;
250 while (mistack && mistack->level > listlevel) {
251 MacroInhibit *temp = mistack;
252 mistack = temp->next;
253 nasm_free (temp);
254 }
255 }
256
257 ListGen nasmlist = {
258 list_init,
259 list_cleanup,
260 list_output,
261 list_line,
262 list_uplevel,
263 list_downlevel
264 };