NASM 0.98.22

This commit is contained in:
H. Peter Anvin 2002-04-30 21:06:16 +00:00
parent 09f6acbb75
commit 225c5926f0
15 changed files with 392 additions and 123 deletions

View file

@ -43,7 +43,7 @@ NROFF = @NROFF@
NASM = nasm.o nasmlib.o float.o insnsa.o assemble.o labels.o \ 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 \ 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 preproc.o listing.o eval.o
NDISASM = ndisasm.o disasm.o sync.o nasmlib.o insnsd.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 outelf.o: outelf.c nasm.h insnsi.h nasmlib.h outform.h
outform.o: outform.c outform.h nasm.h insnsi.h outform.o: outform.c outform.h nasm.h insnsi.h
outobj.o: outobj.c nasm.h insnsi.h nasmlib.h outform.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 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 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 preproc.o: preproc.c nasm.h insnsi.h nasmlib.h macros.c

View file

@ -4,9 +4,6 @@ NASM Wishlist
Numbers on right hand side are version numbers that it would be nice to 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. 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 - Check misc/ide.cfg into RCS as Watcom IDE enhancement thingy. 0.98
(nop@dlc.fi) (nop@dlc.fi)

View file

@ -103,6 +103,7 @@ in \c{elf}
convention convention
\IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to \IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to
\IR{global, elf extensions to} \c{GLOBAL}, \c{elf} 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} GOT
\IR{got relocations} \c{GOT} relocations \IR{got relocations} \c{GOT} relocations
\IR{gotoff relocation} \c{GOTOFF} relocations \IR{gotoff relocation} \c{GOTOFF} relocations
@ -3713,6 +3714,45 @@ which is the name of the module:
\c library mylib.rdl \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 \H{dbgfmt} \i\c{dbg}: Debugging Format
The \c{dbg} output format is not built into NASM in the default The \c{dbg} output format is not built into NASM in the default

2
nasm.h
View file

@ -13,7 +13,7 @@
#define NASM_MAJOR_VER 0 #define NASM_MAJOR_VER 0
#define NASM_MINOR_VER 98 #define NASM_MINOR_VER 98
#define NASM_VER "0.98.21" #define NASM_VER "0.98.22"
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0

View file

@ -57,7 +57,7 @@
/* ====configurable info begins here==== */ /* ====configurable info begins here==== */
/* formats configurable: /* formats configurable:
* bin,obj,elf,aout,aoutb,coff,win32,as86,rdf,rdf2 */ * bin,obj,elf,aout,aoutb,coff,win32,as86,rdf2 */
/* process options... */ /* process options... */
@ -92,9 +92,6 @@
#ifndef OF_AS86 #ifndef OF_AS86
#define OF_AS86 #define OF_AS86
#endif #endif
#ifndef OF_RDF
#define OF_RDF
#endif
#ifndef OF_RDF2 #ifndef OF_RDF2
#define OF_RDF2 #define OF_RDF2
#endif #endif
@ -138,9 +135,6 @@
#ifndef OF_AS86 #ifndef OF_AS86
#define OF_AS86 #define OF_AS86
#endif #endif
#ifndef OF_RDF
#define OF_RDF
#endif
#ifndef OF_RDF2 #ifndef OF_RDF2
#define OF_RDF2 #define OF_RDF2
#endif #endif
@ -174,9 +168,6 @@
#ifdef OF_NO_AS86 #ifdef OF_NO_AS86
#undef OF_AS86 #undef OF_AS86
#endif #endif
#ifdef OF_NO_RDF
#undef OF_RDF
#endif
#ifdef OF_NO_RDF2 #ifdef OF_NO_RDF2
#undef OF_RDF #undef OF_RDF
#endif #endif
@ -201,7 +192,6 @@ extern struct ofmt of_elf;
extern struct ofmt of_as86; extern struct ofmt of_as86;
extern struct ofmt of_obj; extern struct ofmt of_obj;
extern struct ofmt of_win32; extern struct ofmt of_win32;
extern struct ofmt of_rdf;
extern struct ofmt of_rdf2; extern struct ofmt of_rdf2;
extern struct ofmt of_ieee; extern struct ofmt of_ieee;
extern struct ofmt of_dbg; extern struct ofmt of_dbg;
@ -231,9 +221,6 @@ struct ofmt *drivers[]={
#ifdef OF_WIN32 #ifdef OF_WIN32
&of_win32, &of_win32,
#endif #endif
#ifdef OF_RDF
&of_rdf,
#endif
#ifdef OF_RDF2 #ifdef OF_RDF2
&of_rdf2, &of_rdf2,
#endif #endif

View file

@ -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 * 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 * allows up to 65533 external labels to be defined; otherwise it would be
* 32764. */ * 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 { struct RelocRec {
byte type; /* must be 1, or 6 for segment base ref */ byte type; /* must be 1, or 6 for segment base ref */
@ -68,7 +80,8 @@ struct ImportRec {
struct ExportRec { struct ExportRec {
byte type; /* must be 3 */ 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) */ byte segment; /* segment referred to (0/1) */
long offset; /* offset within segment */ long offset; /* offset within segment */
char label[33]; /* zero terminated as above. max len = 32 chars */ 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 */ 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 #define COUNT_SEGTYPES 9
static char * segmenttypes[COUNT_SEGTYPES] = { static char * segmenttypes[COUNT_SEGTYPES] = {
@ -266,7 +284,7 @@ static void write_reloc_rec(struct RelocRec *r)
char buf[4],*b; char buf[4],*b;
if (r->refseg != (int16)NO_SEG && (r->refseg & 1)) /* segment base ref */ 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 */ 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->type,1);
saa_wbytes(header,&r->reclen,1); saa_wbytes(header,&r->reclen,1);
saa_wbytes(header,&r->flags,1);
saa_wbytes(header,&r->segment,1); saa_wbytes(header,&r->segment,1);
b = buf; WRITELONG(b,r->offset); b = buf; WRITELONG(b,r->offset);
saa_wbytes(header,buf,4); saa_wbytes(header,buf,4);
@ -339,20 +358,37 @@ static void rdf2_deflabel(char *name, long segment, long offset,
struct ImportRec ri; struct ImportRec ri;
static int farsym = 0; static int farsym = 0;
static int i; static int i;
byte export_flags = 0;
if (is_global != 1) return; if (is_global != 1) return;
if (special) { if (special) {
while(*special == ' ' || *special == '\t') special++; while(*special == ' ' || *special == '\t') special++;
if (!nasm_strnicmp(special, "export", 6)) {
special += 6;
export_flags |= SYM_GLOBAL;
}
if (!nasm_stricmp(special, "far")) { if (*special) {
farsym = 1; while(isspace(*special)) special++;
} if (!nasm_stricmp(special, "far")) {
else if (!nasm_stricmp(special, "near")) { farsym = 1;
farsym = 0; }
} else if (!nasm_stricmp(special, "near")) {
else farsym = 0;
error(ERR_NONFATAL, "unrecognised symbol type `%s'", special); }
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] != '@') { 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 (i >= nsegments) { /* EXTERN declaration */
if (farsym) if (farsym)
ri.type = 7; ri.type = RDFREC_FARIMPORT;
else else
ri.type = 2; ri.type = RDFREC_IMPORT;
ri.segment = segment; ri.segment = segment;
strncpy(ri.label,name,32); strncpy(ri.label,name,32);
ri.label[32] = 0; ri.label[32] = 0;
ri.reclen = 3 + strlen(ri.label); ri.reclen = 3 + strlen(ri.label);
write_import_rec(&ri); write_import_rec(&ri);
} else if (is_global) { } else if (is_global) {
r.type = 3; r.type = RDFREC_GLOBAL;
r.flags = export_flags;
r.segment = segment; r.segment = segment;
r.offset = offset; r.offset = offset;
strncpy(r.label,name,32); strncpy(r.label,name,32);
r.label[32] = 0; r.label[32] = 0;
r.reclen = 6 + strlen(r.label); r.reclen = 7 + strlen(r.label);
write_export_rec(&r); 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 */ /* 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.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.offset = getsegmentlength(segto); /* current offset */
rr.length = bytes; /* length of reference */ rr.length = bytes; /* length of reference */
rr.refseg = segment; /* segment referred to */ rr.refseg = segment; /* segment referred to */
write_reloc_rec(&rr); 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)*/ rr.refseg = segment; /* segment referred to (will be >>1'd)*/
if (segment != NO_SEG && segment % 2) { if (segment != NO_SEG && segment % 2) {
rr.type = 6; rr.type = RDFREC_SEGRELOC;
rr.segment = segto; /* memory base refs *aren't ever* relative! */ rr.segment = segto; /* memory base refs *aren't ever* relative! */
write_reloc_rec(&rr); write_reloc_rec(&rr);
@ -529,7 +566,7 @@ static void rdf2_out (long segto, void *data, unsigned long type,
} }
else else
{ {
rr.type = 1; /* type signature */ rr.type = RDFREC_RELOC; /* type signature */
rr.segment = segto+64; /* segment we're currently in + rel flag */ rr.segment = segto+64; /* segment we're currently in + rel flag */
write_reloc_rec(&rr); 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?"); 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.segment = segto+64; /* segment we're currently in + rel tag */
rr.offset = getsegmentlength(segto); /* current offset */ rr.offset = getsegmentlength(segto); /* current offset */
rr.length = 4; /* length of reference */ rr.length = 4; /* length of reference */
@ -579,7 +616,7 @@ static void rdf2_cleanup (int debuginfo) {
if (bsslength != 0) /* reserve BSS */ if (bsslength != 0) /* reserve BSS */
{ {
bs.type = 5; bs.type = RDFREC_BSS;
bs.amount = bsslength; bs.amount = bsslength;
bs.reclen = 4; bs.reclen = 4;
write_bss_rec(&bs); write_bss_rec(&bs);
@ -631,7 +668,7 @@ static int rdf2_directive (char *directive, char *value, int pass) {
if (! strcmp(directive, "library")) { if (! strcmp(directive, "library")) {
if (pass == 1) { if (pass == 1) {
r.type = 4; r.type = RDFREC_DLL;
r.reclen=strlen(value)+1; r.reclen=strlen(value)+1;
strcpy(r.name, value); strcpy(r.name, value);
write_dllmod_rec(&r); write_dllmod_rec(&r);
@ -641,14 +678,14 @@ static int rdf2_directive (char *directive, char *value, int pass) {
if (! strcmp(directive, "module")) { if (! strcmp(directive, "module")) {
if (pass == 1) { if (pass == 1) {
r.type = 8; r.type = RDFREC_MODNAME;
r.reclen=strlen(value)+1; r.reclen=strlen(value)+1;
strcpy(r.name, value); strcpy(r.name, value);
write_dllmod_rec(&r); write_dllmod_rec(&r);
} }
return 1; return 1;
} }
return 0; return 0;
} }

View file

@ -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 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 of tools (and general purpose library files) for the manipulation of
RDOFF version 2 object files. Note that these programs (with the RDOFF version 2 object files. Note that these programs (with the
exception of 'rdfdump') will NOT work with version 1 object files. See exception of 'rdfdump') will NOT work with version 1 object files.
the subdirectory v1 for programs that perform that task. Version 1 of RDOFF is no longer supported.
Note: If you do not have a v1 subdirectory, you may have unpacked the There is also a 'doc' directory with 'v1-v2' file, which documents the
ZIP file without specifying the 'restore directory structure' option - differences between RDOFF 1 and 2, and an 'rdoff2.txt' file, with
delete these files, and run your ZIP extracter again with this option complete documentation for the new format.
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.
Here is a brief summary of the programs' usage: Here is a brief summary of the programs' usage:
rdfdump rdfdump
======= =======
@ -40,6 +33,7 @@ Changes from previous versions:
looks for incorrect lengths for header records, and checks the looks for incorrect lengths for header records, and checks the
overall length count at the start of the file) overall length count at the start of the file)
ldrdf ldrdf
===== =====
@ -51,23 +45,43 @@ In normal usage, its command line takes the form:
ldrdf [-o output-file] object files [-llibrary ...] 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 Modules in libraries are not linked to the program unless they are
referred to. referred to.
Most of its options are not implemented, but those that are are listed here: 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 available: default (which only prints error information), normal
(which prints information about the produced object, -v), medium (which prints information about the produced object, -v), medium
(which prints information about what the program is doing, -v -v) (which prints information about what the program is doing, -v -v)
and high (which prints all available information, -v -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, a single segment should be aligned (must be either 1, 2, 4, 8,
16, 32 or 256. Default is 16). 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 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 '_main', which it expects to be a C-style function, which will accept
two parameters, argc and argv in normal C style. two parameters, argc and argv in normal C style.
rdflib rdflib
====== ======
@ -97,13 +112,9 @@ Valid commands are:
ie you'd do 'rdflib x libc.rdl strcpy strcpy.rdf to get ie you'd do 'rdflib x libc.rdl strcpy strcpy.rdf to get
a copy of strcpy.rdf back out again...) a copy of strcpy.rdf back out again...)
t List modules in the library 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 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 each segment in your object, to tell the header writing functions
how long the segment is. how long the segment is.
BUGS BUGS
==== ====
This product has recently undergone a major revision, and as such there This product has recently undergone a major revision, and as such there
are probably several bugs left over from the testing phase (although the 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 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 please report any bugs to maintainers at the addresses below, including the
information: following information:
- A description of the bug - A description of the bug
- What you think the program should be doing - What you think the program should be doing
@ -147,26 +159,22 @@ information:
problem is in code generated) problem is in code generated)
* exact descriptions of error messages/symptoms/etc * exact descriptions of error messages/symptoms/etc
TODO 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 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: 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 - Improve the performace of ldrdf (there are several enhancements I can think
of that wouldn't be too hard to add) of that wouldn't be too hard to add)
- Stop assuming that we're on a little endian machine - 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 - 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
===========
Yuri Zaporogets <yuriz@teraflops.com> - primary maintainer
Julian Hall <jules@earthcorp.com> Julian Hall <jules@dsf.org.uk> - original designer and author

62
rdoff/doc/v1-v2 Normal file
View 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.

View file

@ -23,6 +23,9 @@
* segment exceeds 64K in size, it will not work. This program probably * 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 * wont work if compiled by a 16 bit compiler. Try DJGPP if you're running
* under DOS. '#define STINGY_MEMORY' may help a little. * 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> #include <stdio.h>
@ -36,7 +39,7 @@
#include "rdlib.h" #include "rdlib.h"
#include "segtab.h" #include "segtab.h"
#define LDRDF_VERSION "1.02" #define LDRDF_VERSION "1.03"
#define RDF_MAXSEGS 64 #define RDF_MAXSEGS 64
/* #define STINGY_MEMORY */ /* #define STINGY_MEMORY */
@ -989,10 +992,10 @@ void write_output(const char * filename)
case 3: /* export symbol */ case 3: /* export symbol */
/* /*
* need to insert an export for this symbol into the new * need to insert an export for this symbol into the new
* header, unless we're stripping symbols [unless this * header, unless we're stripping symbols. Even if we're
* symbol is in an explicit keep list]. *** FIXME *** * stripping, put the symbol if it's marked as SYM_GLOBAL.
*/ */
if (options.strip) if (options.strip && !(hr->e.flags & SYM_GLOBAL))
break; break;
if (hr->e.segment == 2) { if (hr->e.segment == 2) {
@ -1019,10 +1022,12 @@ void write_output(const char * filename)
case 8: /* module name */ case 8: /* module name */
/* /*
* insert module name record if export symbols * Insert module name record if export symbols
* are not stripped. * 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); rdfaddheader(rdfheader, hr);
break; break;

View file

@ -78,13 +78,13 @@ int main(int argc, char **argv)
argv++, argc--; argv++, argc--;
} }
if (argc < 2) { if (argc < 2) {
puts("rdf2bin: required parameter missing"); puts("rdf2ihx: required parameter missing");
return -1; return -1;
} }
m = rdfload(*argv); m = rdfload(*argv);
if (!m) { if (!m) {
rdfperror("rdf2bin",*argv); rdfperror("rdf2ihx",*argv);
return 1; return 1;
} }
printf("relocating %s: origin=%lx, align=%d\n",*argv, origin, align); printf("relocating %s: origin=%lx, align=%d\n",*argv, origin, align);

View file

@ -2,12 +2,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "rdoff.h"
#include "multboot.h" #include "multboot.h"
FILE *infile; FILE *infile;
typedef unsigned short int16;
long translatelong(long in) { /* translate from little endian to long translatelong(long in) { /* translate from little endian to
local representation */ local representation */
long r; long r;
@ -22,7 +21,7 @@ long translatelong(long in) { /* translate from little endian to
return r; return r;
} }
int translateshort(int16 in) { int16 translateshort(int16 in) {
int r; int r;
unsigned char *i; unsigned char *i;
@ -33,7 +32,7 @@ int translateshort(int16 in) {
} }
void print_header(long length, int rdf_version) { void print_header(long length, int rdf_version) {
char buf[129],t,s,l; char buf[129],t,s,l,flags;
unsigned char reclen; unsigned char reclen;
long o,ll; long o,ll;
int16 rs; int16 rs;
@ -45,6 +44,7 @@ void print_header(long length, int rdf_version) {
fread(&reclen,1,1,infile); fread(&reclen,1,1,infile);
} }
switch(t) { switch(t) {
case 1: /* relocation record */ case 1: /* relocation record */
case 6: /* segment relocation */ case 6: /* segment relocation */
fread(&s,1,1,infile); fread(&s,1,1,infile);
@ -61,6 +61,7 @@ void print_header(long length, int rdf_version) {
if (rdf_version == 1 && t == 6) if (rdf_version == 1 && t == 6)
printf(" warning: seg relocation not supported in RDOFF1\n"); printf(" warning: seg relocation not supported in RDOFF1\n");
break; break;
case 2: /* import record */ case 2: /* import record */
case 7: /* import far symbol */ case 7: /* import far symbol */
fread(&rs,2,1,infile); fread(&rs,2,1,infile);
@ -83,7 +84,9 @@ void print_header(long length, int rdf_version) {
if (rdf_version == 1 && t == 7) if (rdf_version == 1 && t == 7)
printf (" warning: far import not supported in RDOFF1\n"); printf (" warning: far import not supported in RDOFF1\n");
break; break;
case 3: /* export record */ case 3: /* export record */
fread(&flags,1,1,infile);
fread(&s,1,1,infile); fread(&s,1,1,infile);
fread(&o,4,1,infile); fread(&o,4,1,infile);
ll = 0; ll = 0;
@ -95,12 +98,19 @@ void print_header(long length, int rdf_version) {
} }
else else
{ {
for (; ll < reclen - 5; ll ++) for (; ll < reclen - 6; ll ++)
fread(&buf[ll],1,1,infile); 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; if (rdf_version == 1) length -= ll + 6;
break; break;
case 4: /* DLL and Module records */ case 4: /* DLL and Module records */
case 8: case 8:
ll = 0; ll = 0;

View file

@ -5,12 +5,11 @@
* preceded by the name of the module, an ASCII string of up to 255 * preceded by the name of the module, an ASCII string of up to 255
* characters, terminated by a zero. * characters, terminated by a zero.
* *
* There may be an optional * There may be an optional directory placed on the end of the file.
* directory placed on the end of the file. The format of the * The format of the directory will be 'RDLDD' followed by a version
* directory will be 'RDLDD' followed by a version number, followed by * number, followed by the length of the directory, and then the
* the length of the directory, and then the directory, the format of * directory, the format of which has not yet been designed.
* which has not yet been designed. The module name of the directory * The module name of the directory must be '.dir'.
* must be '.dir'.
* *
* All module names beginning with '.' are reserved * All module names beginning with '.' are reserved
* for possible future extensions. The linker ignores all such modules, * for possible future extensions. The linker ignores all such modules,
@ -21,13 +20,16 @@
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <unistd.h>
/* functions supported: /* functions supported:
create a library (no extra operands required) * create a library (no extra operands required)
add a module from a library (requires filename and name to give mod.) * add a module from a library (requires filename and name to give mod.)
remove a module from a library (requires given name) (not implemented) * replace a module in a library (requires given name and filename)
extract a module from the library (requires given name and filename) * delete a module from a library (requires given name)
list modules */ * extract a module from the library (requires given name and filename)
* list modules
*/
const char *usage = const char *usage =
"usage:\n" "usage:\n"
@ -35,8 +37,9 @@ const char *usage =
" where x is one of:\n" " where x is one of:\n"
" c - create library\n" " c - create library\n"
" a - add module (operands = filename module-name)\n" " a - add module (operands = filename module-name)\n"
" r - remove (module-name) [not implemented]\n"
" x - extract (module-name filename)\n" " x - extract (module-name filename)\n"
" r - replace (module-name filename)\n"
" d - delete (module-name)\n"
" t - list\n"; " t - list\n";
char **_argv; char **_argv;
@ -111,10 +114,11 @@ long copylong(FILE *fp, FILE *fp2)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *fp, *fp2; FILE *fp, *fp2, *fptmp;
char *p, buf[256], c; char *p, buf[256], c;
int i; int i;
long l; long l;
char tmptempl[L_tmpnam], rdbuf[10];
_argv = argv; _argv = argv;
@ -150,7 +154,7 @@ int main(int argc, char **argv)
} }
fp2 = fopen(argv[3],"rb"); fp2 = fopen(argv[3],"rb");
if (! fp) if (! fp2)
{ {
fprintf(stderr,"rdflib: could not open '%s'\n",argv[3]); fprintf(stderr,"rdflib: could not open '%s'\n",argv[3]);
perror("rdflib"); perror("rdflib");
@ -181,15 +185,11 @@ int main(int argc, char **argv)
break; break;
case 'x': case 'x':
if (argc < 5) { if (argc < 5) {
fprintf(stderr,"rdflib: required parameter missing\n");
exit(1);
}
case 't':
if (argc < 3) {
fprintf(stderr, "rdflib: required paramenter missing\n"); fprintf(stderr, "rdflib: required paramenter missing\n");
exit(1); exit(1);
} }
case 't':
fp = fopen(argv[2],"rb"); fp = fopen(argv[2],"rb");
if (! fp) if (! fp)
{ {
@ -275,12 +275,118 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
break; 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: default:
fprintf(stderr,"rdflib: command '%c' not recognised\n", fprintf(stderr,"rdflib: command '%c' not recognized\n",
argv[1][0]); argv[1][0]);
exit(1); exit(1);
} }
return 0; return 0;
} }

View file

@ -13,10 +13,6 @@
/* TODO: The functions in this module assume they are running /* TODO: The functions in this module assume they are running
* on a little-endian machine. This should be fixed to * on a little-endian machine. This should be fixed to
* make it portable. * 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> #include <stdio.h>
@ -388,6 +384,7 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
break; break;
case 3: /* Exported symbol record */ case 3: /* Exported symbol record */
RI8(r.e.flags);
RI8(r.e.segment); RI8(r.e.segment);
RI32(r.e.offset); RI32(r.e.offset);
RS(r.e.label,32); RS(r.e.label,32);
@ -464,6 +461,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
break ; break ;
case 3: /* export */ case 3: /* export */
membufwrite(h->buf,&r->e.flags,1);
membufwrite(h->buf,&r->e.segment,1); membufwrite(h->buf,&r->e.segment,1);
membufwrite(h->buf,&r->e.offset,-4); membufwrite(h->buf,&r->e.offset,-4);
membufwrite(h->buf,&r->e.label,strlen(r->e.label) + 1); membufwrite(h->buf,&r->e.label,strlen(r->e.label) + 1);

View file

@ -48,6 +48,7 @@ struct ImportRec {
struct ExportRec { struct ExportRec {
byte type; /* must be 3 */ byte type; /* must be 3 */
byte reclen; /* content length */ byte reclen; /* content length */
byte flags; /* SYM_* flags (see below) */
byte segment; /* segment referred to (0/1/2) */ byte segment; /* segment referred to (0/1/2) */
long offset; /* offset within segment */ long offset; /* offset within segment */
char label[33]; /* zero terminated as above. max len = 32 chars */ char label[33]; /* zero terminated as above. max len = 32 chars */
@ -71,6 +72,11 @@ struct ModRec {
char modname[128]; /* module name */ char modname[128]; /* module name */
}; };
/* Flags for ExportRec */
#define SYM_DATA 0x01
#define SYM_FUNCTION 0x02
#define SYM_GLOBAL 0x04
#ifdef _MULTBOOT_H #ifdef _MULTBOOT_H
#define RDFLDRMOVER_SIZE 22 #define RDFLDRMOVER_SIZE 22

14
rdoff/test/makelib.sh Normal file
View 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