nasm/rdoff/rdfdump.c

308 lines
7.6 KiB
C
Raw Normal View History

2002-05-01 04:51:32 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2002-05-01 05:00:33 +08:00
#include "multboot.h"
2002-05-01 04:51:32 +08:00
FILE *infile;
2002-05-01 04:58:18 +08:00
typedef unsigned short int16;
2002-05-01 04:51:32 +08:00
long translatelong(long in) { /* translate from little endian to
local representation */
long r;
unsigned char *i;
i = (unsigned char *)&in;
r = i[3];
r = (r << 8) + i[2];
r = (r << 8) + i[1];
r = (r << 8) + *i;
return r;
}
2002-05-01 04:52:08 +08:00
2002-05-01 04:58:18 +08:00
int translateshort(int16 in) {
2002-05-01 04:51:32 +08:00
int r;
unsigned char *i;
i = (unsigned char *)&in;
r = (i[1] << 8) + *i;
return r;
}
2002-05-01 04:58:18 +08:00
void print_header(long length, int rdf_version) {
2002-05-01 04:52:08 +08:00
char buf[129],t,s,l;
2002-05-01 04:58:18 +08:00
unsigned char reclen;
2002-05-01 04:52:08 +08:00
long o,ll;
2002-05-01 04:58:18 +08:00
int16 rs;
2002-05-01 05:00:33 +08:00
struct tMultiBootHeader *mb;
2002-05-01 04:51:32 +08:00
while (length > 0) {
fread(&t,1,1,infile);
2002-05-01 04:58:18 +08:00
if (rdf_version >= 2) {
fread(&reclen,1,1,infile);
}
2002-05-01 04:51:32 +08:00
switch(t) {
case 1: /* relocation record */
2002-05-01 04:58:18 +08:00
case 6: /* segment relocation */
2002-05-01 04:51:32 +08:00
fread(&s,1,1,infile);
fread(&o,4,1,infile);
fread(&l,1,1,infile);
2002-05-01 05:00:33 +08:00
fread(&rs,2,1,infile);
2002-05-01 04:58:18 +08:00
printf(" %s: location (%04x:%08lx), length %d, "
"referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
(int)s,translatelong(o),(int)l,
2002-05-01 04:51:32 +08:00
translateshort(rs));
2002-05-01 04:58:18 +08:00
if (rdf_version >= 2 && reclen != 8)
printf(" warning: reclen != 8\n");
if (rdf_version == 1) length -= 9;
if (rdf_version == 1 && t == 6)
printf(" warning: seg relocation not supported in RDOFF1\n");
2002-05-01 04:51:32 +08:00
break;
case 2: /* import record */
2002-05-01 04:58:18 +08:00
case 7: /* import far symbol */
2002-05-01 04:51:32 +08:00
fread(&rs,2,1,infile);
2002-05-01 04:52:08 +08:00
ll = 0;
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
for (;ll < reclen - 2; ll++)
fread(&buf[ll],1,1,infile);
}
printf(" %simport: segment %04x = %s\n",t == 7 ? "far " : "",
translateshort(rs),buf);
if (rdf_version == 1) length -= ll + 3;
if (rdf_version == 1 && t == 7)
printf (" warning: far import not supported in RDOFF1\n");
2002-05-01 04:51:32 +08:00
break;
case 3: /* export record */
fread(&s,1,1,infile);
fread(&o,4,1,infile);
2002-05-01 04:52:49 +08:00
ll = 0;
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
for (; ll < reclen - 5; ll ++)
fread(&buf[ll],1,1,infile);
}
2002-05-01 04:51:32 +08:00
printf(" export: (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) length -= ll + 6;
2002-05-01 04:51:32 +08:00
break;
2002-05-01 05:00:33 +08:00
case 4: /* DLL and Module records */
case 8:
2002-05-01 04:52:49 +08:00
ll = 0;
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) {
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
}
else
{
2002-05-01 05:00:33 +08:00
for (; ll < reclen; ll++)
2002-05-01 04:58:18 +08:00
fread(&buf[ll],1,1,infile);
}
2002-05-01 05:00:33 +08:00
if (t==4) printf(" dll: %s\n",buf);
else printf(" module: %s\n",buf);
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) length -= ll + 1;
2002-05-01 04:51:32 +08:00
break;
case 5: /* BSS reservation */
2002-05-01 04:52:08 +08:00
fread(&ll,4,1,infile);
printf(" bss reservation: %08lx bytes\n",translatelong(ll));
2002-05-01 04:58:18 +08:00
if (rdf_version == 1) length -= 5;
if (rdf_version > 1 && reclen != 4)
printf(" warning: reclen != 4\n");
2002-05-01 04:51:32 +08:00
break;
2002-05-01 05:00:33 +08:00
case 9: /* MultiBoot header record */
fread(buf,reclen,1,infile);
mb = (struct tMultiBootHeader *)buf;
printf(" multiboot header: load address=0x%X, size=0x%X, entry=0x%X\n",
mb->LoadAddr, mb->LoadEndAddr - mb->LoadAddr, mb->Entry);
break;
2002-05-01 04:51:32 +08:00
default:
2002-05-01 04:58:18 +08:00
printf(" unrecognised record (type %d",(int)t);
2002-05-01 05:00:33 +08:00
if (rdf_version > 1) {
printf(", length %d",(int)reclen);
fseek(infile,reclen,SEEK_CUR);
}
2002-05-01 04:58:18 +08:00
printf(")\n");
if (rdf_version == 1) length --;
2002-05-01 04:51:32 +08:00
}
2002-05-01 04:58:18 +08:00
if (rdf_version != 1) length -= 2 + reclen;
2002-05-01 04:51:32 +08:00
}
}
2002-05-01 04:58:18 +08:00
char * knowntypes[8] = {"NULL", "text", "data", "object comment",
"linked comment", "loader comment",
"symbolic debug", "line number debug"};
char * translatesegmenttype(int16 type) {
if (type < 8) return knowntypes[type];
if (type < 0x0020) return "reserved";
if (type < 0x1000) return "reserved - moscow";
if (type < 0x8000) return "reserved - system dependant";
if (type < 0xFFFF) return "reserved - other";
if (type == 0xFFFF) return "invalid type code";
return "type code out of range";
}
2002-05-01 04:51:32 +08:00
int main(int argc,char **argv) {
char id[7];
long l;
2002-05-01 04:58:18 +08:00
int16 s;
2002-05-01 04:51:32 +08:00
int verbose = 0;
2002-05-01 04:52:49 +08:00
long offset;
2002-05-01 04:58:18 +08:00
int foundnullsegment = 0;
int version;
long segmentcontentlength = 0;
int nsegments = 0;
long headerlength = 0;
long objectlength = 0;
2002-05-01 04:51:32 +08:00
2002-05-01 05:00:33 +08:00
puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
2002-05-01 04:51:32 +08:00
if (argc < 2) {
fputs("Usage: rdfdump [-v] <filename>\n",stderr);
exit(1);
}
if (! strcmp (argv[1], "-v") )
{
verbose = 1;
if (argc < 3)
{
fputs("required parameter missing\n",stderr);
exit(1);
}
argv++;
}
infile = fopen(argv[1],"rb");
if (! infile) {
2002-05-01 05:00:33 +08:00
fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
2002-05-01 04:51:32 +08:00
exit(1);
}
fread(id,6,1,infile);
if (strncmp(id,"RDOFF",5)) {
fputs("rdfdump: File does not contain valid RDOFF header\n",stderr);
exit(1);
}
printf("File %s: RDOFF version %c\n\n",argv[1],id[5]);
2002-05-01 04:58:18 +08:00
if (id[5] < '1' || id[5] > '2') {
2002-05-01 04:51:32 +08:00
fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
exit(1);
}
2002-05-01 04:58:18 +08:00
version = id[5] - '0';
2002-05-01 04:51:32 +08:00
2002-05-01 04:58:18 +08:00
if (version > 1) {
fread(&l, 4, 1, infile);
objectlength = translatelong(l);
printf("Object content size: %ld bytes\n", objectlength);
2002-05-01 04:51:32 +08:00
}
fread(&l,4,1,infile);
2002-05-01 04:58:18 +08:00
headerlength = translatelong(l);
printf("Header (%ld bytes):\n",headerlength);
print_header(headerlength, version);
if (version == 1) {
fread(&l,4,1,infile);
l = translatelong(l);
printf("\nText segment length = %ld bytes\n",l);
offset = 0;
while(l--) {
fread(id,1,1,infile);
if (verbose) {
if (offset % 16 == 0)
printf("\n%08lx ", offset);
printf(" %02x",(int) (unsigned char)id[0]);
offset++;
}
}
if (verbose) printf("\n\n");
fread(&l,4,1,infile);
l = translatelong(l);
printf("Data segment length = %ld bytes\n",l);
2002-05-01 04:51:32 +08:00
2002-05-01 04:58:18 +08:00
if (verbose)
{
offset = 0;
while (l--) {
fread(id,1,1,infile);
if (offset % 16 == 0)
printf("\n%08lx ", offset);
printf(" %02x",(int) (unsigned char) id[0]);
offset++;
}
printf("\n");
}
}
else
2002-05-01 04:51:32 +08:00
{
2002-05-01 04:58:18 +08:00
do {
fread(&s,2,1,infile);
s = translateshort(s);
if (!s) {
printf("\nNULL segment\n");
foundnullsegment = 1;
break;
}
printf("\nSegment:\n Type = %04X (%s)\n",(int)s,
translatesegmenttype(s));
nsegments++;
fread(&s,2,1,infile);
printf(" Number = %04X\n",(int)translateshort(s));
fread(&s,2,1,infile);
printf(" Resrvd = %04X\n",(int)translateshort(s));
fread(&l,4,1,infile);
l = translatelong(l);
printf(" Length = %ld bytes\n",l);
segmentcontentlength += l;
offset = 0;
while(l--) {
fread(id,1,1,infile);
if (verbose) {
if (offset % 16 == 0)
printf("\n%08lx ", offset);
printf(" %02x",(int) (unsigned char)id[0]);
offset++;
}
}
if (verbose) printf("\n");
} while (!feof(infile));
if (! foundnullsegment)
printf("\nWarning: unexpected end of file - "
"NULL segment not found\n");
printf("\nTotal number of segments: %d\n", nsegments);
printf("Total segment content length: %ld bytes\n",segmentcontentlength);
/* calculate what the total object content length should have been */
l = segmentcontentlength + 10 * (nsegments+1) + headerlength + 4;
if (l != objectlength)
printf("Warning: actual object length (%ld) != "
"stored object length (%ld)\n", l, objectlength);
2002-05-01 04:51:32 +08:00
}
fclose(infile);
return 0;
}