diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -6538,17 +6538,42 @@ } return res; } -#define INIT_SEM \ - COMMON_INTERCEPT_FUNCTION(sem_init); \ - COMMON_INTERCEPT_FUNCTION(sem_destroy); \ - COMMON_INTERCEPT_FUNCTION(sem_wait); \ - COMMON_INTERCEPT_FUNCTION(sem_trywait); \ - COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ - COMMON_INTERCEPT_FUNCTION(sem_post); \ - COMMON_INTERCEPT_FUNCTION(sem_getvalue); -#else -#define INIT_SEM -#endif // SANITIZER_INTERCEPT_SEM + +INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) { + void *ctx; + va_list ap; + va_start(ap, oflag); + u32 mode = va_arg(ap, u32); + u32 value = va_arg(ap, u32); + COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value); + if (s) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s)); + va_end(ap); + return s; +} + +INTERCEPTOR(int, sem_unlink, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + return REAL(sem_unlink)(name); +} + +# define INIT_SEM \ + COMMON_INTERCEPT_FUNCTION(sem_init); \ + COMMON_INTERCEPT_FUNCTION(sem_destroy); \ + COMMON_INTERCEPT_FUNCTION(sem_wait); \ + COMMON_INTERCEPT_FUNCTION(sem_trywait); \ + COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ + COMMON_INTERCEPT_FUNCTION(sem_post); \ + COMMON_INTERCEPT_FUNCTION(sem_getvalue); \ + COMMON_INTERCEPT_FUNCTION(sem_open); \ + COMMON_INTERCEPT_FUNCTION(sem_unlink); +#else +# define INIT_SEM +#endif // SANITIZER_INTERCEPT_SEM #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sem_open.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sem_open.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sem_open.cpp @@ -0,0 +1,23 @@ +// RUN: %clangxx -O0 %s -o %t && %run %t + +#include +#include +#include +#include +#include + +int main() { + char name[1024]; + sprintf(name, "/sem_open_test_%d", getpid()); + + sem_t *s1 = sem_open(name, O_CREAT, 0644, 123); + assert(s1 != SEM_FAILED); + + sem_t *s2 = sem_open(name, O_CREAT, 0644, 123); + assert(s2 != SEM_FAILED); + + assert(sem_close(s1) == 0); + assert(sem_close(s2) == 0); + + assert(sem_unlink(name) == 0); +}