preproc: add recursive macro expansion support
[nasm.git] / rdoff / rdfdump.c
blob0e55c67f33727a7b397ac58b85489b54987e26c2
1 /* ----------------------------------------------------------------------- *
2 *
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
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 * rdfdump.c - dump RDOFF file header.
38 #include "compiler.h"
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
44 #define RDOFF_UTILS
46 #include "rdoff.h"
48 #define PROGRAM_VERSION "2.3"
50 FILE *infile;
52 void print_header(int32_t length, int rdf_version)
54 char buf[129], t, l, s, flags;
55 uint8_t reclen;
56 int32_t o, ll;
57 uint16_t rs;
59 while (length > 0) {
60 fread(&t, 1, 1, infile);
61 if (rdf_version >= 2) {
62 fread(&reclen, 1, 1, infile);
64 switch (t) {
65 case RDFREC_GENERIC: /* generic record */
66 printf(" generic record (length=%d)\n", (int)reclen);
67 fseek(infile, reclen, SEEK_CUR);
68 break;
70 case RDFREC_RELOC: /* relocation record */
71 case RDFREC_SEGRELOC: /* segment relocation */
72 fread(&s, 1, 1, infile);
73 fread(&o, 4, 1, infile);
74 fread(&l, 1, 1, infile);
75 fread(&rs, 2, 1, infile);
76 printf(" %s: location (%04x:%08"PRIx32"), length %d, "
77 "referred seg %04x\n",
78 t == 1 ? "relocation" : "seg relocation", (int)s,
79 translateint32_t(o), (int)l, translateint16_t(rs));
80 if (rdf_version >= 2 && reclen != 8)
81 printf(" warning: reclen != 8\n");
82 if (rdf_version == 1)
83 length -= 9;
84 if (rdf_version == 1 && t == 6)
85 printf
86 (" warning: seg relocation not supported in RDOFF1\n");
87 break;
89 case RDFREC_IMPORT: /* import record */
90 case RDFREC_FARIMPORT: /* import far symbol */
91 fread(&flags, 1, 1, infile);
92 fread(&rs, 2, 1, infile);
93 ll = 0;
95 if (rdf_version == 1) {
96 do {
97 fread(&buf[ll], 1, 1, infile);
98 } while (buf[ll++]);
99 } else {
100 for (; ll < reclen - 3; ll++)
101 fread(&buf[ll], 1, 1, infile);
104 if (t == 7)
105 printf("far ");
106 printf((flags & SYM_IMPORT) ? " import" : " extern");
107 if (flags & SYM_FUNCTION)
108 printf(" proc");
109 if (flags & SYM_DATA)
110 printf(" data");
111 printf(": segment %04x = %s\n", translateint16_t(rs), buf);
112 if (rdf_version == 1)
113 length -= ll + 3;
114 if (rdf_version == 1 && t == 7)
115 printf
116 (" warning: far import not supported in RDOFF1\n");
117 break;
119 case RDFREC_GLOBAL: /* export record */
120 fread(&flags, 1, 1, infile);
121 fread(&s, 1, 1, infile);
122 fread(&o, 4, 1, infile);
123 ll = 0;
125 if (rdf_version == 1) {
126 do {
127 fread(&buf[ll], 1, 1, infile);
128 } while (buf[ll++]);
129 } else {
130 for (; ll < reclen - 6; ll++)
131 fread(&buf[ll], 1, 1, infile);
133 printf((flags & SYM_GLOBAL) ? " export" : " public");
134 if (flags & SYM_FUNCTION)
135 printf(" proc");
136 if (flags & SYM_DATA)
137 printf(" data");
138 printf(": (%04x:%08"PRIx32") = %s\n", (int)s, translateint32_t(o), buf);
139 if (rdf_version == 1)
140 length -= ll + 6;
141 break;
143 case RDFREC_DLL: /* DLL and Module records */
144 case RDFREC_MODNAME:
145 ll = 0;
146 if (rdf_version == 1) {
147 do {
148 fread(&buf[ll], 1, 1, infile);
149 } while (buf[ll++]);
150 } else {
151 for (; ll < reclen; ll++)
152 fread(&buf[ll], 1, 1, infile);
154 if (t == 4)
155 printf(" dll: %s\n", buf);
156 else
157 printf(" module: %s\n", buf);
158 if (rdf_version == 1)
159 length -= ll + 1;
160 break;
162 case RDFREC_BSS: /* BSS reservation */
163 fread(&ll, 4, 1, infile);
164 printf(" bss reservation: %08"PRIx32" bytes\n", translateint32_t(ll));
165 if (rdf_version == 1)
166 length -= 5;
167 if (rdf_version > 1 && reclen != 4)
168 printf(" warning: reclen != 4\n");
169 break;
171 case RDFREC_COMMON:{
172 uint16_t seg, align;
173 uint32_t size;
175 fread(&seg, 2, 1, infile);
176 fread(&size, 4, 1, infile);
177 fread(&align, 2, 1, infile);
178 for (ll = 0; ll < reclen - 8; ll++)
179 fread(buf + ll, 1, 1, infile);
180 printf(" common: segment %04x = %s, %"PRId32":%d\n",
181 translateint16_t(seg), buf, translateint32_t(size),
182 translateint16_t(align));
183 break;
186 default:
187 printf(" unrecognized record (type %d", (int)t);
188 if (rdf_version > 1) {
189 printf(", length %d", (int)reclen);
190 fseek(infile, reclen, SEEK_CUR);
191 } else
192 length--;
193 printf(")\n");
195 if (rdf_version != 1)
196 length -= 2 + reclen;
200 int main(int argc, char **argv)
202 char id[7];
203 int32_t l;
204 uint16_t s;
205 int verbose = 0;
206 int32_t offset;
207 int foundnullsegment = 0;
208 int version;
209 int32_t segmentcontentlength = 0;
210 int nsegments = 0;
211 int32_t headerlength = 0;
212 int32_t objectlength = 0;
214 printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
215 printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
216 puts("Copyright (c) 1996,99 Julian R Hall\n"
217 "Improvements and fixes (c) 2002-2004 RET & COM Research.");
219 if (argc < 2) {
220 fputs("Usage: rdfdump [-v] <filename>\n", stderr);
221 exit(1);
224 if (!strcmp(argv[1], "-v")) {
225 verbose = 1;
226 if (argc < 3) {
227 fputs("required parameter missing\n", stderr);
228 exit(1);
230 argv++;
233 infile = fopen(argv[1], "rb");
234 if (!infile) {
235 fprintf(stderr, "rdfdump: Could not open %s\n", argv[1]);
236 exit(1);
239 fread(id, 6, 1, infile);
240 if (strncmp(id, "RDOFF", 5)) {
241 fputs("rdfdump: File does not contain valid RDOFF header\n",
242 stderr);
243 exit(1);
246 printf("File %s: RDOFF version %c\n\n", argv[1], id[5]);
247 if (id[5] < '1' || id[5] > '2') {
248 fprintf(stderr, "rdfdump: unknown RDOFF version '%c'\n", id[5]);
249 exit(1);
251 version = id[5] - '0';
253 if (version > 1) {
254 fread(&l, 4, 1, infile);
255 objectlength = translateint32_t(l);
256 printf("Object content size: %"PRId32" bytes\n", objectlength);
259 fread(&l, 4, 1, infile);
260 headerlength = translateint32_t(l);
261 printf("Header (%"PRId32" bytes):\n", headerlength);
262 print_header(headerlength, version);
264 if (version == 1) {
265 fread(&l, 4, 1, infile);
266 l = translateint32_t(l);
267 printf("\nText segment length = %"PRId32" bytes\n", l);
268 offset = 0;
269 while (l--) {
270 fread(id, 1, 1, infile);
271 if (verbose) {
272 if (offset % 16 == 0)
273 printf("\n%08"PRIx32" ", offset);
274 printf(" %02x", (int)(uint8_t)id[0]);
275 offset++;
278 if (verbose)
279 printf("\n\n");
281 fread(&l, 4, 1, infile);
282 l = translateint32_t(l);
283 printf("Data segment length = %"PRId32" bytes\n", l);
285 if (verbose) {
286 offset = 0;
287 while (l--) {
288 fread(id, 1, 1, infile);
289 if (offset % 16 == 0)
290 printf("\n%08"PRIx32" ", offset);
291 printf(" %02x", (int)(uint8_t)id[0]);
292 offset++;
294 printf("\n");
296 } else {
297 do {
298 fread(&s, 2, 1, infile);
299 s = translateint16_t(s);
300 if (!s) {
301 printf("\nNULL segment\n");
302 foundnullsegment = 1;
303 break;
305 printf("\nSegment:\n Type = %04X (%s)\n", (int)s,
306 translatesegmenttype(s));
307 nsegments++;
309 fread(&s, 2, 1, infile);
310 printf(" Number = %04X\n", (int)translateint16_t(s));
311 fread(&s, 2, 1, infile);
312 printf(" Resrvd = %04X\n", (int)translateint16_t(s));
313 fread(&l, 4, 1, infile);
314 l = translateint32_t(l);
315 printf(" Length = %"PRId32" bytes\n", l);
316 segmentcontentlength += l;
318 offset = 0;
319 while (l--) {
320 fread(id, 1, 1, infile);
321 if (verbose) {
322 if (offset % 16 == 0)
323 printf("\n%08"PRIx32" ", offset);
324 printf(" %02x", (int)(uint8_t)id[0]);
325 offset++;
328 if (verbose)
329 printf("\n");
330 } while (!feof(infile));
331 if (!foundnullsegment)
332 printf("\nWarning: unexpected end of file - "
333 "NULL segment not found\n");
335 printf("\nTotal number of segments: %d\n", nsegments);
336 printf("Total segment content length: %"PRId32" bytes\n",
337 segmentcontentlength);
339 /* calculate what the total object content length should have been */
340 l = segmentcontentlength + 10 * (nsegments + 1) + headerlength + 4;
341 if (l != objectlength)
342 printf("Warning: actual object length (%"PRId32") != "
343 "stored object length (%"PRId32")\n", l, objectlength);
345 fclose(infile);
346 return 0;