NASM 0.98.11
[nasm.git] / rdoff / rdfdump.c
blob347fdb1785479b7e923cf6d5c023ae752f29f1f1
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "multboot.h"
7 FILE *infile;
9 typedef unsigned short int16;
11 long translatelong(long in) { /* translate from little endian to
12 local representation */
13 long r;
14 unsigned char *i;
16 i = (unsigned char *)&in;
17 r = i[3];
18 r = (r << 8) + i[2];
19 r = (r << 8) + i[1];
20 r = (r << 8) + *i;
22 return r;
25 int translateshort(int16 in) {
26 int r;
27 unsigned char *i;
29 i = (unsigned char *)&in;
30 r = (i[1] << 8) + *i;
32 return r;
35 void print_header(long length, int rdf_version) {
36 char buf[129],t,s,l;
37 unsigned char reclen;
38 long o,ll;
39 int16 rs;
40 struct tMultiBootHeader *mb;
42 while (length > 0) {
43 fread(&t,1,1,infile);
44 if (rdf_version >= 2) {
45 fread(&reclen,1,1,infile);
47 switch(t) {
48 case 1: /* relocation record */
49 case 6: /* segment relocation */
50 fread(&s,1,1,infile);
51 fread(&o,4,1,infile);
52 fread(&l,1,1,infile);
53 fread(&rs,2,1,infile);
54 printf(" %s: location (%04x:%08lx), length %d, "
55 "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
56 (int)s,translatelong(o),(int)l,
57 translateshort(rs));
58 if (rdf_version >= 2 && reclen != 8)
59 printf(" warning: reclen != 8\n");
60 if (rdf_version == 1) length -= 9;
61 if (rdf_version == 1 && t == 6)
62 printf(" warning: seg relocation not supported in RDOFF1\n");
63 break;
64 case 2: /* import record */
65 case 7: /* import far symbol */
66 fread(&rs,2,1,infile);
67 ll = 0;
69 if (rdf_version == 1) {
70 do {
71 fread(&buf[ll],1,1,infile);
72 } while (buf[ll++]);
74 else
76 for (;ll < reclen - 2; ll++)
77 fread(&buf[ll],1,1,infile);
80 printf(" %simport: segment %04x = %s\n",t == 7 ? "far " : "",
81 translateshort(rs),buf);
82 if (rdf_version == 1) length -= ll + 3;
83 if (rdf_version == 1 && t == 7)
84 printf (" warning: far import not supported in RDOFF1\n");
85 break;
86 case 3: /* export record */
87 fread(&s,1,1,infile);
88 fread(&o,4,1,infile);
89 ll = 0;
91 if (rdf_version == 1) {
92 do {
93 fread(&buf[ll],1,1,infile);
94 } while (buf[ll++]);
96 else
98 for (; ll < reclen - 5; ll ++)
99 fread(&buf[ll],1,1,infile);
101 printf(" export: (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
102 if (rdf_version == 1) length -= ll + 6;
103 break;
104 case 4: /* DLL and Module records */
105 case 8:
106 ll = 0;
108 if (rdf_version == 1) {
109 do {
110 fread(&buf[ll],1,1,infile);
111 } while (buf[ll++]);
113 else
115 for (; ll < reclen; ll++)
116 fread(&buf[ll],1,1,infile);
118 if (t==4) printf(" dll: %s\n",buf);
119 else printf(" module: %s\n",buf);
120 if (rdf_version == 1) length -= ll + 1;
121 break;
122 case 5: /* BSS reservation */
123 fread(&ll,4,1,infile);
124 printf(" bss reservation: %08lx bytes\n",translatelong(ll));
125 if (rdf_version == 1) length -= 5;
126 if (rdf_version > 1 && reclen != 4)
127 printf(" warning: reclen != 4\n");
128 break;
130 case 9: /* MultiBoot header record */
131 fread(buf,reclen,1,infile);
132 mb = (struct tMultiBootHeader *)buf;
133 printf(" multiboot header: load address=0x%X, size=0x%X, entry=0x%X\n",
134 mb->LoadAddr, mb->LoadEndAddr - mb->LoadAddr, mb->Entry);
135 break;
136 default:
137 printf(" unrecognised record (type %d",(int)t);
138 if (rdf_version > 1) {
139 printf(", length %d",(int)reclen);
140 fseek(infile,reclen,SEEK_CUR);
142 printf(")\n");
143 if (rdf_version == 1) length --;
145 if (rdf_version != 1) length -= 2 + reclen;
149 char * knowntypes[8] = {"NULL", "text", "data", "object comment",
150 "linked comment", "loader comment",
151 "symbolic debug", "line number debug"};
153 char * translatesegmenttype(int16 type) {
154 if (type < 8) return knowntypes[type];
155 if (type < 0x0020) return "reserved";
156 if (type < 0x1000) return "reserved - moscow";
157 if (type < 0x8000) return "reserved - system dependant";
158 if (type < 0xFFFF) return "reserved - other";
159 if (type == 0xFFFF) return "invalid type code";
160 return "type code out of range";
163 int main(int argc,char **argv) {
164 char id[7];
165 long l;
166 int16 s;
167 int verbose = 0;
168 long offset;
169 int foundnullsegment = 0;
170 int version;
171 long segmentcontentlength = 0;
172 int nsegments = 0;
173 long headerlength = 0;
174 long objectlength = 0;
176 puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
178 if (argc < 2) {
179 fputs("Usage: rdfdump [-v] <filename>\n",stderr);
180 exit(1);
183 if (! strcmp (argv[1], "-v") )
185 verbose = 1;
186 if (argc < 3)
188 fputs("required parameter missing\n",stderr);
189 exit(1);
191 argv++;
194 infile = fopen(argv[1],"rb");
195 if (! infile) {
196 fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
197 exit(1);
200 fread(id,6,1,infile);
201 if (strncmp(id,"RDOFF",5)) {
202 fputs("rdfdump: File does not contain valid RDOFF header\n",stderr);
203 exit(1);
206 printf("File %s: RDOFF version %c\n\n",argv[1],id[5]);
207 if (id[5] < '1' || id[5] > '2') {
208 fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
209 exit(1);
211 version = id[5] - '0';
213 if (version > 1) {
214 fread(&l, 4, 1, infile);
215 objectlength = translatelong(l);
216 printf("Object content size: %ld bytes\n", objectlength);
219 fread(&l,4,1,infile);
220 headerlength = translatelong(l);
221 printf("Header (%ld bytes):\n",headerlength);
222 print_header(headerlength, version);
224 if (version == 1) {
225 fread(&l,4,1,infile);
226 l = translatelong(l);
227 printf("\nText segment length = %ld bytes\n",l);
228 offset = 0;
229 while(l--) {
230 fread(id,1,1,infile);
231 if (verbose) {
232 if (offset % 16 == 0)
233 printf("\n%08lx ", offset);
234 printf(" %02x",(int) (unsigned char)id[0]);
235 offset++;
238 if (verbose) printf("\n\n");
240 fread(&l,4,1,infile);
241 l = translatelong(l);
242 printf("Data segment length = %ld bytes\n",l);
244 if (verbose)
246 offset = 0;
247 while (l--) {
248 fread(id,1,1,infile);
249 if (offset % 16 == 0)
250 printf("\n%08lx ", offset);
251 printf(" %02x",(int) (unsigned char) id[0]);
252 offset++;
254 printf("\n");
257 else
259 do {
260 fread(&s,2,1,infile);
261 s = translateshort(s);
262 if (!s) {
263 printf("\nNULL segment\n");
264 foundnullsegment = 1;
265 break;
267 printf("\nSegment:\n Type = %04X (%s)\n",(int)s,
268 translatesegmenttype(s));
269 nsegments++;
271 fread(&s,2,1,infile);
272 printf(" Number = %04X\n",(int)translateshort(s));
273 fread(&s,2,1,infile);
274 printf(" Resrvd = %04X\n",(int)translateshort(s));
275 fread(&l,4,1,infile);
276 l = translatelong(l);
277 printf(" Length = %ld bytes\n",l);
278 segmentcontentlength += l;
280 offset = 0;
281 while(l--) {
282 fread(id,1,1,infile);
283 if (verbose) {
284 if (offset % 16 == 0)
285 printf("\n%08lx ", offset);
286 printf(" %02x",(int) (unsigned char)id[0]);
287 offset++;
290 if (verbose) printf("\n");
291 } while (!feof(infile));
292 if (! foundnullsegment)
293 printf("\nWarning: unexpected end of file - "
294 "NULL segment not found\n");
296 printf("\nTotal number of segments: %d\n", nsegments);
297 printf("Total segment content length: %ld bytes\n",segmentcontentlength);
299 /* calculate what the total object content length should have been */
300 l = segmentcontentlength + 10 * (nsegments+1) + headerlength + 4;
301 if (l != objectlength)
302 printf("Warning: actual object length (%ld) != "
303 "stored object length (%ld)\n", l, objectlength);
305 fclose(infile);
306 return 0;