From e41b69beaf51a725a98b1ba4480751333b24a06f Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 17 Oct 2008 17:13:26 -0700 Subject: [PATCH] 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.) --- test/Makefile | 27 +++++++++++++++++ test/elf64so.asm | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/elftest.c | 2 ++ test/elftest64.c | 42 ++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 test/elf64so.asm create mode 100644 test/elftest64.c diff --git a/test/Makefile b/test/Makefile index fa949f6..dda674a 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 0000000..715d2d1 --- /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 8dd57a2..42b3f7e 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 0000000..5f009a7 --- /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 +#include + +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; +} -- 2.7.4