From e0c059ab4e1e5d471372aa42caa57573de912655 Mon Sep 17 00:00:00 2001 From: Yuri Zaporogets Date: Wed, 15 Sep 2004 06:54:34 +0000 Subject: outrdf2.c now uses the same definitions of RDOFF2 format that RDOFF utils. Export/import/common label size is increased from 33 to 64. Fixed the bug that caused wrong behavior of rdfgetheaderrec() if label length was 32. Changed error codes from numeric values to symbolic constants. Moved some routines from rdfdump.c to rdoff.c. They will be utilized also by rdfdisasm, which is being developed. --- rdoff/Makefile.in | 4 +- rdoff/Mkfiles/Makefile.dj | 4 +- rdoff/Mkfiles/Makefile.emx | 4 +- rdoff/Mkfiles/Makefile.unx | 4 +- rdoff/README | 2 +- rdoff/collectn.c | 46 +++-- rdoff/collectn.h | 10 +- rdoff/doc/rdoff.texi | 4 +- rdoff/hash.c | 1 - rdoff/ldrdf.c | 113 +++++------ rdoff/rdf2bin.c | 5 +- rdoff/rdf2ihx.c | 9 +- rdoff/rdfdump.c | 473 +++++++++++++++++++++------------------------ rdoff/rdfload.c | 31 ++- rdoff/rdfload.h | 2 + rdoff/rdlib.c | 5 +- rdoff/rdlib.h | 6 +- rdoff/rdoff.c | 455 +++++++++++++++++++++++-------------------- rdoff/rdoff.h | 166 +++++++++++----- rdoff/rdx.c | 11 +- rdoff/segtab.h | 1 - 21 files changed, 704 insertions(+), 652 deletions(-) (limited to 'rdoff') diff --git a/rdoff/Makefile.in b/rdoff/Makefile.in index 8ac3242..f2e14f4 100644 --- a/rdoff/Makefile.in +++ b/rdoff/Makefile.in @@ -42,8 +42,8 @@ PROGRAMS = rdfdump$(X) ldrdf$(X) rdx$(X) rdflib$(X) \ all: $(PROGRAMS) -rdfdump$(X): rdfdump.$(O) - $(CC) $(LDFLAGS) -o rdfdump$(X) rdfdump.$(O) +rdfdump$(X): rdfdump.$(O) rdoff.$(O) + $(CC) $(LDFLAGS) -o rdfdump$(X) rdfdump.$(O) rdoff.$(O) ldrdf$(X): ldrdf.$(O) $(LDRDFLIBS) $(CC) $(LDFLAGS) -o ldrdf$(X) ldrdf.$(O) $(LDRDFLIBS) rdx$(X): rdx.$(O) $(RDXLIBS) diff --git a/rdoff/Mkfiles/Makefile.dj b/rdoff/Mkfiles/Makefile.dj index 2099739..163d278 100644 --- a/rdoff/Mkfiles/Makefile.dj +++ b/rdoff/Mkfiles/Makefile.dj @@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o hash.o collectn.o all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com -rdfdump: rdfdump.o - $(CC) -o rdfdump rdfdump.o +rdfdump: rdfdump.o rdoff.o + $(CC) -o rdfdump rdfdump.o rdoff.o ldrdf: ldrdf.o $(LDRDFLIBS) $(CC) -o ldrdf ldrdf.o $(LDRDFLIBS) diff --git a/rdoff/Mkfiles/Makefile.emx b/rdoff/Mkfiles/Makefile.emx index fbaa934..9a28745 100644 --- a/rdoff/Mkfiles/Makefile.emx +++ b/rdoff/Mkfiles/Makefile.emx @@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o hash.o all: rdfdump ldrdf rdx rdflib rdf2bin -rdfdump: rdfdump.o - $(CC) $(LDFLAGS) -o rdfdump rdfdump.o $(LIBS) +rdfdump: rdfdump.o rdoff.o + $(CC) $(LDFLAGS) -o rdfdump rdfdump.o rdoff.o $(LIBS) ldrdf: ldrdf.o $(LDRDFLIBS) $(CC) $(LDFLAGS) -o ldrdf ldrdf.o $(LDRDFLIBS) $(LIBS) rdx: rdx.o $(RDXLIBS) diff --git a/rdoff/Mkfiles/Makefile.unx b/rdoff/Mkfiles/Makefile.unx index 89d439f..1bf9b96 100644 --- a/rdoff/Mkfiles/Makefile.unx +++ b/rdoff/Mkfiles/Makefile.unx @@ -33,8 +33,8 @@ RDXLIBS = rdoff.o rdfload.o symtab.o hash.o collectn.o all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com -rdfdump: rdfdump.o - $(CC) -o rdfdump rdfdump.o +rdfdump: rdfdump.o rdoff.o + $(CC) -o rdfdump rdfdump.o rdoff.o ldrdf: ldrdf.o $(LDRDFLIBS) $(CC) -o ldrdf ldrdf.o $(LDRDFLIBS) diff --git a/rdoff/README b/rdoff/README index 4962b89..a5a6fd1 100644 --- a/rdoff/README +++ b/rdoff/README @@ -181,5 +181,5 @@ file for a comment containing the word 'TODO'. A brief list is given here: MAINTAINERS =========== -Yuri Zaporogets - primary maintainer +Yuri Zaporogets - primary maintainer Julian Hall - original designer and author diff --git a/rdoff/collectn.c b/rdoff/collectn.c index c265c95..71dc10e 100644 --- a/rdoff/collectn.c +++ b/rdoff/collectn.c @@ -1,4 +1,5 @@ -/* collectn.c Implements variable length pointer arrays [collections] +/* + * collectn.c - implements variable length pointer arrays [collections]. * * This file is public domain. */ @@ -8,33 +9,36 @@ void collection_init(Collection * c) { - int i; + int i; - for (i = 0; i < 32; i++) c->p[i] = NULL; - c->next = NULL; + for (i = 0; i < 32; i++) + c->p[i] = NULL; + c->next = NULL; } -void ** colln(Collection * c, int index) +void **colln(Collection * c, int index) { - while (index >= 32) { - index -= 32; - if (c->next == NULL) { - c->next = malloc(sizeof(Collection)); - collection_init(c->next); + while (index >= 32) { + index -= 32; + if (c->next == NULL) { + c->next = malloc(sizeof(Collection)); + collection_init(c->next); + } + c = c->next; } - c = c->next; - } - return &(c->p[index]); + return &(c->p[index]); } -void collection_reset(Collection *c) +void collection_reset(Collection * c) { - int i; - if (c->next) { - collection_reset(c->next); - free(c->next); - } + int i; - c->next = NULL; - for (i = 0; i < 32; i++) c->p[i] = NULL; + if (c->next) { + collection_reset(c->next); + free(c->next); + } + + c->next = NULL; + for (i = 0; i < 32; i++) + c->p[i] = NULL; } diff --git a/rdoff/collectn.h b/rdoff/collectn.h index 2dc786e..dc4f7cc 100644 --- a/rdoff/collectn.h +++ b/rdoff/collectn.h @@ -1,17 +1,18 @@ -/* collectn.h Header file for 'collection' abstract data type +/* + * collectn.h - header file for 'collection' abstract data type. * * This file is public domain, and does not come under the NASM license. * It, along with 'collectn.c' implements what is basically a variable - * length array (of pointers) + * length array (of pointers). */ #ifndef _COLLECTN_H #define _COLLECTN_H typedef struct tagCollection { - void *p[32]; /* array of pointers to objects */ + void *p[32]; /* array of pointers to objects */ - struct tagCollection *next; + struct tagCollection *next; } Collection; void collection_init(Collection * c); @@ -19,4 +20,3 @@ void ** colln(Collection * c, int index); void collection_reset(Collection * c); #endif - diff --git a/rdoff/doc/rdoff.texi b/rdoff/doc/rdoff.texi index c958cc3..4431287 100644 --- a/rdoff/doc/rdoff.texi +++ b/rdoff/doc/rdoff.texi @@ -12,8 +12,8 @@ @end titlepage @ifinfo -Copyright @copyright{} 2002-2003 Netwide Assembler Project. -Written by Yuri Zaporogets @email{yuriz@@ukr.net} +Copyright @copyright{} 2002-2004 Netwide Assembler Project. +Written by Yuri Zaporogets @email{yuriz@@users.sf.net} Based on various sources and notes written by Julian Hall @email{jules@@dsf.org.uk} Distributed under GNU documentation license. @end ifinfo diff --git a/rdoff/hash.c b/rdoff/hash.c index c22d182..7f28f12 100644 --- a/rdoff/hash.c +++ b/rdoff/hash.c @@ -92,4 +92,3 @@ hash (const char *name) return (hashval); } - diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c index f31ca7a..22e077e 100644 --- a/rdoff/ldrdf.c +++ b/rdoff/ldrdf.c @@ -2,7 +2,7 @@ * ldrdf.c - RDOFF Object File linker/loader main program. * * Copyright (c) 1996,99 Julian Hall. All rights reserved. - * Copyright (c) 2000-2003 RET & COM Research. + * Improvements and fixes (c) 1999-2004 RET & COM Research. * * This file is distributed under the terms and conditions of the * GNU Lesser Public License (LGPL), version 2.1. @@ -28,6 +28,8 @@ #include #include +#define RDOFF_UTILS + #include "rdoff.h" #include "symtab.h" #include "collectn.h" @@ -36,7 +38,6 @@ #define LDRDF_VERSION "1.07" -#define RDF_MAXSEGS 64 /* #define STINGY_MEMORY */ /* ======================================================================= @@ -70,8 +71,8 @@ struct modulenode { */ void processmodule(const char * filename, struct modulenode * mod); -int allocnewseg(int16 type,int16 reserved); -int findsegment(int16 type,int16 reserved); +int allocnewseg(uint16 type,uint16 reserved); +int findsegment(uint16 type,uint16 reserved); void symtab_add(const char * symbol, int segment, long offset); int symtab_get(const char * symbol, int * segment, long * offset); @@ -219,8 +220,7 @@ void processmodule(const char * filename, struct modulenode * mod) long bssamount = 0; int bss_was_referenced = 0; - for (seg = 0; seg < mod->f.nsegs; seg++) - { + for (seg = 0; seg < mod->f.nsegs; seg++) { /* * get the segment configuration for this type from the segment * table. getsegconfig() is a macro, defined in ldsegs.h. @@ -418,7 +418,7 @@ int lookformodule(const char *name) * a segment of the type requested, and if one isn't found allocates a * new one. */ -int allocnewseg(int16 type,int16 reserved) +int allocnewseg(uint16 type,uint16 reserved) { outputseg[nsegs].type = type; outputseg[nsegs].number = nsegs; @@ -430,7 +430,7 @@ int allocnewseg(int16 type,int16 reserved) return nsegs++; } -int findsegment(int16 type,int16 reserved) +int findsegment(uint16 type,uint16 reserved) { int i; @@ -463,8 +463,7 @@ void symtab_add(const char * symbol, int segment, long offset) symtabEnt * ste; ste = symtabFind(symtab, symbol); - if (ste) - { + if (ste) { if (ste->segment >= 0) { /* * symbol previously defined @@ -516,9 +515,7 @@ int symtab_get(const char * symbol, int * segment, long * offset) *segment = -1; *offset = 0; return 0; - } - else - { + } else { *segment = ste->segment; *offset = ste->offset; return 1; @@ -539,16 +536,13 @@ void add_library(const char * name) errorcount++; return; } - if (! libraries) - { + if (!libraries) { lastlib = libraries = malloc(sizeof(*libraries)); if (! libraries) { fprintf(stderr, "ldrdf: out of memory\n"); exit(1); } - } - else - { + } else { lastlib->next = malloc(sizeof(*libraries)); if (!lastlib->next) { fprintf(stderr, "ldrdf: out of memory\n"); @@ -588,13 +582,11 @@ int search_libraries() cur = libraries; - while (cur) - { + while (cur) { if (options.verbose > 2) printf("scanning library `%s', pass %d...\n", cur->name, pass); - for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) - { + for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) { if (pass == 2 && lookformodule(f.name)) continue; if (options.verbose > 3) @@ -613,8 +605,7 @@ int search_libraries() keepfile = 0; - while ((hr = rdfgetheaderrec (&f))) - { + while ((hr = rdfgetheaderrec (&f))) { /* We're only interested in exports, so skip others */ if (hr->type != RDFREC_GLOBAL) continue; @@ -744,8 +735,7 @@ void write_output(const char * filename) * 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++) - { + for (i = 0; i < nsegs; i++) { outputseg[i].data=NULL; if(!outputseg[i].length) continue; outputseg[i].data = malloc(outputseg[i].length); @@ -764,21 +754,18 @@ void write_output(const char * filename) /* * Step through the modules, performing required actions on each one */ - for (cur = modules; cur; cur=cur->next) - { + 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++) - { + 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)) - { + outputseg[dest].data + cur->seginfo[i].reloc)) { rdfperror("ldrdf", cur->name); exit(1); } @@ -797,8 +784,7 @@ void write_output(const char * filename) if (cur->f.header_loc) rdfheaderrewind(&cur->f); else - if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) - { + if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) { rdfperror("ldrdf", cur->name); exit(1); } @@ -808,18 +794,16 @@ void write_output(const char * filename) * table for the segments in this module. */ init_seglocations(&segs); - for (i = 0; i < cur->f.nsegs; i++) - { + 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); + add_seglocation(&segs, 2, 2, cur->bss_reloc); - while ((hr = rdfgetheaderrec(&cur->f))) - { + while ((hr = rdfgetheaderrec(&cur->f))) { switch(hr->type) { case RDFREC_RELOC: /* relocation record - need to do a fixup */ /* @@ -834,21 +818,18 @@ void write_output(const char * filename) * case we have to first subtract the amount we've relocated * the containing segment by. */ - - if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) - { + 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; + 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) - { + (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", @@ -857,8 +838,8 @@ void write_output(const char * filename) break; } - if (hr->r.length != 1 && hr->r.length != 2 && hr->r.length!=4) - { + 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++; @@ -883,10 +864,10 @@ void write_output(const char * filename) * Then add 'offset' onto the value at data. */ - if (isrelative) offset -= cur->seginfo[localseg].reloc; - switch (hr->r.length) - { - case 1: + 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 " @@ -894,7 +875,7 @@ void write_output(const char * filename) (int)hr->r.segment, hr->r.offset); *data = (char) offset; break; - case 2: + case 2: offset += * (short *)data; if (offset < -32767 || offset > 32768) fprintf(error_file, "warning: relocation out of range " @@ -902,7 +883,7 @@ void write_output(const char * filename) (int)hr->r.segment, hr->r.offset); * (short *)data = (short) offset; break; - case 4: + case 4: * (long *)data += offset; /* we can't easily detect overflow on this one */ break; @@ -915,13 +896,12 @@ void write_output(const char * filename) * Otherwise, we need to output a new relocation record * with the references updated segment and offset... */ - if (! isrelative || cur->seginfo[localseg].dest_seg != seg) - { + 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 += 64; + hr->r.segment += RDOFF_RELATIVEMASK; rdfaddheader(rdfheader, hr); } break; @@ -1045,8 +1025,7 @@ void write_output(const char * filename) hr->r.segment = cur->seginfo[localseg].dest_seg; hr->r.offset += cur->seginfo[localseg].reloc; - if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) - { + 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++; @@ -1085,8 +1064,7 @@ void write_output(const char * filename) /* * Write the header */ - for (i = 0; i < nsegs; i++) - { + for (i = 0; i < nsegs; i++) { if (i == 2) continue; rdfaddsegment (rdfheader, outputseg[i].length); } @@ -1098,9 +1076,8 @@ void write_output(const char * filename) * Step through the segments, one at a time, writing out into * the output file */ - for (i = 0; i < nsegs; i++) - { - int16 s; + for (i = 0; i < nsegs; i++) { + uint16 s; long l; if (i == 2) continue; @@ -1154,14 +1131,13 @@ int main(int argc, char ** argv) error_file = stderr; - argc --, argv ++; + argc--, argv++; if (argc == 0) usage(); - while (argc && *argv && **argv == '-' && argv[0][1] != 'l') - { + while (argc && *argv && **argv == '-' && argv[0][1] != 'l') { switch(argv[0][1]) { case 'r': printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n"); - printf( _RDOFF_H "\n"); + printf("RDOFF2 revision %s\n", RDOFF2_REVISION); exit(0); case 'v': if (argv[0][2] == '=') { @@ -1318,3 +1294,4 @@ int main(int argc, char ** argv) if (errorcount > 0) exit(1); return 0; } + diff --git a/rdoff/rdf2bin.c b/rdoff/rdf2bin.c index 938b4a9..aee6afb 100644 --- a/rdoff/rdf2bin.c +++ b/rdoff/rdf2bin.c @@ -1,11 +1,12 @@ -/* rdf2bin: convert an RDOFF object file to flat binary */ +/* + * rdf2bin.c - convert an RDOFF object file to flat binary + */ #include #include #include #include "rdfload.h" -#include "rdoff.h" #include "nasmlib.h" long origin = 0; diff --git a/rdoff/rdf2ihx.c b/rdoff/rdf2ihx.c index ed91537..43e5c72 100644 --- a/rdoff/rdf2ihx.c +++ b/rdoff/rdf2ihx.c @@ -1,12 +1,14 @@ -/* rdf2ihx: convert an RDOFF object file to Intel Hex format. This is based - on rdf2bin. Note that this program only writes 16-bit HEX. */ +/* + * rdf2ihx.c - convert an RDOFF object file to Intel Hex format. + * This is based on rdf2bin. + * Note that this program only writes 16-bit HEX. + */ #include #include #include #include "rdfload.h" -#include "rdoff.h" #include "nasmlib.h" #include "symtab.h" @@ -186,4 +188,3 @@ int main(int argc, char **argv) fclose(of); return 0; } - diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c index 09f2d80..626fd2a 100644 --- a/rdoff/rdfdump.c +++ b/rdoff/rdfdump.c @@ -6,74 +6,52 @@ #include #include -#include "rdoff.h" - -FILE *infile; - -/* Translate from little endian to local representation */ -long translatelong(long in) -{ - long r; - unsigned char *i; - - i = (unsigned char *)∈ - r = i[3]; - r = (r << 8) + i[2]; - r = (r << 8) + i[1]; - r = (r << 8) + *i; +#define RDOFF_UTILS - return r; -} - -int16 translateshort(int16 in) -{ - int r; - unsigned char *i; +#include "rdoff.h" - i = (unsigned char *)∈ - r = (i[1] << 8) + *i; +#define PROGRAM_VERSION "2.3" - return r; -} +FILE *infile; void print_header(long length, int rdf_version) { - char buf[129],t,l,s,flags; + char buf[129], t, l, s, flags; unsigned char reclen; - long o,ll; - int16 rs; + long o, ll; + uint16 rs; while (length > 0) { - fread(&t,1,1,infile); + fread(&t, 1, 1, infile); if (rdf_version >= 2) { - fread(&reclen,1,1,infile); + fread(&reclen, 1, 1, infile); } - switch(t) { - case RDFREC_GENERIC: /* generic record */ - printf(" generic record (length=%d)\n", (int)reclen); + 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); + + 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) + "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) + 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(&flags, 1, 1, infile); + break; + + case RDFREC_IMPORT: /* import record */ + case RDFREC_FARIMPORT: /* import far symbol */ + fread(&flags, 1, 1, infile); fread(&rs, 2, 1, infile); ll = 0; @@ -82,22 +60,25 @@ void print_header(long length, int rdf_version) fread(&buf[ll], 1, 1, infile); } while (buf[ll++]); } else { - for (;ll < reclen - 3; ll++) + for (; ll < reclen - 3; ll++) fread(&buf[ll], 1, 1, infile); - } + } if (t == 7) printf("far "); printf((flags & SYM_IMPORT) ? " import" : " extern"); - if (flags & SYM_FUNCTION) printf(" proc"); - if (flags & SYM_DATA) printf(" data"); + if (flags & SYM_FUNCTION) + printf(" proc"); + if (flags & SYM_DATA) + printf(" data"); printf(": segment %04x = %s\n", translateshort(rs), buf); - if (rdf_version == 1) length -= ll + 3; + 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 */ + 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); @@ -105,228 +86,218 @@ void print_header(long length, int rdf_version) if (rdf_version == 1) { do { - fread(&buf[ll], 1, 1, infile); + fread(&buf[ll], 1, 1, infile); } while (buf[ll++]); } else { - for (; ll < reclen - 6; ll ++) - fread(&buf[ll], 1, 1, infile); - } - printf((flags & SYM_GLOBAL) ? " export" : " public"); - 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; + for (; ll < reclen - 6; ll++) + fread(&buf[ll], 1, 1, infile); + } + printf((flags & SYM_GLOBAL) ? " export" : " public"); + 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_DLL: /* DLL and Module records */ case RDFREC_MODNAME: ll = 0; if (rdf_version == 1) { do { - fread(&buf[ll],1,1,infile); + 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 (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; + 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: { + + 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); + fread(buf + ll, 1, 1, infile); printf(" common: segment %04x = %s, %ld:%d\n", translateshort(seg), buf, translatelong(size), translateshort(align)); - break; + break; } default: - printf(" unrecognized record (type %d", (int)t); + 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"); + printf(", length %d", (int) reclen); + fseek(infile, reclen, SEEK_CUR); + } else + length--; + printf(")\n"); } - if (rdf_version != 1) length -= 2 + reclen; + 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.2\n"\ - "Copyright (c) 1996,99 Julian R Hall\n" - "Copyright (c) 2000-2002 RET & COM Research."); - - if (argc < 2) { - fputs("Usage: rdfdump [-v] \n",stderr); - exit(1); - } - - if (! strcmp (argv[1], "-v") ) - { - verbose = 1; - if (argc < 3) - { - fputs("required parameter missing\n",stderr); - exit(1); +int main(int argc, char **argv) +{ + char id[7]; + long l; + uint16 s; + int verbose = 0; + long offset; + int foundnullsegment = 0; + int version; + long segmentcontentlength = 0; + int nsegments = 0; + long headerlength = 0; + long objectlength = 0; + + printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION); + printf("RDOFF2 revision %s\n", RDOFF2_REVISION); + puts("Copyright (c) 1996,99 Julian R Hall\n" + "Improvements and fixes (c) 2002-2004 RET & COM Research."); + + if (argc < 2) { + fputs("Usage: rdfdump [-v] \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); } - 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; + fclose(infile); + return 0; } diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c index 8fb6ca3..2f8bf6b 100644 --- a/rdoff/rdfload.c +++ b/rdoff/rdfload.c @@ -23,7 +23,6 @@ #include "rdfload.h" #include "symtab.h" -#include "rdoff.h" #include "collectn.h" extern int rdf_errno; @@ -36,17 +35,15 @@ rdfmodule * rdfload(const char *filename) rdfheaderrec *r; f = malloc(sizeof(rdfmodule)); - if (f == NULL) - { - rdf_errno = 6; /* out of memory */ + if (f == NULL) { + rdf_errno = RDF_ERR_NOMEM; return NULL; } f->symtab = symtabNew(); - if (!f->symtab) - { + if (!f->symtab) { free(f); - rdf_errno = 6; + rdf_errno = RDF_ERR_NOMEM; return NULL; } @@ -63,7 +60,7 @@ rdfmodule * rdfload(const char *filename) hdr = malloc (f->f.header_len); if (! f->t || ! f->d || !hdr) { - rdf_errno = 6; + rdf_errno = RDF_ERR_NOMEM; rdfclose(&f->f); if (f->t) free(f->t); if (f->d) free(f->d); @@ -87,20 +84,18 @@ rdfmodule * rdfload(const char *filename) /* Allocate BSS segment; step through header and count BSS records */ - while ( ( r = rdfgetheaderrec (&f->f) ) ) - { + while ((r = rdfgetheaderrec(&f->f))) { if (r->type == 5) bsslength += r->b.amount; } f->b = malloc ( bsslength ); - if (bsslength && (!f->b)) - { + if (bsslength && (!f->b)) { free(f->t); free(f->d); free(f); free(hdr); - rdf_errno = 6; + rdf_errno = RDF_ERR_NOMEM; return NULL; } @@ -121,13 +116,11 @@ int rdf_relocate(rdfmodule * m) long rel; unsigned char * seg; - rdfheaderrewind ( & m->f ); + rdfheaderrewind (&m->f); collection_init(&imports); - while ( (r = rdfgetheaderrec ( & m->f ) ) ) - { - switch (r->type) - { + while ((r = rdfgetheaderrec(&m->f))) { + switch (r->type) { case 1: /* Relocation record */ /* calculate relocation factor */ @@ -154,7 +147,7 @@ int rdf_relocate(rdfmodule * m) seg[r->r.offset] += (char) rel; break; case 2: - *(int16 *)(seg + r->r.offset) += (int16) rel; + *(uint16 *)(seg + r->r.offset) += (uint16) rel; break; case 4: *(long *)(seg + r->r.offset) += rel; diff --git a/rdoff/rdfload.h b/rdoff/rdfload.h index 5e264b9..3889a4e 100644 --- a/rdoff/rdfload.h +++ b/rdoff/rdfload.h @@ -12,6 +12,8 @@ #ifndef _RDFLOAD_H #define _RDFLOAD_H +#define RDOFF_UTILS + #include "rdoff.h" typedef struct RDFModuleStruct { diff --git a/rdoff/rdlib.c b/rdoff/rdlib.c index f511c1c..97f682f 100644 --- a/rdoff/rdlib.c +++ b/rdoff/rdlib.c @@ -6,6 +6,8 @@ #include #include +#define RDOFF_UTILS + #include "rdoff.h" #include "rdlib.h" #include "rdlar.h" @@ -264,6 +266,3 @@ void rdl_perror(const char *apname, const char *filename) else fprintf(stderr,"%s:%s:%s\n",apname,filename,rdl_errors[rdl_error]); } - - - diff --git a/rdoff/rdlib.h b/rdoff/rdlib.h index 28c6ee7..6255024 100644 --- a/rdoff/rdlib.h +++ b/rdoff/rdlib.h @@ -1,4 +1,6 @@ -/* rdlib.h Functions for manipulating librarys of RDOFF object files */ +/* + * rdlib.h Functions for manipulating libraries of RDOFF object files. + */ struct librarynode { @@ -23,5 +25,3 @@ int rdl_searchlib (struct librarynode * lib, int rdl_openmodule (struct librarynode * lib, int module, rdffile * f); void rdl_perror(const char *apname, const char *filename); - - diff --git a/rdoff/rdoff.c b/rdoff/rdoff.c index 504d842..bfdb9cc 100644 --- a/rdoff/rdoff.c +++ b/rdoff/rdoff.c @@ -19,6 +19,9 @@ #include #include #include + +#define RDOFF_UTILS + #include "rdoff.h" #define newstr(str) strcpy(malloc(strlen(str) + 1),str) @@ -53,7 +56,7 @@ memorybuffer * newmembuf() void membufwrite(memorybuffer *const b, void *data, int bytes) { - int16 w; + uint16 w; long l; if (b->next) { /* memory buffer full - use next buffer */ @@ -85,7 +88,7 @@ void membufwrite(memorybuffer *const b, void *data, int bytes) break; case -2: - w = * (int16 *) data ; + w = * (uint16 *) data ; b->buffer[b->length++] = w & 0xFF; w >>= 8 ; b->buffer[b->length++] = w & 0xFF; @@ -146,9 +149,9 @@ long translatelong(long in) return r; } -int16 translateshort(int16 in) +uint16 translateshort(uint16 in) { - int16 r; + uint16 r; unsigned char * i; i = (unsigned char *)∈ @@ -157,15 +160,48 @@ int16 translateshort(int16 in) return r; } -const char *RDOFFId = "RDOFF2"; /* written to the start of RDOFF files */ +/* Segment types */ +static char *knownsegtypes[8] = { + "NULL", "text", "data", "object comment", + "linked comment", "loader comment", + "symbolic debug", "line number debug" +}; + +/* Get a textual string describing the segment type */ +char *translatesegmenttype(uint16 type) +{ + if (type < 8) + return knownsegtypes[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"; +} + +/* This signature is written to the start of RDOFF files */ +const char *RDOFFId = RDOFF2_SIGNATURE; +/* Error messages. Must correspond to the codes defined in rdoff.h */ const char *rdf_errors[11] = { - "no error occurred","could not open file","invalid file format", - "error reading file","unknown error","header not read", - "out of memory", "RDOFF v1 not supported", - "unknown extended header record", - "header record of known type but unknown length", - "no such segment"}; + /* 0 */ "no error occurred", + /* 1 */ "could not open file", + /* 2 */ "invalid file format", + /* 3 */ "error reading file", + /* 4 */ "unknown error", + /* 5 */ "header not read", + /* 6 */ "out of memory", + /* 7 */ "RDOFF v1 not supported", + /* 8 */ "unknown extended header record", + /* 9 */ "header record of known type but unknown length", + /* 10 */ "no such segment" +}; int rdf_errno = 0; @@ -178,119 +214,120 @@ int rdfopen(rdffile *f, const char *name) FILE * fp; fp = fopen(name,"rb"); - if (!fp) return rdf_errno = 1; /* error 1: file open error */ + if (!fp) + return rdf_errno = RDF_ERR_OPEN; return rdfopenhere(f,fp,NULL,name); } 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 " + char buf[8]; + long initpos; + long l; + uint16 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 = RDF_ERR_VER; + return rdf_errno = RDF_ERR_FORMAT; + } + + if (fread(&l,1,4,f->fp) != 4 || fread(&f->header_len,1,4,f->fp) != 4) { + fclose(f->fp); + return rdf_errno = RDF_ERR_READ; + } + + 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 = RDF_ERR_FORMAT; /* seek past end of file...? */ + } + + if (fread(&s,1,2,f->fp) != 2) { + fclose(f->fp); + return rdf_errno = RDF_ERR_READ; + } + + 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 = RDF_ERR_READ; + } + + 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 = RDF_ERR_FORMAT; + } + f->nsegs++; + + if (fread(&s,1,2,f->fp) != 2) { + fclose(f->fp); + return rdf_errno = RDF_ERR_READ; + } + } + + 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; + } + fseek(f->fp,initpos,SEEK_SET); + f->header_loc = NULL; + + f->name = newstr(name); + f->refcount = refcount; + if (refcount) (*refcount)++; + return RDF_OK; } int rdfclose(rdffile *f) { - if (! f->refcount || ! --(*f->refcount)) - { - fclose(f->fp); - f->fp = NULL; - } + if (! f->refcount || ! --(*f->refcount)) { + fclose(f->fp); + f->fp = NULL; + } free(f->name); return 0; } -void rdfperror(const char *app,const char *name) +/* + * Print the message for last error (from rdf_errno) + */ +void rdfperror(const char *app, const char *name) { - fprintf(stderr,"%s:%s: %s\n",app,name,rdf_errors[rdf_errno]); - if (rdf_errno == 1 || rdf_errno == 3) - { - perror(app); - } - + fprintf(stderr,"%s:%s: %s\n",app,name,rdf_errors[rdf_errno]); + if (rdf_errno == RDF_ERR_OPEN || rdf_errno == RDF_ERR_READ) { + perror(app); + } } +/* + * Find the segment by its number. + * Returns segment array index, or -1 if segment with such number was not found. + */ int rdffindsegment(rdffile * f, int segno) { int i; @@ -299,36 +336,37 @@ int rdffindsegment(rdffile * f, int segno) return -1; } +/* + * Load the segment. Returns status. + */ int rdfloadseg(rdffile *f,int segment,void *buffer) { - long fpos; - long slen; - - switch(segment) { - case RDOFF_HEADER: - fpos = f->header_ofs; - slen = f->header_len; - f->header_loc = (byte *)buffer; - f->header_fp = 0; - break; - default: - if (segment < f->nsegs) { - fpos = f->seg[segment].offset; - slen = f->seg[segment].length; - f->seg[segment].data = (byte *)buffer; - } - else { - return rdf_errno = 10; /* no such segment */ - } - } - - if (fseek(f->fp,fpos,SEEK_SET)) - return rdf_errno = 4; + long fpos, slen; + + switch(segment) { + case RDOFF_HEADER: + fpos = f->header_ofs; + slen = f->header_len; + f->header_loc = (byte *)buffer; + f->header_fp = 0; + break; + default: + if (segment < f->nsegs) { + fpos = f->seg[segment].offset; + slen = f->seg[segment].length; + f->seg[segment].data = (byte *)buffer; + } else { + return rdf_errno = RDF_ERR_SEGMENT; + } + } + + if (fseek(f->fp,fpos,SEEK_SET)) + return rdf_errno = RDF_ERR_UNKNOWN; - if (fread(buffer,1,slen,f->fp) != slen) - return rdf_errno = 3; + if (fread(buffer,1,slen,f->fp) != slen) + return rdf_errno = RDF_ERR_READ; - return 0; + return RDF_OK; } /* Macros for reading integers from header in memory */ @@ -347,86 +385,93 @@ int rdfloadseg(rdffile *f,int segment,void *buffer) #define RS(str,max) { for(i=0;iheader_loc) { - rdf_errno = 5; - return NULL; - } - - if (f->header_fp >= f->header_len) return 0; - - RI8(r.type); - RI8(r.g.reclen); - - switch(r.type) { - case RDFREC_RELOC: /* Relocation record */ - case RDFREC_SEGRELOC: - if (r.r.reclen != 8) { - rdf_errno = 9; - return NULL; - } - RI8(r.r.segment); - RI32(r.r.offset); - RI8(r.r.length); - RI16(r.r.refseg); - break; - - case RDFREC_IMPORT: /* Imported symbol record */ - case RDFREC_FARIMPORT: - RI8(r.i.flags); - RI16(r.i.segment); - RS(r.i.label,32); - break; - - case RDFREC_GLOBAL: /* Exported symbol record */ - RI8(r.e.flags); - RI8(r.e.segment); - RI32(r.e.offset); - RS(r.e.label,32); - break; - - case RDFREC_DLL: /* DLL record */ - RS(r.d.libname,127); - break; - - case RDFREC_BSS: /* BSS reservation record */ - if (r.r.reclen != 4) { - rdf_errno = 9; - return NULL; - } - RI32(r.b.amount); - break; - - case RDFREC_MODNAME: /* Module name record */ - RS(r.m.modname,127); - break; - - case RDFREC_COMMON: /* Common variable */ - RI16(r.c.segment); - RI32(r.c.size); - RI16(r.c.align); - RS(r.c.label,32); - break; + static rdfheaderrec r; + int i; + + if (!f->header_loc) { + rdf_errno = RDF_ERR_HEADER; + return NULL; + } + + if (f->header_fp >= f->header_len) return 0; + + RI8(r.type); + RI8(r.g.reclen); + + switch(r.type) { + case RDFREC_RELOC: /* Relocation record */ + case RDFREC_SEGRELOC: + if (r.r.reclen != 8) { + rdf_errno = RDF_ERR_RECLEN; + return NULL; + } + RI8(r.r.segment); + RI32(r.r.offset); + RI8(r.r.length); + RI16(r.r.refseg); + break; + + case RDFREC_IMPORT: /* Imported symbol record */ + case RDFREC_FARIMPORT: + RI8(r.i.flags); + RI16(r.i.segment); + RS(r.i.label, EXIM_LABEL_MAX); + break; + + case RDFREC_GLOBAL: /* Exported symbol record */ + RI8(r.e.flags); + RI8(r.e.segment); + RI32(r.e.offset); + RS(r.e.label, EXIM_LABEL_MAX); + break; + + case RDFREC_DLL: /* DLL record */ + RS(r.d.libname, MODLIB_NAME_MAX); + break; + + case RDFREC_BSS: /* BSS reservation record */ + if (r.r.reclen != 4) { + rdf_errno = RDF_ERR_RECLEN; + return NULL; + } + RI32(r.b.amount); + break; + + case RDFREC_MODNAME: /* Module name record */ + RS(r.m.modname, MODLIB_NAME_MAX); + break; + + case RDFREC_COMMON: /* Common variable */ + RI16(r.c.segment); + RI32(r.c.size); + RI16(r.c.align); + RS(r.c.label, EXIM_LABEL_MAX); + break; - default: + default: #ifdef STRICT_ERRORS - rdf_errno = 8; /* unknown header record */ - return NULL; + rdf_errno = RDF_ERR_RECTYPE; /* unknown header record */ + return NULL; #else - for (i = 0; i < r.g.reclen; i++) - RI8(r.g.data[i]); + for (i = 0; i < r.g.reclen; i++) + RI8(r.g.data[i]); #endif - } - return &r; + } + return &r; } - + +/* + * Rewind to the beginning of the file + */ void rdfheaderrewind(rdffile *f) { - f->header_fp = 0; + f->header_fp = 0; } @@ -450,8 +495,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r) membufwrite(h->buf,&r->type,1); membufwrite(h->buf,&r->g.reclen,1); - switch (r->type) - { + switch (r->type) { case RDFREC_GENERIC: /* generic */ membufwrite(h->buf, &r->g.data, r->g.reclen); break; @@ -491,7 +535,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r) default: #ifdef STRICT_ERRORS - return (rdf_errno = 8); + return rdf_errno = RDF_ERR_RECTYPE; #else for (i = 0; i < r->g.reclen; i++) membufwrite(h->buf, r->g.data[i], 1); @@ -530,4 +574,3 @@ void rdfdoneheader(rdf_headerbuf * h) freemembuf(h->buf); free(h); } - diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h index c6957dc..dd43126 100644 --- a/rdoff/rdoff.h +++ b/rdoff/rdoff.h @@ -1,4 +1,5 @@ -/* rdoff.h RDOFF Object File manipulation routines header file +/* + * rdoff.h RDOFF Object File manipulation routines header file * * The Netwide Assembler is copyright (C) 1996 Simon Tatham and * Julian Hall. All rights reserved. The software is @@ -11,17 +12,37 @@ */ #ifndef _RDOFF_H -#define _RDOFF_H "RDOFF2 support routines v0.3" +#define _RDOFF_H -/* Some systems don't define this automatically */ -extern char *strdup(const char *); +/* + * RDOFF definitions. They are used by RDOFF utilities and by NASM's + * 'outrdf2.c' output module. + */ -typedef unsigned short int16; +/* Type definitions */ +typedef unsigned long uint32; +typedef unsigned short uint16; typedef unsigned char byte; +typedef unsigned int bool; + +/* RDOFF format revision (currently used only when printing the version) */ +#define RDOFF2_REVISION "0.6.1" + +/* RDOFF2 file signature */ +#define RDOFF2_SIGNATURE "RDOFF2" + +/* Maximum size of an import/export label (including trailing zero) */ +#define EXIM_LABEL_MAX 64 -#define RDF_MAXSEGS 64 +/* Maximum size of library or module name (including trailing zero) */ +#define MODLIB_NAME_MAX 128 -/* the records that can be found in the RDOFF header */ +/* Maximum number of segments that we can handle in one file */ +#define RDF_MAXSEGS 64 + + +/* Record types that may present the RDOFF header */ +#define RDFREC_GENERIC 0 #define RDFREC_RELOC 1 #define RDFREC_IMPORT 2 #define RDFREC_GLOBAL 3 @@ -31,8 +52,21 @@ typedef unsigned char byte; #define RDFREC_FARIMPORT 7 #define RDFREC_MODNAME 8 #define RDFREC_COMMON 10 -#define RDFREC_GENERIC 0 + +/* + * Generic record - contains the type and length field, plus a 128 byte + * char array 'data' + */ +struct GenericRec { + byte type; + byte reclen; + char data[128]; +}; + +/* + * Relocation record + */ struct RelocRec { byte type; /* must be 1 */ byte reclen; /* content length */ @@ -41,55 +75,73 @@ struct RelocRec { reloc @ loadtime, only linkage) */ long offset; /* from start of segment in which reference is loc'd */ byte length; /* 1 2 or 4 bytes */ - int16 refseg; /* segment to which reference refers to */ + uint16 refseg; /* segment to which reference refers to */ }; +/* + * Extern/import record + */ struct ImportRec { byte type; /* must be 2 */ byte reclen; /* content length */ byte flags; /* SYM_* flags (see below) */ - int16 segment; /* segment number allocated to the label for reloc + uint16 segment; /* segment number allocated to the label for reloc records - label is assumed to be at offset zero in this segment, so linker must fix up with offset of segment and of offset within segment */ - char label[33]; /* zero terminated... should be written to file until - the zero, but not after it - max len = 32 chars */ + char label[EXIM_LABEL_MAX]; /* zero terminated, should be written to file + until the zero, but not after it */ }; +/* + * Public/export record + */ struct ExportRec { byte type; /* must be 3 */ byte reclen; /* content length */ byte flags; /* SYM_* flags (see below) */ byte segment; /* segment referred to (0/1/2) */ long offset; /* offset within segment */ - char label[33]; /* zero terminated as above. max len = 32 chars */ + char label[EXIM_LABEL_MAX]; /* zero terminated as in import */ }; +/* + * DLL record + */ struct DLLRec { byte type; /* must be 4 */ byte reclen; /* content length */ - char libname[128]; /* name of library to link with at load time */ + char libname[MODLIB_NAME_MAX]; /* name of library to link with at load time */ }; +/* + * BSS record + */ struct BSSRec { byte type; /* must be 5 */ - byte reclen; /* content length */ + byte reclen; /* content length */ long amount; /* number of bytes BSS to reserve */ }; +/* + * Module name record + */ struct ModRec { byte type; /* must be 8 */ byte reclen; /* content length */ - char modname[128]; /* module name */ + char modname[MODLIB_NAME_MAX]; /* module name */ }; +/* + * Common variable record + */ struct CommonRec { byte type; /* must be 10 */ byte reclen; /* equals 7+label length */ - int16 segment; /* segment number */ + uint16 segment; /* segment number */ long size; /* size of common variable */ - int16 align; /* alignment (power of two) */ - char label[33]; /* zero terminated as above. max len = 32 chars */ + uint16 align; /* alignment (power of two) */ + char label[EXIM_LABEL_MAX]; /* zero terminated as in import */ }; /* Flags for ExportRec */ @@ -98,15 +150,13 @@ struct CommonRec { #define SYM_GLOBAL 4 #define SYM_IMPORT 8 -/* - * GenericRec - contains the type and length field, plus a 128 byte - * char array 'data' - */ -struct GenericRec { - byte type; - byte reclen; - char data[128]; -}; + +/*** The following part is used only by the utilities *************************/ + +#ifdef RDOFF_UTILS + +/* Some systems don't define this automatically */ +extern char *strdup(const char *); typedef union RDFHeaderRec { char type; /* invariant throughout all below */ @@ -122,9 +172,9 @@ typedef union RDFHeaderRec { struct SegmentHeaderRec { /* information from file */ - int16 type; - int16 number; - int16 reserved; + uint16 type; + uint16 number; + uint16 reserved; long length; /* information built up here */ @@ -133,30 +183,30 @@ struct SegmentHeaderRec { }; typedef struct RDFFileInfo { - FILE *fp; /* file descriptor; must be open to use this struct */ - int rdoff_ver; /* should be 1; any higher => not guaranteed to work */ - long header_len; - long header_ofs; + FILE *fp; /* file descriptor; must be open to use this struct */ + int rdoff_ver; /* should be 1; any higher => not guaranteed to work */ + long header_len; + long header_ofs; - byte *header_loc; /* keep location of header */ - long header_fp; /* current location within header for reading */ + byte *header_loc; /* keep location of header */ + long header_fp; /* current location within header for reading */ - struct SegmentHeaderRec seg[RDF_MAXSEGS]; - int nsegs; + struct SegmentHeaderRec seg[RDF_MAXSEGS]; + int nsegs; - long eof_offset; /* offset of the first byte beyond the end of this + long eof_offset; /* offset of the first byte beyond the end of this module */ - char *name; /* name of module in libraries */ - int *refcount; /* pointer to reference count on file, or NULL */ + char *name; /* name of module in libraries */ + int *refcount; /* pointer to reference count on file, or NULL */ } rdffile; #define BUF_BLOCK_LEN 4088 /* selected to match page size (4096) * on 80x86 machines for efficiency */ typedef struct memorybuffer { - int length; - byte buffer[BUF_BLOCK_LEN]; - struct memorybuffer *next; + int length; + byte buffer[BUF_BLOCK_LEN]; + struct memorybuffer *next; } memorybuffer; typedef struct { @@ -166,9 +216,9 @@ typedef struct { } rdf_headerbuf; /* segments used by RDOFF, understood by rdoffloadseg */ -#define RDOFF_CODE 0 -#define RDOFF_DATA 1 -#define RDOFF_HEADER -1 +#define RDOFF_CODE 0 +#define RDOFF_DATA 1 +#define RDOFF_HEADER -1 /* mask for 'segment' in relocation records to find if relative relocation */ #define RDOFF_RELATIVEMASK 64 /* mask to find actual segment value in relocation records */ @@ -176,9 +226,25 @@ typedef struct { extern int rdf_errno; +/* rdf_errno can hold these error codes */ +enum { + /* 0 */ RDF_OK, + /* 1 */ RDF_ERR_OPEN, + /* 2 */ RDF_ERR_FORMAT, + /* 3 */ RDF_ERR_READ, + /* 4 */ RDF_ERR_UNKNOWN, + /* 5 */ RDF_ERR_HEADER, + /* 6 */ RDF_ERR_NOMEM, + /* 7 */ RDF_ERR_VER, + /* 8 */ RDF_ERR_RECTYPE, + /* 9 */ RDF_ERR_RECLEN, + /* 10 */ RDF_ERR_SEGMENT +}; + /* utility functions */ -int16 translateshort(int16 in); long translatelong(long in); +uint16 translateshort(uint16 in); +char *translatesegmenttype(uint16 type); /* RDOFF file manipulation functions */ int rdfopen(rdffile *f,const char *name); @@ -203,4 +269,6 @@ int rdfaddsegment(rdf_headerbuf *h, long seglength); int rdfwriteheader(FILE *fp,rdf_headerbuf *h); void rdfdoneheader(rdf_headerbuf *h); +#endif /* RDOFF_UTILS */ + #endif /* _RDOFF_H */ diff --git a/rdoff/rdx.c b/rdoff/rdx.c index 5a3058d..778b29f 100644 --- a/rdoff/rdx.c +++ b/rdoff/rdx.c @@ -16,7 +16,6 @@ #include #include "rdfload.h" -#include "rdoff.h" #include "symtab.h" typedef int (*main_fn) (int,char**); /* Main function prototype */ @@ -27,16 +26,14 @@ int main(int argc, char **argv) main_fn code; symtabEnt * s; - if (argc < 2) - { + if (argc < 2) { puts("usage: rdx [params]\n"); exit(255); } m = rdfload(argv[1]); - if (! m) - { + if (! m) { rdfperror("rdx",argv[1]); exit(255); } @@ -46,8 +43,7 @@ int main(int argc, char **argv) in other cases... */ s = symtabFind(m->symtab, "_main"); - if (! s) - { + if (! s) { fprintf(stderr,"rdx: could not find symbol '_main' in '%s'\n",argv[1]); exit(255); } @@ -58,4 +54,3 @@ int main(int argc, char **argv) return code(argc,argv); /* execute */ } - diff --git a/rdoff/segtab.h b/rdoff/segtab.h index b5d96fa..7e8e193 100644 --- a/rdoff/segtab.h +++ b/rdoff/segtab.h @@ -4,4 +4,3 @@ void init_seglocations(segtab * r); void add_seglocation(segtab * r, int localseg, int destseg, long offset); int get_seglocation(segtab * r, int localseg, int * destseg, long * offset); void done_seglocations(segtab * r); - -- cgit v1.2.3