summaryrefslogtreecommitdiff
path: root/rdoff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:49 +0000
committerH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:49 +0000
commit76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6 (patch)
tree6d1fe5322184b3e53a9378ce65f6a95f05b59f28 /rdoff
parent6768eb71d8debde65562619c938b997aea1bd9f9 (diff)
downloadnasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.tar.gz
nasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.tar.bz2
nasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.zip
NASM 0.96
Diffstat (limited to 'rdoff')
-rw-r--r--rdoff/Makefile.in74
-rw-r--r--rdoff/Makefile.unx73
-rw-r--r--rdoff/ldrdf.c4
-rw-r--r--rdoff/rdf.doc99
-rw-r--r--rdoff/rdfdump.c19
-rw-r--r--rdoff/test/Makefile2
-rw-r--r--rdoff/test/makelib14
-rw-r--r--rdoff/test/rdftest1.asm54
-rw-r--r--rdoff/test/rdftest2.asm33
-rw-r--r--rdoff/test/rdtlib.asm48
-rw-r--r--rdoff/test/rdtmain.asm47
-rw-r--r--rdoff/test/testlib.asm18
12 files changed, 480 insertions, 5 deletions
diff --git a/rdoff/Makefile.in b/rdoff/Makefile.in
new file mode 100644
index 0000000..5ab409d
--- /dev/null
+++ b/rdoff/Makefile.in
@@ -0,0 +1,74 @@
+#
+# Auto-configuring Makefile for RDOFF object file utils; part of the
+# Netwide Assembler
+#
+# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
+# Julian Hall. All rights reserved. The software is
+# redistributable under the licence given in the file "Licence"
+# distributed in the NASM archive.
+
+top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+mandir = @mandir@
+
+CC = @CC@
+CFLAGS = @CFLAGS@ @GCCFLAGS@ -I$(top_srcdir)
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+LN_S = @LN_S@
+
+LDRDFLIBS = rdoff.o nasmlib.o symtab.o collectn.o rdlib.o
+RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o
+
+.c.o:
+ $(CC) -c $(CFLAGS) $<
+
+all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+rdfdump: rdfdump.o
+ $(CC) -o rdfdump rdfdump.o
+
+ldrdf: ldrdf.o $(LDRDFLIBS)
+ $(CC) -o ldrdf ldrdf.o $(LDRDFLIBS)
+rdx: rdx.o $(RDXLIBS)
+ $(CC) -o rdx rdx.o $(RDXLIBS)
+rdflib: rdflib.o
+ $(CC) -o rdflib rdflib.o
+rdf2bin: rdf2bin.o $(RDXLIBS) nasmlib.o
+ $(CC) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o
+rdf2com:
+ $(LN_S) rdf2bin rdf2com
+
+rdf2bin.o: rdf2bin.c
+rdfdump.o: rdfdump.c
+rdoff.o: rdoff.c rdoff.h
+ldrdf.o: ldrdf.c rdoff.h $(top_srcdir)/nasmlib.h symtab.h collectn.h rdlib.h
+symtab.o: symtab.c symtab.h
+collectn.o: collectn.c collectn.h
+rdx.o: rdx.c rdoff.h rdfload.h symtab.h
+rdfload.o: rdfload.c rdfload.h rdoff.h collectn.h symtab.h
+rdlib.o: rdlib.c rdlib.h
+rdflib.o: rdflib.c
+
+nasmlib.o: $(top_srcdir)/nasmlib.c
+ $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
+
+clean:
+ rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+spotless: clean
+ rm -f Makefile
+
+install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+ $(INSTALL_PROGRAM) rdfdump $(bindir)/rdfdump
+ $(INSTALL_PROGRAM) ldrdf $(bindir)/ldrdf
+ $(INSTALL_PROGRAM) rdx $(bindir)/rdx
+ $(INSTALL_PROGRAM) rdflib $(bindir)/rdflib
+ $(INSTALL_PROGRAM) rdf2bin $(bindir)/rdf2bin
+ cd $(bindir); $(LN_S) rdf2bin rdf2com
diff --git a/rdoff/Makefile.unx b/rdoff/Makefile.unx
new file mode 100644
index 0000000..f155839
--- /dev/null
+++ b/rdoff/Makefile.unx
@@ -0,0 +1,73 @@
+# Generated automatically from Makefile.in by configure.
+#
+# Auto-configuring Makefile for RDOFF object file utils; part of the
+# Netwide Assembler
+#
+# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
+# Julian Hall. All rights reserved. The software is
+# redistributable under the licence given in the file "Licence"
+# distributed in the NASM archive.
+
+# You may need to adjust these values.
+
+prefix = /usr/local
+CC = cc
+CFLAGS = -O -I..
+
+# You _shouldn't_ need to adjust anything below this line.
+
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+mandir = ${prefix}/man
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+LN_S = ln -s
+
+LDRDFLIBS = rdoff.o nasmlib.o symtab.o collectn.o rdlib.o
+RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+rdfdump: rdfdump.o
+ $(CC) -o rdfdump rdfdump.o
+
+ldrdf: ldrdf.o $(LDRDFLIBS)
+ $(CC) -o ldrdf ldrdf.o $(LDRDFLIBS)
+rdx: rdx.o $(RDXLIBS)
+ $(CC) -o rdx rdx.o $(RDXLIBS)
+rdflib: rdflib.o
+ $(CC) -o rdflib rdflib.o
+rdf2bin: rdf2bin.o $(RDXLIBS) nasmlib.o
+ $(CC) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o
+rdf2com:
+ $(LN_S) rdf2bin rdf2com
+
+rdf2bin.o: rdf2bin.c
+rdfdump.o: rdfdump.c
+rdoff.o: rdoff.c rdoff.h
+ldrdf.o: ldrdf.c rdoff.h ../nasmlib.h symtab.h collectn.h rdlib.h
+symtab.o: symtab.c symtab.h
+collectn.o: collectn.c collectn.h
+rdx.o: rdx.c rdoff.h rdfload.h symtab.h
+rdfload.o: rdfload.c rdfload.h rdoff.h collectn.h symtab.h
+rdlib.o: rdlib.c rdlib.h
+rdflib.o: rdflib.c
+
+nasmlib.o: ../nasmlib.c ../nasmlib.h ../names.c ../nasm.h
+ $(CC) -c $(CFLAGS) ../nasmlib.c
+
+clean:
+ rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+ $(INSTALL_PROGRAM) rdfdump $(bindir)/rdfdump
+ $(INSTALL_PROGRAM) ldrdf $(bindir)/ldrdf
+ $(INSTALL_PROGRAM) rdx $(bindir)/rdx
+ $(INSTALL_PROGRAM) rdflib $(bindir)/rdflib
+ $(INSTALL_PROGRAM) rdf2bin $(bindir)/rdf2bin
+ cd $(bindir); $(LN_S) rdf2bin rdf2com
diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c
index e2541fa..9e4a215 100644
--- a/rdoff/ldrdf.c
+++ b/rdoff/ldrdf.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <string.h>
-#include "nasm.h"
#include "rdoff.h"
#include "nasmlib.h"
#include "symtab.h"
@@ -419,8 +418,11 @@ void link_segments(void)
relto = r->r.segment == 0 ? mod->coderel : mod->datarel;
}
else
+ {
bRelative = 0; /* non-relative - need to relocate
* at load time */
+ relto = 0; /* placate optimiser warnings */
+ }
/* calculate absolute offset of reference, not rel to beginning of
segment */
diff --git a/rdoff/rdf.doc b/rdoff/rdf.doc
new file mode 100644
index 0000000..300c2bc
--- /dev/null
+++ b/rdoff/rdf.doc
@@ -0,0 +1,99 @@
+RDOFF: Relocatable Dynamically-linked Object File Format
+========================================================
+
+RDOFF was designed initially to test the object-file production
+interface to NASM. It soon became apparent that it could be enhanced
+for use in serious applications due to its simplicity; code to load
+and execute an RDOFF object module is very simple. It also contains
+enhancements to allow it to be linked with a dynamic link library at
+either run- or load- time, depending on how complex you wish to make
+your loader.
+
+The RDOFF format (version 1.1, as produced by NASM v0.91) is defined
+as follows:
+
+The first six bytes of the file contain the string 'RDOFF1'. Other
+versions of the format may contain other last characters other than
+'1' - all little endian versions of the file will always contain an
+ASCII character with value greater than 32. If RDOFF is used on a
+big-endian machine at some point in the future, the version will be
+encoded in decimal rather than ASCII, so will be below 32.
+
+All multi-byte fields follwing this are encoded in either little- or
+big-endian format depending on the system described by this version
+information. Object files should be encoded in the endianness of
+their target machine; files of incorrect endianness will be rejected
+by the loader - this means that loaders do not need to convert
+endianness, as RDOFF has been designed with simplicity of loading at
+the forefront of the design requirements.
+
+The next 4 byte field is the length of the header in bytes. The
+header consists of a sequence of variable length records. Each
+record's type is identified by the first byte of the record. Record
+types 1-4 are currently supported. Record type 5 will be added in
+the near future, when I implement BSS segments. Record type 6 may be
+to do with debugging, when I get debugging implemented.
+
+Type 1: Relocation
+==================
+
+Offset Length Description
+0 1 Type (contains 1)
+1 1 Segment that contains reference (0 = text, 1 = data)
+ Add 64 to this number to indicate a relative linkage
+ to an external symbol (see notes)
+2 4 Offset of reference
+6 1 Length of reference (1,2 or 4 bytes)
+7 2 Segment to which reference is made (0 = text, 1 =
+ data, 2 = BSS [when implemented]) others are external
+ symbols.
+
+Total length = 9 bytes
+
+Type 2: Symbol Import
+=====================
+
+0 1 Type (2)
+1 2 Segment number that will be used in references to this
+ symbol.
+3 ? Null terminated string containing label (up to 32
+ chars) to match against exports in linkage.
+
+Type 3: Symbol Export
+=====================
+
+0 1 Type (3)
+1 1 Segment containing object to be exported (0/1/2)
+2 4 Offset within segment
+6 ? Null terminate string containing label to export (32
+ char maximum length)
+
+Type 4: Dynamic Link Library
+============================
+
+0 1 Type (4)
+1 ? Library name (up to 128 chars)
+
+Type 5: Reserve BSS
+===================
+
+0 1 Type (5)
+1 4 Amount of BSS space to reserve in bytes
+
+Total length: 5 bytes
+
+-----------------------------------------------------------------------------
+
+Following the header is the text (code) segment. This is preceded by
+a 4-byte integer, which is its length in bytes. This is followed by
+the length of the data segment (also 4 bytes), and finally the data
+segment.
+
+Notes
+=====
+
+Relative linking: The number stored at the address is offset
+required from the imported symbol, with the address of the end of
+the instruction subtracted from it. This means that the linker can
+simply add the address of the label relative to the beginning of the
+current segment to it.
diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c
index bc55a97..080c2e7 100644
--- a/rdoff/rdfdump.c
+++ b/rdoff/rdfdump.c
@@ -57,7 +57,7 @@ void print_header(long length) {
case 3: /* export record */
fread(&s,1,1,infile);
fread(&o,4,1,infile);
- l = 0;
+ ll = 0;
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
@@ -65,7 +65,7 @@ void print_header(long length) {
length -= ll + 6;
break;
case 4: /* DLL record */
- l = 0;
+ ll = 0;
do {
fread(&buf[ll],1,1,infile);
} while (buf[ll++]);
@@ -88,6 +88,7 @@ int main(int argc,char **argv) {
char id[7];
long l;
int verbose = 0;
+ long offset;
puts("RDOFF Dump utility v1.1 (C) Copyright 1996 Julian R Hall");
@@ -133,9 +134,15 @@ int main(int argc,char **argv) {
fread(&l,4,1,infile);
l = translatelong(l);
printf("\nText segment length = %ld bytes\n",l);
+ offset = 0;
while(l--) {
fread(id,1,1,infile);
- if (verbose) printf(" %02x",(int) (unsigned char)id[0]);
+ if (verbose) {
+ if (offset % 16 == 0)
+ printf("\n%08lx ", offset);
+ printf(" %02x",(int) (unsigned char)id[0]);
+ offset++;
+ }
}
if (verbose) printf("\n\n");
@@ -145,9 +152,13 @@ int main(int argc,char **argv) {
if (verbose)
{
+ offset = 0;
while (l--) {
fread(id,1,1,infile);
- printf(" %02x",(int) (unsigned char) id[0]);
+ if (offset % 16 == 0)
+ printf("\n%08lx ", offset);
+ printf(" %02x",(int) (unsigned char) id[0]);
+ offset++;
}
printf("\n");
}
diff --git a/rdoff/test/Makefile b/rdoff/test/Makefile
new file mode 100644
index 0000000..8e9f42e
--- /dev/null
+++ b/rdoff/test/Makefile
@@ -0,0 +1,2 @@
+clean:
+ rm -f *.rdf *.rdx
diff --git a/rdoff/test/makelib b/rdoff/test/makelib
new file mode 100644
index 0000000..baa4676
--- /dev/null
+++ b/rdoff/test/makelib
@@ -0,0 +1,14 @@
+
+LIBNAME=$1;
+shift;
+
+if [ "$LIBNAME" = "" ]; then
+ echo 'Usage: makelib <library name> <module> [...]'
+fi
+
+rdflib c $LIBNAME
+
+for FILE in $*; do
+ rdflib a $LIBNAME $FILE $FILE
+done
+
diff --git a/rdoff/test/rdftest1.asm b/rdoff/test/rdftest1.asm
new file mode 100644
index 0000000..76f1e43
--- /dev/null
+++ b/rdoff/test/rdftest1.asm
@@ -0,0 +1,54 @@
+ ;; program to test RDOFF production and linkage
+
+ ;; items to test include:
+ ;; [1] relocation within the same segment in each module
+ ;; [2] relocation to different segments in same module
+ ;; [3] relocation to same segment in different module
+ ;; [4] relocation to different segment in different module
+ ;; [5] relative relocation to same module
+ ;; [6] relative relocation to different module
+ ;; [7] correct generation of BSS addresses
+
+[SECTION .text]
+[BITS 32]
+
+_main:
+ mov ax,localdata ; [2] (16 bit) => 66 b8 0000
+ mov eax,localdata2 ; [2] (32 bit) => b8 0000000a
+
+[EXTERN _fardata]
+
+ mov eax,[_fardata] ; [4] => a1 00000000 (+20)
+ mov cx,next ; [1] => 66 b9 0012
+next:
+ call localproc ; [5] => e8 00000019
+
+[EXTERN _farproc]
+ mov eax,_farproc ; [3] => b8 00000000 (+40+0)
+ call _farproc ; [6] => e8 -$ (-0+40+0) (=1f)
+
+ mov eax,localbss ; [7] => b8 00000000
+
+[GLOBAL _term]
+_term: xor ax,ax ; => 66 31 c0
+ int 21h ; => cd 21
+ jmp _term ; => e9 -0a (=fffffff6)
+
+localproc:
+ ret ; => c3
+
+[GLOBAL _test1proc]
+_test1proc:
+ call localproc ; [5] => e8 -$ (-0+0+?) (=-6=fffffffa)
+ ret ; => c3
+
+[SECTION .data]
+[GLOBAL localdata2]
+localdata: db 'localdata',0
+localdata2: db 'localdata2',0
+farref: dd _fardata ; [3] => 0 (+20)
+localref: dd _main ; [2] => 0 (+0)
+
+[SECTION .bss]
+localbss: resw 4 ; reserve 8 bytes BSS
+ \ No newline at end of file
diff --git a/rdoff/test/rdftest2.asm b/rdoff/test/rdftest2.asm
new file mode 100644
index 0000000..25b8c18
--- /dev/null
+++ b/rdoff/test/rdftest2.asm
@@ -0,0 +1,33 @@
+ ;; rdftest2.asm - test linkage and generation of RDOFF files
+
+[SECTION .text]
+[BITS 32]
+
+[GLOBAL _farproc]
+[EXTERN _test1proc]
+[EXTERN localdata2]
+[EXTERN _term]
+_farproc:
+
+ mov bx,localdata2 ; [4] 0 => 66 bb 000a(+0)
+ mov eax,_term ; [3] 5 => b8 00000000(+26+0)
+ call _test1proc ; [6] A => e8 fffffff2(-40+0+31)(=ffffffe3)
+
+ mov eax,_farproc ; [1] => b8 00000000(+40)
+ add eax,[_fardata] ; [2] => 03 05 00000000(+20)
+
+ mov ebx,mybssdata ; [7] => bb 00000000(+08)
+ call myproc ; [5] => e8 00000001
+ ret
+
+myproc:
+ add eax,ebx
+ ret
+
+[SECTION .data]
+[GLOBAL _fardata]
+_fardata: dw _term ; [4]
+_localref: dd _farproc ; [2]
+
+[SECTION .bss]
+mybssdata: resw 1
diff --git a/rdoff/test/rdtlib.asm b/rdoff/test/rdtlib.asm
new file mode 100644
index 0000000..6c2b8ec
--- /dev/null
+++ b/rdoff/test/rdtlib.asm
@@ -0,0 +1,48 @@
+ ;; library functions for rdtmain - test of rdx linking and execution
+
+ ;; library function = _strcmp, defined as in C
+
+[SECTION .text]
+[BITS 32]
+
+[GLOBAL _strcmp]
+_strcmp:
+ push ebp
+ mov ebp,esp
+
+ ;; ebp+8 = first paramater, ebp+12 = second
+
+ mov esi,[ebp+8]
+ mov edi,[ebp+12]
+
+.loop:
+ mov cl,byte [esi]
+ mov dl,byte [edi]
+ cmp cl,dl
+ jb .below
+ ja .above
+ or cl,cl
+ jz .match
+ inc esi
+ inc edi
+ jmp .loop
+
+.below:
+ mov eax,-1
+ pop ebp
+ ret
+
+.above:
+ mov eax,1
+ pop ebp
+ ret
+
+.match:
+ xor eax,eax
+ pop ebp
+ ret
+
+[SECTION .data]
+[GLOBAL _message]
+
+_message: db 'hello',0 \ No newline at end of file
diff --git a/rdoff/test/rdtmain.asm b/rdoff/test/rdtmain.asm
new file mode 100644
index 0000000..626a2e2
--- /dev/null
+++ b/rdoff/test/rdtmain.asm
@@ -0,0 +1,47 @@
+ ;; rdtmain - main part of test program for RDX execution.
+ ;; returns true (0) if its parameter equals the phrase "hello"
+ ;; "hello" is stored in the library part, to complicate the
+ ;; linkage.
+
+ ;; assemble and link with the following commands:
+ ;; nasm -f rdf rdtmain.asm
+ ;; nasm -f rdf rdtlib.asm
+ ;; ldrdf rdtmain.rdf rdtlib.rdf -o rdxtest.rdx
+
+ ;; run with 'rdx rdxtest.rdx [parameters]' on a Linux (or possibly
+ ;; other 32 bit OS) systems (x86 architectures only!)
+ ;; try using '&& echo Yes' afterwards to find out when it returns 0.
+
+[EXTERN _strcmp] ; strcmp is an imported function
+[EXTERN _message] ; imported data
+[SECTION .text]
+[BITS 32]
+
+ ;; main(int argc,char **argv)
+[GLOBAL _main]
+_main:
+ push ebp
+ mov ebp,esp
+
+ ;; ebp+8 = argc, ebp+12 = argv
+
+ cmp dword [ebp+8],2
+ jb error ; cause error if < 1 parameters
+
+ mov eax, [ebp+12] ; eax = argv
+
+ mov ebx, [eax+4] ; ebx = argv[1]
+ mov ecx, _message ; ecx = "hello"
+
+ push ecx
+ push ebx
+ call _strcmp ; compare strings
+ add esp,8 ; caller clears stack
+
+ pop ebp
+ ret ; return return value of _strcmp
+
+error:
+ mov eax,2 ; return 2 on error
+ pop ebp
+ ret
diff --git a/rdoff/test/testlib.asm b/rdoff/test/testlib.asm
new file mode 100644
index 0000000..6ee3d89
--- /dev/null
+++ b/rdoff/test/testlib.asm
@@ -0,0 +1,18 @@
+; program to test retrieval of and linkage to modules in libraries by
+; ldrdf
+
+[SECTION .text]
+[GLOBAL _main]
+[EXTERN _strcmp]
+
+_main:
+ push dword string1
+ push dword string2
+ call _strcmp
+ add esp,8 ; doh! clear up stack ;-)
+ ret
+
+[SECTION .data]
+
+string1: db 'abc',0 ; try changing these strings and see
+string2: db 'abd',0 ; what happens!