diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index b10ce7fa44afc..a35ff2306c14e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -10387,6 +10387,24 @@ INTERCEPTOR(int, getservbyport_r, int port, const char *proto, # define INIT_GETSERVBYPORT_R #endif +#if SANITIZER_INTERCEPT_CPUSET_GETDOMAIN +INTERCEPTOR(int, cpuset_getdomain, int level, int which, __int64 id, + SIZE_T domainsetsize, __sanitizer_domainset_t *mask, int *policy) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cpuset_getdomain, level, which, id, domainsetsize, + mask, policy); + int res = REAL(cpuset_getdomain)(level, which, id, domainsetsize, mask, policy); + if (mask && !res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, domainsetsize); + if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); + } + return res; +} +#define INIT_CPUSET_GETDOMAIN COMMON_INTERCEPT_FUNCTION(cpuset_getdomain); +#else +#define INIT_CPUSET_GETDOMAIN +#endif + #include "sanitizer_common_interceptors_netbsd_compat.inc" namespace __sanitizer { @@ -10711,6 +10729,7 @@ static void InitializeCommonInterceptors() { INIT_PREADV2; INIT_PWRITEV2; INIT_FREADLINK; + INIT_CPUSET_GETDOMAIN; INIT___PRINTF_CHK; INIT_GETSERVENT_R; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 88ecd7e16306a..e1461d4f9cb4e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -649,6 +649,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD #define SANITIZER_INTERCEPT_ARGP_PARSE SI_GLIBC #define SANITIZER_INTERCEPT_CPUSET_GETAFFINITY SI_FREEBSD + // FIXME: also available from musl 1.2.5 #define SANITIZER_INTERCEPT_PREADV2 (SI_LINUX && __GLIBC_PREREQ(2, 26)) #define SANITIZER_INTERCEPT_PWRITEV2 (SI_LINUX && __GLIBC_PREREQ(2, 26)) @@ -673,6 +674,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, # define SANITIZER_INTERCEPT_FREE_SIZED 0 # define SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED 0 #endif +#define SANITIZER_INTERCEPT CPUSET_GETDOMAIN SI_FREEBSD // This macro gives a way for downstream users to override the above // interceptor macros irrespective of the platform they are on. They have diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index c4fa1e3c1f6fa..bbbf2c4ca2628 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,7 @@ void *__sanitizer_get_link_map_by_dlopen_handle(void *handle) { } unsigned struct_cpuset_sz = sizeof(cpuset_t); +unsigned struct_domainset_sz = sizeof(domainset_t); unsigned struct_cap_rights_sz = sizeof(cap_rights_t); unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index 1cbb40e0b2ffc..eb7e314486661 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -728,9 +728,16 @@ struct __sanitizer_cpuset { #endif }; +struct __sanitizer_domainset { + long __bits[(256 + (sizeof(long) * 8) - 1) / (sizeof(long) * 8)]; +}; + typedef struct __sanitizer_cpuset __sanitizer_cpuset_t; extern unsigned struct_cpuset_sz; +typedef struct __sanitizer_domainset __sanitizer_domainset_t; +extern unsigned struct_domainset_sz; + typedef unsigned long long __sanitizer_eventfd_t; } // namespace __sanitizer diff --git a/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/cpuset_getcomain.cpp b/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/cpuset_getcomain.cpp new file mode 100644 index 0000000000000..96aba81bc3792 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/cpuset_getcomain.cpp @@ -0,0 +1,17 @@ +// RUN: %clangxx -O0 %s -o %t && %run %t + +#include +#include +#include +#include + +int main() { + domainset_t ds; + int pc; + + int res = + cpuset_getdomain(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, sizeof(ds), &ds, &pc); + assert(res == 0); + assert(pc != DOMAINSET_POLICY_INVALID); + return 0; +}