aboutsummaryrefslogtreecommitdiffstats
path: root/rdoff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2002-04-30 21:06:16 +0000
committerH. Peter Anvin <hpa@zytor.com>2002-04-30 21:06:16 +0000
commit225c5926f04fb8052be3c12fcd1445934a9fd44f (patch)
treecd1cc5cbe59e1782e510bb4fb31d757797053592 /rdoff
parent09f6acbb75d7f58aa78691844620b85b6c44919b (diff)
downloadnasm-225c5926f04fb8052be3c12fcd1445934a9fd44f.tar.gz
nasm-225c5926f04fb8052be3c12fcd1445934a9fd44f.tar.xz
nasm-225c5926f04fb8052be3c12fcd1445934a9fd44f.zip
NASM 0.98.22nasm-0.98.22
Diffstat (limited to 'rdoff')
-rw-r--r--rdoff/README84
-rw-r--r--rdoff/doc/v1-v262
-rw-r--r--rdoff/ldrdf.c17
-rw-r--r--rdoff/rdf2ihx.c4
-rw-r--r--rdoff/rdfdump.c22
-rw-r--r--rdoff/rdflib.c150
-rw-r--r--rdoff/rdoff.c6
-rw-r--r--rdoff/rdoff.h6
-rw-r--r--rdoff/test/makelib.sh14
9 files changed, 287 insertions, 78 deletions
diff --git a/rdoff/README b/rdoff/README
index 29f9aa03..1c59e758 100644
--- a/rdoff/README
+++ b/rdoff/README
@@ -1,26 +1,19 @@
-RDOFF Utils v0.3
-================
+RDOFF Utilities, version 0.3
+============================
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 2 object files. Note that these programs (with the
-exception of 'rdfdump') will NOT work with version 1 object files. See
-the subdirectory v1 for programs that perform that task.
+exception of 'rdfdump') will NOT work with version 1 object files.
+Version 1 of RDOFF is no longer supported.
-Note: If you do not have a v1 subdirectory, you may have unpacked the
-ZIP file without specifying the 'restore directory structure' option -
-delete these files, and run your ZIP extracter again with this option
-turned on ('-d' for PKUNZIP).
-
-RDOFF version 1 is no longer really supported, you should be using
-v2 instead now.
-
-There is also a 'Changes' file, which documents the differences between
-RDOFF 1 and 2, and an 'rdoff2.txt' file, with complete documentation for the
-new format.
+There is also a 'doc' directory with 'v1-v2' file, which documents the
+differences between RDOFF 1 and 2, and an 'rdoff2.txt' file, with
+complete documentation for the new format.
Here is a brief summary of the programs' usage:
+
rdfdump
=======
@@ -40,6 +33,7 @@ Changes from previous versions:
looks for incorrect lengths for header records, and checks the
overall length count at the start of the file)
+
ldrdf
=====
@@ -51,23 +45,43 @@ 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
+ -2 redirect all output from stderr to stdout. It is useful for some
+ systems which don't have such a redirection in shell (e.g. DOS).
+
+ -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 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'.
+
+ -s strip exported symbols from output file. Symbols marked as
+ SYM_GLOBAL (see rdoff2.txt) are never stripped.
+
+ -x warn about unresolved symbols.
+
+ -xe issue an error when at least one symbol is unresolved.
+
+ -o name write output to file <name>. The default output filename
+ is 'aout.rdx'.
+
+ -j path specify search path for object files. Default path is a
+ current directory.
+
+ -L path specify search path for libraries. Default path is a
+ current directory.
+
+ -mbh [addr] add a Multiboot header to output file. If addr is not
+ specified, default loading address is 0x110000.
+
rdx
===
@@ -76,6 +90,7 @@ 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
======
@@ -97,13 +112,9 @@ Valid commands are:
ie you'd do 'rdflib x libc.rdl strcpy strcpy.rdf to get
a copy of strcpy.rdf back out again...)
t List modules in the library
+ d Delete modules from library
+ r Replace a module in library with a new file
-A remove command will be added soon (it is already documented
-as existing, but I haven't had time to implement it... 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).
Library functions
=================
@@ -126,14 +137,15 @@ just reading them), then please note the existance of a new function
each segment in your object, to tell the header writing functions
how long the segment is.
+
BUGS
====
This product has recently undergone a major revision, and as such there
are probably several bugs left over from the testing phase (although the
previous version had quite a few that have now been fixed!). Could you
-please report any bugs to me at the address below, including the following
-information:
+please report any bugs to maintainers at the addresses below, including the
+following information:
- A description of the bug
- What you think the program should be doing
@@ -147,26 +159,22 @@ information:
problem is in code generated)
* exact descriptions of error messages/symptoms/etc
+
TODO
====
-There are still various things unimplemented that I would like to add.
+There are still various things unimplemented that we would like to add.
If you want to find out what these are, search near the top of each *.c
file for a comment containing the word 'TODO'. A brief list is given here:
- Improve the performace of ldrdf (there are several enhancements I can think
of that wouldn't be too hard to add)
- Stop assuming that we're on a little endian machine
-- Make everything work with both formats (?)
-- Add extra functions to ldrdf (strip symbols/keep symbol list)
- Check for more bugs
-One last thing I have to say: good luck! Whatever it is that you want to use
-RDOFF for, I hope its a success. People out there are using it for many
-diverse applications, from operating system boot-loaders to loadable modules
-in games. Whatever your application is, I hope that it works, and that you
-have a good time writing it.
-
+MAINTAINERS
+===========
-Julian Hall <jules@earthcorp.com>
+Yuri Zaporogets <yuriz@teraflops.com> - primary maintainer
+Julian Hall <jules@dsf.org.uk> - original designer and author
diff --git a/rdoff/doc/v1-v2 b/rdoff/doc/v1-v2
new file mode 100644
index 00000000..800896bd
--- /dev/null
+++ b/rdoff/doc/v1-v2
@@ -0,0 +1,62 @@
+Differences between RDOFF versions 1 & 2
+========================================
+
+This document is designed primarily for people maintaining code which
+uses RDOFF version 1, and would like to upgrade that code to work
+with version 2.
+
+The main changes are summarised here:
+
+Overall format
+==============
+
+The overall format has changed somewhat since version 1, in order
+to make RDOFF more flexible. After the file type identifier (which
+has been changed to 'RDOFF2', obviously), there is now a 4 byte
+integer describing the length of the object module. This allows
+multiple objects to be concatenated, while the loader can easily
+build an index of the locations of each object. This isn't as
+pointless as it sounds; I'm using RDOFF in a microkernel operating
+system, and this is the ideal way of loading multiple driver modules
+at boot time.
+
+There are also no longer a fixed number of segments; instead there
+is a list of segments, immediately following the header.
+Each segment is preceded by a 10 byte header giving information about
+that segment. This header has the following format:
+
+Length Description
+2 Type
+2 Number
+2 Reserved
+4 Length
+
+'Type' is a number describing what sort of segment it is (eg text, data,
+comment, debug info). See 'rdoff2.txt' for a list of the segment types.
+'Number' is the number used to refer to the segment in the header records.
+Not all segments will be loaded; it is only intended that one code
+and one data segment will be loaded into memory. It is possible, however,
+for a loaded segment to contain a reference to an unloaded segment.
+This is an error, and should be flagged at load time. Or maybe you should
+load the segment... its up to you, really.
+
+The segment's data immediately follows the end of the segment header.
+
+HEADER RECORDS
+==============
+
+All of the header records have changed in this version, but not
+substantially. Each record type has had a content-length code added,
+a single byte immediately following the type byte. This contains the
+length of the rest of the record (excluding the type and length bytes,
+but including the terminating nulls on any strings in the record).
+
+There are two new record types, Segment Relocation (6), and FAR import (7).
+The record formats are identical to Relocation (1) and import (2). They are
+only of real use on systems using segmented architectures. Systems using
+a flat model should treat FAR import (7) exactly the same as an import (2),
+and should either flag segment relocation as an error, or attempt to figure
+out whether it is a reference to a code or data symbol, and set the value
+referenced to the according selector value. I am opting for the former
+approach, and would recommend that others working on 32 bit flat systems
+do the same.
diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c
index 3d9d749e..b7070fe9 100644
--- a/rdoff/ldrdf.c
+++ b/rdoff/ldrdf.c
@@ -23,6 +23,9 @@
* segment exceeds 64K in size, it will not work. This program probably
* wont work if compiled by a 16 bit compiler. Try DJGPP if you're running
* under DOS. '#define STINGY_MEMORY' may help a little.
+ *
+ * TO FIX: enhance search of required export symbols in libraries (now depends
+ * on modules order in library).
*/
#include <stdio.h>
@@ -36,7 +39,7 @@
#include "rdlib.h"
#include "segtab.h"
-#define LDRDF_VERSION "1.02"
+#define LDRDF_VERSION "1.03"
#define RDF_MAXSEGS 64
/* #define STINGY_MEMORY */
@@ -989,10 +992,10 @@ void write_output(const char * filename)
case 3: /* export symbol */
/*
* need to insert an export for this symbol into the new
- * header, unless we're stripping symbols [unless this
- * symbol is in an explicit keep list]. *** FIXME ***
+ * header, unless we're stripping symbols. Even if we're
+ * stripping, put the symbol if it's marked as SYM_GLOBAL.
*/
- if (options.strip)
+ if (options.strip && !(hr->e.flags & SYM_GLOBAL))
break;
if (hr->e.segment == 2) {
@@ -1019,10 +1022,12 @@ void write_output(const char * filename)
case 8: /* module name */
/*
- * insert module name record if export symbols
+ * Insert module name record if export symbols
* are not stripped.
+ * If module name begins with '$' - insert it anyway.
*/
- if (options.strip) break;
+
+ if (options.strip && hr->m.modname[0] != '$') break;
rdfaddheader(rdfheader, hr);
break;
diff --git a/rdoff/rdf2ihx.c b/rdoff/rdf2ihx.c
index c6dd8e3e..ed915370 100644
--- a/rdoff/rdf2ihx.c
+++ b/rdoff/rdf2ihx.c
@@ -78,13 +78,13 @@ int main(int argc, char **argv)
argv++, argc--;
}
if (argc < 2) {
- puts("rdf2bin: required parameter missing");
+ puts("rdf2ihx: required parameter missing");
return -1;
}
m = rdfload(*argv);
if (!m) {
- rdfperror("rdf2bin",*argv);
+ rdfperror("rdf2ihx",*argv);
return 1;
}
printf("relocating %s: origin=%lx, align=%d\n",*argv, origin, align);
diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c
index 347fdb17..5bf6264c 100644
--- a/rdoff/rdfdump.c
+++ b/rdoff/rdfdump.c
@@ -2,12 +2,11 @@
#include <stdlib.h>
#include <string.h>
+#include "rdoff.h"
#include "multboot.h"
FILE *infile;
-typedef unsigned short int16;
-
long translatelong(long in) { /* translate from little endian to
local representation */
long r;
@@ -22,7 +21,7 @@ long translatelong(long in) { /* translate from little endian to
return r;
}
-int translateshort(int16 in) {
+int16 translateshort(int16 in) {
int r;
unsigned char *i;
@@ -33,7 +32,7 @@ int translateshort(int16 in) {
}
void print_header(long length, int rdf_version) {
- char buf[129],t,s,l;
+ char buf[129],t,s,l,flags;
unsigned char reclen;
long o,ll;
int16 rs;
@@ -45,6 +44,7 @@ void print_header(long length, int rdf_version) {
fread(&reclen,1,1,infile);
}
switch(t) {
+
case 1: /* relocation record */
case 6: /* segment relocation */
fread(&s,1,1,infile);
@@ -61,6 +61,7 @@ void print_header(long length, int rdf_version) {
if (rdf_version == 1 && t == 6)
printf(" warning: seg relocation not supported in RDOFF1\n");
break;
+
case 2: /* import record */
case 7: /* import far symbol */
fread(&rs,2,1,infile);
@@ -83,7 +84,9 @@ void print_header(long length, int rdf_version) {
if (rdf_version == 1 && t == 7)
printf (" warning: far import not supported in RDOFF1\n");
break;
+
case 3: /* export record */
+ fread(&flags,1,1,infile);
fread(&s,1,1,infile);
fread(&o,4,1,infile);
ll = 0;
@@ -95,12 +98,19 @@ void print_header(long length, int rdf_version) {
}
else
{
- for (; ll < reclen - 5; ll ++)
+ for (; ll < reclen - 6; ll ++)
fread(&buf[ll],1,1,infile);
}
- printf(" export: (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
+ if (flags & SYM_GLOBAL)
+ printf(" export");
+ else
+ printf(" global");
+ if (flags & SYM_FUNCTION) printf(" proc");
+ if (flags & SYM_DATA) printf(" data");
+ printf(": (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
if (rdf_version == 1) length -= ll + 6;
break;
+
case 4: /* DLL and Module records */
case 8:
ll = 0;
diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c
index 7a00fc6d..c8bab74b 100644
--- a/rdoff/rdflib.c
+++ b/rdoff/rdflib.c
@@ -5,12 +5,11 @@
* 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 'RDLDD' 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. The module name of the directory
- * must be '.dir'.
+ * There may be an optional directory placed on the end of the file.
+ * The format of the directory will be 'RDLDD' 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.
+ * The module name of the directory must be '.dir'.
*
* All module names beginning with '.' are reserved
* for possible future extensions. The linker ignores all such modules,
@@ -21,13 +20,16 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <unistd.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) (not implemented)
- extract a module from the library (requires given name and filename)
- list modules */
+ * create a library (no extra operands required)
+ * add a module from a library (requires filename and name to give mod.)
+ * replace a module in a library (requires given name and filename)
+ * delete 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"
@@ -35,8 +37,9 @@ const char *usage =
" where x is one of:\n"
" c - create library\n"
" a - add module (operands = filename module-name)\n"
- " r - remove (module-name) [not implemented]\n"
" x - extract (module-name filename)\n"
+ " r - replace (module-name filename)\n"
+ " d - delete (module-name)\n"
" t - list\n";
char **_argv;
@@ -111,10 +114,11 @@ long copylong(FILE *fp, FILE *fp2)
int main(int argc, char **argv)
{
- FILE *fp, *fp2;
+ FILE *fp, *fp2, *fptmp;
char *p, buf[256], c;
int i;
long l;
+ char tmptempl[L_tmpnam], rdbuf[10];
_argv = argv;
@@ -150,7 +154,7 @@ int main(int argc, char **argv)
}
fp2 = fopen(argv[3],"rb");
- if (! fp)
+ if (! fp2)
{
fprintf(stderr,"rdflib: could not open '%s'\n",argv[3]);
perror("rdflib");
@@ -181,15 +185,11 @@ int main(int argc, char **argv)
break;
case 'x':
- if (argc < 5) {
- fprintf(stderr,"rdflib: required parameter missing\n");
- exit(1);
- }
- case 't':
- if (argc < 3) {
+ if (argc < 5) {
fprintf(stderr, "rdflib: required paramenter missing\n");
exit(1);
}
+ case 't':
fp = fopen(argv[2],"rb");
if (! fp)
{
@@ -275,12 +275,118 @@ int main(int argc, char **argv)
exit(1);
}
break;
+
+ case 'r': /* replace module */
+ argc--;
+ case 'd': /* delete module */
+ if (argc < 4) {
+ fprintf(stderr, "rdflib: required paramenter missing\n");
+ exit(1);
+ }
+
+ fp = fopen(argv[2],"rb");
+ if (! fp)
+ {
+ fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
+ perror("rdflib");
+ exit(1);
+ }
+
+ if (argv[1][0] == 'r') {
+ fp2 = fopen(argv[4],"rb");
+ if (! fp2)
+ {
+ fprintf(stderr, "rdflib: could not open '%s'\n", argv[4]);
+ perror("rdflib");
+ exit(1);
+ }
+ }
+
+ tmpnam(tmptempl);
+ fptmp = fopen(tmptempl,"wb");
+ if (! fptmp)
+ {
+ fprintf(stderr,"rdflib: could not open temporary file\n");
+ perror("rdflib");
+ exit(1);
+ }
+
+ /* copy library into temporary file */
+ fseek(fp, 0, SEEK_END); /* get file length */
+ l = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ copybytes(fp, fptmp, l);
+ freopen(tmptempl, "rb", fptmp); /* reopen files */
+ freopen(argv[2], "wb", fp);
+
+ while (! feof(fptmp) ) {
+ /* read name */
+ p = buf;
+ while( ( *(p++) = (char) fgetc(fptmp) ) )
+ if (feof(fptmp)) break;
+
+ if (feof(fptmp)) break;
+
+ /* check against desired name */
+ if (! strcmp(buf, argv[3]) ) {
+ fread(p=rdbuf, 1, sizeof(rdbuf), fptmp);
+ l = *(long*)(p+6);
+ fseek(fptmp, l, SEEK_CUR);
+ break;
+ } else {
+ fwrite(buf, 1, strlen(buf)+1, fp); /* module name */
+ if ((c=copybytes(fptmp, fp, 6)) >= '2') {
+ l = copylong(fptmp, fp); /* version 2 or above */
+ copybytes(fptmp, fp, l); /* entire object */
+ }
+ }
+ }
+
+ if (argv[1][0] == 'r') {
+ /* copy new module into library */
+ p = argv[3];
+ do {
+ if ( fputc(*p, fp) == EOF ) {
+ fprintf(stderr, "rdflib: write error\n");
+ exit(1);
+ }
+ } while (*p++);
+
+ while (! feof (fp2) ) {
+ i = fgetc (fp2);
+ if (i == EOF) {
+ break;
+ }
+ if ( fputc(i, fp) == EOF ) {
+ fprintf(stderr, "rdflib: write error\n");
+ exit(1);
+ }
+ }
+ fclose(fp2);
+ }
+
+ /* copy rest of library if any */
+ while (! feof (fptmp) ) {
+ i = fgetc (fptmp);
+ if (i == EOF) {
+ break;
+ }
+
+ if ( fputc(i, fp) == EOF ) {
+ fprintf(stderr,"rdflib: write error\n");
+ exit(1);
+ }
+ }
+
+ fclose(fp);
+ fclose(fptmp);
+ unlink(tmptempl);
+ break;
default:
- fprintf(stderr,"rdflib: command '%c' not recognised\n",
+ fprintf(stderr,"rdflib: command '%c' not recognized\n",
argv[1][0]);
exit(1);
}
return 0;
}
-
diff --git a/rdoff/rdoff.c b/rdoff/rdoff.c
index e7d8b764..80b96cc2 100644
--- a/rdoff/rdoff.c
+++ b/rdoff/rdoff.c
@@ -13,10 +13,6 @@
/* TODO: The functions in this module assume they are running
* on a little-endian machine. This should be fixed to
* make it portable.
- *
- * This module no longer supports RDOFF1. If anybody *really*
- * needs the functionality of supporting both types at the
- * same time, I'll add it back in.
*/
#include <stdio.h>
@@ -388,6 +384,7 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
break;
case 3: /* Exported symbol record */
+ RI8(r.e.flags);
RI8(r.e.segment);
RI32(r.e.offset);
RS(r.e.label,32);
@@ -464,6 +461,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
break ;
case 3: /* export */
+ membufwrite(h->buf,&r->e.flags,1);
membufwrite(h->buf,&r->e.segment,1);
membufwrite(h->buf,&r->e.offset,-4);
membufwrite(h->buf,&r->e.label,strlen(r->e.label) + 1);
diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h
index 0c572315..4a81017d 100644
--- a/rdoff/rdoff.h
+++ b/rdoff/rdoff.h
@@ -48,6 +48,7 @@ struct ImportRec {
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 */
@@ -71,6 +72,11 @@ struct ModRec {
char modname[128]; /* module name */
};
+/* Flags for ExportRec */
+#define SYM_DATA 0x01
+#define SYM_FUNCTION 0x02
+#define SYM_GLOBAL 0x04
+
#ifdef _MULTBOOT_H
#define RDFLDRMOVER_SIZE 22
diff --git a/rdoff/test/makelib.sh b/rdoff/test/makelib.sh
new file mode 100644
index 00000000..520bb193
--- /dev/null
+++ b/rdoff/test/makelib.sh
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+[ $1 ] || {
+ echo "Usage: $0 <library name> <module> [...]"
+ exit 1
+}
+
+libname=$1; shift
+
+rdflib c $libname
+
+for f in $*; do
+ rdflib a $libname $f $f
+done