Logo Search packages:      
Sourcecode: nasm version File versions  Download package

rdfdump.c

/*
 * rdfdump.c - dump RDOFF file header.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "rdoff.h"

FILE *infile;

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;
}
  
int16 translateshort(int16 in) {
  int r;
  unsigned char *i;

  i = (unsigned char *)&in;
  r = (i[1] << 8) + *i;

  return r;
}

void print_header(long length, int rdf_version)
{
    char buf[129],t,l,s,flags;
  unsigned char reclen;
  long o,ll;
  int16 rs;

  while (length > 0) {
    fread(&t,1,1,infile);
    if (rdf_version >= 2) {
      fread(&reclen,1,1,infile);
    }
    switch(t) {
          case RDFREC_GENERIC:            /* generic record */
            printf("  generic record (length=%d)\n", (int)reclen);
            fseek(infile, reclen, SEEK_CUR);
            break;
    
          case RDFREC_RELOC:              /* relocation record */
          case RDFREC_SEGRELOC:           /* segment relocation */
      fread(&s,1,1,infile);
      fread(&o,4,1,infile);
      fread(&l,1,1,infile);
      fread(&rs,2,1,infile);
      printf("  %s: location (%04x:%08lx), length %d, "
           "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
           (int)s,translatelong(o),(int)l,
           translateshort(rs));
      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");
      break;
      
          case RDFREC_IMPORT:             /* import record */
          case RDFREC_FARIMPORT:          /* import far symbol */
      fread(&rs,2,1,infile);
      ll = 0;

      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");
      break;
      
          case RDFREC_GLOBAL:             /* export record */
      fread(&flags,1,1,infile);
      fread(&s,1,1,infile);
      fread(&o,4,1,infile);
      ll = 0;

      if (rdf_version == 1) {
        do {
            fread(&buf[ll],1,1,infile);
        } while (buf[ll++]);
            } else {
        for (; ll < reclen - 6; ll ++)
            fread(&buf[ll],1,1,infile);
      }
      if (flags & SYM_GLOBAL)
        printf("  export");
      else
        printf("  global");
      if (flags & SYM_FUNCTION) printf(" proc");
      if (flags & SYM_DATA) printf(" data");
      printf(": (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
      if (rdf_version == 1) length -= ll + 6;
      break;
      
          case RDFREC_DLL:                /* DLL and Module records */
          case RDFREC_MODNAME:
      ll = 0;

      if (rdf_version == 1) {
        do {
            fread(&buf[ll],1,1,infile);
        } while (buf[ll++]);
            } else {
        for (; ll < reclen; ll++)
            fread(&buf[ll],1,1,infile);
      }
      if (t==4) printf("  dll: %s\n",buf);
      else printf("  module: %s\n",buf);
      if (rdf_version == 1) length -= ll + 1;
      break;
            
          case RDFREC_BSS:                /* BSS reservation */
      fread(&ll,4,1,infile);
      printf("  bss reservation: %08lx bytes\n",translatelong(ll));
      if (rdf_version == 1) length -= 5;
      if (rdf_version > 1 && reclen != 4)
        printf("    warning: reclen != 4\n");
      break;
      
          case RDFREC_COMMON: {
            unsigned short seg, align;
            unsigned long size;
            
            fread(&seg, 2, 1, infile);
            fread(&size, 4, 1, infile);
            fread(&align, 2, 1, infile);
            for (ll = 0; ll < reclen - 8; ll++)
                  fread(buf+ll, 1, 1, infile);
            printf("  common: segment %04x = %s, %ld:%d\n", translateshort(seg),
                   buf, translatelong(size), translateshort(align));
      break;  
          }

    default:
            printf("  unrecognized record (type %d", (int)t);
      if (rdf_version > 1) {
            printf(", length %d",(int)reclen);
      fseek(infile,reclen,SEEK_CUR);
            } else length --;
      printf(")\n");
    }
    if (rdf_version != 1) length -= 2 + reclen;
  }
}

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";
}    

int main(int argc,char **argv) {
  char id[7];
  long l;
  int16 s;
  int verbose = 0;
  long offset;
  int  foundnullsegment = 0;
  int  version;
  long segmentcontentlength = 0;
  int  nsegments = 0;
  long headerlength = 0;
  long objectlength = 0;

  puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");

  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) {
    fprintf(stderr,"rdfdump: Could not open %s\n",argv[1]);
    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]);
  if (id[5] < '1' || id[5] > '2') {
    fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
    exit(1);
  }
  version = id[5] - '0';

  if (version > 1) {
      fread(&l, 4, 1, infile);
      objectlength = translatelong(l);
      printf("Object content size: %ld bytes\n", objectlength);
  }

  fread(&l,4,1,infile);
  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);

      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
  {
      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);
  }
  fclose(infile);
  return 0;
}

Generated by  Doxygen 1.6.0   Back to index