Merge commit 'nasm-2.05.01'
[nasm.git] / rdoff / rdfdump.c
blob83305570eebf48fcdf487e4bb2587e538822da91
1 /*
2 * rdfdump.c - dump RDOFF file header.
3 */
5 #include "compiler.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #define RDOFF_UTILS
13 #include "rdoff.h"
15 #define PROGRAM_VERSION "2.3"
17 FILE *infile;
19 void print_header(int32_t length, int rdf_version)
21 char buf[129], t, l, s, flags;
22 uint8_t reclen;
23 int32_t o, ll;
24 uint16_t rs;
26 while (length > 0) {
27 fread(&t, 1, 1, infile);
28 if (rdf_version >= 2) {
29 fread(&reclen, 1, 1, infile);
31 switch (t) {
32 case RDFREC_GENERIC: /* generic record */
33 printf(" generic record (length=%d)\n", (int)reclen);
34 fseek(infile, reclen, SEEK_CUR);
35 break;
37 case RDFREC_RELOC: /* relocation record */
38 case RDFREC_SEGRELOC: /* segment relocation */
39 fread(&s, 1, 1, infile);
40 fread(&o, 4, 1, infile);
41 fread(&l, 1, 1, infile);
42 fread(&rs, 2, 1, infile);
43 printf(" %s: location (%04x:%08"PRIx32"), length %d, "
44 "referred seg %04x\n",
45 t == 1 ? "relocation" : "seg relocation", (int)s,
46 translateint32_t(o), (int)l, translateint16_t(rs));
47 if (rdf_version >= 2 && reclen != 8)
48 printf(" warning: reclen != 8\n");
49 if (rdf_version == 1)
50 length -= 9;
51 if (rdf_version == 1 && t == 6)
52 printf
53 (" warning: seg relocation not supported in RDOFF1\n");
54 break;
56 case RDFREC_IMPORT: /* import record */
57 case RDFREC_FARIMPORT: /* import far symbol */
58 fread(&flags, 1, 1, infile);
59 fread(&rs, 2, 1, infile);
60 ll = 0;
62 if (rdf_version == 1) {
63 do {
64 fread(&buf[ll], 1, 1, infile);
65 } while (buf[ll++]);
66 } else {
67 for (; ll < reclen - 3; ll++)
68 fread(&buf[ll], 1, 1, infile);
71 if (t == 7)
72 printf("far ");
73 printf((flags & SYM_IMPORT) ? " import" : " extern");
74 if (flags & SYM_FUNCTION)
75 printf(" proc");
76 if (flags & SYM_DATA)
77 printf(" data");
78 printf(": segment %04x = %s\n", translateint16_t(rs), buf);
79 if (rdf_version == 1)
80 length -= ll + 3;
81 if (rdf_version == 1 && t == 7)
82 printf
83 (" warning: far import not supported in RDOFF1\n");
84 break;
86 case RDFREC_GLOBAL: /* export record */
87 fread(&flags, 1, 1, infile);
88 fread(&s, 1, 1, infile);
89 fread(&o, 4, 1, infile);
90 ll = 0;
92 if (rdf_version == 1) {
93 do {
94 fread(&buf[ll], 1, 1, infile);
95 } while (buf[ll++]);
96 } else {
97 for (; ll < reclen - 6; ll++)
98 fread(&buf[ll], 1, 1, infile);
100 printf((flags & SYM_GLOBAL) ? " export" : " public");
101 if (flags & SYM_FUNCTION)
102 printf(" proc");
103 if (flags & SYM_DATA)
104 printf(" data");
105 printf(": (%04x:%08"PRIx32") = %s\n", (int)s, translateint32_t(o), buf);
106 if (rdf_version == 1)
107 length -= ll + 6;
108 break;
110 case RDFREC_DLL: /* DLL and Module records */
111 case RDFREC_MODNAME:
112 ll = 0;
113 if (rdf_version == 1) {
114 do {
115 fread(&buf[ll], 1, 1, infile);
116 } while (buf[ll++]);
117 } else {
118 for (; ll < reclen; ll++)
119 fread(&buf[ll], 1, 1, infile);
121 if (t == 4)
122 printf(" dll: %s\n", buf);
123 else
124 printf(" module: %s\n", buf);
125 if (rdf_version == 1)
126 length -= ll + 1;
127 break;
129 case RDFREC_BSS: /* BSS reservation */
130 fread(&ll, 4, 1, infile);
131 printf(" bss reservation: %08"PRIx32" bytes\n", translateint32_t(ll));
132 if (rdf_version == 1)
133 length -= 5;
134 if (rdf_version > 1 && reclen != 4)
135 printf(" warning: reclen != 4\n");
136 break;
138 case RDFREC_COMMON:{
139 uint16_t seg, align;
140 uint32_t size;
142 fread(&seg, 2, 1, infile);
143 fread(&size, 4, 1, infile);
144 fread(&align, 2, 1, infile);
145 for (ll = 0; ll < reclen - 8; ll++)
146 fread(buf + ll, 1, 1, infile);
147 printf(" common: segment %04x = %s, %"PRId32":%d\n",
148 translateint16_t(seg), buf, translateint32_t(size),
149 translateint16_t(align));
150 break;
153 default:
154 printf(" unrecognized record (type %d", (int)t);
155 if (rdf_version > 1) {
156 printf(", length %d", (int)reclen);
157 fseek(infile, reclen, SEEK_CUR);
158 } else
159 length--;
160 printf(")\n");
162 if (rdf_version != 1)
163 length -= 2 + reclen;
167 int main(int argc, char **argv)
169 char id[7];
170 int32_t l;
171 uint16_t s;
172 int verbose = 0;
173 int32_t offset;
174 int foundnullsegment = 0;
175 int version;
176 int32_t segmentcontentlength = 0;
177 int nsegments = 0;
178 int32_t headerlength = 0;
179 int32_t objectlength = 0;
181 printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
182 printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
183 puts("Copyright (c) 1996,99 Julian R Hall\n"
184 "Improvements and fixes (c) 2002-2004 RET & COM Research.");
186 if (argc < 2) {
187 fputs("Usage: rdfdump [-v] <filename>\n", stderr);
188 exit(1);
191 if (!strcmp(argv[1], "-v")) {
192 verbose = 1;
193 if (argc < 3) {
194 fputs("required parameter missing\n", stderr);
195 exit(1);
197 argv++;
200 infile = fopen(argv[1], "rb");
201 if (!infile) {
202 fprintf(stderr, "rdfdump: Could not open %s\n", argv[1]);
203 exit(1);
206 fread(id, 6, 1, infile);
207 if (strncmp(id, "RDOFF", 5)) {
208 fputs("rdfdump: File does not contain valid RDOFF header\n",
209 stderr);
210 exit(1);
213 printf("File %s: RDOFF version %c\n\n", argv[1], id[5]);
214 if (id[5] < '1' || id[5] > '2') {
215 fprintf(stderr, "rdfdump: unknown RDOFF version '%c'\n", id[5]);
216 exit(1);
218 version = id[5] - '0';
220 if (version > 1) {
221 fread(&l, 4, 1, infile);
222 objectlength = translateint32_t(l);
223 printf("Object content size: %"PRId32" bytes\n", objectlength);
226 fread(&l, 4, 1, infile);
227 headerlength = translateint32_t(l);
228 printf("Header (%"PRId32" bytes):\n", headerlength);
229 print_header(headerlength, version);
231 if (version == 1) {
232 fread(&l, 4, 1, infile);
233 l = translateint32_t(l);
234 printf("\nText segment length = %"PRId32" bytes\n", l);
235 offset = 0;
236 while (l--) {
237 fread(id, 1, 1, infile);
238 if (verbose) {
239 if (offset % 16 == 0)
240 printf("\n%08"PRIx32" ", offset);
241 printf(" %02x", (int)(uint8_t)id[0]);
242 offset++;
245 if (verbose)
246 printf("\n\n");
248 fread(&l, 4, 1, infile);
249 l = translateint32_t(l);
250 printf("Data segment length = %"PRId32" bytes\n", l);
252 if (verbose) {
253 offset = 0;
254 while (l--) {
255 fread(id, 1, 1, infile);
256 if (offset % 16 == 0)
257 printf("\n%08"PRIx32" ", offset);
258 printf(" %02x", (int)(uint8_t)id[0]);
259 offset++;
261 printf("\n");
263 } else {
264 do {
265 fread(&s, 2, 1, infile);
266 s = translateint16_t(s);
267 if (!s) {
268 printf("\nNULL segment\n");
269 foundnullsegment = 1;
270 break;
272 printf("\nSegment:\n Type = %04X (%s)\n", (int)s,
273 translatesegmenttype(s));
274 nsegments++;
276 fread(&s, 2, 1, infile);
277 printf(" Number = %04X\n", (int)translateint16_t(s));
278 fread(&s, 2, 1, infile);
279 printf(" Resrvd = %04X\n", (int)translateint16_t(s));
280 fread(&l, 4, 1, infile);
281 l = translateint32_t(l);
282 printf(" Length = %"PRId32" bytes\n", l);
283 segmentcontentlength += l;
285 offset = 0;
286 while (l--) {
287 fread(id, 1, 1, infile);
288 if (verbose) {
289 if (offset % 16 == 0)
290 printf("\n%08"PRIx32" ", offset);
291 printf(" %02x", (int)(uint8_t)id[0]);
292 offset++;
295 if (verbose)
296 printf("\n");
297 } while (!feof(infile));
298 if (!foundnullsegment)
299 printf("\nWarning: unexpected end of file - "
300 "NULL segment not found\n");
302 printf("\nTotal number of segments: %d\n", nsegments);
303 printf("Total segment content length: %"PRId32" bytes\n",
304 segmentcontentlength);
306 /* calculate what the total object content length should have been */
307 l = segmentcontentlength + 10 * (nsegments + 1) + headerlength + 4;
308 if (l != objectlength)
309 printf("Warning: actual object length (%"PRId32") != "
310 "stored object length (%"PRId32")\n", l, objectlength);
312 fclose(infile);
313 return 0;