summaryrefslogtreecommitdiff
path: root/rdoff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:08 +0000
committerH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:08 +0000
commitd7ed89eac9580f280fe0017b22c8e38ca75ed8e3 (patch)
tree98c4fcdd286b44e14f79aa65271e5caa1c2c7be4 /rdoff
parentea8382740dbe5e1607742d0a7c7c139dffcc5ae5 (diff)
downloadnasm-d7ed89eac9580f280fe0017b22c8e38ca75ed8e3.tar.gz
nasm-d7ed89eac9580f280fe0017b22c8e38ca75ed8e3.tar.bz2
nasm-d7ed89eac9580f280fe0017b22c8e38ca75ed8e3.zip
NASM 0.94
Diffstat (limited to 'rdoff')
-rw-r--r--rdoff/Makefile26
-rw-r--r--rdoff/README85
-rw-r--r--rdoff/collectn.h2
-rw-r--r--rdoff/ldrdf.c362
-rw-r--r--rdoff/rdf.doc99
-rw-r--r--rdoff/rdf2bin.c125
-rw-r--r--rdoff/rdfdump.c32
-rw-r--r--rdoff/rdflib.c235
-rw-r--r--rdoff/rdfload.c12
-rw-r--r--rdoff/rdlib.c88
-rw-r--r--rdoff/rdlib.h18
-rw-r--r--rdoff/rdoff.c52
-rw-r--r--rdoff/rdoff.h8
-rw-r--r--rdoff/rdoff.txt114
-rw-r--r--rdoff/symtab.c2
15 files changed, 1029 insertions, 231 deletions
diff --git a/rdoff/Makefile b/rdoff/Makefile
index 2e55dde..78eca4e 100644
--- a/rdoff/Makefile
+++ b/rdoff/Makefile
@@ -9,19 +9,19 @@
# portably).
CC = gcc
-CCFLAGS = -c -O -g -Wall -ansi -pedantic -I..
+CCFLAGS = -c -g -Wall -ansi -pedantic -I..
LINK = gcc
-LINKFLAGS = -o
+LINKFLAGS = -g -o
DLINKFLAGS = -o
-LIBRARIES =
+LIBRARIES =
STRIP = strip
-LDRDFLIBS = rdoff.o ../nasmlib.o symtab.o collectn.o
+LDRDFLIBS = rdoff.o ../nasmlib.o symtab.o collectn.o rdlib.o
RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o
.c.o:
$(CC) $(CCFLAGS) $*.c
-all : rdfdump ldrdf rdx
+all : rdfdump ldrdf rdx rdflib rdf2bin rdf2com
rdfdump : rdfdump.o
$(LINK) $(LINKFLAGS) rdfdump rdfdump.o
@@ -29,15 +29,25 @@ ldrdf : ldrdf.o $(LDRDFLIBS)
$(LINK) $(LINKFLAGS) ldrdf ldrdf.o $(LDRDFLIBS)
rdx : rdx.o $(RDXLIBS)
$(LINK) $(LINKFLAGS) rdx rdx.o $(RDXLIBS)
+rdflib : rdflib.o
+ $(LINK) $(LINKFLAGS) rdflib rdflib.o
+rdf2bin : rdf2bin.o $(RDXLIBS) ../nasmlib.o
+ $(LINK) $(LINKFLAGS) rdf2bin rdf2bin.o $(RDXLIBS) ../nasmlib.o
+rdf2com :
+ ln -s rdf2bin rdf2com
+rdf2bin.o : rdf2bin.c
rdfdump.o : rdfdump.c
rdoff.o : rdoff.c rdoff.h
-ldrdf.o : ldrdf.c rdoff.h ../nasmlib.h symtab.h collectn.h
+ldrdf.o : ldrdf.c rdoff.h ../nasmlib.h symtab.h collectn.h rdlib.h
symtab.o : symtab.c symtab.h
collectn.o : collectn.c collectn.h
rdx.o : rdx.c rdoff.h rdfload.h symtab.h
rdfload.o : rdfload.c rdfload.h rdoff.h collectn.h symtab.h
+rdlib.o : rdlib.c rdlib.h
+rdflib.o : rdflib.c
clean :
- rm -f *.o *~ rdfdump ldrdf rdx
- make -C test clean
+ rm -f *.o *~ rdfdump ldrdf rdx rdflib rdf2bin
+
+
diff --git a/rdoff/README b/rdoff/README
new file mode 100644
index 0000000..54f3b2a
--- /dev/null
+++ b/rdoff/README
@@ -0,0 +1,85 @@
+RDOFF Utils v0.2
+================
+
+The files contained in this directory are the C source code of a set
+of tools (and general purpose library files) for the manipulation of
+RDOFF version 1 object files. Here is a brief summary of their usage:
+
+rdfdump
+=======
+
+This tool prints a list of the header records in an RDOFF object in
+human-readable form, and optionally prints a hex dump of the contents
+of the code and data segments.
+
+Usage:
+ rdfdump [-v] filename
+
+The -v flag specifies that the hex dump (see above) should be printed.
+
+ldrdf
+=====
+
+This tool is a version of unix 'ld' (or DOS 'link') for use with RDOFF
+files. It is capable of linking RDOFF objects, and libraries produced
+with the 'rdlib' utility discussed below.
+
+In normal usage, its command line takes the form:
+
+ ldrdf [-o output-file] object files [-llibrary ...]
+
+Libraries must be specified with their path as no search is performed.
+Modules in libraries are not linked to the program unless they are
+referred to.
+
+Most of its options are not implemented, but those that are are listed here:
+
+ -v increase verbosity level. Currently 4 verbosity levels are
+ available: default (which only prints error information), normal
+ (which prints information about the produced object, -v), medium
+ (which prints information about what the program is doing, -v -v)
+ and high (which prints all available information, -v -v -v).
+
+ -p change alignment value to which multiple segments combigned into
+ a single segment should be aligned (must be either 1, 2, 4, 8,
+ 16, 32 or 256. Default is 16).
+
+The default output filename is 'aout.rdx'.
+
+rdx
+===
+
+This program simply loads and executes an RDOFF object, by calling
+'_main', which it expects to be a C-style function, which will accept
+two parameters, argc and argv in normal C style.
+
+rdflib
+======
+
+This program creates a library file for use with ldrdf.
+
+It is supplied with a shell script 'makelib' which should probably be used
+to create libraries.
+
+Usage:
+ rdflib command library [optional arguments]
+
+Valid commands are:
+
+ c Create the library
+ a Add a module (requires a filename and a name to give the
+ module, ie 'rdflib a libc.rdl strcpy.rdf strcpy' puts the
+ file 'strcpy.rdf' into 'libc.rdl', and calls it 'strcpy'.
+ x Extract (arguments are the opposite to the 'a' command,
+ ie you'd do 'rdflib x libc.rdl strcpy strcpy.rdf to get
+ a copy of strcpy.rdf back out again...)
+
+Remove and List commands will be added soon (they're already documented
+as existing, but I haven't had time to implement them... if anyone
+else wants to do this, they're welcome to. The file format should be
+amply documented in the source code... look at 'rdflib.c' and 'rdlib.c',
+and the relevant sections of 'ldrdf.c' to see how libraries can be
+handled).
+
+Julian Hall (jules@dcs.warwick.ac.uk)
+
diff --git a/rdoff/collectn.h b/rdoff/collectn.h
index b3f2d52..2dc786e 100644
--- a/rdoff/collectn.h
+++ b/rdoff/collectn.h
@@ -10,7 +10,7 @@
typedef struct tagCollection {
void *p[32]; /* array of pointers to objects */
-
+
struct tagCollection *next;
} Collection;
diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c
index ce86b7e..e2541fa 100644
--- a/rdoff/ldrdf.c
+++ b/rdoff/ldrdf.c
@@ -11,21 +11,27 @@
* May require the system to make an extra pass of the modules to be
* loaded eliminating those that aren't required.
*
+ * Support all the existing documented options...
+ *
* Support libaries (.a files - requires a 'ranlib' type utility)
+ * (I think I've got this working, so I've upped the version)
*
- * -s option to strip resolved symbols from exports.
+ * -s option to strip resolved symbols from exports. (Could make this an
+ * external utility)
*/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "nasm.h"
#include "rdoff.h"
#include "nasmlib.h"
#include "symtab.h"
#include "collectn.h"
+#include "rdlib.h"
-#define LDRDF_VERSION "0.11"
+#define LDRDF_VERSION "0.30"
/* global variables - those to set options: */
@@ -46,8 +52,17 @@ struct modulenode {
struct modulenode *next;
};
+#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
+#define newstrcat(s1,s2) strcat(strcpy(malloc(strlen(s1)+strlen(s2)+1),s1),s2)
+
+
struct modulenode *modules = NULL,*lastmodule = NULL;
+/* the linked list of libraries to be searched for missing imported
+ symbols */
+
+struct librarynode * libraries = NULL, * lastlib = NULL;
+
void *symtab; /* The symbol table */
rdf_headerbuf * newheader ; /* New header to be written to output */
@@ -101,6 +116,218 @@ void loadmodule(char *filename)
lastmodule->coderel,lastmodule->f.code_len,
lastmodule->datarel,lastmodule->f.data_len);
+ lastmodule->header = malloc(lastmodule->f.header_len);
+ if (!lastmodule->header) {
+ fprintf(stderr,"ldrdf: out of memory\n");
+ exit(1);
+ }
+
+ if (rdfloadseg(&lastmodule->f,RDOFF_HEADER,lastmodule->header))
+ {
+ rdfperror("ldrdf",filename);
+ exit(1);
+ }
+}
+
+/* load_library add a library to list of libraries to search
+ * for undefined symbols
+ */
+
+void load_library(char * name)
+{
+ if (verbose)
+ printf("adding library %s to search path\n",name);
+
+ if (! lastlib) {
+ lastlib = libraries = malloc(sizeof(struct librarynode));
+ }
+ else
+ {
+ lastlib->next = malloc(sizeof(struct librarynode));
+ lastlib = lastlib->next;
+ }
+
+ if (! lastlib) {
+ fprintf(stderr, "ldrdf: out of memory\n");
+ exit(1);
+ }
+ strcpy (lastlib->name = malloc (1+strlen(name)), name);
+ lastlib->fp = NULL;
+ lastlib->referenced = 0;
+ lastlib->next = NULL;
+}
+
+
+/* build_symbols() step through each module's header, and locate
+ * exported symbols, placing them in a global table
+ */
+
+long bsslength;
+
+void mod_addsymbols(struct modulenode * mod)
+{
+ rdfheaderrec *r;
+ symtabEnt e;
+ long cbBss;
+
+ mod->bssrel = bsslength;
+ cbBss = 0;
+ rdfheaderrewind(&mod->f);
+ while ((r = rdfgetheaderrec(&mod->f)))
+ {
+
+ if (r->type == 5) /* Allocate BSS */
+ cbBss += r->b.amount;
+
+ if (r->type != 3) continue; /* ignore all but export recs */
+
+ e.segment = r->e.segment;
+ e.offset = r->e.offset +
+ (e.segment == 0 ? mod->coderel : /* 0 -> code */
+ e.segment == 1 ? mod->datarel : /* 1 -> data */
+ mod->bssrel) ; /* 2 -> bss */
+
+ e.flags = 0;
+ e.name = malloc(strlen(r->e.label) + 1);
+ if (! e.name)
+ {
+ fprintf(stderr,"ldrdf: out of memory\n");
+ exit(1);
+ }
+ strcpy(e.name,r->e.label);
+ symtabInsert(symtab,&e);
+ }
+ bsslength += cbBss;
+}
+
+void build_symbols()
+{
+ struct modulenode *mod;
+
+ if (verbose) printf("building global symbol table:\n");
+ newheader = rdfnewheader();
+
+ symtab = symtabNew();
+ bsslength = 0; /* keep track of location of BSS symbols */
+
+ for (mod = modules; mod; mod = mod->next)
+ {
+ mod_addsymbols( mod );
+ }
+ if (verbose)
+ {
+ symtabDump(symtab,stdout);
+ printf("BSS length = %ld bytes\n\n",bsslength);
+ }
+}
+
+
+/* scan_libraries() search through headers of modules for undefined
+ * symbols, and scan libraries for those symbols,
+ * adding library modules found to list of modules
+ * to load. */
+
+void scan_libraries(void)
+{
+ struct modulenode * mod, * nm;
+ struct librarynode * lib;
+ rdfheaderrec * r;
+ int found;
+ char * tmp;
+
+ if (verbose) printf("Scanning libraries for unresolved symbols...\n");
+
+ mod = modules;
+
+ while (mod)
+ {
+ rdfheaderrewind(&mod->f);
+
+ while ((r = rdfgetheaderrec(&mod->f)))
+ {
+ if (r->type != 2) continue; /* not an import record */
+ if ( symtabFind (symtab,r->i.label) )
+ continue; /* symbol already defined */
+
+ /* okay, we have an undefined symbol... step through
+ the libraries now */
+ if (verbose >= 2) {
+ printf("undefined symbol '%s'...",r->i.label);
+ fflush(stdout);
+ }
+
+ lib = libraries;
+ found = 0;
+
+ tmp = newstr(r->i.label);
+ while (! found && lib)
+ {
+ /* move this to an outer loop...! */
+ nm = malloc(sizeof(struct modulenode));
+
+ if (rdl_searchlib(lib,tmp,&nm->f))
+ { /* found a module in the library */
+
+ /* create a modulenode for it */
+
+ if (! nm) {
+ fprintf(stderr,"ldrdf: out of memory\n");
+ exit(1);
+ }
+
+ nm->name = newstrcat(lib->name,nm->f.name);
+ if (verbose >= 2) printf("found in '%s'\n",nm->name);
+
+ nm->coderel = lastmodule->coderel + lastmodule->f.code_len;
+ if (nm->coderel % align != 0)
+ nm->coderel += align - (nm->coderel % align);
+
+ nm->datarel = lastmodule->datarel + lastmodule->f.data_len;
+ if (nm->datarel % align != 0)
+ nm->datarel += align - (nm->datarel % align);
+
+ nm->header = malloc(nm->f.header_len);
+ if (! nm->header)
+ {
+ fprintf(stderr,"ldrdf: out of memory\n");
+ exit(1);
+ }
+
+ if (rdfloadseg(&nm->f,RDOFF_HEADER,nm->header))
+ {
+ rdfperror("ldrdf",nm->name);
+ exit(1);
+ }
+
+ nm->next = NULL;
+ found = 1;
+ lastmodule->next = nm;
+ lastmodule = nm;
+
+ if (verbose)
+ printf("%s code = %08lx (+%04lx), data = %08lx "
+ "(+%04lx)\n",lastmodule->name,
+ lastmodule->coderel,lastmodule->f.code_len,
+ lastmodule->datarel,lastmodule->f.data_len);
+
+ /* add the module's info to the symbol table */
+ mod_addsymbols(nm);
+ }
+ else
+ {
+ if (rdl_error) {
+ rdl_perror("ldrdf",lib->name);
+ exit(1);
+ }
+ free(nm);
+ }
+ lib = lib->next;
+ }
+ free(tmp);
+ if (!found && verbose >= 2) printf("not found\n");
+ }
+ mod = mod->next;
+ }
}
/* load_segments() allocates memory for & loads the code & data segs
@@ -108,7 +335,7 @@ void loadmodule(char *filename)
*/
char *text,*data;
-long textlength,datalength,bsslength;
+long textlength,datalength;
void load_segments(void)
{
@@ -150,77 +377,17 @@ void load_segments(void)
mod = modules;
while (mod) { /* load the segments for each module */
- mod->header = malloc(mod->f.header_len);
- if (!mod->header) {
- fprintf(stderr,"ldrdf: out of memory\n");
- exit(1);
- }
- if (rdfloadseg(&mod->f,RDOFF_HEADER,mod->header) ||
- rdfloadseg(&mod->f,RDOFF_CODE,&text[mod->coderel]) ||
- rdfloadseg(&mod->f,RDOFF_DATA,&data[mod->datarel])) {
- rdfperror("ldrdf",mod->name);
- exit(1);
- }
- rdfclose(&mod->f); /* close file; segments remain */
- mod = mod->next;
- }
-}
-
-/* build_symbols() step through each module's header, and locate
- * exported symbols, placing them in a global table
- */
-
-void build_symbols()
-{
- struct modulenode *mod;
- rdfheaderrec *r;
- symtabEnt e;
- long bssloc,cbBss;
-
- if (verbose) printf("building global symbol table:\n");
- newheader = rdfnewheader();
-
- symtab = symtabNew();
- bssloc = 0; /* keep track of location of BSS symbols */
-
- for (mod = modules; mod; mod = mod->next)
- {
- mod->bssrel = bssloc;
- cbBss = 0;
- rdfheaderrewind(&mod->f);
- while ((r = rdfgetheaderrec(&mod->f)))
- {
-
- if (r->type == 5) /* Allocate BSS */
- cbBss += r->b.amount;
-
- if (r->type != 3) continue; /* ignore all but export recs */
-
- e.segment = r->e.segment;
- e.offset = r->e.offset +
- (e.segment == 0 ? mod->coderel : /* 0 -> code */
- e.segment == 1 ? mod->datarel : /* 1 -> data */
- mod->bssrel) ; /* 2 -> bss */
- e.flags = 0;
- e.name = malloc(strlen(r->e.label) + 1);
- if (! e.name)
- {
- fprintf(stderr,"ldrdf: out of memory\n");
- exit(1);
- }
- strcpy(e.name,r->e.label);
- symtabInsert(symtab,&e);
+ if (verbose >= 2) printf(" loading %s\n",mod->name);
+ if (rdfloadseg(&mod->f,RDOFF_CODE,&text[mod->coderel]) ||
+ rdfloadseg(&mod->f,RDOFF_DATA,&data[mod->datarel])) {
+ rdfperror("ldrdf",mod->name);
+ exit(1);
}
- bssloc += cbBss;
+ rdfclose(&mod->f); /* close file; segments remain */
+ mod = mod->next;
}
- if (verbose)
- {
- symtabDump(symtab,stdout);
- printf("BSS length = %ld bytes\n\n",bssloc);
- }
- bsslength = bssloc;
}
-
+
/* link_segments() step through relocation records in each module's
* header, fixing up references.
*/
@@ -230,7 +397,7 @@ void link_segments(void)
struct modulenode *mod;
Collection imports;
symtabEnt *s;
- long rel,relto = 0; /* placate gcc */
+ long rel,relto;
char *seg;
rdfheaderrec *r;
int bRelative;
@@ -243,6 +410,7 @@ void link_segments(void)
if (verbose >= 2) printf("* processing %s\n",mod->name);
rdfheaderrewind(&mod->f);
while((r = rdfgetheaderrec(&mod->f))) {
+ if (verbose >= 3) printf("record type: %d\n",r->type);
switch(r->type) {
case 1: /* relocation record */
if (r->r.segment >= 64) { /* Relative relocation; */
@@ -275,19 +443,19 @@ void link_segments(void)
break;
}
rel = s->offset;
-
- r->r.refseg = s->segment; /* change referred segment,
+
+ r->r.refseg = s->segment; /* change referred segment,
so that new header is
correct */
}
if (bRelative) /* Relative - subtract current segment start */
- rel -= relto;
- else
+ rel -= relto;
+ else
{ /* Add new relocation header */
rdfaddheader(newheader,r);
}
-
+
/* Work out which segment we're making changes to ... */
if (r->r.segment == 0) seg = text;
else if (r->r.segment == 1) seg = data;
@@ -326,7 +494,7 @@ void link_segments(void)
r->i.label,mod->name);
errors = 1;
}
- else
+ else
{
*colln(&imports,r->i.segment - 2) = s;
if (verbose >= 2)
@@ -336,8 +504,11 @@ void link_segments(void)
case 3: /* export; dump to output new version */
s = symtabFind(symtab, r->e.label);
- if (! s) continue; /* eh? probably doesn't matter... */
-
+ if (! s) {
+ fprintf(stderr,"ldrdf: internal error - undefined symbol %s "
+ "exported in header of '%s'\n",r->e.label,mod->name);
+ continue;
+ }
r->e.offset = s->offset;
rdfaddheader(newheader,r);
break;
@@ -347,10 +518,14 @@ void link_segments(void)
break;
}
}
+ if (rdf_errno != 0) {
+ rdfperror("ldrdf",mod->name);
+ exit(1);
+ }
collection_reset(&imports);
}
}
-
+
/* write_output() write linked program out to a file */
void write_output(char *filename)
@@ -358,14 +533,16 @@ void write_output(char *filename)
FILE * fp;
rdfheaderrec r;
+ if (verbose) printf("writing output to '%s'\n",filename);
+
fp = fopen(filename,"wb");
if (! fp)
{
fprintf(stderr,"ldrdf: could not open '%s' for writing\n",filename);
exit(1);
}
-
-
+
+
/* add BSS length count to header... */
if (bsslength)
{
@@ -412,7 +589,8 @@ void write_output(char *filename)
*/
const char *usagemsg = "usage:\n"
-" ldrdf [-o outfile | -x] [-a x] [-v] [-p x] [--] infile [infile ...]\n\n"
+" ldrdf [-o outfile | -x] [-a x] [-v] [-p x] [--] infile [infile ...]\n"
+" [-l<libname> ...]\n\n"
" ldrdf -h displays this message\n"
" ldrdf -r displays version information\n\n"
" -o selects output filename (default is aout.rdx)\n"
@@ -420,7 +598,9 @@ const char *usagemsg = "usage:\n"
" -a x causes object program to be statically relocated to address 'x'\n"
" -v turns on verbose mode\n"
" -p x causes segments to be aligned (padded) to x byte boundaries\n"
-" (default is 16 bytes)\n";
+" (default is 16 bytes)\n"
+" -l<name> causes 'name' to be linked in as a library. Note no search is\n"
+" performed - the entire pathname MUST be specified.\n";
void usage(void)
{
@@ -499,6 +679,9 @@ int main(int argc,char **argv)
}
if (verbose > 1) printf("alignment %d selected\n",align);
}
+ else if (procsw && !strncmp(*argv,"-l",2)) {
+ load_library(*argv + 2);
+ }
else if (procsw && !strcmp(*argv,"--")) {
procsw = 0;
}
@@ -512,12 +695,15 @@ int main(int argc,char **argv)
unreferenced modules from the list of modules here, so that
we know about the final size once libraries have been linked in */
+ build_symbols(); /* build a global symbol table... */
+
+ scan_libraries(); /* check for imported symbols not in table,
+ and ensure the relevant library modules
+ are loaded */
+
load_segments(); /* having calculated size of reqd segments, load
each rdoff module's segments into memory */
- build_symbols(); /* build a global symbol table...
- perhaps this should be done before load_segs? */
-
link_segments(); /* step through each module's header, and resolve
references to the global symbol table.
This also does local address fixups. */
diff --git a/rdoff/rdf.doc b/rdoff/rdf.doc
deleted file mode 100644
index 300c2bc..0000000
--- a/rdoff/rdf.doc
+++ /dev/null
@@ -1,99 +0,0 @@
-RDOFF: Relocatable Dynamically-linked Object File Format
-========================================================
-
-RDOFF was designed initially to test the object-file production
-interface to NASM. It soon became apparent that it could be enhanced
-for use in serious applications due to its simplicity; code to load
-and execute an RDOFF object module is very simple. It also contains
-enhancements to allow it to be linked with a dynamic link library at
-either run- or load- time, depending on how complex you wish to make
-your loader.
-
-The RDOFF format (version 1.1, as produced by NASM v0.91) is defined
-as follows:
-
-The first six bytes of the file contain the string 'RDOFF1'. Other
-versions of the format may contain other last characters other than
-'1' - all little endian versions of the file will always contain an
-ASCII character with value greater than 32. If RDOFF is used on a
-big-endian machine at some point in the future, the version will be
-encoded in decimal rather than ASCII, so will be below 32.
-
-All multi-byte fields follwing this are encoded in either little- or
-big-endian format depending on the system described by this version
-information. Object files should be encoded in the endianness of
-their target machine; files of incorrect endianness will be rejected
-by the loader - this means that loaders do not need to convert
-endianness, as RDOFF has been designed with simplicity of loading at
-the forefront of the design requirements.
-
-The next 4 byte field is the length of the header in bytes. The
-header consists of a sequence of variable length records. Each
-record's type is identified by the first byte of the record. Record
-types 1-4 are currently supported. Record type 5 will be added in
-the near future, when I implement BSS segments. Record type 6 may be
-to do with debugging, when I get debugging implemented.
-
-Type 1: Relocation
-==================
-
-Offset Length Description
-0 1 Type (contains 1)
-1 1 Segment that contains reference (0 = text, 1 = data)
- Add 64 to this number to indicate a relative linkage
- to an external symbol (see notes)
-2 4 Offset of reference
-6 1 Length of reference (1,2 or 4 bytes)
-7 2 Segment to which reference is made (0 = text, 1 =
- data, 2 = BSS [when implemented]) others are external
- symbols.
-
-Total length = 9 bytes
-
-Type 2: Symbol Import
-=====================
-
-0 1 Type (2)
-1 2 Segment number that will be used in references to this
- symbol.
-3 ? Null terminated string containing label (up to 32
- chars) to match against exports in linkage.
-
-Type 3: Symbol Export
-=====================
-
-0 1 Type (3)
-1 1 Segment containing object to be exported (0/1/2)
-2 4 Offset within segment
-6 ? Null terminate string containing label to export (32
- char maximum length)
-
-Type 4: Dynamic Link Library
-============================
-
-0 1 Type (4)
-1 ? Library name (up to 128 chars)
-
-Type 5: Reserve BSS
-===================
-
-0 1 Type (5)
-1 4 Amount of BSS space to reserve in bytes
-
-Total length: 5 bytes
-
------------------------------------------------------------------------------
-
-Following the header is the text (code) segment. This is preceded by
-a 4-byte integer, which is its length in bytes. This is followed by
-the length of the data segment (also 4 bytes), and finally the data
-segment.
-
-Notes
-=====
-
-Relative linking: The number stored at the address is offset
-required from the imported symbol, with the address of the end of
-the instruction subtracted from it. This means that the linker can
-simply add the address of the label relative to the beginning of the
-current segment to it.
diff --git a/rdoff/rdf2bin.c b/rdoff/rdf2bin.c
new file mode 100644
index 0000000..97b45b4
--- /dev/null
+++ b/rdoff/rdf2bin.c
@@ -0,0 +1,125 @@
+/* rdf2bin: 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;
+int align = 16;
+
+char *getfilename(char * pathname)
+{
+ char * lastslash = pathname - 1;
+ char * i = pathname;
+
+ while ( *i ) {
+ if (*i == '/') lastslash = i;
+ i++;
+ }
+ return lastslash + 1;
+}
+
+int main(int argc, char **argv)
+{
+ rdfmodule * m;
+ int tmp;
+ FILE *of;
+ char * padding;
+ int codepad, datapad;
+
+ if (argc < 2) {
+ puts("Usage: rdf2bin [-o relocation-origin] [-p segment-alignment] "
+ "input-file output-file");
+ puts(" rdf2com [-p segment-alignment] input-file output-file");
+ return 1;
+ }
+
+ if (! nasm_stricmp(getfilename(*argv),"rdf2com")) {
+ origin = 0x100;
+ }
+ argv++, argc--;
+
+ while (argc > 2) {
+ if (! strcmp(*argv,"-o")) {
+ argv++, argc--;
+ origin = readnum(*argv, &tmp);
+ if (tmp) {
+ fprintf(stderr,"rdf2bin: invalid parameter: %s\n",*argv);
+ return 1;
+ }
+ } else if (! strcmp(*argv,"-p")) {
+ argv++, argc--;
+ align = readnum(*argv, &tmp);
+ if (tmp) {
+ fprintf(stderr,"rdf2bin: invalid parameter: %s\n",*argv);
+ return 1;
+ }
+ } else
+ break;
+
+ argv++, argc--;
+ }
+ if (argc < 2) {
+ puts("rdf2bin: required parameter missing");
+ return -1;
+ }
+ m = rdfload(*argv);
+
+ if (! m)
+ {
+ rdfperror("rdf2bin",*argv);
+ return 1;
+ }
+ printf("relocating %s: origin=%lx, align=%d\n",*argv,origin,align);
+
+ m->textrel = origin;
+ m->datarel = origin + m->f.code_len;
+ if (m->datarel % align != 0) {
+ codepad = align - (m->datarel % align);
+ m->datarel += codepad;
+ }
+ else
+ codepad = 0;
+
+ m->bssrel = m->datarel + m->f.data_len;
+ if (m->bssrel % align != 0) {
+ datapad = align - (m->bssrel % align);
+ m->bssrel += datapad;
+ }
+ else
+ datapad = 0;
+
+ printf("code: %08lx\ndata: %08lx\nbss: %08lx\n",
+ m->textrel, m->datarel, m->bssrel);
+
+ rdf_relocate(m);
+
+ argv++;
+
+ of = fopen(*argv,"wb");
+ if (!of) {
+ fprintf(stderr,"rdf2bin: could not open output file %s\n",*argv);
+ return 1;
+ }
+
+ padding = malloc(align);
+ if (!padding) {
+ fprintf(stderr,"rdf2bin: out of memory\n");
+ return 1;
+ }
+
+ if (fwrite(m->t,1,m->f.code_len,of) != m->f.code_len ||
+ fwrite(padding,1,codepad,of) != codepad ||
+ fwrite(m->d,1,m->f.data_len,of) != m->f.data_len)
+ {
+ fprintf(stderr,"rdf2bin: error writing to %s\n", *argv);
+ return 1;
+ }
+
+ fclose(of);
+ return 0;
+}
diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c
index 4d4f4df..bc55a97 100644
--- a/rdoff/rdfdump.c
+++ b/rdoff/rdfdump.c
@@ -17,7 +17,7 @@ long translatelong(long in) { /* translate from little endian to
return r;
}
-
+
int translateshort(short in) {
int r;
unsigned char *i;
@@ -28,8 +28,8 @@ int translateshort(short in) {
return r;
}
void print_header(long length) {
- unsigned char buf[129],t,s,l;
- long o;
+ char buf[129],t,s,l;
+ long o,ll;
short rs;
while (length > 0) {
@@ -39,7 +39,7 @@ void print_header(long length) {
fread(&s,1,1,infile);
fread(&o,4,1,infile);
fread(&l,1,1,infile);
- fread(&rs,2,1,infile);
+ fread(&rs,2,1,infile);
printf(" relocation: location (%04x:%08lx), length %d, "
"referred seg %04x\n",(int)s,translatelong(o),(int)l,
translateshort(rs));
@@ -47,34 +47,34 @@ void print_header(long length) {
break;
case 2: /* import record */
fread(&rs,2,1,infile);
- l = 0;
+ ll = 0;
do {
- fread(&buf[l],1,1,infile);
- } while (buf[l++]);
+ fread(&buf[ll],1,1,infile);
+ } while (buf[ll++]);
printf(" import: segment %04x = %s\n",translateshort(rs),buf);
- length -= l + 3;
+ length -= ll + 3;
break;
case 3: /* export record */
fread(&s,1,1,infile);
fread(&o,4,1,infile);
l = 0;
do {
- fread(&buf[l],1,1,infile);
- } while (buf[l++]);
+ fread(&buf[ll],1,1,infile);
+ } while (buf[ll++]);
printf(" export: (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
- length -= l + 6;
+ length -= ll + 6;
break;
case 4: /* DLL record */
l = 0;
do {
- fread(&buf[l],1,1,infile);
- } while (buf[l++]);
+ fread(&buf[ll],1,1,infile);
+ } while (buf[ll++]);
printf(" dll: %s\n",buf);
- length -= l + 1;
+ length -= ll + 1;
break;
case 5: /* BSS reservation */
- fread(&l,4,1,infile);
- printf(" bss reservation: %08lx bytes\n",translatelong(l));
+ fread(&ll,4,1,infile);
+ printf(" bss reservation: %08lx bytes\n",translatelong(ll));
length -= 5;
break;
default:
diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c
new file mode 100644
index 0000000..5846562
--- /dev/null
+++ b/rdoff/rdflib.c
@@ -0,0 +1,235 @@
+/* rdflib - manipulate RDOFF library files (.rdl) */
+
+/* an rdoff library is simply a sequence of RDOFF object files, each
+ preceded by the name of the module, an ASCII string of up to 255
+ characters, terminated by a zero. There may be an optional
+ directory placed on the end of the file. The format of the
+ directory will be 'RDL' followed by a version number, followed by
+ the length of the directory, and then the directory, the format of
+ which has not yet been designed. */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+/* functions supported:
+ create a library (no extra operands required)
+ add a module from a library (requires filename and name to give mod.)
+ remove a module from a library (requires given name)
+ extract a module from the library (requires given name and filename)
+ list modules */
+
+const char *usage =
+ "usage:\n"
+ " rdflib x libname [extra operands]\n\n"
+ " where x is one of:\n"
+ " c - create library\n"
+ " a - add module (operands = filename module-name)\n"
+ " r - remove (module-name)\n"
+ " x - extract (module-name filename)\n"
+ " t - list\n";
+
+char **_argv;
+
+#define _ENDIANNESS 0 /* 0 for little, 1 for big */
+
+static void longtolocal(long * l)
+{
+#if _ENDIANNESS
+ unsigned char t;
+ unsigned char * p = (unsigned char *) l;
+
+ t = p[0];
+ p[0] = p[3];
+ p[3] = t;
+ t = p[1];
+ p[1] = p[2];
+ p[2] = p[1];
+#endif
+}
+
+void copybytes(FILE *fp, FILE *fp2, int n)
+{
+ int i,t;
+
+ for (i = 0 ; i < n; i++ )
+ {
+ t = fgetc(fp);
+ if (t == EOF)
+ {
+ fprintf(stderr,"ldrdf: premature end of file in '%s'\n",
+ _argv[2]);
+ exit(1);
+ }
+ if (fp2)
+ if (fputc(t, fp2) == EOF)
+ {
+ fprintf(stderr,"ldrdf: write error\n");
+ exit(1);
+ }
+ }
+}
+
+long copylong(FILE *fp, FILE *fp2)
+{
+ long l;
+ int i,t;
+ unsigned char * p = (unsigned char *) &l;
+
+
+ for (i = 0 ; i < 4; i++ ) /* skip magic no */
+ {
+ t = fgetc(fp);
+ if (t == EOF)
+ {
+ fprintf(stderr,"ldrdf: premature end of file in '%s'\n",
+ _argv[2]);
+ exit(1);
+ }
+ if (fp2)
+ if (fputc(t, fp2) == EOF)
+ {
+ fprintf(stderr,"ldrdf: write error\n");
+ exit(1);
+ }
+ *p++ = t;
+ }
+ longtolocal (&l);
+ return l;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *fp, *fp2;
+ char *p, buf[256];
+ int i;
+
+ _argv = argv;
+
+ if (argc < 3 || !strncmp(argv[1],"-h",2) || !strncmp(argv[1],"--h",3))
+ {
+ printf(usage);
+ exit(1);
+ }
+
+ switch(argv[1][0])
+ {
+ case 'c': /* create library */
+ fp = fopen(argv[2],"wb");
+ if (! fp) {
+ fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
+ perror("ldrdf");
+ exit(1);
+ }
+ fclose(fp);
+ break;
+
+ case 'a': /* add module */
+ if (argc < 5) {
+ fprintf(stderr,"ldrdf: required parameter missing\n");
+ exit(1);
+ }
+ fp = fopen(argv[2],"ab");
+ if (! fp)
+ {
+ fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
+ perror("ldrdf");
+ exit(1);
+ }
+
+ fp2 = fopen(argv[3],"rb");
+ if (! fp)
+ {
+ fprintf(stderr,"ldrdf: could not open '%s'\n",argv[3]);
+ perror("ldrdf");
+ exit(1);
+ }
+
+ p = argv[4];
+ do {
+ if ( fputc(*p,fp) == EOF ) {
+ fprintf(stderr,"ldrdf: write error\n");
+ exit(1);
+ }
+ } while (*p++);
+
+ while (! feof (fp2) ) {
+ i = fgetc (fp2);
+ if (i == EOF) {
+ break;
+ }
+
+ if ( fputc(i, fp) == EOF ) {
+ fprintf(stderr,"ldrdf: write error\n");
+ exit(1);
+ }
+ }
+ fclose(fp2);
+ fclose(fp);
+ break;
+
+ case 'x':
+ if (argc < 5) {
+ fprintf(stderr,"ldrdf: required parameter missing\n");
+ exit(1);
+ }
+
+ fp = fopen(argv[2],"rb");
+ if (! fp)
+ {
+ fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
+ perror("ldrdf");
+ exit(1);
+ }
+
+ fp2 = NULL;
+ while (! feof(fp) ) {
+ /* read name */
+ p = buf;
+ while( ( *(p++) = (char) fgetc(fp) ) )
+ if (feof(fp)) break;
+
+ if (feof(fp)) break;
+
+ /* check against desired name */
+ if (! strcmp(buf,argv[3]) )
+ {
+ fp2 = fopen(argv[4],"wb");
+ if (! fp2)
+ {
+ fprintf(stderr,"ldrdf: could not open '%s'\n", argv[4]);
+ perror("ldrdf");
+ exit(1);
+ }
+ }
+ else
+ fp2 = NULL;
+
+ /* step over the RDOFF file, copying it if fp2 != NULL */
+ copybytes(fp,fp2,6); /* magic number */
+ copybytes(fp,fp2, copylong(fp,fp2)); /* header */
+ copybytes(fp,fp2, copylong(fp,fp2)); /* text */
+ copybytes(fp,fp2, copylong(fp,fp2)); /* data */
+
+ if (fp2)
+ break;
+ }
+ fclose(fp);
+ if (fp2)
+ fclose(fp2);
+ else
+ {
+ fprintf(stderr,"ldrdf: module '%s' not found in '%s'\n",
+ argv[3],argv[2]);
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr,"ldrdf: command '%c' not recognised\n",
+ argv[1][0]);
+ exit(1);
+ }
+ return 0;
+}
+
diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c
index ad340b3..b848344 100644
--- a/rdoff/rdfload.c
+++ b/rdoff/rdfload.c
@@ -27,7 +27,7 @@ rdfmodule * rdfload(const char *filename)
char * hdr;
rdfheaderrec *r;
- if (f == NULL)
+ if (f == NULL)
{
rdf_errno = 6; /* out of memory */
return NULL;
@@ -48,7 +48,7 @@ rdfmodule * rdfload(const char *filename)
}
/* read in text and data segments, and header */
-
+
f->t = malloc (f->f.code_len);
f->d = malloc (f->f.data_len); /* BSS seg allocated later */
hdr = malloc (f->f.header_len);
@@ -107,11 +107,11 @@ rdfmodule * rdfload(const char *filename)
int rdf_relocate(rdfmodule * m)
{
rdfheaderrec * r;
- Collection imports;
+ Collection imports;
symtabEnt e;
long rel;
unsigned char * seg;
-
+
rdfheaderrewind ( & m->f );
collection_init(&imports);
@@ -155,7 +155,7 @@ int rdf_relocate(rdfmodule * m)
case 3: /* export record - add to symtab */
e.segment = r->e.segment;
- e.offset = r->e.offset +
+ e.offset = r->e.offset +
(e.segment == 0 ? m->textrel : /* 0 -> code */
e.segment == 1 ? m->datarel : /* 1 -> data */
m->bssrel) ; /* 2 -> bss */
@@ -168,6 +168,6 @@ int rdf_relocate(rdfmodule * m)
symtabInsert(m->symtab,&e);
break;
}
- }
+ }
return 0;
}
diff --git a/rdoff/rdlib.c b/rdoff/rdlib.c
new file mode 100644
index 0000000..bc8d1e3
--- /dev/null
+++ b/rdoff/rdlib.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "rdoff.h"
+#include "rdlib.h"
+
+int rdl_error = 0;
+
+char *rdl_errors[3] = {
+ "no error","could not open file", "invalid file structure",
+};
+
+int rdl_searchlib (struct librarynode * lib,
+ const char * label, rdffile * f)
+{
+ char buf[257];
+ int i;
+ void * hdr;
+ rdfheaderrec * r;
+
+ rdl_error = 0;
+ lib->referenced ++;
+
+ if (! lib->fp)
+ {
+ lib->fp = fopen(lib->name,"rb");
+
+ if (! lib->fp) {
+ rdl_error = 1;
+ return 0;
+ }
+ }
+ else
+ rewind(lib->fp);
+
+ while (! feof(lib->fp) )
+ {
+ i = 1;
+ while (fread(buf + i,1,1,lib->fp) == 1 && buf[i] && i < 257)
+ i++;
+ buf[0] = ':';
+
+ if (feof(lib->fp)) break;
+
+ if ( rdfopenhere(f,lib->fp,&lib->referenced,buf) ) {
+ rdl_error = 2;
+ return 0;
+ }
+
+ hdr = malloc(f->header_len);
+ rdfloadseg(f,RDOFF_HEADER,hdr);
+
+ while ((r = rdfgetheaderrec(f)))
+ {
+ if (r->type != 3) /* not an export */
+ continue;
+
+ if (! strcmp(r->e.label, label) ) /* match! */
+ {
+ free(hdr); /* reset to 'just open' */
+ f->header_loc = NULL; /* state... */
+ f->header_fp = 0;
+ return 1;
+ }
+ }
+
+ /* find start of next module... */
+ i = f->data_ofs + f->data_len;
+ rdfclose(f);
+ fseek(lib->fp,i,SEEK_SET);
+ }
+
+ lib->referenced --;
+ if (! lib->referenced)
+ {
+ fclose(lib->fp);
+ lib->fp = NULL;
+ }
+ return 0;
+}
+
+void rdl_perror(const char *apname, const char *filename)
+{
+ fprintf(stderr,"%s:%s:%s\n",apname,filename,rdl_errors[rdl_error]);
+}
+
+
+
diff --git a/rdoff/rdlib.h b/rdoff/rdlib.h
new file mode 100644
index 0000000..94592ce
--- /dev/null
+++ b/rdoff/rdlib.h
@@ -0,0 +1,18 @@
+/* rdlib.h Functions for manipulating librarys of RDOFF object files */
+
+
+struct librarynode {
+ char * name;
+ FILE * fp; /* initialised to NULL - always check*/
+ int referenced; /* & open if required. Close afterwards */
+ struct librarynode * next; /* if ! referenced. */
+};
+
+
+extern int rdl_error;
+
+int rdl_searchlib (struct librarynode * lib,
+ const char * label, rdffile * f);
+void rdl_perror(const char *apname, const char *filename);
+
+
diff --git a/rdoff/rdoff.c b/rdoff/rdoff.c
index 9a969ad..96620ec 100644
--- a/rdoff/rdoff.c
+++ b/rdoff/rdoff.c
@@ -13,9 +13,15 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
#include "rdoff.h"
+#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
+#define newstrcat(s1,s2) strcat(strcpy(malloc(strlen(s1) + strlen(s2) + 1), \
+ s1),s2)
+
/* ========================================================================
* Code for memory buffers (for delayed writing of header until we know
* how long it is).
@@ -42,7 +48,7 @@ void membufwrite(memorybuffer *b, void *data, int bytes) {
}
if ((bytes < 0 && b->length - bytes > BUF_BLOCK_LEN)
|| (bytes > 0 && b->length + bytes > BUF_BLOCK_LEN)) {
-
+
/* buffer full and no next allocated... allocate and initialise next
* buffer */
@@ -84,7 +90,7 @@ void membufdump(memorybuffer *b,FILE *fp)
if (!b) return;
fwrite (b->buffer, 1, b->length, fp);
-
+
membufdump(b->next,fp);
}
@@ -134,7 +140,18 @@ int rdf_errno = 0;
int rdfopen(rdffile *f, const char *name)
{
+ FILE * fp;
+
+ fp = fopen(name,"rb");
+ if (!fp) return rdf_errno = 1; /* error 1: file open error */
+
+ return rdfopenhere(f,fp,NULL,"");
+}
+
+int rdfopenhere(rdffile *f, FILE *fp, int *refcount, char *name)
+{
char buf[8];
+ long initpos;
if (translatelong(0x01020304) != 0x01020304)
{ /* fix this to be portable! */
@@ -143,9 +160,8 @@ int rdfopen(rdffile *f, const char *name)
exit(3);
}
-
- f->fp = fopen(name,"rb");
- if (!f->fp) return rdf_errno = 1; /* error 1: file open error */
+ f->fp = fp;
+ initpos = ftell(fp);
fread(buf,6,1,f->fp); /* read header */
buf[6] = 0;
@@ -160,6 +176,8 @@ int rdfopen(rdffile *f, const char *name)
return rdf_errno = 3; /* error 3: file read error */
}
+ f->header_ofs = ftell(f->fp);
+
if (fseek(f->fp,f->header_len,SEEK_CUR)) {
fclose(f->fp);
return rdf_errno = 2; /* seek past end of file...? */
@@ -182,20 +200,32 @@ int rdfopen(rdffile *f, const char *name)
}
f->data_ofs = ftell(f->fp);
- rewind(f->fp);
+ fseek(f->fp,initpos,SEEK_SET);
f->header_loc = NULL;
+
+ f->name = newstr(name);
+ f->refcount = refcount;
+ if (refcount) (*refcount)++;
return 0;
}
int rdfclose(rdffile *f)
{
- fclose(f->fp);
+ if (! f->refcount || ! *--f->refcount)
+ fclose(f->fp);
+ free(f->name);
+
return 0;
}
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);
+ }
+
}
int rdfloadseg(rdffile *f,int segment,void *buffer)
@@ -205,7 +235,7 @@ int rdfloadseg(rdffile *f,int segment,void *buffer)
switch(segment) {
case RDOFF_HEADER:
- fpos = 10;
+ fpos = f->header_ofs;
slen = f->header_len;
f->header_loc = (char *)buffer;
f->header_fp = 0;
@@ -224,8 +254,8 @@ int rdfloadseg(rdffile *f,int segment,void *buffer)
}
if (fseek(f->fp,fpos,SEEK_SET))
- return rdf_errno = 4;
-
+ return rdf_errno = 4;
+
if (fread(buffer,1,slen,f->fp) != slen)
return rdf_errno = 3;
@@ -294,7 +324,7 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
}
return &r;
}
-
+
void rdfheaderrewind(rdffile *f)
{
f->header_fp = 0;
diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h
index b022400..0f74b80 100644
--- a/rdoff/rdoff.h
+++ b/rdoff/rdoff.h
@@ -50,7 +50,7 @@ struct BSSRec {
char type; /* must be 5 */
long amount; /* number of bytes BSS to reserve */
};
-
+
typedef union RDFHeaderRec {
char type; /* invariant throughout all below */
struct RelocRec r; /* type == 1 */
@@ -66,10 +66,13 @@ typedef struct RDFFileInfo {
long header_len;
long code_len;
long data_len;
+ long header_ofs;
long code_ofs;
long data_ofs;
char *header_loc; /* keep location of header */
long header_fp; /* current location within header for reading */
+ 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)
@@ -91,8 +94,11 @@ typedef memorybuffer rdf_headerbuf;
/* mask to find actual segment value in relocation records */
#define RDOFF_SEGMENTMASK 63
+extern int rdf_errno;
+
/* RDOFF file manipulation functions */
int rdfopen(rdffile *f,const char *name);
+int rdfopenhere(rdffile *f, FILE *fp, int *refcount, char *name);
int rdfclose(rdffile *f);
int rdfloadseg(rdffile *f,int segment,void *buffer);
rdfheaderrec *rdfgetheaderrec(rdffile *f); /* returns static storage */
diff --git a/rdoff/rdoff.txt b/rdoff/rdoff.txt
new file mode 100644
index 0000000..7ee86d6
--- /dev/null
+++ b/rdoff/rdoff.txt
@@ -0,0 +1,114 @@
+The RDOFF version 1.1 Object File Format
+========================================
+
+I seem to keep writing this document... I don't know what keeps
+happening to it. Anyway, this one will hopefully stay around for a
+while.
+
+RDOFF is a relocatable object file format whose design goals were
+mainly to keep it simple, so that an RDOFF object can be loaded and
+executed by a very small piece of code (primarily so that it can be
+used by the microkernel of an operating system to store system
+modules, which can then go on to load and execute more complex object
+files, eg ELF, if so desired), yet still be able to be cope with
+everything required by the operating system; linkage of multiple
+modules together (possibly with automatic loading of new libraries
+that are referred to by the object) at load time, allowing static or
+dynamic linking as required by the application.
+
+The overall format of the file is summarised in this table:
+
+Length (bytes) Description
+ 6 Contains the string 'RDOFF1' (little-endian targets),
+ or 'RDOFF' followed by the single byte 0x01
+ (big-endian targets).
+ 4 Length of the header section
+ ? Header section (see above for length)
+ 4 Length of code section (.text)
+ ? Code section
+ 4 Length of data section (.data)
+ ? Data section
+
+Segments are referred to as numbers. Imported labels are implicitly
+at offset zero from a segment; each is assigned a segment number when
+it is imported. Segments in the object file itself are numbered:
+ 0 - text segemnt
+ 1 - data segment
+ 2 - bss segment
+
+The header consists of a sequence of records, each of which is
+preceded by a byte to represent its type.
+
+These records are one of the following types:
+
+1: Relocation Record
+--------------------
+
+ This record points to an address that will need either
+ relocation or linkage to an external segment when the object
+ is loaded or linked.
+
+ Length Description
+ 1 Type identifier (must be 1)
+ 1 Segment number (0 or 1) plus 64 if the reference is
+ relative (and thus does not require relocation with
+ the base of the code, only by the difference between
+ the start of this segment, and the segment referred to
+ (see below)
+ 4 Offset from start of segment of item requiring reloc.
+ 1 Length of item (1, 2, or 4 bytes...)
+ 2 Segment number to which reference is made.
+
+2: Import Symbol Record
+-----------------------
+
+ This record defines a segment to start at the location of a
+ named symbol; this symbol may need to be fetched from an
+ external library.
+
+ Length Description
+ 1 Type identifier (must be 2)
+ 2 Segment number to allocate
+ ? String containing label (null terminated, max length =
+ 32 chars)
+
+3: Export Symbol Record
+-----------------------
+
+ This record defines a symbol, to which external modules can
+ link using the above record type.
+
+ Length Description
+ 1 Type identifier (must be 3)
+ 1 Segment containing symbol (0,1 or 2)
+ 4 Offset of symbol within segment
+ ? String containing label (null terminated, max length =
+ 32 chars)
+
+4: Import Library Record
+------------------------
+
+ This record tells the loader that an extra library should be
+ loaded and linked to the module at either load- or run-time
+ (load time is easier, run-time is good, though...)
+
+ Length Description
+ 1 Type identifier (must be 4)
+ ? Name of library (null terminated string, max len = 128)
+
+5: Reserve BSS Bytes
+--------------------
+
+ This record tells the loader how much memory to reserve after
+ the executable code loaded from the object file for the BSS
+ segment (referred to as segment number 2).
+ A loader can safely assume that there will only be one of
+ these records per module, but the linker probably cannot...
+ NASM will only output one, but other utilities may be written
+ that do, and future versions of NASM may output more than one.
+
+ Length Description
+ 1 Type identifier (must be 5)
+ 4 Number of bytes to reserve
+
+
diff --git a/rdoff/symtab.c b/rdoff/symtab.c
index c0ff3e5..3fc363e 100644
--- a/rdoff/symtab.c
+++ b/rdoff/symtab.c
@@ -62,7 +62,7 @@ symtabEnt *symtabFind(void *symtab,char *name)
return &(l->ent);
}
l = l->next;
- }
+ }
return NULL;
}