コード例 #1
0
ファイル: rdoff.c プロジェクト: happyg1t/nasmVC
int rdfopenhere(rdffile *f, FILE *fp, int *refcount, char *name)
{
  char buf[8];
  long initpos;

  if (translatelong(0x01020304) != 0x01020304)
  {					/* fix this to be portable! */
    fputs("*** this program requires a little endian machine\n",stderr);
    fprintf(stderr,"01020304h = %08lxh\n",translatelong(0x01020304));
    exit(3);
  }

  f->fp = fp;
  initpos = ftell(fp);

  fread(buf,6,1,f->fp);		/* read header */
  buf[6] = 0;

  if (strcmp(buf,RDOFFId)) {
    fclose(f->fp);
    return rdf_errno = 2; 	/* error 2: invalid file format */
  }

  if (fread(&f->header_len,1,4,f->fp) != 4) {
    fclose(f->fp);
    return rdf_errno = 3;	/* error 3: file read error */
  }

  f->header_ofs = ftell(f->fp);

  if (fseek(f->fp,f->header_len,SEEK_CUR)) {
    fclose(f->fp);
    return rdf_errno = 2;	/* seek past end of file...? */
  }

  if (fread(&f->code_len,1,4,f->fp) != 4) {
    fclose(f->fp);
    return rdf_errno = 3;
  }

  f->code_ofs = ftell(f->fp);
  if (fseek(f->fp,f->code_len,SEEK_CUR)) {
    fclose(f->fp);
    return rdf_errno = 2;
  }

  if (fread(&f->data_len,1,4,f->fp) != 4) {
    fclose(f->fp);
    return rdf_errno = 3;
  }

  f->data_ofs = ftell(f->fp);
  fseek(f->fp,initpos,SEEK_SET);
  f->header_loc = NULL;

  f->name = newstr(name);
  f->refcount = refcount;
  if (refcount) (*refcount)++;
  return 0;
}
コード例 #2
0
ファイル: rdfdump.c プロジェクト: happyg1t/nasmVC
void print_header(long length) {
  char buf[129],t,s,l;
  long o,ll;
  short rs;

  while (length > 0) {
    fread(&t,1,1,infile);
    switch(t) {
    case 1:		/* relocation record */
      fread(&s,1,1,infile);
      fread(&o,4,1,infile);
      fread(&l,1,1,infile);
      fread(&rs,2,1,infile); 
      printf("  relocation: location (%04x:%08lx), length %d, "
	     "referred seg %04x\n",(int)s,translatelong(o),(int)l,
	     translateshort(rs));
      length -= 9;
      break;
    case 2:             /* import record */
      fread(&rs,2,1,infile);
      ll = 0;
      do {
	fread(&buf[ll],1,1,infile);
      } while (buf[ll++]);
      printf("  import: segment %04x = %s\n",translateshort(rs),buf);
      length -= ll + 3;
      break;
    case 3:             /* export record */
      fread(&s,1,1,infile);
      fread(&o,4,1,infile);
      ll = 0;
      do {
	fread(&buf[ll],1,1,infile);
      } while (buf[ll++]);
      printf("  export: (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
      length -= ll + 6;
      break;
    case 4:		/* DLL record */
      ll = 0;
      do {
	fread(&buf[ll],1,1,infile);
      } while (buf[ll++]);
      printf("  dll: %s\n",buf);
      length -= ll + 1;
      break;
    case 5:		/* BSS reservation */
      fread(&ll,4,1,infile);
      printf("  bss reservation: %08lx bytes\n",translatelong(ll));
      length -= 5;
      break;
    default:
      printf("  unrecognised record (type %d)\n",(int)t);
      length --;
    }
  }
}
コード例 #3
0
ファイル: rdoff.c プロジェクト: happyg1t/nasmVC
int rdfwriteheader(FILE * fp, rdf_headerbuf * h)
{
    long		l, l2;

    fwrite (RDOFFId, 1, strlen(RDOFFId), fp) ;

    l = membuflength (h->buf);
    l2 = l + 14 + 10*h->nsegments + h->seglength;
    l = translatelong(l);
    l2 = translatelong(l2);
    fwrite (&l2, 4, 1, fp);	/* object length */
    fwrite (&l, 4, 1, fp);	/* header length */

    membufdump(h->buf, fp);

    return 0;		/* no error handling in here... CHANGE THIS! */
}
コード例 #4
0
ファイル: rdoff.c プロジェクト: happyg1t/nasmVC
int rdfwriteheader(FILE * fp, rdf_headerbuf * h)
{
    long		l;

    fwrite (RDOFFId, 1, strlen(RDOFFId), fp) ;

    l = translatelong ( membuflength (h) );
    fwrite (&l, 4, 1, fp);

    membufdump(h, fp);

    return 0;		/* no error handling in here... CHANGE THIS! */
}
コード例 #5
0
ファイル: ldrdf.c プロジェクト: aosm/nasm
/*
 * write_output()
 *
 * this takes the linked list of modules, and walks through it, merging
 * all the modules into a single output module, and then writes this to a
 * file.
 */
void write_output(const char *filename)
{
    FILE *f;
    rdf_headerbuf *rdfheader;
    struct modulenode *cur;
    int i, availableseg, seg, localseg, isrelative;
    void *header;
    rdfheaderrec *hr, newrec;
    symtabEnt *se;
    segtab segs;
    long offset;
    byte *data;

    if ((f = fopen(filename, "wb")) == NULL) {
        fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename);
        exit(1);
    }
    if ((rdfheader = rdfnewheader()) == NULL) {
        fprintf(stderr, "ldrdf: out of memory\n");
        exit(1);
    }

    /*
     * If '-g' option was given, first record in output file will be a
     * `generic' record, filled with a given file content.
     * This can be useful, for example, when constructing multiboot
     * compliant kernels.
     */
    if (generic_rec_file) {
        FILE *ff;

        if (options.verbose)
            printf("\nadding generic record from binary file %s\n",
                   generic_rec_file);

        hr = (rdfheaderrec *) malloc(sizeof(struct GenericRec));
        if ((ff = fopen(generic_rec_file, "r")) == NULL) {
            fprintf(stderr, "ldrdf: couldn't open %s for input\n",
                    generic_rec_file);
            exit(1);
        }
        i = fread(hr->g.data, 1, sizeof(hr->g.data), ff);
        fseek(ff, 0, SEEK_END);
        if (ftell(ff) > sizeof(hr->g.data)) {
            fprintf(error_file,
                    "warning: maximum generic record size is %d, rest of file ignored\n",
                    sizeof(hr->g.data));
        }
        fclose(ff);

        hr->g.type = 0;
        hr->g.reclen = i;
        rdfaddheader(rdfheader, hr);
        free(hr);
    }

    if (options.verbose)
        printf("\nbuilding output module (%d segments)\n", nsegs);

    /*
     * Allocate the memory for the segments. We may be better off
     * building the output module one segment at a time when running
     * under 16 bit DOS, but that would be a slower way of doing this.
     * And you could always use DJGPP...
     */
    for (i = 0; i < nsegs; i++) {
        outputseg[i].data = NULL;
        if (!outputseg[i].length)
            continue;
        outputseg[i].data = malloc(outputseg[i].length);
        if (!outputseg[i].data) {
            fprintf(stderr, "ldrdf: out of memory\n");
            exit(1);
        }
    }

    /*
     * initialise availableseg, used to allocate segment numbers for
     * imported and exported labels...
     */
    availableseg = nsegs;

    /*
     * Step through the modules, performing required actions on each one
     */
    for (cur = modules; cur; cur = cur->next) {
        /*
         * Read the actual segment contents into the correct places in
         * the newly allocated segments
         */

        for (i = 0; i < cur->f.nsegs; i++) {
            int dest = cur->seginfo[i].dest_seg;

            if (dest == -1)
                continue;
            if (rdfloadseg(&cur->f, i,
                           outputseg[dest].data + cur->seginfo[i].reloc)) {
                rdfperror("ldrdf", cur->name);
                exit(1);
            }
        }

        /*
         * Perform fixups, and add new header records where required
         */

        header = malloc(cur->f.header_len);
        if (!header) {
            fprintf(stderr, "ldrdf: out of memory\n");
            exit(1);
        }

        if (cur->f.header_loc)
            rdfheaderrewind(&cur->f);
        else if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) {
            rdfperror("ldrdf", cur->name);
            exit(1);
        }

        /*
         * we need to create a local segment number -> location
         * table for the segments in this module.
         */
        init_seglocations(&segs);
        for (i = 0; i < cur->f.nsegs; i++) {
            add_seglocation(&segs, cur->f.seg[i].number,
                            cur->seginfo[i].dest_seg,
                            cur->seginfo[i].reloc);
        }
        /*
         * and the BSS segment (doh!)
         */
        add_seglocation(&segs, 2, 2, cur->bss_reloc);

        while ((hr = rdfgetheaderrec(&cur->f))) {
            switch (hr->type) {
            case RDFREC_RELOC: /* relocation record - need to do a fixup */
                /*
                 * First correct the offset stored in the segment from
                 * the start of the segment (which may well have changed).
                 *
                 * To do this we add to the number stored the relocation
                 * factor associated with the segment that contains the
                 * target segment.
                 *
                 * The relocation could be a relative relocation, in which
                 * case we have to first subtract the amount we've relocated
                 * the containing segment by.
                 */
                if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
                    fprintf(stderr,
                            "%s: reloc to undefined segment %04x\n",
                            cur->name, (int)hr->r.refseg);
                    errorcount++;
                    break;
                }

                isrelative =
                    (hr->r.segment & RDOFF_RELATIVEMASK) ==
                    RDOFF_RELATIVEMASK;
                hr->r.segment &= (RDOFF_RELATIVEMASK - 1);

                if (hr->r.segment == 2 ||
                    (localseg =
                     rdffindsegment(&cur->f, hr->r.segment)) == -1) {
                    fprintf(stderr, "%s: reloc from %s segment (%d)\n",
                            cur->name,
                            hr->r.segment == 2 ? "BSS" : "unknown",
                            hr->r.segment);
                    errorcount++;
                    break;
                }

                if (hr->r.length != 1 && hr->r.length != 2 &&
                    hr->r.length != 4) {
                    fprintf(stderr, "%s: nonstandard length reloc "
                            "(%d bytes)\n", cur->name, hr->r.length);
                    errorcount++;
                    break;
                }

                /* 
                 * okay, now the relocation is in the segment pointed to by
                 * cur->seginfo[localseg], and we know everything else is
                 * okay to go ahead and do the relocation
                 */
                data = outputseg[cur->seginfo[localseg].dest_seg].data;
                data += cur->seginfo[localseg].reloc + hr->r.offset;

                /*
                 * data now points to the reference that needs
                 * relocation. Calculate the relocation factor.
                 * Factor is:
                 *      offset of referred object in segment [in offset]
                 *      (- relocation of localseg, if ref is relative)
                 * For simplicity, the result is stored in 'offset'.
                 * Then add 'offset' onto the value at data.
                 */

                if (isrelative)
                    offset -= cur->seginfo[localseg].reloc;
                switch (hr->r.length) {
                case 1:
                    offset += *data;
                    if (offset < -127 || offset > 128)
                        fprintf(error_file,
                                "warning: relocation out of range "
                                "at %s(%02x:%08lx)\n", cur->name,
                                (int)hr->r.segment, hr->r.offset);
                    *data = (char)offset;
                    break;
                case 2:
                    offset += *(short *)data;
                    if (offset < -32767 || offset > 32768)
                        fprintf(error_file,
                                "warning: relocation out of range "
                                "at %s(%02x:%08lx)\n", cur->name,
                                (int)hr->r.segment, hr->r.offset);
                    *(short *)data = (short)offset;
                    break;
                case 4:
                    *(long *)data += offset;
                    /* we can't easily detect overflow on this one */
                    break;
                }

                /*
                 * If the relocation was relative between two symbols in
                 * the same segment, then we're done.
                 *
                 * Otherwise, we need to output a new relocation record
                 * with the references updated segment and offset...
                 */
                if (!isrelative || cur->seginfo[localseg].dest_seg != seg) {
                    hr->r.segment = cur->seginfo[localseg].dest_seg;
                    hr->r.offset += cur->seginfo[localseg].reloc;
                    hr->r.refseg = seg;
                    if (isrelative)
                        hr->r.segment += RDOFF_RELATIVEMASK;
                    rdfaddheader(rdfheader, hr);
                }
                break;

            case RDFREC_IMPORT:        /* import symbol */
            case RDFREC_FARIMPORT:
                /*
                 * scan the global symbol table for the symbol
                 * and associate its location with the segment number 
                 * for this module
                 */
                se = symtabFind(symtab, hr->i.label);
                if (!se || se->segment == -1) {
                    if (!options.dynalink && !(hr->i.flags & SYM_IMPORT)) {
                        fprintf(error_file,
                                "error: unresolved reference to `%s'"
                                " in module `%s'\n", hr->i.label,
                                cur->name);
                        errorcount++;
                    }
                    /*
                     * we need to allocate a segment number for this
                     * symbol, and store it in the symbol table for
                     * future reference
                     */
                    if (!se) {
                        se = malloc(sizeof(*se));
                        if (!se) {
                            fprintf(stderr, "ldrdf: out of memory\n");
                            exit(1);
                        }
                        se->name = strdup(hr->i.label);
                        se->flags = 0;
                        se->segment = availableseg++;
                        se->offset = 0;
                        symtabInsert(symtab, se);
                    } else {
                        se->segment = availableseg++;
                        se->offset = 0;
                    }
                    /*
                     * output a header record that imports it to the
                     * recently allocated segment number...
                     */
                    newrec = *hr;
                    newrec.i.segment = se->segment;
                    rdfaddheader(rdfheader, &newrec);
                }

                add_seglocation(&segs, hr->i.segment, se->segment,
                                se->offset);
                break;

            case RDFREC_GLOBAL:        /* export symbol */
                /*
                 * need to insert an export for this symbol into the new
                 * header, unless we're stripping symbols. Even if we're
                 * stripping, put the symbol if it's marked as SYM_GLOBAL.
                 */
                if (options.strip && !(hr->e.flags & SYM_GLOBAL))
                    break;

                if (hr->e.segment == 2) {
                    seg = 2;
                    offset = cur->bss_reloc;
                } else {
                    localseg = rdffindsegment(&cur->f, hr->e.segment);
                    if (localseg == -1) {
                        fprintf(stderr, "%s: exported symbol `%s' from "
                                "unrecognised segment\n", cur->name,
                                hr->e.label);
                        errorcount++;
                        break;
                    }
                    offset = cur->seginfo[localseg].reloc;
                    seg = cur->seginfo[localseg].dest_seg;
                }

                hr->e.segment = seg;
                hr->e.offset += offset;
                rdfaddheader(rdfheader, hr);
                break;

            case RDFREC_MODNAME:       /* module name */
                /*
                 * Insert module name record if export symbols
                 * are not stripped.
                 * If module name begins with '$' - insert it anyway.
                 */
                if (options.strip && hr->m.modname[0] != '$')
                    break;
                rdfaddheader(rdfheader, hr);
                break;

            case RDFREC_DLL:   /* DLL name */
                /*
                 * Insert DLL name if it begins with '$'
                 */
                if (hr->d.libname[0] != '$')
                    break;
                rdfaddheader(rdfheader, hr);
                break;

            case RDFREC_SEGRELOC:      /* segment fixup */
                /*
                 * modify the segment numbers if necessary, and
                 * pass straight through to the output module header
                 *
                 * *** FIXME ***
                 */
                if (hr->r.segment == 2) {
                    fprintf(stderr, "%s: segment fixup in BSS section\n",
                            cur->name);
                    errorcount++;
                    break;
                }
                localseg = rdffindsegment(&cur->f, hr->r.segment);
                if (localseg == -1) {
                    fprintf(stderr, "%s: segment fixup in unrecognised"
                            " segment (%d)\n", cur->name, hr->r.segment);
                    errorcount++;
                    break;
                }
                hr->r.segment = cur->seginfo[localseg].dest_seg;
                hr->r.offset += cur->seginfo[localseg].reloc;

                if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) {
                    fprintf(stderr, "%s: segment fixup to undefined "
                            "segment %04x\n", cur->name,
                            (int)hr->r.refseg);
                    errorcount++;
                    break;
                }
                hr->r.refseg = seg;
                rdfaddheader(rdfheader, hr);
                break;

            case RDFREC_COMMON:        /* Common variable */
                /* Is this symbol already in the table? */
                se = symtabFind(symtab, hr->c.label);
                if (!se) {
                    printf("%s is not in symtab yet\n", hr->c.label);
                    break;
                }
                /* Add segment location */
                add_seglocation(&segs, hr->c.segment, se->segment,
                                se->offset);
                break;
            }
        }

        free(header);
        done_seglocations(&segs);

    }

    /*
     * combined BSS reservation for the entire results
     */
    newrec.type = RDFREC_BSS;
    newrec.b.reclen = 4;
    newrec.b.amount = bss_length;
    rdfaddheader(rdfheader, &newrec);

    /*
     * Write the header
     */
    for (i = 0; i < nsegs; i++) {
        if (i == 2)
            continue;
        rdfaddsegment(rdfheader, outputseg[i].length);
    }

    rdfwriteheader(f, rdfheader);
    rdfdoneheader(rdfheader);

    /*
     * Step through the segments, one at a time, writing out into
     * the output file
     */
    for (i = 0; i < nsegs; i++) {
        uint16 s;
        long l;

        if (i == 2)
            continue;

        s = translateshort(outputseg[i].type);
        fwrite(&s, 2, 1, f);
        s = translateshort(outputseg[i].number);
        fwrite(&s, 2, 1, f);
        s = translateshort(outputseg[i].reserved);
        fwrite(&s, 2, 1, f);
        l = translatelong(outputseg[i].length);
        fwrite(&l, 4, 1, f);

        fwrite(outputseg[i].data, outputseg[i].length, 1, f);
    }

    fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);
}
コード例 #6
0
ファイル: rdoff.c プロジェクト: happyg1t/nasmVC
int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name)
{
  char buf[8];
  long initpos;
  long l;
  int16 s;

  if (translatelong(0x01020304) != 0x01020304)
  {					/* fix this to be portable! */
    fputs("*** this program requires a little endian machine\n",stderr);
    fprintf(stderr,"01020304h = %08lxh\n",translatelong(0x01020304));
    exit(3);
  }

  f->fp = fp;
  initpos = ftell(fp);

  fread(buf,6,1,f->fp);		/* read header */
  buf[6] = 0;

  if (strcmp(buf,RDOFFId)) {
    fclose(f->fp);
    if (!strcmp(buf,"RDOFF1"))
	return rdf_errno = 7;	/* error 7: RDOFF 1 not supported */
    return rdf_errno = 2; 	/* error 2: invalid file format */
  }

  if (fread(&l,1,4,f->fp) != 4 ||
      fread(&f->header_len,1,4,f->fp) != 4) {
    fclose(f->fp);
    return rdf_errno = 3;	/* error 3: file read error */
  }

  f->header_ofs = ftell(f->fp);
  f->eof_offset = f->header_ofs + translatelong(l) - 4;

  if (fseek(f->fp,f->header_len,SEEK_CUR)) {
    fclose(f->fp);
    return rdf_errno = 2;	/* seek past end of file...? */
  }

  if (fread(&s,1,2,f->fp) != 2) {
      fclose(f->fp);
      return rdf_errno = 3;
  }

  f->nsegs = 0;

  while (s != 0)
  {
      f->seg[f->nsegs].type = s;
      if (fread(&f->seg[f->nsegs].number,1,2,f->fp) != 2 ||
	  fread(&f->seg[f->nsegs].reserved,1,2,f->fp) != 2 ||
	  fread(&f->seg[f->nsegs].length,1,4,f->fp) != 4)
      {
	  fclose(f->fp);
	  return rdf_errno = 3;
      }

      f->seg[f->nsegs].offset = ftell(f->fp);
      if (fseek(f->fp,f->seg[f->nsegs].length,SEEK_CUR)) {
	  fclose(f->fp);
	  return rdf_errno = 2;
      }
      f->nsegs++;

      if (fread(&s,1,2,f->fp) != 2) {
	  fclose(f->fp);
	  return rdf_errno = 3;
      }
  }

  if (f->eof_offset != ftell(f->fp) + 8)  /* +8 = skip null segment header */
  {
      fprintf(stderr, "warning: eof_offset [%ld] and actual eof offset "
	      "[%ld] don't match\n", f->eof_offset, ftell(f->fp) + 8);
  }
  fseek(f->fp,initpos,SEEK_SET);
  f->header_loc = NULL;

  f->name = newstr(name);
  f->refcount = refcount;
  if (refcount) (*refcount)++;
  return 0;
}
コード例 #7
0
ファイル: rdfdump.c プロジェクト: brandw/8086-toolchain
void print_header(long length, int rdf_version) {
  char buf[129],t,s,l,flags;
  unsigned char reclen;
  long o,ll;
  int16 rs;
  struct tMultiBootHeader *mb;

  while (length > 0) {
    fread(&t,1,1,infile);
    if (rdf_version >= 2) {
	fread(&reclen,1,1,infile);
    }
    switch(t) {
    
    case 1:		/* relocation record */
    case 6:		/* 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 2:             /* import record */
    case 7:		/* 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 3:             /* 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 4:		/* DLL and Module records */
    case 8:
      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 5:		/* 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 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;  
    default:
      printf("  unrecognised record (type %d",(int)t);
      if (rdf_version > 1) {
      	printf(", length %d",(int)reclen);
	fseek(infile,reclen,SEEK_CUR);
      }		
      printf(")\n");
      if (rdf_version == 1) length --;
    }
    if (rdf_version != 1) length -= 2 + reclen;
  }
}
コード例 #8
0
ファイル: rdfdump.c プロジェクト: brandw/8086-toolchain
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;
}
コード例 #9
0
ファイル: ldrdf.c プロジェクト: happyg1t/nasmVC
/*
 * write_output()
 *
 * this takes the linked list of modules, and walks through it, merging
 * all the modules into a single output module, and then writes this to a
 * file.
 */
void write_output(const char * filename)
{
    FILE          * f = fopen(filename, "wb");
    rdf_headerbuf * rdfheader = rdfnewheader();
    struct modulenode * cur;
    int		  i, availableseg, seg, localseg, isrelative;
    void	  * header;
    rdfheaderrec  * hr, newrec;
    symtabEnt 	  * se;
    segtab	  segs;
    long	  offset;
    byte 	  * data;

    if (!f) {
	fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename);
	exit(1);
    }
    if (!rdfheader) {
	fprintf(stderr, "ldrdf: out of memory\n");
	exit(1);
    }

    if (options.verbose)
	printf ("\nbuilding output module (%d segments)\n", nsegs);
    
    /*
     * Allocate the memory for the segments. We may be better off
     * building the output module one segment at a time when running
     * under 16 bit DOS, but that would be a slower way of doing this.
     * And you could always use DJGPP...
     */
    for (i = 0; i < nsegs; i++)
    {
	outputseg[i].data = malloc(outputseg[i].length);
	if (!outputseg[i].data) {
	    fprintf(stderr, "ldrdf: out of memory\n");
	    exit(1);
	}
    }

    /*
     * initialise availableseg, used to allocate segment numbers for
     * imported and exported labels...
     */
    availableseg = nsegs;

    /*
     * Step through the modules, performing required actions on each one
     */
    for (cur = modules; cur; cur=cur->next)
    {
	/*
	 * Read the actual segment contents into the correct places in
	 * the newly allocated segments
	 */

	for (i = 0; i < cur->f.nsegs; i++)
	{
	    int dest = cur->seginfo[i].dest_seg;

	    if (dest == -1) continue;
	    if (rdfloadseg(&cur->f, i, 
			   outputseg[dest].data + cur->seginfo[i].reloc))
	    {
		rdfperror("ldrdf", cur->name);
		exit(1);
	    }
	}
 
	/*
	 * Perform fixups, and add new header records where required
	 */

	header = malloc(cur->f.header_len);
	if (!header) {
	    fprintf(stderr, "ldrdf: out of memory\n");
	    exit(1);
	}

	if (cur->f.header_loc)
	    rdfheaderrewind(&cur->f);
	else
	    if (rdfloadseg(&cur->f, RDOFF_HEADER, header))
	    {
		rdfperror("ldrdf", cur->name);
		exit(1);
	    }
	
	/*
	 * we need to create a local segment number -> location
	 * table for the segments in this module.
	 */
	init_seglocations(&segs);
	for (i = 0; i < cur->f.nsegs; i++)
	{
	    add_seglocation(&segs, cur->f.seg[i].number,
			    cur->seginfo[i].dest_seg, cur->seginfo[i].reloc);
	}
	/*
	 * and the BSS segment (doh!)
	 */
	add_seglocation (&segs, 2, 2, cur->bss_reloc);

	while ((hr = rdfgetheaderrec(&cur->f)))
	{
	    switch(hr->type) {
	    case 1: /* relocation record - need to do a fixup */
		/*
		 * First correct the offset stored in the segment from
		 * the start of the segment (which may well have changed).
		 *
		 * To do this we add to the number stored the relocation
		 * factor associated with the segment that contains the
		 * target segment.
		 *
		 * The relocation could be a relative relocation, in which
		 * case we have to first subtract the amount we've relocated
		 * the containing segment by.
		 */
		
		if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
		{
		    fprintf(stderr, "%s: reloc to undefined segment %04x\n",
			    cur->name, (int) hr->r.refseg);
		    errorcount++;
		    break;
		}

		isrelative = (hr->r.segment & 64) == 64;
		hr->r.segment &= 63;

		if (hr->r.segment == 2 || 
		    (localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1)
		{
		    fprintf(stderr, "%s: reloc from %s segment (%d)\n", 
			    cur->name,
			    hr->r.segment == 2 ? "BSS" : "unknown",
			    hr->r.segment);
		    errorcount++;
		    break;
		}

		if (hr->r.length != 1 && hr->r.length != 2 && hr->r.length!=4)
		{
		    fprintf(stderr, "%s: nonstandard length reloc "
			    "(%d bytes)\n", cur->name, hr->r.length);
		    errorcount++;
		    break;
		}

		/* 
		 * okay, now the relocation is in the segment pointed to by
		 * cur->seginfo[localseg], and we know everything else is
		 * okay to go ahead and do the relocation
		 */
		data = outputseg[cur->seginfo[localseg].dest_seg].data;
		data += cur->seginfo[localseg].reloc + hr->r.offset;

		/*
		 * data now points to the reference that needs
		 * relocation. Calculate the relocation factor.
		 * Factor is:
		 *      offset of referred object in segment [in offset]
		 *	(- relocation of localseg, if ref is relative)
		 * For simplicity, the result is stored in 'offset'.
		 * Then add 'offset' onto the value at data.
		 */
		
		if (isrelative) offset -= cur->seginfo[localseg].reloc;
		switch (hr->r.length)
		{
		case 1:
		    offset += *data;
		    if (offset < -127 || offset > 128)
			fprintf(stderr, "warning: relocation out of range "
				"at %s(%02x:%08lx)\n", cur->name,
				(int)hr->r.segment, hr->r.offset);
		    *data = (char) offset;
		    break;
		case 2:
		    offset += * (short *)data;
		    if (offset < -32767 || offset > 32768)
			fprintf(stderr, "warning: relocation out of range "
				"at %s(%02x:%08lx)\n", cur->name,
				(int)hr->r.segment, hr->r.offset);
		    * (short *)data = (short) offset;
		    break;
		case 4:
		    * (long *)data += offset;
		    /* we can't easily detect overflow on this one */
		    break;
		}

		/*
		 * If the relocation was relative between two symbols in
		 * the same segment, then we're done.
		 *
		 * Otherwise, we need to output a new relocation record
		 * with the references updated segment and offset...
		 */
		if (! isrelative 
		    || cur->seginfo[localseg].dest_seg != seg)
		{
		    hr->r.segment = cur->seginfo[localseg].dest_seg;
		    hr->r.offset += cur->seginfo[localseg].reloc;
		    hr->r.refseg = seg;
		    rdfaddheader(rdfheader, hr);
		}
		break;

	    case 2: /* import symbol */
	    case 7:
		/*
		 * scan the global symbol table for the symbol
		 * and associate its location with the segment number 
		 * for this module
		 */
		se = symtabFind(symtab, hr->i.label);
		if (!se || se->segment == -1) {
		    if (options.warnUnresolved) {
			fprintf(stderr, "warning: unresolved reference to `%s'"
				" in module `%s'\n", hr->i.label, cur->name);
		    }
		    /*
		     * we need to allocate a segment number for this
		     * symbol, and store it in the symbol table for
		     * future reference
		     */ 
		    if (!se) {
			se=malloc(sizeof(*se));
			if (!se) {
			    fprintf(stderr, "ldrdf: out of memory\n");
			    exit(1);
			}
			se->name = strdup(hr->i.label);
			se->flags = 0;
			se->segment = availableseg++;
			se->offset = 0;
			symtabInsert(symtab, se);
		    }
		    else {
			se->segment = availableseg++;
			se->offset = 0;
		    }
		    /*
		     * output a header record that imports it to the
		     * recently allocated segment number...
		     */
		    newrec = *hr;
		    newrec.i.segment = se->segment;
		    rdfaddheader(rdfheader, &newrec);
		}

		add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
		
		break;

	    case 3: /* export symbol */
		/*
		 * need to insert an export for this symbol into the new
		 * header, unless we're stripping symbols [unless this
		 * symbol is in an explicit keep list]. *** FIXME ***
		 */
		if (options.strip)
		    break;

		if (hr->e.segment == 2) {
		    seg = 2;
		    offset = cur->bss_reloc;
		}
		else {
		    localseg = rdffindsegment(&cur->f, hr->e.segment);
		    if (localseg == -1) {
			fprintf(stderr, "%s: exported symbol `%s' from "
				"unrecognised segment\n", cur->name,
				hr->e.label);
			errorcount++;
			break;
		    }
		    offset = cur->seginfo[localseg].reloc;
		    seg = cur->seginfo[localseg].dest_seg;
		}

		hr->e.segment = seg;	
		hr->e.offset += offset;
		rdfaddheader(rdfheader, hr);
		break;

	    case 6: /* segment fixup */
		/*
		 * modify the segment numbers if necessary, and
		 * pass straight through to the output module header
		 *
		 * *** FIXME ***
		 */
		if (hr->r.segment == 2) {
		    fprintf(stderr, "%s: segment fixup in BSS section\n",
			    cur->name);
		    errorcount++;
		    break;
		}
		localseg = rdffindsegment(&cur->f, hr->r.segment);
		if (localseg == -1) {
		    fprintf(stderr, "%s: segment fixup in unrecognised"
			    " segment (%d)\n", cur->name, hr->r.segment);
		    errorcount++;
		    break;
		}
		hr->r.segment = cur->seginfo[localseg].dest_seg;
		hr->r.offset += cur->seginfo[localseg].reloc;

		if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
		{
		    fprintf(stderr, "%s: segment fixup to undefined "
			    "segment %04x\n", cur->name, (int)hr->r.refseg);
		    errorcount++;
		    break;
		}
		hr->r.refseg = seg;
		rdfaddheader(rdfheader, hr);
		break;
	    }
	}

	free(header);
	done_seglocations(&segs);

   }

    /*
     * combined BSS reservation for the entire results
     */
    newrec.type = 5;
    newrec.b.reclen = 4;
    newrec.b.amount = bss_length;
    rdfaddheader(rdfheader, &newrec);

    /*
     * Write the header
     */
    for (i = 0; i < nsegs; i++)
    {
	if (i == 2) continue;
	rdfaddsegment (rdfheader, outputseg[i].length);
    }
    rdfwriteheader(f, rdfheader);
    rdfdoneheader(rdfheader);
    /*
     * Step through the segments, one at a time, writing out into
     * the output file
     */
    
    for (i = 0; i < nsegs; i++)
    {
	int16 s;
	long l;
	
	if (i == 2) continue;

	s = translateshort(outputseg[i].type);
	fwrite(&s, 2, 1, f);
	s = translateshort(outputseg[i].number);
	fwrite(&s, 2, 1, f);
	s = translateshort(outputseg[i].reserved);
	fwrite(&s, 2, 1, f);
	l = translatelong(outputseg[i].length);
	fwrite(&l, 4, 1, f);

	fwrite(outputseg[i].data, outputseg[i].length, 1, f);
    }

    fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);
}
コード例 #10
0
ファイル: rdfdump.c プロジェクト: happyg1t/nasmVC
int main(int argc,char **argv) {
  char id[7];
  long l;
  int verbose = 0;
  long offset;

  puts("RDOFF Dump utility v1.1 (C) Copyright 1996 Julian R Hall");

  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",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] > '1') {
    fprintf(stderr,"rdfdump: unknown RDOFF version '%c'\n",id[5]);
    exit(1);
  }

  fread(&l,4,1,infile);
  l = translatelong(l);
  printf("Header (%ld bytes):\n",l);
  print_header(l);

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