summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-10-17 17:13:26 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-10-17 17:13:26 -0700
commite41b69beaf51a725a98b1ba4480751333b24a06f (patch)
treeb40ec2308741a20be270f3f50f085fe807a7c3a0
parentd83fb7e3388e516263fceaba27f2d36450bdf74a (diff)
downloadnasm-e41b69beaf51a725a98b1ba4480751333b24a06f.tar.gz
Test and Makefile rules for 32- and 64-bit ELF shared libraries
Add Makefile rules for the 32-bit ELF shared library test, and add a 64-bit ELF shared library test (still work in progress.)
-rw-r--r--test/Makefile27
-rw-r--r--test/elf64so.asm89
-rw-r--r--test/elftest.c2
-rw-r--r--test/elftest64.c42
4 files changed, 160 insertions, 0 deletions
diff --git a/test/Makefile b/test/Makefile
index fa949f6c..dda674a4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -37,6 +37,33 @@ diff: performtest.pl $(NASM) $(TESTS)
clean:
rm -f *.com *.o *.o64 *.obj *.obj64 *.exe *.lst *.bin
rm -rf testresults
+ rm -f elftest elftest64
spotless: clean
rm -rf golden
+
+#
+# Test for ELF32 shared libraries; assumes an x86 Linux system
+#
+elfso.o: elfso.asm
+ $(NASM) $(NASMOPT) -f elf32 -o $@ -l $*.lst $<
+
+elfso.so: elfso.o
+ $(LD) -m elf_i386 -shared -o $@ $<
+
+elftest: elftest.c elfso.so
+ $(CC) -m32 -o $@ $^
+ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./elftest
+
+#
+# Test for ELF64 shared libraries; assumes an x86-64 Linux system
+#
+elf64so.o: elf64so.asm
+ $(NASM) $(NASMOPT) -f elf64 -o $@ -l $*.lst $<
+
+elf64so.so: elf64so.o
+ $(LD) -shared -o $@ $<
+
+elftest64: elftest64.c elf64so.so
+ $(CC) -o $@ $^
+ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./elftest64
diff --git a/test/elf64so.asm b/test/elf64so.asm
new file mode 100644
index 00000000..715d2d12
--- /dev/null
+++ b/test/elf64so.asm
@@ -0,0 +1,89 @@
+; test source file for assembling to ELF64 shared library
+; build with:
+; nasm -f elf64 elf64so.asm
+; ld -shared -o elf64so.so elf64so.o
+; test with:
+; gcc -o elf64so elftest64.c ./elf64so.so
+; ./elf64so
+
+; This file should test the following:
+; [1] Define and export a global text-section symbol
+; [2] Define and export a global data-section symbol
+; [3] Define and export a global BSS-section symbol
+; [4] Define a non-global text-section symbol
+; [5] Define a non-global data-section symbol
+; [6] Define a non-global BSS-section symbol
+; [7] Define a COMMON symbol
+; [8] Define a NASM local label
+; [9] Reference a NASM local label
+; [10] Import an external symbol
+; [11] Make a PC-relative call to an external symbol
+; [12] Reference a text-section symbol in the text section
+; [13] Reference a data-section symbol in the text section
+; [14] Reference a BSS-section symbol in the text section
+; [15] Reference a text-section symbol in the data section
+; [16] Reference a data-section symbol in the data section
+; [17] Reference a BSS-section symbol in the data section
+
+ BITS 64
+ GLOBAL lrotate:function ; [1]
+ GLOBAL greet:function ; [1]
+ GLOBAL asmstr:data asmstr.end-asmstr ; [2]
+ GLOBAL textptr:data 8 ; [2]
+ GLOBAL selfptr:data 8 ; [2]
+ GLOBAL integer:data 8 ; [3]
+ EXTERN printf ; [10]
+ COMMON commvar 8:8 ; [7]
+ EXTERN _GLOBAL_OFFSET_TABLE_
+
+ SECTION .text
+
+; prototype: long lrotate(long x, int num);
+lrotate: ; [1]
+ push rbp
+ mov rbp,rsp
+ mov rax,rdi
+ mov rcx,rsi
+.label rol rax,1 ; [4] [8]
+ loop .label ; [9] [12]
+ mov rsp,rbp
+ pop rbp
+ ret
+
+; prototype: void greet(void);
+;; rdi - rsi - rdx - rcx - r8 - r9
+;; rbx, rbp, r12-r15 are saved
+greet:
+ mov rax,[rel commvar wrt ..got] ; &commvar
+ mov rcx,[rax] ; commvar
+ mov rax,[rel integer wrt ..got] ; &integer
+ mov rsi,[rax]
+ lea rdx,[rsi+1]
+ mov [rel localint],rdx ; localint = integer+1
+ mov rax,[rel localptr] ; localptr
+ mov rdx,[rax] ; *localptr = localint
+ lea rdi,[rel printfstr]
+ xor eax,eax ; No fp arguments
+ jmp printf wrt ..plt ; [10]
+
+ SECTION .data
+
+; a string
+asmstr db 'hello, world', 0 ; [2]
+.end:
+
+; a string for Printf
+printfstr db "integer=%ld, localint=%ld, commvar=%ld", 10, 0
+
+; some pointers
+localptr dq localint ; [5] [17]
+textptr dq greet wrt ..sym ; [15]
+selfptr dq selfptr wrt ..sym ; [16]
+
+ SECTION .bss
+
+; an integer
+integer resq 1 ; [3]
+
+; a local integer
+localint resq 1 ; [6]
diff --git a/test/elftest.c b/test/elftest.c
index 8dd57a2c..42b3f7e9 100644
--- a/test/elftest.c
+++ b/test/elftest.c
@@ -33,4 +33,6 @@ int main(void)
printf("These pointers should be equal: %p and %p\n", &greet, textptr);
printf("So should these: %p and %p\n", selfptr, &selfptr);
+
+ return 0;
}
diff --git a/test/elftest64.c b/test/elftest64.c
new file mode 100644
index 00000000..5f009a75
--- /dev/null
+++ b/test/elftest64.c
@@ -0,0 +1,42 @@
+/*
+ * build with:
+ * nasm -f elf64 elf64so.asm
+ * ld -shared -o elf64so.so elf64so.o
+ * test with:
+ * gcc -o elf64so elftest64.c ./elf64so.so
+ * ./elf64so
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+
+extern long lrotate(long, int);
+extern void greet(void);
+extern int8_t asmstr[];
+extern void *selfptr;
+extern void *textptr;
+extern long integer;
+long commvar;
+
+int main(void)
+{
+
+ printf("Testing lrotate: should get 0x00400000, 0x00000001\n");
+ printf("lrotate(0x00040000, 4) = 0x%08lx\n", lrotate(0x40000, 4));
+ printf("lrotate(0x00040000, 46) = 0x%08lx\n", lrotate(0x40000, 46));
+
+ printf("This string should read `hello, world': `%s'\n", asmstr);
+
+ printf("&integer = %p, &commvar = %p\n", &integer, &commvar);
+ printf("The integers here should be 1234, 1235 and 4321:\n");
+ integer = 1234;
+ commvar = 4321;
+
+ greet();
+
+ printf("These pointers should be equal: %p and %p\n", &greet, textptr);
+
+ printf("So should these: %p and %p\n", selfptr, &selfptr);
+
+ return 0;
+}