NASM 0.98.22
This commit is contained in:
parent
09f6acbb75
commit
225c5926f0
15 changed files with 392 additions and 123 deletions
|
@ -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
|
||||
|
|
3
Wishlist
3
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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
2
nasm.h
2
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
|
||||
|
|
15
outform.h
15
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
|
||||
|
|
87
outrdf2.c
87
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_strnicmp(special, "export", 6)) {
|
||||
special += 6;
|
||||
export_flags |= SYM_GLOBAL;
|
||||
}
|
||||
|
||||
if (!nasm_stricmp(special, "far")) {
|
||||
farsym = 1;
|
||||
}
|
||||
else if (!nasm_stricmp(special, "near")) {
|
||||
farsym = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
84
rdoff/README
84
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
|
||||
|
|
62
rdoff/doc/v1-v2
Normal file
62
rdoff/doc/v1-v2
Normal file
|
@ -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.
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
150
rdoff/rdflib.c
150
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
14
rdoff/test/makelib.sh
Normal file
14
rdoff/test/makelib.sh
Normal file
|
@ -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
|
Loading…
Reference in a new issue