Automatically update the LATEST tag if doing a "real" release
[nasm.git] / rdoff / rdfdump.c
blob5bf6264cba2974c8c94cfcf463b3b3e478af308a
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "rdoff.h"
6 #include "multboot.h"
8 FILE *infile;
10 long translatelong(long in) { /* translate from little endian to
11 local representation */
12 long r;
13 unsigned char *i;
15 i = (unsigned char *)&in;
16 r = i[3];
17 r = (r << 8) + i[2];
18 r = (r << 8) + i[1];
19 r = (r << 8) + *i;
21 return r;
24 int16 translateshort(int16 in) {
25 int r;
26 unsigned char *i;
28 i = (unsigned char *)&in;
29 r = (i[1] << 8) + *i;
31 return r;
34 void print_header(long length, int rdf_version) {
35 char buf[129],t,s,l,flags;
36 unsigned char reclen;
37 long o,ll;
38 int16 rs;
39 struct tMultiBootHeader *mb;
41 while (length > 0) {
42 fread(&t,1,1,infile);
43 if (rdf_version >= 2) {
44 fread(&reclen,1,1,infile);
46 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;
65 case 2: /* import record */
66 case 7: /* import far symbol */
67 fread(&rs,2,1,infile);
68 ll = 0;
70 if (rdf_version == 1) {
71 do {
72 fread(&buf[ll],1,1,infile);
73 } while (buf[ll++]);
75 else
77 for (;ll < reclen - 2; ll++)
78 fread(&buf[ll],1,1,infile);
81 printf(" %simport: segment %04x = %s\n",t == 7 ? "far " : "",
82 translateshort(rs),buf);
83 if (rdf_version == 1) length -= ll + 3;
84 if (rdf_version == 1 && t == 7)
85 printf (" warning: far import not supported in RDOFF1\n");
86 break;
88 case 3: /* export record */
89 fread(&flags,1,1,infile);
90 fread(&s,1,1,infile);
91 fread(&o,4,1,infile);
92 ll = 0;
94 if (rdf_version == 1) {
95 do {
96 fread(&buf[ll],1,1,infile);
97 } while (buf[ll++]);
99 else
101 for (; ll < reclen - 6; ll ++)
102 fread(&buf[ll],1,1,infile);
104 if (flags & SYM_GLOBAL)
105 printf(" export");
106 else
107 printf(" global");
108 if (flags & SYM_FUNCTION) printf(" proc");
109 if (flags & SYM_DATA) printf(" data");
110 printf(": (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
111 if (rdf_version == 1) length -= ll + 6;
112 break;
114 case 4: /* DLL and Module records */
115 case 8:
116 ll = 0;
118 if (rdf_version == 1) {
119 do {
120 fread(&buf[ll],1,1,infile);
121 } while (buf[ll++]);
123 else
125 for (; ll < reclen; ll++)
126 fread(&buf[ll],1,1,infile);
128 if (t==4) printf(" dll: %s\n",buf);
129 else printf(" module: %s\n",buf);
130 if (rdf_version == 1) length -= ll + 1;
131 break;
132 case 5: /* BSS reservation */
133 fread(&ll,4,1,infile);
134 printf(" bss reservation: %08lx bytes\n",translatelong(ll));
135 if (rdf_version == 1) length -= 5;
136 if (rdf_version > 1 && reclen != 4)
137 printf(" warning: reclen != 4\n");
138 break;
140 case 9: /* MultiBoot header record */
141 fread(buf,reclen,1,infile);
142 mb = (struct tMultiBootHeader *)buf;
143 printf(" multiboot header: load address=0x%X, size=0x%X, entry=0x%X\n",
144 mb->LoadAddr, mb->LoadEndAddr - mb->LoadAddr, mb->Entry);
145 break;
146 default:
147 printf(" unrecognised record (type %d",(int)t);
148 if (rdf_version > 1) {
149 printf(", length %d",(int)reclen);
150 fseek(infile,reclen,SEEK_CUR);
152 printf(")\n");
153 if (rdf_version == 1) length --;
155 if (rdf_version != 1) length -= 2 + reclen;
159 char * knowntypes[8] = {"NULL", "text", "data", "object comment",
160 "linked comment", "loader comment",
161 "symbolic debug", "line number debug"};
163 char * translatesegmenttype(int16 type) {
164 if (type < 8) return knowntypes[type];
165 if (type < 0x0020) return "reserved";
166 if (type < 0x1000) return "reserved - moscow";
167 if (type < 0x8000) return "reserved - system dependant";
168 if (type < 0xFFFF) return "reserved - other";
169 if (type == 0xFFFF) return "invalid type code";
170 return "type code out of range";
173 int main(int argc,char **argv) {
174 char id[7];
175 long l;
176 int16 s;
177 int verbose = 0;
178 long offset;
179 int foundnullsegment = 0;
180 int version;
181 long segmentcontentlength = 0;
182 int nsegments = 0;
183 long headerlength = 0;
184 long objectlength = 0;
186 puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
188 if (argc < 2) {
189 fputs("Usage: rdfdump [-v] <filename>\n",stderr);
190 exit(1);
193 if (! strcmp (argv[1], "-v") )
195 verbose = 1;
196 if (argc < 3)
198 fputs("required parameter missing\n",stderr);
199 exit(1);
201 argv++;
204 infile = fopen(argv[1],"rb");
205 if (! infile) {
206 fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
207 exit(1);
210 fread(id,6,1,infile);
211 if (strncmp(id,"RDOFF",5)) {
212 fputs("rdfdump: File does not contain valid RDOFF header\n",stderr);
213 exit(1);
216 printf("File %s: RDOFF version %c\n\n",argv[1],id[5]);
217 if (id[5] < '1' || id[5] > '2') {
218 fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
219 exit(1);
221 version = id[5] - '0';
223 if (version > 1) {
224 fread(&l, 4, 1, infile);
225 objectlength = translatelong(l);
226 printf("Object content size: %ld bytes\n", objectlength);
229 fread(&l,4,1,infile);
230 headerlength = translatelong(l);
231 printf("Header (%ld bytes):\n",headerlength);
232 print_header(headerlength, version);
234 if (version == 1) {
235 fread(&l,4,1,infile);
236 l = translatelong(l);
237 printf("\nText segment length = %ld bytes\n",l);
238 offset = 0;
239 while(l--) {
240 fread(id,1,1,infile);
241 if (verbose) {
242 if (offset % 16 == 0)
243 printf("\n%08lx ", offset);
244 printf(" %02x",(int) (unsigned char)id[0]);
245 offset++;
248 if (verbose) printf("\n\n");
250 fread(&l,4,1,infile);
251 l = translatelong(l);
252 printf("Data segment length = %ld bytes\n",l);
254 if (verbose)
256 offset = 0;
257 while (l--) {
258 fread(id,1,1,infile);
259 if (offset % 16 == 0)
260 printf("\n%08lx ", offset);
261 printf(" %02x",(int) (unsigned char) id[0]);
262 offset++;
264 printf("\n");
267 else
269 do {
270 fread(&s,2,1,infile);
271 s = translateshort(s);
272 if (!s) {
273 printf("\nNULL segment\n");
274 foundnullsegment = 1;
275 break;
277 printf("\nSegment:\n Type = %04X (%s)\n",(int)s,
278 translatesegmenttype(s));
279 nsegments++;
281 fread(&s,2,1,infile);
282 printf(" Number = %04X\n",(int)translateshort(s));
283 fread(&s,2,1,infile);
284 printf(" Resrvd = %04X\n",(int)translateshort(s));
285 fread(&l,4,1,infile);
286 l = translatelong(l);
287 printf(" Length = %ld bytes\n",l);
288 segmentcontentlength += l;
290 offset = 0;
291 while(l--) {
292 fread(id,1,1,infile);
293 if (verbose) {
294 if (offset % 16 == 0)
295 printf("\n%08lx ", offset);
296 printf(" %02x",(int) (unsigned char)id[0]);
297 offset++;
300 if (verbose) printf("\n");
301 } while (!feof(infile));
302 if (! foundnullsegment)
303 printf("\nWarning: unexpected end of file - "
304 "NULL segment not found\n");
306 printf("\nTotal number of segments: %d\n", nsegments);
307 printf("Total segment content length: %ld bytes\n",segmentcontentlength);
309 /* calculate what the total object content length should have been */
310 l = segmentcontentlength + 10 * (nsegments+1) + headerlength + 4;
311 if (l != objectlength)
312 printf("Warning: actual object length (%ld) != "
313 "stored object length (%ld)\n", l, objectlength);
315 fclose(infile);
316 return 0;