phash.ph: yet another attempt at getting Perl to behave, arithmetically
[nasm/avx512.git] / rdoff / rdfdump.c
blob691241d519187d9d20a1593255ea1f2438ebe420
1 /*
2 * rdfdump.c - dump RDOFF file header.
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
9 #define RDOFF_UTILS
11 #include "rdoff.h"
13 #define PROGRAM_VERSION "2.3"
15 FILE *infile;
17 void print_header(int32_t length, int rdf_version)
19 char buf[129], t, l, s, flags;
20 uint8_t reclen;
21 int32_t o, ll;
22 uint16_t rs;
24 while (length > 0) {
25 fread(&t, 1, 1, infile);
26 if (rdf_version >= 2) {
27 fread(&reclen, 1, 1, infile);
29 switch (t) {
30 case RDFREC_GENERIC: /* generic record */
31 printf(" generic record (length=%d)\n", (int)reclen);
32 fseek(infile, reclen, SEEK_CUR);
33 break;
35 case RDFREC_RELOC: /* relocation record */
36 case RDFREC_SEGRELOC: /* segment relocation */
37 fread(&s, 1, 1, infile);
38 fread(&o, 4, 1, infile);
39 fread(&l, 1, 1, infile);
40 fread(&rs, 2, 1, infile);
41 printf(" %s: location (%04x:%08"PRIx32"), length %d, "
42 "referred seg %04x\n",
43 t == 1 ? "relocation" : "seg relocation", (int)s,
44 translateint32_t(o), (int)l, translateint16_t(rs));
45 if (rdf_version >= 2 && reclen != 8)
46 printf(" warning: reclen != 8\n");
47 if (rdf_version == 1)
48 length -= 9;
49 if (rdf_version == 1 && t == 6)
50 printf
51 (" warning: seg relocation not supported in RDOFF1\n");
52 break;
54 case RDFREC_IMPORT: /* import record */
55 case RDFREC_FARIMPORT: /* import far symbol */
56 fread(&flags, 1, 1, infile);
57 fread(&rs, 2, 1, infile);
58 ll = 0;
60 if (rdf_version == 1) {
61 do {
62 fread(&buf[ll], 1, 1, infile);
63 } while (buf[ll++]);
64 } else {
65 for (; ll < reclen - 3; ll++)
66 fread(&buf[ll], 1, 1, infile);
69 if (t == 7)
70 printf("far ");
71 printf((flags & SYM_IMPORT) ? " import" : " extern");
72 if (flags & SYM_FUNCTION)
73 printf(" proc");
74 if (flags & SYM_DATA)
75 printf(" data");
76 printf(": segment %04x = %s\n", translateint16_t(rs), buf);
77 if (rdf_version == 1)
78 length -= ll + 3;
79 if (rdf_version == 1 && t == 7)
80 printf
81 (" warning: far import not supported in RDOFF1\n");
82 break;
84 case RDFREC_GLOBAL: /* export record */
85 fread(&flags, 1, 1, infile);
86 fread(&s, 1, 1, infile);
87 fread(&o, 4, 1, infile);
88 ll = 0;
90 if (rdf_version == 1) {
91 do {
92 fread(&buf[ll], 1, 1, infile);
93 } while (buf[ll++]);
94 } else {
95 for (; ll < reclen - 6; ll++)
96 fread(&buf[ll], 1, 1, infile);
98 printf((flags & SYM_GLOBAL) ? " export" : " public");
99 if (flags & SYM_FUNCTION)
100 printf(" proc");
101 if (flags & SYM_DATA)
102 printf(" data");
103 printf(": (%04x:%08"PRIx32") = %s\n", (int)s, translateint32_t(o), buf);
104 if (rdf_version == 1)
105 length -= ll + 6;
106 break;
108 case RDFREC_DLL: /* DLL and Module records */
109 case RDFREC_MODNAME:
110 ll = 0;
111 if (rdf_version == 1) {
112 do {
113 fread(&buf[ll], 1, 1, infile);
114 } while (buf[ll++]);
115 } else {
116 for (; ll < reclen; ll++)
117 fread(&buf[ll], 1, 1, infile);
119 if (t == 4)
120 printf(" dll: %s\n", buf);
121 else
122 printf(" module: %s\n", buf);
123 if (rdf_version == 1)
124 length -= ll + 1;
125 break;
127 case RDFREC_BSS: /* BSS reservation */
128 fread(&ll, 4, 1, infile);
129 printf(" bss reservation: %08"PRIx32" bytes\n", translateint32_t(ll));
130 if (rdf_version == 1)
131 length -= 5;
132 if (rdf_version > 1 && reclen != 4)
133 printf(" warning: reclen != 4\n");
134 break;
136 case RDFREC_COMMON:{
137 uint16_t seg, align;
138 uint32_t size;
140 fread(&seg, 2, 1, infile);
141 fread(&size, 4, 1, infile);
142 fread(&align, 2, 1, infile);
143 for (ll = 0; ll < reclen - 8; ll++)
144 fread(buf + ll, 1, 1, infile);
145 printf(" common: segment %04x = %s, %"PRId32":%d\n",
146 translateint16_t(seg), buf, translateint32_t(size),
147 translateint16_t(align));
148 break;
151 default:
152 printf(" unrecognized record (type %d", (int)t);
153 if (rdf_version > 1) {
154 printf(", length %d", (int)reclen);
155 fseek(infile, reclen, SEEK_CUR);
156 } else
157 length--;
158 printf(")\n");
160 if (rdf_version != 1)
161 length -= 2 + reclen;
165 int main(int argc, char **argv)
167 char id[7];
168 int32_t l;
169 uint16_t s;
170 int verbose = 0;
171 int32_t offset;
172 int foundnullsegment = 0;
173 int version;
174 int32_t segmentcontentlength = 0;
175 int nsegments = 0;
176 int32_t headerlength = 0;
177 int32_t objectlength = 0;
179 printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
180 printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
181 puts("Copyright (c) 1996,99 Julian R Hall\n"
182 "Improvements and fixes (c) 2002-2004 RET & COM Research.");
184 if (argc < 2) {
185 fputs("Usage: rdfdump [-v] <filename>\n", stderr);
186 exit(1);
189 if (!strcmp(argv[1], "-v")) {
190 verbose = 1;
191 if (argc < 3) {
192 fputs("required parameter missing\n", stderr);
193 exit(1);
195 argv++;
198 infile = fopen(argv[1], "rb");
199 if (!infile) {
200 fprintf(stderr, "rdfdump: Could not open %s\n", argv[1]);
201 exit(1);
204 fread(id, 6, 1, infile);
205 if (strncmp(id, "RDOFF", 5)) {
206 fputs("rdfdump: File does not contain valid RDOFF header\n",
207 stderr);
208 exit(1);
211 printf("File %s: RDOFF version %c\n\n", argv[1], id[5]);
212 if (id[5] < '1' || id[5] > '2') {
213 fprintf(stderr, "rdfdump: unknown RDOFF version '%c'\n", id[5]);
214 exit(1);
216 version = id[5] - '0';
218 if (version > 1) {
219 fread(&l, 4, 1, infile);
220 objectlength = translateint32_t(l);
221 printf("Object content size: %"PRId32" bytes\n", objectlength);
224 fread(&l, 4, 1, infile);
225 headerlength = translateint32_t(l);
226 printf("Header (%"PRId32" bytes):\n", headerlength);
227 print_header(headerlength, version);
229 if (version == 1) {
230 fread(&l, 4, 1, infile);
231 l = translateint32_t(l);
232 printf("\nText segment length = %"PRId32" bytes\n", l);
233 offset = 0;
234 while (l--) {
235 fread(id, 1, 1, infile);
236 if (verbose) {
237 if (offset % 16 == 0)
238 printf("\n%08"PRIx32" ", offset);
239 printf(" %02x", (int)(uint8_t)id[0]);
240 offset++;
243 if (verbose)
244 printf("\n\n");
246 fread(&l, 4, 1, infile);
247 l = translateint32_t(l);
248 printf("Data segment length = %"PRId32" bytes\n", l);
250 if (verbose) {
251 offset = 0;
252 while (l--) {
253 fread(id, 1, 1, infile);
254 if (offset % 16 == 0)
255 printf("\n%08"PRIx32" ", offset);
256 printf(" %02x", (int)(uint8_t)id[0]);
257 offset++;
259 printf("\n");
261 } else {
262 do {
263 fread(&s, 2, 1, infile);
264 s = translateint16_t(s);
265 if (!s) {
266 printf("\nNULL segment\n");
267 foundnullsegment = 1;
268 break;
270 printf("\nSegment:\n Type = %04X (%s)\n", (int)s,
271 translatesegmenttype(s));
272 nsegments++;
274 fread(&s, 2, 1, infile);
275 printf(" Number = %04X\n", (int)translateint16_t(s));
276 fread(&s, 2, 1, infile);
277 printf(" Resrvd = %04X\n", (int)translateint16_t(s));
278 fread(&l, 4, 1, infile);
279 l = translateint32_t(l);
280 printf(" Length = %"PRId32" bytes\n", l);
281 segmentcontentlength += l;
283 offset = 0;
284 while (l--) {
285 fread(id, 1, 1, infile);
286 if (verbose) {
287 if (offset % 16 == 0)
288 printf("\n%08"PRIx32" ", offset);
289 printf(" %02x", (int)(uint8_t)id[0]);
290 offset++;
293 if (verbose)
294 printf("\n");
295 } while (!feof(infile));
296 if (!foundnullsegment)
297 printf("\nWarning: unexpected end of file - "
298 "NULL segment not found\n");
300 printf("\nTotal number of segments: %d\n", nsegments);
301 printf("Total segment content length: %"PRId32" bytes\n",
302 segmentcontentlength);
304 /* calculate what the total object content length should have been */
305 l = segmentcontentlength + 10 * (nsegments + 1) + headerlength + 4;
306 if (l != objectlength)
307 printf("Warning: actual object length (%"PRId32") != "
308 "stored object length (%"PRId32")\n", l, objectlength);
310 fclose(infile);
311 return 0;