output: macho -- Add support for N_PEXT in macho output
[nasm.git] / rdoff / rdfdump.c
blobb483477bf177599b4c9ff3e72b0c2076731a1433
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2014 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 #include "rdfutils.h"
46 #define PROGRAM_VERSION "2.3"
48 FILE *infile;
50 static void print_header(int32_t length, int rdf_version)
52 char buf[129], t, l, s, flags;
53 uint8_t reclen;
54 int32_t o, ll;
55 uint16_t rs;
57 while (length > 0) {
58 nasm_read(&t, 1, infile);
59 if (rdf_version >= 2) {
60 nasm_read(&reclen, 1, infile);
62 switch (t) {
63 case RDFREC_GENERIC: /* generic record */
64 printf(" generic record (length=%d)\n", (int)reclen);
65 fseek(infile, reclen, SEEK_CUR);
66 break;
68 case RDFREC_RELOC: /* relocation record */
69 case RDFREC_SEGRELOC: /* segment relocation */
70 nasm_read(&s, 1, infile);
71 nasm_read(&o, 4, infile);
72 nasm_read(&l, 1, infile);
73 nasm_read(&rs, 2, infile);
74 printf(" %s: location (%04x:%08"PRIx32"), length %d, "
75 "referred seg %04x\n",
76 t == 1 ? "relocation" : "seg relocation", (int)s,
77 translateint32_t(o), (int)l, translateint16_t(rs));
78 if (rdf_version >= 2 && reclen != 8)
79 printf(" warning: reclen != 8\n");
80 if (rdf_version == 1)
81 length -= 9;
82 if (rdf_version == 1 && t == 6)
83 printf
84 (" warning: seg relocation not supported in RDOFF1\n");
85 break;
87 case RDFREC_IMPORT: /* import record */
88 case RDFREC_FARIMPORT: /* import far symbol */
89 nasm_read(&flags, 1, infile);
90 nasm_read(&rs, 2, infile);
91 ll = 0;
93 if (rdf_version == 1) {
94 do {
95 nasm_read(&buf[ll], 1, infile);
96 } while (buf[ll++]);
97 } else {
98 for (; ll < reclen - 3; ll++)
99 nasm_read(&buf[ll], 1, infile);
102 if (t == 7)
103 printf("far ");
104 printf((flags & SYM_IMPORT) ? " import" : " extern");
105 if (flags & SYM_FUNCTION)
106 printf(" proc");
107 if (flags & SYM_DATA)
108 printf(" data");
109 printf(": segment %04x = %s\n", translateint16_t(rs), buf);
110 if (rdf_version == 1)
111 length -= ll + 3;
112 if (rdf_version == 1 && t == 7)
113 printf
114 (" warning: far import not supported in RDOFF1\n");
115 break;
117 case RDFREC_GLOBAL: /* export record */
118 nasm_read(&flags, 1, infile);
119 nasm_read(&s, 1, infile);
120 nasm_read(&o, 4, infile);
121 ll = 0;
123 if (rdf_version == 1) {
124 do {
125 nasm_read(&buf[ll], 1, infile);
126 } while (buf[ll++]);
127 } else {
128 for (; ll < reclen - 6; ll++)
129 nasm_read(&buf[ll], 1, infile);
131 printf((flags & SYM_GLOBAL) ? " export" : " public");
132 if (flags & SYM_FUNCTION)
133 printf(" proc");
134 if (flags & SYM_DATA)
135 printf(" data");
136 printf(": (%04x:%08"PRIx32") = %s\n", (int)s, translateint32_t(o), buf);
137 if (rdf_version == 1)
138 length -= ll + 6;
139 break;
141 case RDFREC_DLL: /* DLL and Module records */
142 case RDFREC_MODNAME:
143 ll = 0;
144 if (rdf_version == 1) {
145 do {
146 nasm_read(&buf[ll], 1, infile);
147 } while (buf[ll++]);
148 } else {
149 for (; ll < reclen; ll++)
150 nasm_read(&buf[ll], 1, infile);
152 if (t == 4)
153 printf(" dll: %s\n", buf);
154 else
155 printf(" module: %s\n", buf);
156 if (rdf_version == 1)
157 length -= ll + 1;
158 break;
160 case RDFREC_BSS: /* BSS reservation */
161 nasm_read(&ll, 4, infile);
162 printf(" bss reservation: %08"PRIx32" bytes\n", translateint32_t(ll));
163 if (rdf_version == 1)
164 length -= 5;
165 if (rdf_version > 1 && reclen != 4)
166 printf(" warning: reclen != 4\n");
167 break;
169 case RDFREC_COMMON:{
170 uint16_t seg, align;
171 uint32_t size;
173 nasm_read(&seg, 2, infile);
174 nasm_read(&size, 4, infile);
175 nasm_read(&align, 2, infile);
176 for (ll = 0; ll < reclen - 8; ll++)
177 nasm_read(buf + ll, 1, infile);
178 printf(" common: segment %04x = %s, %"PRId32":%d\n",
179 translateint16_t(seg), buf, translateint32_t(size),
180 translateint16_t(align));
181 break;
184 default:
185 printf(" unrecognized record (type %d", (int)t);
186 if (rdf_version > 1) {
187 printf(", length %d", (int)reclen);
188 fseek(infile, reclen, SEEK_CUR);
189 } else
190 length--;
191 printf(")\n");
193 if (rdf_version != 1)
194 length -= 2 + reclen;
198 int main(int argc, char **argv)
200 char id[7];
201 int32_t l;
202 uint16_t s;
203 int verbose = 0;
204 int32_t offset;
205 int foundnullsegment = 0;
206 int version;
207 int32_t segmentcontentlength = 0;
208 int nsegments = 0;
209 int32_t headerlength = 0;
210 int32_t objectlength = 0;
212 printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
213 printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
214 puts("Copyright (c) 1996,99 Julian R Hall\n"
215 "Improvements and fixes (c) 2002-2004 RET & COM Research.");
217 if (argc < 2) {
218 fputs("Usage: rdfdump [-v] <filename>\n", stderr);
219 exit(1);
222 rdoff_init();
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 nasm_read(id, 6, 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 nasm_read(&l, 4, infile);
255 objectlength = translateint32_t(l);
256 printf("Object content size: %"PRId32" bytes\n", objectlength);
259 nasm_read(&l, 4, infile);
260 headerlength = translateint32_t(l);
261 printf("Header (%"PRId32" bytes):\n", headerlength);
262 print_header(headerlength, version);
264 if (version == 1) {
265 nasm_read(&l, 4, infile);
266 l = translateint32_t(l);
267 printf("\nText segment length = %"PRId32" bytes\n", l);
268 offset = 0;
269 while (l--) {
270 nasm_read(id, 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 nasm_read(&l, 4, 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 nasm_read(id, 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 nasm_read(&s, 2, 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 nasm_read(&s, 2, infile);
310 printf(" Number = %04X\n", (int)translateint16_t(s));
311 nasm_read(&s, 2, infile);
312 printf(" Resrvd = %04X\n", (int)translateint16_t(s));
313 nasm_read(&l, 4, infile);
314 l = translateint32_t(l);
315 printf(" Length = %"PRId32" bytes\n", l);
316 segmentcontentlength += l;
318 offset = 0;
319 while (l--) {
320 nasm_read(id, 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;