diff --git a/core/arch/arch_exports.h b/core/arch/arch_exports.h index 8eab49dc6ec..56605fef734 100644 --- a/core/arch/arch_exports.h +++ b/core/arch/arch_exports.h @@ -708,9 +708,6 @@ dynamorio_condvar_wake_and_jmp(KSYNCH_TYPE *ksynch /*in xax/r0*/, void dynamorio_nonrt_sigreturn(void); # endif -thread_id_t -dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, void *ctid, - void (*func)(void)); void xfer_to_new_libdr(app_pc entry, void **init_sp, byte *cur_dr_map, size_t cur_dr_size); # endif diff --git a/core/drlibc/drlibc.h b/core/drlibc/drlibc.h index fdc26c2ae68..d65570dfe34 100644 --- a/core/drlibc/drlibc.h +++ b/core/drlibc/drlibc.h @@ -72,6 +72,10 @@ dynamorio_mach_syscall(uint sysnum, uint num_args, ...); # else ptr_int_t dynamorio_syscall(uint sysnum, uint num_args, ...); +/* N.B. func must not return. */ +thread_id_t +dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, void *ctid, + void (*func)(void)); # endif #endif diff --git a/core/ir/decode_shared.c b/core/ir/decode_shared.c index 10b3c784464..8a190790e69 100644 --- a/core/ir/decode_shared.c +++ b/core/ir/decode_shared.c @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2011-2021 Google, Inc. All rights reserved. + * Copyright (c) 2011-2024 Google, Inc. All rights reserved. * Copyright (c) 2001-2010 VMware, Inc. All rights reserved. * **********************************************************/ @@ -179,17 +179,18 @@ int sve_veclen; int sve_veclens[] = { 128, 256, 384, 512, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, 2048 }; -void +bool dr_set_sve_vector_length(int vl) { - /* TODO i#3044: Vector length will be read from h/w when running on SVE. */ - for (int i = 0; i < sizeof(sve_veclens); i++) { + for (int i = 0; i < sizeof(sve_veclens) / sizeof(sve_veclens[0]); i++) { if (vl == sve_veclens[i]) { sve_veclen = vl; - return; + return true; } } - CLIENT_ASSERT(false, "invalid SVE vector length"); + /* Make unusual values visible in case our internal uses mess up. */ + ASSERT_CURIOSITY(false); + return false; } int diff --git a/core/ir/encode_api.h b/core/ir/encode_api.h index d0e0b85366a..be9a94c79ae 100644 --- a/core/ir/encode_api.h +++ b/core/ir/encode_api.h @@ -78,10 +78,11 @@ DR_API /** * AArch64 Scalable Vector Extension's vector length in bits is one of: * 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 + * Returns whether successful. * TODO i#3044: This function will only allow setting vector length if not * running on SVE. */ -void +bool dr_set_sve_vector_length(int vl); DR_API diff --git a/suite/tests/api/ir_aarch64.c b/suite/tests/api/ir_aarch64.c index 1097108f8b0..15ad4f97448 100644 --- a/suite/tests/api/ir_aarch64.c +++ b/suite/tests/api/ir_aarch64.c @@ -6929,11 +6929,16 @@ test_vector_length(void *dcontext) { /* XXX i#6575: Add further tests. For now, make sure these are exported. */ const int new_len = 2048; - /* XXX: Probably this should return a bool so we know whether it succeeded! - * It says it fails if on actual SVE hardware: but is there an easy way to know? + /* XXX: Make this test work when on actual SVE hardware where this API routine + * is documented as failing. */ - dr_set_sve_vector_length(new_len); + bool res = dr_set_sve_vector_length(new_len); + ASSERT(res); ASSERT(dr_get_sve_vector_length() == new_len); + /* Ensure invalid lengths return failure. */ + ASSERT(!dr_set_sve_vector_length(0)); + ASSERT(!dr_set_sve_vector_length(1)); + ASSERT(!dr_set_sve_vector_length(4096)); } int diff --git a/suite/tests/linux/clone.c b/suite/tests/linux/clone.c index e8329ad3b94..afb08ef0318 100644 --- a/suite/tests/linux/clone.c +++ b/suite/tests/linux/clone.c @@ -64,10 +64,6 @@ typedef unsigned long ulong; */ #define CLONE3_SYSCALL_NUM 435 -/* i#762: Hard to get clone() from sched.h, so copy prototype. */ -extern int -clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...); - #define THREAD_STACK_SIZE (32 * 1024) #ifdef X64 @@ -80,8 +76,7 @@ clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...); static int make_clone3_syscall(void *clone_args, ulong clone_args_size, void (*fcn)(void)); static pid_t -create_thread(int (*fcn)(void *), void *arg, void **stack, bool share_sighand, - bool clone_vm); +create_thread(void (*fcn)(void), void **stack, bool share_sighand, bool clone_vm); #ifdef SYS_clone3 static pid_t create_thread_clone3(void (*fcn)(void), void **stack, bool share_sighand, bool clone_vm); @@ -113,10 +108,10 @@ test_thread(bool share_sighand, bool clone_vm, bool use_clone3) /* If SYS_clone3 is not defined, we simply use SYS_clone instead, so that * the expected output is the same in both cases. */ - child = create_thread(run, NULL, &stack, share_sighand, clone_vm); + child = create_thread(run_with_exit, &stack, share_sighand, clone_vm); #endif } else - child = create_thread(run, NULL, &stack, share_sighand, clone_vm); + child = create_thread(run_with_exit, &stack, share_sighand, clone_vm); assert(child > -1); delete_thread(child, stack); } @@ -192,14 +187,14 @@ void *p_tid, *c_tid; * first argument is passed in "arg". Returns the PID of the new * thread */ static pid_t -create_thread(int (*fcn)(void *), void *arg, void **stack, bool share_sighand, - bool clone_vm) +create_thread(void (*fcn)(void), void **stack, bool share_sighand, bool clone_vm) { /* !clone_vm && share_sighand is not supported. */ assert(clone_vm || !share_sighand); pid_t newpid; int flags; void *my_stack; + void *stack_ptr; my_stack = stack_alloc(THREAD_STACK_SIZE); @@ -211,10 +206,12 @@ create_thread(int (*fcn)(void *), void *arg, void **stack, bool share_sighand, flags = (SIGCHLD | CLONE_FS | CLONE_FILES | (share_sighand ? CLONE_SIGHAND : 0) | (clone_vm ? CLONE_VM : 0)); /* The stack arg should point to the stack's highest address (non-inclusive). */ - newpid = clone(fcn, (void *)((size_t)my_stack + THREAD_STACK_SIZE), flags, arg, - &p_tid, NULL, &c_tid); + stack_ptr = (void *)((size_t)my_stack + THREAD_STACK_SIZE); + newpid = dynamorio_clone(flags, stack_ptr, &p_tid, NULL, &c_tid, fcn); - if (newpid == -1) { + if (newpid < 0) { + /* dynamorio_clone doesn't set errno */ + errno = -newpid; perror("Error calling clone\n"); stack_free(my_stack, THREAD_STACK_SIZE); return -1;