1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * rdfdump.c - dump RDOFF file header.
48 #define PROGRAM_VERSION "2.3"
52 void print_header(int32_t length
, int rdf_version
)
54 char buf
[129], t
, l
, s
, flags
;
60 fread(&t
, 1, 1, infile
);
61 if (rdf_version
>= 2) {
62 fread(&reclen
, 1, 1, infile
);
65 case RDFREC_GENERIC
: /* generic record */
66 printf(" generic record (length=%d)\n", (int)reclen
);
67 fseek(infile
, reclen
, SEEK_CUR
);
70 case RDFREC_RELOC
: /* relocation record */
71 case RDFREC_SEGRELOC
: /* segment relocation */
72 fread(&s
, 1, 1, infile
);
73 fread(&o
, 4, 1, infile
);
74 fread(&l
, 1, 1, infile
);
75 fread(&rs
, 2, 1, infile
);
76 printf(" %s: location (%04x:%08"PRIx32
"), length %d, "
77 "referred seg %04x\n",
78 t
== 1 ? "relocation" : "seg relocation", (int)s
,
79 translateint32_t(o
), (int)l
, translateint16_t(rs
));
80 if (rdf_version
>= 2 && reclen
!= 8)
81 printf(" warning: reclen != 8\n");
84 if (rdf_version
== 1 && t
== 6)
86 (" warning: seg relocation not supported in RDOFF1\n");
89 case RDFREC_IMPORT
: /* import record */
90 case RDFREC_FARIMPORT
: /* import far symbol */
91 fread(&flags
, 1, 1, infile
);
92 fread(&rs
, 2, 1, infile
);
95 if (rdf_version
== 1) {
97 fread(&buf
[ll
], 1, 1, infile
);
100 for (; ll
< reclen
- 3; ll
++)
101 fread(&buf
[ll
], 1, 1, infile
);
106 printf((flags
& SYM_IMPORT
) ? " import" : " extern");
107 if (flags
& SYM_FUNCTION
)
109 if (flags
& SYM_DATA
)
111 printf(": segment %04x = %s\n", translateint16_t(rs
), buf
);
112 if (rdf_version
== 1)
114 if (rdf_version
== 1 && t
== 7)
116 (" warning: far import not supported in RDOFF1\n");
119 case RDFREC_GLOBAL
: /* export record */
120 fread(&flags
, 1, 1, infile
);
121 fread(&s
, 1, 1, infile
);
122 fread(&o
, 4, 1, infile
);
125 if (rdf_version
== 1) {
127 fread(&buf
[ll
], 1, 1, infile
);
130 for (; ll
< reclen
- 6; ll
++)
131 fread(&buf
[ll
], 1, 1, infile
);
133 printf((flags
& SYM_GLOBAL
) ? " export" : " public");
134 if (flags
& SYM_FUNCTION
)
136 if (flags
& SYM_DATA
)
138 printf(": (%04x:%08"PRIx32
") = %s\n", (int)s
, translateint32_t(o
), buf
);
139 if (rdf_version
== 1)
143 case RDFREC_DLL
: /* DLL and Module records */
146 if (rdf_version
== 1) {
148 fread(&buf
[ll
], 1, 1, infile
);
151 for (; ll
< reclen
; ll
++)
152 fread(&buf
[ll
], 1, 1, infile
);
155 printf(" dll: %s\n", buf
);
157 printf(" module: %s\n", buf
);
158 if (rdf_version
== 1)
162 case RDFREC_BSS
: /* BSS reservation */
163 fread(&ll
, 4, 1, infile
);
164 printf(" bss reservation: %08"PRIx32
" bytes\n", translateint32_t(ll
));
165 if (rdf_version
== 1)
167 if (rdf_version
> 1 && reclen
!= 4)
168 printf(" warning: reclen != 4\n");
175 fread(&seg
, 2, 1, infile
);
176 fread(&size
, 4, 1, infile
);
177 fread(&align
, 2, 1, infile
);
178 for (ll
= 0; ll
< reclen
- 8; ll
++)
179 fread(buf
+ ll
, 1, 1, infile
);
180 printf(" common: segment %04x = %s, %"PRId32
":%d\n",
181 translateint16_t(seg
), buf
, translateint32_t(size
),
182 translateint16_t(align
));
187 printf(" unrecognized record (type %d", (int)t
);
188 if (rdf_version
> 1) {
189 printf(", length %d", (int)reclen
);
190 fseek(infile
, reclen
, SEEK_CUR
);
195 if (rdf_version
!= 1)
196 length
-= 2 + reclen
;
200 int main(int argc
, char **argv
)
207 int foundnullsegment
= 0;
209 int32_t segmentcontentlength
= 0;
211 int32_t headerlength
= 0;
212 int32_t objectlength
= 0;
214 printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION
);
215 printf("RDOFF2 revision %s\n", RDOFF2_REVISION
);
216 puts("Copyright (c) 1996,99 Julian R Hall\n"
217 "Improvements and fixes (c) 2002-2004 RET & COM Research.");
220 fputs("Usage: rdfdump [-v] <filename>\n", stderr
);
224 if (!strcmp(argv
[1], "-v")) {
227 fputs("required parameter missing\n", stderr
);
233 infile
= fopen(argv
[1], "rb");
235 fprintf(stderr
, "rdfdump: Could not open %s\n", argv
[1]);
239 fread(id
, 6, 1, infile
);
240 if (strncmp(id
, "RDOFF", 5)) {
241 fputs("rdfdump: File does not contain valid RDOFF header\n",
246 printf("File %s: RDOFF version %c\n\n", argv
[1], id
[5]);
247 if (id
[5] < '1' || id
[5] > '2') {
248 fprintf(stderr
, "rdfdump: unknown RDOFF version '%c'\n", id
[5]);
251 version
= id
[5] - '0';
254 fread(&l
, 4, 1, infile
);
255 objectlength
= translateint32_t(l
);
256 printf("Object content size: %"PRId32
" bytes\n", objectlength
);
259 fread(&l
, 4, 1, infile
);
260 headerlength
= translateint32_t(l
);
261 printf("Header (%"PRId32
" bytes):\n", headerlength
);
262 print_header(headerlength
, version
);
265 fread(&l
, 4, 1, infile
);
266 l
= translateint32_t(l
);
267 printf("\nText segment length = %"PRId32
" bytes\n", l
);
270 fread(id
, 1, 1, infile
);
272 if (offset
% 16 == 0)
273 printf("\n%08"PRIx32
" ", offset
);
274 printf(" %02x", (int)(uint8_t)id
[0]);
281 fread(&l
, 4, 1, infile
);
282 l
= translateint32_t(l
);
283 printf("Data segment length = %"PRId32
" bytes\n", l
);
288 fread(id
, 1, 1, infile
);
289 if (offset
% 16 == 0)
290 printf("\n%08"PRIx32
" ", offset
);
291 printf(" %02x", (int)(uint8_t)id
[0]);
298 fread(&s
, 2, 1, infile
);
299 s
= translateint16_t(s
);
301 printf("\nNULL segment\n");
302 foundnullsegment
= 1;
305 printf("\nSegment:\n Type = %04X (%s)\n", (int)s
,
306 translatesegmenttype(s
));
309 fread(&s
, 2, 1, infile
);
310 printf(" Number = %04X\n", (int)translateint16_t(s
));
311 fread(&s
, 2, 1, infile
);
312 printf(" Resrvd = %04X\n", (int)translateint16_t(s
));
313 fread(&l
, 4, 1, infile
);
314 l
= translateint32_t(l
);
315 printf(" Length = %"PRId32
" bytes\n", l
);
316 segmentcontentlength
+= l
;
320 fread(id
, 1, 1, infile
);
322 if (offset
% 16 == 0)
323 printf("\n%08"PRIx32
" ", offset
);
324 printf(" %02x", (int)(uint8_t)id
[0]);
330 } while (!feof(infile
));
331 if (!foundnullsegment
)
332 printf("\nWarning: unexpected end of file - "
333 "NULL segment not found\n");
335 printf("\nTotal number of segments: %d\n", nsegments
);
336 printf("Total segment content length: %"PRId32
" bytes\n",
337 segmentcontentlength
);
339 /* calculate what the total object content length should have been */
340 l
= segmentcontentlength
+ 10 * (nsegments
+ 1) + headerlength
+ 4;
341 if (l
!= objectlength
)
342 printf("Warning: actual object length (%"PRId32
") != "
343 "stored object length (%"PRId32
")\n", l
, objectlength
);