diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c new file mode 100644 index 000000000000..49d9fb6f37cd --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c @@ -0,0 +1,55 @@ +// Test that __orc_rt_macho_jit_dlopen and __orc_rt_macho_jit_dlclose work as +// expected for a dlopen; dlclose; dlopen; dlclose; sequence: the first dlclose +// should run destructors, and the second dlopen should re-run initializers. +// +// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S +// RUN: %clang -c -o %t.test.o %s +// RUN: %llvm_jitlink \ +// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s + +// CHECK: entering main +// CHECK-NEXT: first dlopen +// CHECK-NEXT: constructor +// CHECK-NEXT: second dlopen +// CHECK-NEXT: first dlclose +// CHECK-NEXT: second dlclose +// CHECK-NEXT: destructor +// CHECK-NEXT: leaving main + +int printf(const char * restrict format, ...); +void *dlopen(const char* path, int mode); +int dlclose(void *handle); + +int main(int argc, char *argv[]) { + printf("entering main\n"); + printf("first dlopen\n"); + void *H = dlopen("inits", 0); + if (!H) { + printf("failed\n"); + return -1; + } + printf("second dlopen\n"); + void *I = dlopen("inits", 0); + if (!I) { + printf("failed\n"); + return -1; + } + if (I != H) { + printf("handles do not match\n"); + return -1; + } + printf("first dlclose\n"); + if (dlclose(I) == -1) { + printf("failed\n"); + return -1; + } + printf("second dlclose\n"); + if (dlclose(H) == -1) { + printf("failed\n"); + return -1; + } + printf("leaving main\n"); + return 0; +} diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.S deleted file mode 100644 index 5076f7248600..000000000000 --- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.S +++ /dev/null @@ -1,119 +0,0 @@ -// Test that __orc_rt_macho_jit_dlopen and __orc_rt_macho_jit_dlclose run -// constructors and destructors as expected. -// -// This test calls dlopen and dlclose twice. We expect the inner calls to be -// no-ops. -// -// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S -// RUN: %clang -c -o %t.test.o %s -// RUN: %llvm_jitlink \ -// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ -// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ -// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s -// -// CHECK: entering main -// CHECK-NEXT: first dlopen -// CHECK-NEXT: constructor -// CHECK-NEXT: second dlopen -// CHECK-NEXT: first dlclose -// CHECK-NEXT: second dlclose -// CHECK-NEXT: destructor -// CHECK-NEXT: leaving main - - .section __TEXT,__text,regular,pure_instructions - .build_version macos, 12, 0 sdk_version 13, 0 - .globl _main - .p2align 4, 0x90 -_main: - - pushq %rbp - movq %rsp, %rbp - pushq %r15 - pushq %r14 - pushq %rbx - pushq %rax - leaq L_str(%rip), %rdi - callq _puts - leaq L_str.9(%rip), %rdi - callq _puts - leaq L_.str.2(%rip), %rdi - movl $1, %esi - callq _dlopen - movl $-1, %r14d - leaq L_str.17(%rip), %r15 - testq %rax, %rax - je LBB0_6 - - movq %rax, %rbx - leaq L_str.11(%rip), %rdi - callq _puts - leaq L_.str.2(%rip), %rdi - movl $1, %esi - callq _dlopen - testq %rax, %rax - je LBB0_6 - - cmpq %rbx, %rax - je LBB0_4 - - leaq L_str.18(%rip), %r15 - jmp LBB0_6 -LBB0_4: - leaq L_str.13(%rip), %rdi - callq _puts - movq %rbx, %rdi - callq _dlclose - cmpl $-1, %eax - je LBB0_6 - - leaq L_str.14(%rip), %rdi - callq _puts - movq %rbx, %rdi - callq _dlclose - xorl %r14d, %r14d - cmpl $-1, %eax - sete %r14b - leaq L_str.17(%rip), %rax - leaq L_str.15(%rip), %r15 - cmoveq %rax, %r15 - negl %r14d -LBB0_6: - movq %r15, %rdi - callq _puts - movl %r14d, %eax - addq $8, %rsp - popq %rbx - popq %r14 - popq %r15 - popq %rbp - retq - - .section __TEXT,__cstring,cstring_literals -L_.str.2: - .asciz "inits" - -L_str: - .asciz "entering main" - -L_str.9: - .asciz "first dlopen" - -L_str.11: - .asciz "second dlopen" - -L_str.13: - .asciz "first dlclose" - -L_str.14: - .asciz "second dlclose" - -L_str.15: - .asciz "leaving main" - -L_str.17: - .asciz "failed" - -L_str.18: - .asciz "handles do not match" - -.subsections_via_symbols diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c new file mode 100644 index 000000000000..ee9b9890934c --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c @@ -0,0 +1,34 @@ +// Test that __orc_rt_macho_jit_dlopen and __orc_rt_macho_jit_dlclose work as +// expected for a straightforward dlopen; dlclose sequence: first the +// constructors should be run, then destructors. +// +// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S +// RUN: %clang -c -o %t.test.o %s +// RUN: %llvm_jitlink \ +// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s + +// CHECK: entering main +// CHECK-NEXT: constructor +// CHECK-NEXT: destructor +// CHECK-NEXT: leaving main + +int printf(const char * restrict format, ...); +void *dlopen(const char* path, int mode); +int dlclose(void *handle); + +int main(int argc, char *argv[]) { + printf("entering main\n"); + void *H = dlopen("inits", 0); + if (!H) { + printf("failed\n"); + return -1; + } + if (dlclose(H) == -1) { + printf("failed\n"); + return -1; + } + printf("leaving main\n"); + return 0; +} diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-re-dlopen.c b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-re-dlopen.c new file mode 100644 index 000000000000..1f3c88bf9b43 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-re-dlopen.c @@ -0,0 +1,45 @@ +// Test that __orc_rt_macho_jit_dlopen and __orc_rt_macho_jit_dlclose work as +// expected for a dlopen; dlclose; dlopen; dlclose; sequence: the first dlclose +// should run destructors, and the second dlopen should re-run initializers. +// +// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S +// RUN: %clang -c -o %t.test.o %s +// RUN: %llvm_jitlink \ +// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s + +// CHECK: entering main +// CHECK-NEXT: constructor +// CHECK-NEXT: destructor +// CHECK-NEXT: constructor +// CHECK-NEXT: destructor +// CHECK-NEXT: leaving main + +int printf(const char * restrict format, ...); +void *dlopen(const char* path, int mode); +int dlclose(void *handle); + +int main(int argc, char *argv[]) { + printf("entering main\n"); + void *H = dlopen("inits", 0); + if (!H) { + printf("failed\n"); + return -1; + } + if (dlclose(H) == -1) { + printf("failed\n"); + return -1; + } + H = dlopen("inits", 0); + if (!H) { + printf("failed\n"); + return -1; + } + if (dlclose(H) == -1) { + printf("failed\n"); + return -1; + } + printf("leaving main\n"); + return 0; +}