[ORC-RT] Add two new jit-dlopen testcases, and switch to .c for dlopen tests.

We don't need precise control over the low-level behavior of these testcases so
C should be preferred for readability.

The new testcases test (1) the base dlopen case (running initializers and
deinitializers), and (2) the serial case of dlopen; dlclose; dlopen; dlclose,
where we expect the initializers and deinitializers to be run twice.
This commit is contained in:
Lang Hames 2022-02-10 13:53:03 +11:00
parent c2246eb893
commit 8be890b8cd
4 changed files with 134 additions and 119 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}