Test and Makefile rules for 32- and 64-bit ELF shared libraries
authorH. Peter Anvin <hpa@zytor.com>
Sat, 18 Oct 2008 00:13:26 +0000 (17:13 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 18 Oct 2008 00:13:26 +0000 (17:13 -0700)
Add Makefile rules for the 32-bit ELF shared library test, and add a
64-bit ELF shared library test (still work in progress.)

test/Makefile
test/elf64so.asm [new file with mode: 0644]
test/elftest.c
test/elftest64.c [new file with mode: 0644]

index fa949f6..dda674a 100644 (file)
@@ -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 (file)
index 0000000..715d2d1
--- /dev/null
@@ -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]
index 8dd57a2..42b3f7e 100644 (file)
@@ -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 (file)
index 0000000..5f009a7
--- /dev/null
@@ -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;
+}