More test files...
[nasm.git] / rdoff / rdfdump.c
blobd8690d209d39658c3782e1dbd67d41ece1f503ab
1 /*
2 * rdfdump.c - dump RDOFF file header.
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
9 #include "rdoff.h"
11 FILE *infile;
13 long translatelong(long in) { /* translate from little endian to
14 local representation */
15 long r;
16 unsigned char *i;
18 i = (unsigned char *)&in;
19 r = i[3];
20 r = (r << 8) + i[2];
21 r = (r << 8) + i[1];
22 r = (r << 8) + *i;
24 return r;
27 int16 translateshort(int16 in) {
28 int r;
29 unsigned char *i;
31 i = (unsigned char *)&in;
32 r = (i[1] << 8) + *i;
34 return r;
37 void print_header(long length, int rdf_version)
39 char buf[129],t,l,s,flags;
40 unsigned char reclen;
41 long o,ll;
42 int16 rs;
44 while (length > 0) {
45 fread(&t,1,1,infile);
46 if (rdf_version >= 2) {
47 fread(&reclen,1,1,infile);
49 switch(t) {
50 case RDFREC_GENERIC: /* generic record */
51 printf(" generic record (length=%d)\n", (int)reclen);
52 fseek(infile, reclen, SEEK_CUR);
53 break;
55 case RDFREC_RELOC: /* relocation record */
56 case RDFREC_SEGRELOC: /* segment relocation */
57 fread(&s,1,1,infile);
58 fread(&o,4,1,infile);
59 fread(&l,1,1,infile);
60 fread(&rs,2,1,infile);
61 printf(" %s: location (%04x:%08lx), length %d, "
62 "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
63 (int)s,translatelong(o),(int)l,
64 translateshort(rs));
65 if (rdf_version >= 2 && reclen != 8)
66 printf(" warning: reclen != 8\n");
67 if (rdf_version == 1) length -= 9;
68 if (rdf_version == 1 && t == 6)
69 printf(" warning: seg relocation not supported in RDOFF1\n");
70 break;
72 case RDFREC_IMPORT: /* import record */
73 case RDFREC_FARIMPORT: /* import far symbol */
74 fread(&rs,2,1,infile);
75 ll = 0;
77 if (rdf_version == 1) {
78 do {
79 fread(&buf[ll],1,1,infile);
80 } while (buf[ll++]);
81 } else {
82 for (;ll < reclen - 2; ll++)
83 fread(&buf[ll],1,1,infile);
86 printf(" %simport: segment %04x = %s\n",t == 7 ? "far " : "",
87 translateshort(rs),buf);
88 if (rdf_version == 1) length -= ll + 3;
89 if (rdf_version == 1 && t == 7)
90 printf (" warning: far import not supported in RDOFF1\n");
91 break;
93 case RDFREC_GLOBAL: /* export record */
94 fread(&flags,1,1,infile);
95 fread(&s,1,1,infile);
96 fread(&o,4,1,infile);
97 ll = 0;
99 if (rdf_version == 1) {
100 do {
101 fread(&buf[ll],1,1,infile);
102 } while (buf[ll++]);
103 } else {
104 for (; ll < reclen - 6; ll ++)
105 fread(&buf[ll],1,1,infile);
107 if (flags & SYM_GLOBAL)
108 printf(" export");
109 else
110 printf(" global");
111 if (flags & SYM_FUNCTION) printf(" proc");
112 if (flags & SYM_DATA) printf(" data");
113 printf(": (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
114 if (rdf_version == 1) length -= ll + 6;
115 break;
117 case RDFREC_DLL: /* DLL and Module records */
118 case RDFREC_MODNAME:
119 ll = 0;
121 if (rdf_version == 1) {
122 do {
123 fread(&buf[ll],1,1,infile);
124 } while (buf[ll++]);
125 } else {
126 for (; ll < reclen; ll++)
127 fread(&buf[ll],1,1,infile);
129 if (t==4) printf(" dll: %s\n",buf);
130 else printf(" module: %s\n",buf);
131 if (rdf_version == 1) length -= ll + 1;
132 break;
134 case RDFREC_BSS: /* BSS reservation */
135 fread(&ll,4,1,infile);
136 printf(" bss reservation: %08lx bytes\n",translatelong(ll));
137 if (rdf_version == 1) length -= 5;
138 if (rdf_version > 1 && reclen != 4)
139 printf(" warning: reclen != 4\n");
140 break;
142 case RDFREC_COMMON: {
143 unsigned short seg, align;
144 unsigned long size;
146 fread(&seg, 2, 1, infile);
147 fread(&size, 4, 1, infile);
148 fread(&align, 2, 1, infile);
149 for (ll = 0; ll < reclen - 8; ll++)
150 fread(buf+ll, 1, 1, infile);
151 printf(" common: segment %04x = %s, %ld:%d\n", translateshort(seg),
152 buf, translatelong(size), translateshort(align));
153 break;
156 default:
157 printf(" unrecognized record (type %d", (int)t);
158 if (rdf_version > 1) {
159 printf(", length %d",(int)reclen);
160 fseek(infile,reclen,SEEK_CUR);
161 } else length --;
162 printf(")\n");
164 if (rdf_version != 1) length -= 2 + reclen;
168 char * knowntypes[8] = {"NULL", "text", "data", "object comment",
169 "linked comment", "loader comment",
170 "symbolic debug", "line number debug"};
172 char * translatesegmenttype(int16 type) {
173 if (type < 8) return knowntypes[type];
174 if (type < 0x0020) return "reserved";
175 if (type < 0x1000) return "reserved - moscow";
176 if (type < 0x8000) return "reserved - system dependant";
177 if (type < 0xFFFF) return "reserved - other";
178 if (type == 0xFFFF) return "invalid type code";
179 return "type code out of range";
182 int main(int argc,char **argv) {
183 char id[7];
184 long l;
185 int16 s;
186 int verbose = 0;
187 long offset;
188 int foundnullsegment = 0;
189 int version;
190 long segmentcontentlength = 0;
191 int nsegments = 0;
192 long headerlength = 0;
193 long objectlength = 0;
195 puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
197 if (argc < 2) {
198 fputs("Usage: rdfdump [-v] <filename>\n",stderr);
199 exit(1);
202 if (! strcmp (argv[1], "-v") )
204 verbose = 1;
205 if (argc < 3)
207 fputs("required parameter missing\n",stderr);
208 exit(1);
210 argv++;
213 infile = fopen(argv[1],"rb");
214 if (! infile) {
215 fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
216 exit(1);
219 fread(id,6,1,infile);
220 if (strncmp(id,"RDOFF",5)) {
221 fputs("rdfdump: File does not contain valid RDOFF header\n",stderr);
222 exit(1);
225 printf("File %s: RDOFF version %c\n\n",argv[1],id[5]);
226 if (id[5] < '1' || id[5] > '2') {
227 fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
228 exit(1);
230 version = id[5] - '0';
232 if (version > 1) {
233 fread(&l, 4, 1, infile);
234 objectlength = translatelong(l);
235 printf("Object content size: %ld bytes\n", objectlength);
238 fread(&l,4,1,infile);
239 headerlength = translatelong(l);
240 printf("Header (%ld bytes):\n",headerlength);
241 print_header(headerlength, version);
243 if (version == 1) {
244 fread(&l,4,1,infile);
245 l = translatelong(l);
246 printf("\nText segment length = %ld bytes\n",l);
247 offset = 0;
248 while(l--) {
249 fread(id,1,1,infile);
250 if (verbose) {
251 if (offset % 16 == 0)
252 printf("\n%08lx ", offset);
253 printf(" %02x",(int) (unsigned char)id[0]);
254 offset++;
257 if (verbose) printf("\n\n");
259 fread(&l,4,1,infile);
260 l = translatelong(l);
261 printf("Data segment length = %ld bytes\n",l);
263 if (verbose)
265 offset = 0;
266 while (l--) {
267 fread(id,1,1,infile);
268 if (offset % 16 == 0)
269 printf("\n%08lx ", offset);
270 printf(" %02x",(int) (unsigned char) id[0]);
271 offset++;
273 printf("\n");
276 else
278 do {
279 fread(&s,2,1,infile);
280 s = translateshort(s);
281 if (!s) {
282 printf("\nNULL segment\n");
283 foundnullsegment = 1;
284 break;
286 printf("\nSegment:\n Type = %04X (%s)\n",(int)s,
287 translatesegmenttype(s));
288 nsegments++;
290 fread(&s,2,1,infile);
291 printf(" Number = %04X\n",(int)translateshort(s));
292 fread(&s,2,1,infile);
293 printf(" Resrvd = %04X\n",(int)translateshort(s));
294 fread(&l,4,1,infile);
295 l = translatelong(l);
296 printf(" Length = %ld bytes\n",l);
297 segmentcontentlength += l;
299 offset = 0;
300 while(l--) {
301 fread(id,1,1,infile);
302 if (verbose) {
303 if (offset % 16 == 0)
304 printf("\n%08lx ", offset);
305 printf(" %02x",(int) (unsigned char)id[0]);
306 offset++;
309 if (verbose) printf("\n");
310 } while (!feof(infile));
311 if (! foundnullsegment)
312 printf("\nWarning: unexpected end of file - "
313 "NULL segment not found\n");
315 printf("\nTotal number of segments: %d\n", nsegments);
316 printf("Total segment content length: %ld bytes\n",segmentcontentlength);
318 /* calculate what the total object content length should have been */
319 l = segmentcontentlength + 10 * (nsegments+1) + headerlength + 4;
320 if (l != objectlength)
321 printf("Warning: actual object length (%ld) != "
322 "stored object length (%ld)\n", l, objectlength);
324 fclose(infile);
325 return 0;