aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in3
-rw-r--r--Wishlist3
-rw-r--r--doc/nasmdoc.src40
-rw-r--r--nasm.h2
-rw-r--r--outform.h15
-rw-r--r--outrdf2.c87
-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
15 files changed, 392 insertions, 123 deletions
diff --git a/Makefile.in b/Makefile.in
index 52a772a4..fb1f3877 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,7 +43,7 @@ NROFF = @NROFF@
NASM = nasm.o nasmlib.o float.o insnsa.o assemble.o labels.o \
parser.o outform.o outbin.o outaout.o outcoff.o outelf.o \
- outobj.o outas86.o outrdf.o outrdf2.o outdbg.o zoutieee.o \
+ outobj.o outas86.o outrdf2.o outdbg.o zoutieee.o \
preproc.o listing.o eval.o
NDISASM = ndisasm.o disasm.o sync.o nasmlib.o insnsd.o
@@ -77,7 +77,6 @@ outdbg.o: outdbg.c nasm.h insnsi.h nasmlib.h outform.h
outelf.o: outelf.c nasm.h insnsi.h nasmlib.h outform.h
outform.o: outform.c outform.h nasm.h insnsi.h
outobj.o: outobj.c nasm.h insnsi.h nasmlib.h outform.h
-outrdf.o: outrdf.c nasm.h insnsi.h nasmlib.h outform.h
outrdf2.o: outrdf2.c nasm.h insnsi.h nasmlib.h outform.h
parser.o: parser.c nasm.h insnsi.h nasmlib.h parser.h float.h names.c insnsn.c
preproc.o: preproc.c nasm.h insnsi.h nasmlib.h macros.c
diff --git a/Wishlist b/Wishlist
index 4fbcbcf0..ccf7760d 100644
--- a/Wishlist
+++ b/Wishlist
@@ -4,9 +4,6 @@ NASM Wishlist
Numbers on right hand side are version numbers that it would be nice to
have this done by. ? means I haven't looked at it yet.
-- Create a binary RDF tools distribution. Should probably be distributed 0.98
- seperately.
-
- Check misc/ide.cfg into RCS as Watcom IDE enhancement thingy. 0.98
(nop@dlc.fi)
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index fcf47006..cabeff5f 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -103,6 +103,7 @@ in \c{elf}
convention
\IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to
\IR{global, elf extensions to} \c{GLOBAL}, \c{elf} extensions to
+\IR{global, rdf extensions to} \c{GLOBAL}, \c{rdf} extensions to
\IR{got} GOT
\IR{got relocations} \c{GOT} relocations
\IR{gotoff relocation} \c{GOTOFF} relocations
@@ -3713,6 +3714,45 @@ which is the name of the module:
\c library mylib.rdl
+\S{rdfmod} Specifying a Module Name: The \i\c{MODULE} Directive
+
+Special RDOFF header record is used to store the name of the module.
+It can be used, for example, by run-time loader to perform dynamic
+linking. \c{MODULE} directive takes one argument which is the name
+of current module:
+
+\c module mymodname
+
+Note that when you statically link modules and tell linker to strip
+the symbols from output file, all module names will be stripped too.
+To avoid it, you should start module names with \I{$prefix}\c{$}, like:
+
+\c module $kernel.core
+
+\S{rdfglob} \c{rdf} Extensions to the \c{GLOBAL} directive\I{GLOBAL,
+rdf extensions to}
+
+RDOFF global symbols can contain additional information needed by the
+static linker. You can mark a global symbol as exported, thus telling
+the linker do not strip it from target executable or library file.
+Like in ELF, you can also specify whether an exported symbol is a
+procedure (function) or data object.
+
+Suffixing the name with a colon and the word \i\c{export} you make the
+symbol exported:
+
+\c global sys_open:export
+
+To specify that exported symbol is a procedure (function), you add the
+word \i\c{proc} or \i\c{function} after declaration:
+
+\c global sys_open:export proc
+
+Similarly, to specify exported data object, add the word \i\c{data}
+or \i\c{object} to the directive:
+
+\c global kernel_ticks:export data
+
\H{dbgfmt} \i\c{dbg}: Debugging Format
The \c{dbg} output format is not built into NASM in the default
diff --git a/nasm.h b/nasm.h
index 1a58ac19..684b4e83 100644
--- a/nasm.h
+++ b/nasm.h
@@ -13,7 +13,7 @@
#define NASM_MAJOR_VER 0
#define NASM_MINOR_VER 98
-#define NASM_VER "0.98.21"
+#define NASM_VER "0.98.22"
#ifndef NULL
#define NULL 0
diff --git a/outform.h b/outform.h
index 18d47689..7da8e32c 100644
--- a/outform.h
+++ b/outform.h
@@ -57,7 +57,7 @@
/* ====configurable info begins here==== */
/* formats configurable:
- * bin,obj,elf,aout,aoutb,coff,win32,as86,rdf,rdf2 */
+ * bin,obj,elf,aout,aoutb,coff,win32,as86,rdf2 */
/* process options... */
@@ -92,9 +92,6 @@
#ifndef OF_AS86
#define OF_AS86
#endif
-#ifndef OF_RDF
-#define OF_RDF
-#endif
#ifndef OF_RDF2
#define OF_RDF2
#endif
@@ -138,9 +135,6 @@
#ifndef OF_AS86
#define OF_AS86
#endif
-#ifndef OF_RDF
-#define OF_RDF
-#endif
#ifndef OF_RDF2
#define OF_RDF2
#endif
@@ -174,9 +168,6 @@
#ifdef OF_NO_AS86
#undef OF_AS86
#endif
-#ifdef OF_NO_RDF
-#undef OF_RDF
-#endif
#ifdef OF_NO_RDF2
#undef OF_RDF
#endif
@@ -201,7 +192,6 @@ extern struct ofmt of_elf;
extern struct ofmt of_as86;
extern struct ofmt of_obj;
extern struct ofmt of_win32;
-extern struct ofmt of_rdf;
extern struct ofmt of_rdf2;
extern struct ofmt of_ieee;
extern struct ofmt of_dbg;
@@ -231,9 +221,6 @@ struct ofmt *drivers[]={
#ifdef OF_WIN32
&of_win32,
#endif
-#ifdef OF_RDF
- &of_rdf,
-#endif
#ifdef OF_RDF2
&of_rdf2,
#endif
diff --git a/outrdf2.c b/outrdf2.c
index be33643d..e0988739 100644
--- a/outrdf2.c
+++ b/outrdf2.c
@@ -43,6 +43,18 @@ static const char *RDOFF2Id = "RDOFF2"; /* written to start of RDOFF files */
* waste any of the 16 bits of segment number written to the file - this
* 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_MULTIBOOTHDR 9
+#define RDFREC_GENERIC 0
+
struct RelocRec {
byte type; /* must be 1, or 6 for segment base ref */
@@ -68,7 +80,8 @@ struct ImportRec {
struct ExportRec {
byte type; /* must be 3 */
- byte reclen; /* equals 6+label length */
+ 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 */
@@ -86,6 +99,11 @@ struct DLLModRec {
char name[128]; /* library to link at load time or module name */
};
+/* Flags for ExportRec */
+#define SYM_DATA 0x01
+#define SYM_FUNCTION 0x02
+#define SYM_GLOBAL 0x04
+
#define COUNT_SEGTYPES 9
static char * segmenttypes[COUNT_SEGTYPES] = {
@@ -266,7 +284,7 @@ static void write_reloc_rec(struct RelocRec *r)
char buf[4],*b;
if (r->refseg != (int16)NO_SEG && (r->refseg & 1)) /* segment base ref */
- r->type = 6;
+ r->type = RDFREC_SEGRELOC;
r->refseg >>= 1; /* adjust segment nos to RDF rather than NASM */
@@ -289,6 +307,7 @@ static void write_export_rec(struct ExportRec *r)
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);
@@ -339,20 +358,37 @@ static void rdf2_deflabel(char *name, long segment, long offset,
struct ImportRec ri;
static int farsym = 0;
static int i;
+ byte export_flags = 0;
if (is_global != 1) return;
if (special) {
while(*special == ' ' || *special == '\t') special++;
-
- if (!nasm_stricmp(special, "far")) {
- farsym = 1;
- }
- else if (!nasm_stricmp(special, "near")) {
- farsym = 0;
+
+ if (!nasm_strnicmp(special, "export", 6)) {
+ special += 6;
+ export_flags |= SYM_GLOBAL;
}
- 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")) {
+ export_flags |= SYM_FUNCTION;
+ }
+ else if (!nasm_stricmp(special, "data") ||
+ !nasm_stricmp(special, "object")) {
+ export_flags |= SYM_DATA;
+ }
+ else
+ error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
+ }
}
if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
@@ -365,21 +401,22 @@ static void rdf2_deflabel(char *name, long segment, long offset,
}
if (i >= nsegments) { /* EXTERN declaration */
if (farsym)
- ri.type = 7;
+ ri.type = RDFREC_FARIMPORT;
else
- ri.type = 2;
+ ri.type = RDFREC_IMPORT;
ri.segment = segment;
strncpy(ri.label,name,32);
ri.label[32] = 0;
ri.reclen = 3 + strlen(ri.label);
write_import_rec(&ri);
} else if (is_global) {
- r.type = 3;
+ r.type = RDFREC_GLOBAL;
+ r.flags = export_flags;
r.segment = segment;
r.offset = offset;
strncpy(r.label,name,32);
r.label[32] = 0;
- r.reclen = 6 + strlen(r.label);
+ r.reclen = 7 + strlen(r.label);
write_export_rec(&r);
}
}
@@ -489,12 +526,12 @@ static void rdf2_out (long segto, void *data, unsigned long type,
{
/* it's an address, so we must write a relocation record */
- rr.type = 1; /* type signature */
+ rr.type = RDFREC_RELOC; /* type signature */
rr.reclen = 8;
- rr.segment = segto; /* segment we're currently in */
+ rr.segment = segto; /* segment we're currently in */
rr.offset = getsegmentlength(segto); /* current offset */
- rr.length = bytes; /* length of reference */
- rr.refseg = segment; /* segment referred to */
+ rr.length = bytes; /* length of reference */
+ rr.refseg = segment; /* segment referred to */
write_reloc_rec(&rr);
}
@@ -518,7 +555,7 @@ static void rdf2_out (long segto, void *data, unsigned long type,
rr.refseg = segment; /* segment referred to (will be >>1'd)*/
if (segment != NO_SEG && segment % 2) {
- rr.type = 6;
+ rr.type = RDFREC_SEGRELOC;
rr.segment = segto; /* memory base refs *aren't ever* relative! */
write_reloc_rec(&rr);
@@ -529,7 +566,7 @@ static void rdf2_out (long segto, void *data, unsigned long type,
}
else
{
- rr.type = 1; /* type signature */
+ rr.type = RDFREC_RELOC; /* type signature */
rr.segment = segto+64; /* segment we're currently in + rel flag */
write_reloc_rec(&rr);
@@ -551,7 +588,7 @@ static void rdf2_out (long segto, void *data, unsigned long type,
error(ERR_PANIC, "erm... 4 byte segment base ref?");
}
- rr.type = 1; /* type signature */
+ rr.type = RDFREC_RELOC; /* type signature */
rr.segment = segto+64; /* segment we're currently in + rel tag */
rr.offset = getsegmentlength(segto); /* current offset */
rr.length = 4; /* length of reference */
@@ -579,7 +616,7 @@ static void rdf2_cleanup (int debuginfo) {
if (bsslength != 0) /* reserve BSS */
{
- bs.type = 5;
+ bs.type = RDFREC_BSS;
bs.amount = bsslength;
bs.reclen = 4;
write_bss_rec(&bs);
@@ -631,7 +668,7 @@ static int rdf2_directive (char *directive, char *value, int pass) {
if (! strcmp(directive, "library")) {
if (pass == 1) {
- r.type = 4;
+ r.type = RDFREC_DLL;
r.reclen=strlen(value)+1;
strcpy(r.name, value);
write_dllmod_rec(&r);
@@ -641,14 +678,14 @@ static int rdf2_directive (char *directive, char *value, int pass) {
if (! strcmp(directive, "module")) {
if (pass == 1) {
- r.type = 8;
+ r.type = RDFREC_MODNAME;
r.reclen=strlen(value)+1;
strcpy(r.name, value);
write_dllmod_rec(&r);
}
return 1;
}
-
+
return 0;
}
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