From 7861991a3c003faf60ac185caf4f08e01077b0aa Mon Sep 17 00:00:00 2001 From: Daryl Ronningen Date: Fri, 8 Dec 2023 12:31:42 -0800 Subject: [PATCH 2/6] scudo: add necessary plumbing --- Makefile | 31 ++++++++++++++-- configure | 72 ++++++++++++++++++++++++++++++++++--- src/env/__init_tls.c | 1 + src/include/errno.h | 8 +++++ src/include/features.h | 2 ++ src/include/pthread.h | 4 +++ src/include/sys/stat.h | 2 ++ src/include/time.h | 4 +++ src/internal/atomic.h | 4 +++ src/internal/linux/futex.h | 31 ++++++++++++++++ src/internal/pthread_impl.h | 3 ++ src/internal/syscall.h | 4 +++ src/malloc/calloc.c | 4 +++ src/malloc/libc_calloc.c | 4 +++ src/thread/pthread_create.c | 6 ++++ 15 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 src/internal/linux/futex.h diff --git a/Makefile b/Makefile index e8cc4436..17158106 100644 --- a/Makefile +++ b/Makefile @@ -17,16 +17,19 @@ includedir = $(prefix)/include libdir = $(prefix)/lib syslibdir = /lib -MALLOC_DIR = mallocng +MALLOC_DIR = scudo SRC_DIRS = $(addprefix $(srcdir)/,src/* src/malloc/$(MALLOC_DIR) crt ldso $(COMPAT_SRC_DIRS)) BASE_GLOBS = $(addsuffix /*.c,$(SRC_DIRS)) +CPP_GLOBS = $(addsuffix /*.cpp,$(SRC_DIRS)) ARCH_GLOBS = $(addsuffix /$(ARCH)/*.[csS],$(SRC_DIRS)) BASE_SRCS = $(sort $(wildcard $(BASE_GLOBS))) +CPP_SRCS = $(sort $(wildcard $(CPP_GLOBS))) ARCH_SRCS = $(sort $(wildcard $(ARCH_GLOBS))) BASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS))) +CPP_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(CPP_SRCS))) ARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS))) REPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS))) -ALL_OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS)))) +ALL_OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(CPP_OBJS) $(ARCH_OBJS)))) LIBC_OBJS = $(filter obj/src/%,$(ALL_OBJS)) $(filter obj/compat/%,$(ALL_OBJS)) LDSO_OBJS = $(filter obj/ldso/%,$(ALL_OBJS:%.o=%.lo)) @@ -45,10 +48,18 @@ CPPFLAGS = CFLAGS = CFLAGS_AUTO = -Os -pipe CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc +CXXFLAGS = +CXXFLAGS_AUTO = -Os -pipe +CXXFLAGS_FSE = -std=c++17 -ffreestanding -nostdinc -nostdinc++ -fno-exceptions -fno-rtti -fvisibility=hidden CFLAGS_ALL = $(CFLAGS_C99FSE) CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/include -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include + +CXXFLAGS_ALL = $(CXXFLAGS_FSE) +CXXFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/include -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include + CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS) +CXXFLAGS_ALL += $(CPPFLAGS) $(CXXFLAGS_AUTO) $(CXXFLAGS) LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS) @@ -117,6 +128,7 @@ obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%)) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3 +$(OPTIMIZE_SRCS:$(srcdir)/%.cpp=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.cpp=obj/%.lo): CXXFLAGS += -O3 MEMOPS_OBJS = $(filter %/memcpy.o %/memmove.o %/memcmp.o %/memset.o, $(LIBC_OBJS)) $(MEMOPS_OBJS) $(MEMOPS_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS) @@ -130,8 +142,17 @@ $(NOSSP_OBJS) $(NOSSP_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP) $(CRT_OBJS): CFLAGS_ALL += -DCRT $(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC +$(LOBJS) $(LDSO_OBJS): CXXFLAGS_ALL += -fPIC + +obj/src/malloc/scudo/crc32_hw.lo: CXXFLAGS_ALL += $(CXXFLAGS_CRC) + +ifeq (scudo,$(MALLOC_DIR)) +obj/src/malloc/calloc.lo: CFLAGS_ALL += -DLIBC_CALLOC_EXTERNAL +obj/src/malloc/libc_calloc.lo: CFLAGS_ALL += -DLIBC_CALLOC_EXTERNAL +endif CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $< +CXX_CMD = $(CXX) $(CXXFLAGS_ALL) -c -o $@ $< # Choose invocation of assembler to be used ifeq ($(ADD_CFI),yes) @@ -149,6 +170,9 @@ obj/%.o: $(srcdir)/%.S obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH) $(CC_CMD) +obj/%.o: $(srcdir)/%.cpp $(GENH) $(IMPH) + $(CXX_CMD) + obj/%.lo: $(srcdir)/%.s $(AS_CMD) @@ -158,6 +182,9 @@ obj/%.lo: $(srcdir)/%.S obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH) $(CC_CMD) +obj/%.lo: $(srcdir)/%.cpp $(GENH) $(IMPH) + $(CXX_CMD) + lib/libc.so: $(LOBJS) $(LDSO_OBJS) $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \ -Wl,-e,_dlstart -o $@ $(LOBJS) $(LDSO_OBJS) $(LIBCC) diff --git a/configure b/configure index 853bf05e..2a0632fa 100755 --- a/configure +++ b/configure @@ -63,6 +63,7 @@ fail () { echo "$*" ; exit 1 ; } fnmatch () { eval "case \"\$2\" in $1) return 0 ;; *) return 1 ;; esac" ; } cmdexists () { type "$1" >/dev/null 2>&1 ; } trycc () { test -z "$CC" && cmdexists "$1" && CC=$1 ; } +trycxx () { test -z "$CXX" && cmdexists "$1" && CXX=$1 ; } stripdir () { while eval "fnmatch '*/' \"\${$1}\"" ; do eval "$1=\${$1%/}" ; done @@ -97,6 +98,20 @@ return 1 fi } +tryxflag () { +printf "checking whether C++ compiler accepts %s... " "$2" +echo "typedef int x;" > "$tmpc" +if $CXX $CXXFLAGS_TRY $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then +printf "yes\n" +eval "$1=\"\${$1} \$2\"" +eval "$1=\${$1# }" +return 0 +else +printf "no\n" +return 1 +fi +} + tryldflag () { printf "checking whether linker accepts %s... " "$2" echo "typedef int x;" > "$tmpc" @@ -120,6 +135,10 @@ CFLAGS_AUTO= CFLAGS_MEMOPS= CFLAGS_NOSSP= CFLAGS_TRY= +CXXFLAGS_FSE= +CXXFLAGS_AUTO= +CXXFLAGS_CRC= +CXXFLAGS_TRY= LDFLAGS_AUTO= LDFLAGS_TRY= OPTIMIZE_GLOBS= @@ -142,7 +161,7 @@ static=yes wrapper=auto gcc_wrapper=no clang_wrapper=no -malloc_dir=mallocng +malloc_dir=scudo for arg ; do case "$arg" in @@ -180,7 +199,9 @@ case "$arg" in AR=*) AR=${arg#*=} ;; RANLIB=*) RANLIB=${arg#*=} ;; CC=*) CC=${arg#*=} ;; +CXX=*) CXX=${arg#*=} ;; CFLAGS=*) CFLAGS=${arg#*=} ;; +CXXFLAGS=*) CXXFLAGS=${arg#*=} ;; CPPFLAGS=*) CPPFLAGS=${arg#*=} ;; LDFLAGS=*) LDFLAGS=${arg#*=} ;; CROSS_COMPILE=*) CROSS_COMPILE=${arg#*=} ;; @@ -253,6 +274,21 @@ printf "no; compiler output follows:\n%s\n" "$output" exit 1 fi +printf "checking for C++ compiler... " +trycxx ${CROSS_COMPILE}g++ +trycxx ${CROSS_COMPILE}c++ +printf "%s\n" "$CXX" +test -n "$CXX" || { echo "$0: cannot find a C++ compiler" ; exit 1 ; } + +printf "checking whether C++ compiler works... " +echo "typedef int x;" > "$tmpc" +if output=$($CXX $CPPFLAGS $CXXFLAGS -c -o /dev/null "$tmpc" 2>&1) ; then +printf "yes\n" +else +printf "no; compiler output follows:\n%s\n" "$output" +exit 1 +fi + # # Figure out options to force errors on unknown flags. # @@ -353,6 +389,14 @@ tryflag CFLAGS_C99FSE -fexcess-precision=standard \ || { test "$ARCH" = i386 && tryflag CFLAGS_C99FSE -ffloat-store ; } tryflag CFLAGS_C99FSE -frounding-math +tryxflag CXXFLAGS_FSE -std=c++17 +tryxflag CXXFLAGS_FSE -nostdinc +tryxflag CXXFLAGS_FSE -nostdinc++ +tryxflag CXXFLAGS_FSE -fno-exceptions +tryxflag CXXFLAGS_FSE -fno-rtti +tryxflag CXXFLAGS_FSE -ffreestanding || tryxflag CXXFLAGS_FSE -fno-builtin +tryxflag CXXFLAGS_FSE -fvisibility=internal || tryxflag CXXFLAGS_FSE -fvisibility=hidden + # # Semantically we want to insist that our sources follow the # C rules for type-based aliasing, but most if not all real-world @@ -388,6 +432,7 @@ fi # linked with such object files. Fix this. # tryflag CFLAGS_C99FSE -Wa,--noexecstack +tryxflag CXXFLAGS_FSE -Wa,--noexecstack # # Check for options to disable stack protector, which needs to be @@ -405,10 +450,16 @@ tryflag CFLAGS_NOSSP -fno-stack-protector # tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns +# enable the necessary instruction set for hardware crc32 +if test "$ARCH" = "x86_64"; then + tryxflag CXXFLAGS_CRC -mcrc32 || tryxflag CXXFLAGS_CRC -msse4.2 +fi +test "$ARCH" = "aarch64" && tryflag CXXFLAGS_CRC -mcrc + # # Enable debugging if requessted. # -test "$debug" = yes && CFLAGS_AUTO=-g +test "$debug" = yes && CFLAGS_AUTO=-g && CXXFLAGS_AUTO=-g # # Preprocess asm files to add extra debugging information if debug is @@ -445,7 +496,8 @@ xno|x) printf "disabled\n" ; optimize=no ;; esac test "$optimize" = no || tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O2 -test "$optimize" = yes && optimize="internal,malloc,string" +test "$optimize" = no || tryflag CXXFLAGS_AUTO -Os || tryflag CXXFLAGS_AUTO -O2 +test "$optimize" = yes && optimize="internal,malloc,malloc/scudo,string" if fnmatch 'no|size' "$optimize" ; then : else @@ -457,6 +509,7 @@ case "$optimize" in esac printf " $this" case "$this" in +malloc/scudo) this=$this/*.cpp ;; */*.c) ;; */*) this=$this*.c ;; *) this=$this/*.c ;; @@ -469,6 +522,7 @@ fi # Always try -pipe tryflag CFLAGS_AUTO -pipe +tryxflag CXXFLAGS_AUTO -pipe # # If debugging is disabled, omit frame pointer. Modern GCC does this @@ -478,6 +532,7 @@ tryflag CFLAGS_AUTO -pipe if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then : else tryflag CFLAGS_AUTO -fomit-frame-pointer +tryxflag CXXFLAGS_AUTO -fomit-frame-pointer fi # @@ -488,6 +543,8 @@ fi # tryflag CFLAGS_AUTO -fno-unwind-tables tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables +tryxflag CXXFLAGS_AUTO -fno-unwind-tables +tryxflag CXXFLAGS_AUTO -fno-asynchronous-unwind-tables # # Attempt to put each function and each data object in its own @@ -499,6 +556,8 @@ tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables # tryflag CFLAGS_AUTO -ffunction-sections tryflag CFLAGS_AUTO -fdata-sections +tryxflag CXXFLAGS_AUTO -ffunction-sections +tryxflag CXXFLAGS_AUTO -fdata-sections # # On x86, make sure we don't have incompatible instruction set @@ -519,7 +578,7 @@ fi # to start from a clean slate. So use -w if building with clang. Also # turn off a common on-by-default cast warning regardless of compiler. # -test "$cc_family" = clang && tryflag CFLAGS_AUTO -w +test "$cc_family" = clang && tryflag CFLAGS_AUTO -w && tryxflag CXXFLAGS_AUTO -w tryflag CFLAGS_AUTO -Wno-pointer-to-int-cast @@ -787,11 +846,16 @@ libdir = $libdir includedir = $includedir syslibdir = $syslibdir CC = $CC +CXX = $CXX CFLAGS = $CFLAGS CFLAGS_AUTO = $CFLAGS_AUTO CFLAGS_C99FSE = $CFLAGS_C99FSE CFLAGS_MEMOPS = $CFLAGS_MEMOPS CFLAGS_NOSSP = $CFLAGS_NOSSP +CXXFLAGS = $CXXFLAGS +CXXFLAGS_AUTO = $CXXFLAGS_AUTO +CXXFLAGS_FSE = $CXXFLAGS_FSE +CXXFLAGS_CRC = $CXXFLAGS_CRC CPPFLAGS = $CPPFLAGS LDFLAGS = $LDFLAGS LDFLAGS_AUTO = $LDFLAGS_AUTO diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c index a93141ed..6347577c 100644 --- a/src/env/__init_tls.c +++ b/src/env/__init_tls.c @@ -21,6 +21,7 @@ int __init_tp(void *p) td->detach_state = DT_JOINABLE; td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock); td->locale = &libc.global_locale; + td->scudo_tsd = NULL; td->robust_list.head = &td->robust_list.head; td->sysinfo = __sysinfo; td->next = td->prev = td; diff --git a/src/include/errno.h b/src/include/errno.h index 8ec49377..547e2af0 100644 --- a/src/include/errno.h +++ b/src/include/errno.h @@ -3,6 +3,10 @@ #include "../../include/errno.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifdef __GNUC__ __attribute__((const)) #endif @@ -11,4 +15,8 @@ hidden int *___errno_location(void); #undef errno #define errno (*___errno_location()) +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/include/features.h b/src/include/features.h index f17bd151..157f2def 100644 --- a/src/include/features.h +++ b/src/include/features.h @@ -3,7 +3,9 @@ #include "../../include/features.h" +#ifndef __cplusplus #define weak __attribute__((__weak__)) +#endif #define hidden __attribute__((__visibility__("hidden"))) #define weak_alias(old, new) \ extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) diff --git a/src/include/pthread.h b/src/include/pthread.h index 7167d3e1..0107a704 100644 --- a/src/include/pthread.h +++ b/src/include/pthread.h @@ -3,6 +3,8 @@ #include "../../include/pthread.h" +#ifndef __cplusplus + hidden int __pthread_once(pthread_once_t *, void (*)(void)); hidden void __pthread_testcancel(void); hidden int __pthread_setcancelstate(int, int *); @@ -26,4 +28,6 @@ hidden int __pthread_rwlock_trywrlock(pthread_rwlock_t *); hidden int __pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict); hidden int __pthread_rwlock_unlock(pthread_rwlock_t *); +#endif /* __cplusplus */ + #endif diff --git a/src/include/sys/stat.h b/src/include/sys/stat.h index 59339bee..cc3af59d 100644 --- a/src/include/sys/stat.h +++ b/src/include/sys/stat.h @@ -3,7 +3,9 @@ #include "../../../include/sys/stat.h" +#ifndef __cplusplus hidden int __fstat(int, struct stat *); hidden int __fstatat(int, const char *restrict, struct stat *restrict, int); +#endif #endif diff --git a/src/include/time.h b/src/include/time.h index cbabde47..8eefd311 100644 --- a/src/include/time.h +++ b/src/include/time.h @@ -3,6 +3,8 @@ #include "../../include/time.h" +#ifndef __cplusplus + hidden int __clock_gettime(clockid_t, struct timespec *); hidden int __clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *); @@ -12,4 +14,6 @@ hidden struct tm *__localtime_r(const time_t *restrict, struct tm *restrict); hidden size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t); +#endif /* __cplusplus */ + #endif diff --git a/src/internal/atomic.h b/src/internal/atomic.h index 96c1552d..9c4e720c 100644 --- a/src/internal/atomic.h +++ b/src/internal/atomic.h @@ -3,6 +3,8 @@ #include +#ifndef __cplusplus + #include "atomic_arch.h" #ifdef a_ll @@ -330,4 +332,6 @@ static inline int a_clz_32(uint32_t x) } #endif +#endif /* __cplusplus */ + #endif diff --git a/src/internal/linux/futex.h b/src/internal/linux/futex.h new file mode 100644 index 00000000..0e216dcc --- /dev/null +++ b/src/internal/linux/futex.h @@ -0,0 +1,31 @@ +#ifndef _INTERNAL_LINUX_FUTEX_H +#define _INTERNAL_LINUX_FUTEX_H + +extern "C" { +/* while at it, use the prefixed versions for mmap and so on */ +#include +/* must be first, otherwise the below include here would result in the syscall + * function in unistd being replaced by a macro into what would be invalid code + */ +#include +/* we include this here, so that linux.cpp in scudo does not use the unistd + * syscall definition but instead uses the macro that expands to raw calls + */ +#include "syscall.h" +} + +#define mmap __mmap +#define munmap __munmap +#define mremap __mremap +#define madvise __madvise +#define mprotect __mprotect + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +#define FUTEX_PRIVATE_FLAG 128 + +#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) + +#endif diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index de2b9d8b..22b39232 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -56,6 +56,7 @@ struct pthread { volatile int timer_id; locale_t locale; volatile int killlock[1]; + void *scudo_tsd; char *dlerror_buf; void *stdio_locks; @@ -187,6 +188,8 @@ hidden void __tl_lock(void); hidden void __tl_unlock(void); hidden void __tl_sync(pthread_t); +hidden void __malloc_tsd_teardown(void *p); + extern hidden volatile int __thread_list_lock; extern hidden volatile int __abort_lock[1]; diff --git a/src/internal/syscall.h b/src/internal/syscall.h index 4a446157..a4ae20b5 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -58,6 +58,7 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) +#ifndef __cplusplus static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f) { long r; @@ -74,6 +75,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) #define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \ __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) +#endif /* __cplusplus */ /* fixup legacy 16-bit junk */ @@ -391,8 +393,10 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) #define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) +#ifndef __cplusplus hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); hidden void *__vdsosym(const char *, const char *); +#endif #endif diff --git a/src/malloc/calloc.c b/src/malloc/calloc.c index bf6bddca..6aa482c6 100644 --- a/src/malloc/calloc.c +++ b/src/malloc/calloc.c @@ -32,6 +32,10 @@ weak_alias(allzerop, __malloc_allzerop); void *calloc(size_t m, size_t n) { +#ifdef LIBC_CALLOC_EXTERNAL + if (!__malloc_replaced) + return __libc_calloc(m, n); +#endif if (n && m > (size_t)-1/n) { errno = ENOMEM; return 0; diff --git a/src/malloc/libc_calloc.c b/src/malloc/libc_calloc.c index d25eabea..3895c8cf 100644 --- a/src/malloc/libc_calloc.c +++ b/src/malloc/libc_calloc.c @@ -1,4 +1,8 @@ +#ifndef LIBC_CALLOC_EXTERNAL + #define calloc __libc_calloc #define malloc __libc_malloc #include "calloc.c" + +#endif diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 087f6206..b1345b34 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -68,6 +68,7 @@ _Noreturn void __pthread_exit(void *result) } __pthread_tsd_run_dtors(); + __malloc_tsd_teardown(&self->scudo_tsd); __block_app_sigs(&set); @@ -319,6 +320,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att new->self = new; new->tsd = (void *)tsd; new->locale = &libc.global_locale; + new->scudo_tsd = NULL; if (attr._a_detach) { new->detach_state = DT_DETACHED; } else { @@ -395,3 +397,7 @@ fail: weak_alias(__pthread_exit, pthread_exit); weak_alias(__pthread_create, pthread_create); + +static void malloc_tsd_teardown(void *p) {} + +weak_alias(malloc_tsd_teardown, __malloc_tsd_teardown); -- 2.43.0