diff options
-rw-r--r-- | output/outrdf2.c | 432 | ||||
-rw-r--r-- | rdoff/Makefile.in | 4 | ||||
-rw-r--r-- | rdoff/Mkfiles/Makefile.dj | 4 | ||||
-rw-r--r-- | rdoff/Mkfiles/Makefile.emx | 4 | ||||
-rw-r--r-- | rdoff/Mkfiles/Makefile.unx | 4 | ||||
-rw-r--r-- | rdoff/README | 2 | ||||
-rw-r--r-- | rdoff/collectn.c | 46 | ||||
-rw-r--r-- | rdoff/collectn.h | 10 | ||||
-rw-r--r-- | rdoff/doc/rdoff.texi | 4 | ||||
-rw-r--r-- | rdoff/hash.c | 1 | ||||
-rw-r--r-- | rdoff/ldrdf.c | 113 | ||||
-rw-r--r-- | rdoff/rdf2bin.c | 5 | ||||
-rw-r--r-- | rdoff/rdf2ihx.c | 9 | ||||
-rw-r--r-- | rdoff/rdfdump.c | 473 | ||||
-rw-r--r-- | rdoff/rdfload.c | 31 | ||||
-rw-r--r-- | rdoff/rdfload.h | 2 | ||||
-rw-r--r-- | rdoff/rdlib.c | 5 | ||||
-rw-r--r-- | rdoff/rdlib.h | 6 | ||||
-rw-r--r-- | rdoff/rdoff.c | 455 | ||||
-rw-r--r-- | rdoff/rdoff.h | 166 | ||||
-rw-r--r-- | rdoff/rdx.c | 11 | ||||
-rw-r--r-- | rdoff/segtab.h | 1 |
22 files changed, 905 insertions, 883 deletions
diff --git a/output/outrdf2.c b/output/outrdf2.c index 931f872..6c7a102 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -1,10 +1,9 @@ -/* outrdf2.c output routines for the Netwide Assembler to produce - * RDOFF version 2 format object files (which are intended - * mainly for use in proprietary projects, as the code to - * load and execute them is very simple). They will also be - * used for device drivers and possibly some executable files - * in the MOSCOW operating system. See Rdoff.txt for - * details. +/* + * outrdf2.c output routines for the Netwide Assembler to produce + * RDOFF version 2 format object files, which is used as a + * main binary format in the RadiOS (http://radios.sf.net). + * Originally Julian planned to use it in his MOSCOW + * operating system. * * The Netwide Assembler is copyright (C) 1996-1998 Simon Tatham and * Julian Hall. All rights reserved. The software is @@ -23,19 +22,15 @@ #include "outform.h" /* VERBOSE_WARNINGS: define this to add some extra warnings... */ -#define VERBOSE_WARNINGS +#define VERBOSE_WARNINGS #ifdef OF_RDF2 -#define RDF_MAXSEGS 64 /* maximum number of segments - user configurable */ - -typedef unsigned short int16; -typedef unsigned char byte; - -static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */ +#include "rdoff/rdoff.h" +/* This signature is written to start of RDOFF files */ +static const char *RDOFF2Id = RDOFF2_SIGNATURE; -/* the records that can be found in the RDOFF header */ /* Note that whenever a segment is referred to in the RDOFF file, its number * is always half of the segment number that NASM uses to refer to it; this @@ -44,86 +39,16 @@ static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */ * allows up to 65533 external labels to be defined; otherwise it would be * 32764. */ -#define RDFREC_RELOC 1 -#define RDFREC_IMPORT 2 -#define RDFREC_GLOBAL 3 -#define RDFREC_DLL 4 -#define RDFREC_BSS 5 -#define RDFREC_SEGRELOC 6 -#define RDFREC_FARIMPORT 7 -#define RDFREC_MODNAME 8 -#define RDFREC_COMMON 10 -#define RDFREC_GENERIC 0 - - -struct RelocRec { - byte type; /* must be 1, or 6 for segment base ref */ - byte reclen; /* set to 8 */ - byte segment; /* only 0 for code, or 1 for data supported, - * but add 64 for relative refs (ie do not require - * 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 */ -}; - -struct ImportRec { - byte type; /* must be 2, or 7 for FAR import */ - byte reclen; /* equals 3+label length */ - byte flags; /* SYM_* flags (see below) */ - int16 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 */ -}; - -struct ExportRec { - byte type; /* must be 3 */ - byte reclen; /* equals 7+label length */ - byte flags; /* SYM_* flags (see below) */ - byte segment; /* segment referred to (0/1) */ - long offset; /* offset within segment */ - char label[33]; /* zero terminated as above. max len = 32 chars */ -}; - -struct BSSRec { - byte type; /* must be 5 */ - byte reclen; /* equals 4 */ - long amount; /* number of bytes BSS to reserve */ -}; - -struct DLLModRec { - byte type; /* 4 for DLLRec, 8 for ModRec */ - byte reclen; /* 1+lib name length for DLLRec, 1+mod name length */ - char name[128]; /* library to link at load time or module name */ -}; - -struct CommonRec { - byte type; /* must be 10 */ - byte reclen; /* equals 9+label length */ - int16 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 */ -}; - -/* Flags for ExportRec */ -#define SYM_DATA 1 -#define SYM_FUNCTION 2 -#define SYM_GLOBAL 4 -#define SYM_IMPORT 8 - #define COUNT_SEGTYPES 9 static char * segmenttypes[COUNT_SEGTYPES] = { - "null", "text", "code", "data", "comment", "lcomment", "pcomment", - "symdebug", "linedebug" + "null", "text", "code", "data", + "comment", "lcomment", "pcomment", + "symdebug", "linedebug" }; static int segmenttypenumbers[COUNT_SEGTYPES] = { - 0, 1, 1, 2, 3, 4, 5, 6, 7 + 0, 1, 1, 2, 3, 4, 5, 6, 7 }; /* code for managing buffers needed to separate code and data into individual @@ -147,11 +72,11 @@ static FILE *ofile; static efunc error; static struct seginfo { - char *segname; - int segnumber; - int16 segtype; - int16 segreserved; - long seglength; + char *segname; + int segnumber; + uint16 segtype; + uint16 segreserved; + long seglength; } segments[RDF_MAXSEGS]; static int nsegments; @@ -290,11 +215,15 @@ static long rdf2_section_names(char *name, int pass, int *bits) return i; } + +/* + * Write relocation record + */ static void write_reloc_rec(struct RelocRec *r) { char buf[4],*b; - if (r->refseg != (int16)NO_SEG && (r->refseg & 1)) /* segment base ref */ + if (r->refseg != (uint16)NO_SEG && (r->refseg & 1)) /* segment base ref */ r->type = RDFREC_SEGRELOC; r->refseg >>= 1; /* adjust segment nos to RDF rather than NASM */ @@ -310,37 +239,45 @@ static void write_reloc_rec(struct RelocRec *r) headerlength += r->reclen + 2; } + +/* + * Write export record + */ static void write_export_rec(struct ExportRec *r) { - char buf[4], *b; + char buf[4], *b; - r->segment >>= 1; + r->segment >>= 1; - saa_wbytes(header,&r->type,1); - saa_wbytes(header,&r->reclen,1); - saa_wbytes(header,&r->flags,1); - saa_wbytes(header,&r->segment,1); - b = buf; WRITELONG(b,r->offset); - saa_wbytes(header,buf,4); - saa_wbytes(header,r->label,strlen(r->label) + 1); - headerlength += r->reclen + 2; + saa_wbytes(header, &r->type, 1); + saa_wbytes(header, &r->reclen, 1); + saa_wbytes(header, &r->flags, 1); + saa_wbytes(header, &r->segment, 1); + b = buf; WRITELONG(b, r->offset); + saa_wbytes(header, buf, 4); + saa_wbytes(header, r->label, strlen(r->label) + 1); + headerlength += r->reclen + 2; } static void write_import_rec(struct ImportRec *r) { - char buf[4], *b; + char buf[4], *b; - r->segment >>= 1; + r->segment >>= 1; - saa_wbytes(header,&r->type,1); - saa_wbytes(header,&r->reclen,1); - saa_wbytes(header,&r->flags,1); - b = buf; WRITESHORT(b,r->segment); - saa_wbytes(header,buf,2); - saa_wbytes(header,r->label,strlen(r->label) + 1); - headerlength += r->reclen + 2; + saa_wbytes(header, &r->type, 1); + saa_wbytes(header, &r->reclen, 1); + saa_wbytes(header, &r->flags, 1); + b = buf; WRITESHORT(b,r->segment); + saa_wbytes(header, buf, 2); + saa_wbytes(header, r->label, strlen(r->label) + 1); + headerlength += r->reclen + 2; } + +/* + * Write BSS record + */ static void write_bss_rec(struct BSSRec *r) { char buf[4], *b; @@ -353,139 +290,160 @@ static void write_bss_rec(struct BSSRec *r) } /* - * Write common variable record. + * Write common variable record */ static void write_common_rec(struct CommonRec *r) { - char buf[4], *b; + char buf[4], *b; - r->segment >>= 1; + r->segment >>= 1; - saa_wbytes(header,&r->type,1); - saa_wbytes(header,&r->reclen,1); - b = buf; WRITESHORT(b,r->segment); - saa_wbytes(header,buf,2); - b = buf; WRITELONG(b,r->size); - saa_wbytes(header,buf,4); - b = buf; WRITESHORT(b,r->align); - saa_wbytes(header,buf,2); - saa_wbytes(header,r->label,strlen(r->label) + 1); - headerlength += r->reclen + 2; + saa_wbytes(header, &r->type, 1); + saa_wbytes(header, &r->reclen, 1); + b = buf; WRITESHORT(b,r->segment); + saa_wbytes(header, buf, 2); + b = buf; WRITELONG(b, r->size); + saa_wbytes(header,buf,4); + b = buf; WRITESHORT(b, r->align); + saa_wbytes(header, buf, 2); + saa_wbytes(header, r->label, strlen(r->label) + 1); + headerlength += r->reclen + 2; +} + +/* + * Write library record + */ +static void write_dll_rec(struct DLLRec *r) +{ + saa_wbytes(header,&r->type,1); + saa_wbytes(header,&r->reclen,1); + saa_wbytes(header, r->libname, strlen(r->libname) + 1); + headerlength += r->reclen + 2; } + /* - * Write library record. Also used for module name records. + * Write module name record */ -static void write_dllmod_rec(struct DLLModRec *r) +static void write_modname_rec(struct ModRec *r) { saa_wbytes(header,&r->type,1); saa_wbytes(header,&r->reclen,1); - saa_wbytes(header,r->name,strlen(r->name) + 1); + saa_wbytes(header, r->modname, strlen(r->modname) + 1); headerlength += r->reclen + 2; } + +/* + * Handle export, import and common records. + */ static void rdf2_deflabel(char *name, long segment, long offset, int is_global, char *special) { - struct ExportRec r; - struct ImportRec ri; - struct CommonRec ci; - static int farsym = 0; - static int i; - byte symflags = 0; - - if (is_global == 2) { - /* Common variable */ - ci.type = RDFREC_COMMON; - ci.size = offset; - ci.segment = segment; - strncpy(ci.label, name, 32); - ci.label[32] = 0; - ci.reclen = 9 + strlen(ci.label); - ci.align = 0; + struct ExportRec r; + struct ImportRec ri; + struct CommonRec ci; + static int farsym = 0; + static int i; + byte symflags = 0; + int len; + + /* Check if the label length is OK */ + if ((len = strlen(name)) >= EXIM_LABEL_MAX) { + error(ERR_NONFATAL, "label size exceeds %d bytes", EXIM_LABEL_MAX); + return; + } + if (!len) { + error(ERR_NONFATAL, "zero-length label"); + return; + } + + if (is_global == 2) { + /* Common variable */ + ci.type = RDFREC_COMMON; + ci.size = offset; + ci.segment = segment; + strcpy(ci.label, name); + ci.reclen = 9 + len; + ci.align = 0; - /* - * Check the special text to see if it's a valid number and power - * of two; if so, store it as the alignment for the common variable. - */ - if (special) { - int err; - ci.align = readnum(special, &err); - if (err) error(ERR_NONFATAL, "alignment constraint `%s' is not a" - " valid number", special); - else if ( (ci.align | (ci.align-1)) != 2*ci.align - 1) - error(ERR_NONFATAL, "alignment constraint `%s' is not a" - " power of two", special); - } - write_common_rec(&ci); - } + /* + * Check the special text to see if it's a valid number and power + * of two; if so, store it as the alignment for the common variable. + */ + if (special) { + int err; + ci.align = readnum(special, &err); + if (err) + error(ERR_NONFATAL, "alignment constraint `%s' is not a" + " valid number", special); + else if ( (ci.align | (ci.align-1)) != 2*ci.align - 1) + error(ERR_NONFATAL, "alignment constraint `%s' is not a" + " power of two", special); + } + write_common_rec(&ci); + } - /* We don't care about local labels or fix-up hints */ - if (is_global != 1) return; + /* We don't care about local labels or fix-up hints */ + if (is_global != 1) return; - if (special) { - while(*special == ' ' || *special == '\t') special++; + if (special) { + while(*special == ' ' || *special == '\t') special++; - if (!nasm_strnicmp(special, "export", 6)) { - special += 6; - symflags |= SYM_GLOBAL; - } - else if (!nasm_strnicmp(special, "import", 6)) { - special += 6; - symflags |= SYM_IMPORT; + if (!nasm_strnicmp(special, "export", 6)) { + special += 6; + symflags |= SYM_GLOBAL; + } else if (!nasm_strnicmp(special, "import", 6)) { + special += 6; + symflags |= SYM_IMPORT; + } + + if (*special) { + while (isspace(*special)) special++; + if (!nasm_stricmp(special, "far")) { + farsym = 1; + } else if (!nasm_stricmp(special, "near")) { + farsym = 0; + } else if (!nasm_stricmp(special, "proc") || + !nasm_stricmp(special, "function")) { + symflags |= SYM_FUNCTION; + } else if (!nasm_stricmp(special, "data") || + !nasm_stricmp(special, "object")) { + symflags |= SYM_DATA; + } else + error(ERR_NONFATAL, "unrecognised symbol type `%s'", special); + } } - if (*special) { - while(isspace(*special)) special++; - if (!nasm_stricmp(special, "far")) { - farsym = 1; - } - else if (!nasm_stricmp(special, "near")) { - farsym = 0; - } - else if (!nasm_stricmp(special, "proc") || - !nasm_stricmp(special, "function")) { - symflags |= SYM_FUNCTION; - } - else if (!nasm_stricmp(special, "data") || - !nasm_stricmp(special, "object")) { - symflags |= SYM_DATA; - } - else - error(ERR_NONFATAL, "unrecognised symbol type `%s'", special); - } - } + if (name[0] == '.' && name[1] == '.' && name[2] != '@') { + error (ERR_NONFATAL, "unrecognised special symbol `%s'", name); + return; + } - if (name[0] == '.' && name[1] == '.' && name[2] != '@') { - error (ERR_NONFATAL, "unrecognised special symbol `%s'", name); - return; - } + for (i = 0; i < nsegments; i++) { + if (segments[i].segnumber == segment>>1) break; + } - for (i = 0; i < nsegments; i++) { - if (segments[i].segnumber == segment>>1) break; - } - if (i >= nsegments) { /* EXTERN declaration */ - ri.type = farsym ? RDFREC_FARIMPORT : RDFREC_IMPORT; - if (symflags & SYM_GLOBAL) - error(ERR_NONFATAL, "symbol type conflict - EXTERN cannot be EXPORT"); - ri.flags = symflags; - ri.segment = segment; - strncpy(ri.label,name,32); - ri.label[32] = 0; - ri.reclen = 4 + strlen(ri.label); - write_import_rec(&ri); - } else if (is_global) { - r.type = RDFREC_GLOBAL; - if (symflags & SYM_IMPORT) - error(ERR_NONFATAL, "symbol type conflict - GLOBAL cannot be IMPORT"); - r.flags = symflags; - r.segment = segment; - r.offset = offset; - strncpy(r.label,name,32); - r.label[32] = 0; - r.reclen = 7 + strlen(r.label); - write_export_rec(&r); - } + if (i >= nsegments) { /* EXTERN declaration */ + ri.type = farsym ? RDFREC_FARIMPORT : RDFREC_IMPORT; + if (symflags & SYM_GLOBAL) + error(ERR_NONFATAL, "symbol type conflict - EXTERN cannot be EXPORT"); + ri.flags = symflags; + ri.segment = segment; + strcpy(ri.label, name); + ri.reclen = 4 + len; + write_import_rec(&ri); + } else if (is_global) { + r.type = RDFREC_GLOBAL; /* GLOBAL declaration */ + if (symflags & SYM_IMPORT) + error(ERR_NONFATAL, "symbol type conflict - GLOBAL cannot be IMPORT"); + r.flags = symflags; + r.segment = segment; + r.offset = offset; + strcpy(r.label, name); + r.reclen = 7 + len; + write_export_rec(&r); + } } static void membufwrite(int segment, const void * data, int bytes) @@ -681,8 +639,7 @@ static void rdf2_cleanup (int debuginfo) { /* generate the output file... */ fwrite(RDOFF2Id,6,1,ofile); /* file type magic number */ - if (bsslength != 0) /* reserve BSS */ - { + if (bsslength != 0) { /* reserve BSS */ bs.type = RDFREC_BSS; bs.amount = bsslength; bs.reclen = 4; @@ -730,25 +687,38 @@ static long rdf2_segbase (long segment) { return segment; } -static int rdf2_directive (char *directive, char *value, int pass) { - struct DLLModRec r; + +/* + * Handle RDOFF2 specific directives + */ +static int rdf2_directive (char *directive, char *value, int pass) +{ + int n; + + /* Check if the name length is OK */ + if ((n = strlen(value)) >= MODLIB_NAME_MAX) { + error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); + return 0; + } if (! strcmp(directive, "library")) { if (pass == 1) { + struct DLLRec r; r.type = RDFREC_DLL; - r.reclen=strlen(value)+1; - strcpy(r.name, value); - write_dllmod_rec(&r); + r.reclen = n+1; + strcpy(r.libname, value); + write_dll_rec(&r); } return 1; } if (! strcmp(directive, "module")) { if (pass == 1) { + struct ModRec r; r.type = RDFREC_MODNAME; - r.reclen=strlen(value)+1; - strcpy(r.name, value); - write_dllmod_rec(&r); + r.reclen = n+1; + strcpy(r.modname, value); + write_modname_rec(&r); } return 1; } 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 <yuriz@ukr.net> - primary maintainer +Yuri Zaporogets <yuriz@users.sf.net> - primary maintainer Julian Hall <jules@dsf.org.uk> - 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 <stdlib.h> #include <string.h> +#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 <stdlib.h> #include <stdio.h> #include <string.h> #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 <stdlib.h> #include <stdio.h> #include <string.h> #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 <stdlib.h> #include <string.h> -#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] <filename>\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] <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); } - 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 <stdlib.h> #include <string.h> +#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 <stdlib.h> #include <string.h> #include <errno.h> + +#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;i<max;i++){\ RI8(str[i]); if (!str[i]) break;} str[i]=0; } +/* + * Read a header record. + * Returns the address of record, or NULL in case of error. + */ rdfheaderrec *rdfgetheaderrec(rdffile *f) { - static rdfheaderrec r; - int i; - - if (!f->header_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 <stdlib.h> #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 <rdoff-executable> [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); - |