Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -330,6 +330,64 @@ -isysroot ${IOSSIM_SDK_DIR}) endif() +set(ct_c ${COMPILER_RT_SOURCE_DIR}/make/platform/clang_linux_test_libc.c) +check_include_file(sys/ustat.h HAVE_SYS_USTAT_H) +check_include_file(utime.h HAVE_UTIME_H) +check_include_file(wordexp.h HAVE_WORDEXP_H) +check_include_file(glob.h HAVE_GLOB_H) +include(FunctionExistsNotStub) +check_function_exists_not_stub(${ct_c} nanosleep HAVE_NANOSLEEP) +check_function_exists_not_stub(${ct_c} usleep HAVE_USLEEP) +include(CheckTypeSize) +# check for sizeof sigset_t +set(oCMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES}") +set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} signal.h) +check_type_size("sigset_t" SIZEOF_SIGSET_T BUILTIN_TYPES_ONLY) +if(EXISTS HAVE_SIZEOF_SIGSET_T) + set(SIZEOF_SIGSET_T ${HAVE_SIZEOF_SIGSET_T}) +endif() +set(CMAKE_EXTRA_INCLUDE_FILES "${oCMAKE_EXTRA_INCLUDE_FILES}") +# check for sizeof struct statfs64 +set(oCMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES}") +check_include_file(sys/statfs.h HAVE_SYS_STATFS_H) +check_include_file(sys/vfs.h HAVE_SYS_VFS_H) +if(HAVE_SYS_STATFS_H) + set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} sys/statfs.h) +endif() +if(HAVE_SYS_VFS_H) + set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} sys/vfs.h) +endif() +# Have to pass _LARGEFILE64_SOURCE otherwise there is no struct statfs64. +# We forcefully enable LFS to retain glibc legacy behaviour herein. +set(oCMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) +set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_LARGEFILE64_SOURCE) +check_type_size("struct statfs64" SIZEOF_STRUCT_STATFS64) +if(EXISTS HAVE_SIZEOF_STRUCT_STATFS64) + set(SIZEOF_STRUCT_STATFS64 ${HAVE_SIZEOF_STRUCT_STATFS64}) +else() + set(CMAKE_REQUIRED_DEFINITIONS ${oCMAKE_REQUIRED_DEFINITIONS}) +endif() +set(CMAKE_EXTRA_INCLUDE_FILES "${oCMAKE_EXTRA_INCLUDE_FILES}") +# do not set(CMAKE_REQUIRED_DEFINITIONS ${oCMAKE_REQUIRED_DEFINITIONS}) +# it back here either way. +include(CheckStructHasMember) +check_struct_has_member(glob_t gl_flags glob.h HAVE_GLOB_T_GL_FLAGS) +check_struct_has_member(glob_t gl_closedir glob.h HAVE_GLOB_T_GL_CLOSEDIR) +check_struct_has_member(glob_t gl_readdir glob.h HAVE_GLOB_T_GL_READDIR) +check_struct_has_member(glob_t gl_opendir glob.h HAVE_GLOB_T_GL_OPENDIR) +check_struct_has_member(glob_t gl_lstat glob.h HAVE_GLOB_T_GL_LSTAT) +check_struct_has_member(glob_t gl_stat glob.h HAVE_GLOB_T_GL_STAT) + +# folks seem to have an aversion to configure_file? So be it.. +foreach(x HAVE_SYS_USTAT_H HAVE_UTIME_H HAVE_WORDEXP_H HAVE_GLOB_H +HAVE_NANOSLEEP HAVE_USLEEP SIZEOF_SIGSET_T SIZEOF_STRUCT_STATFS64 +HAVE_GLOB_T_GL_FLAGS HAVE_GLOB_T_GL_CLOSEDIR +HAVE_GLOB_T_GL_READDIR HAVE_GLOB_T_GL_OPENDIR +HAVE_GLOB_T_GL_LSTAT HAVE_GLOB_T_GL_STAT) +def_undef_string(${x} SANITIZER_COMMON_CFLAGS) +endforeach() + + # Architectures supported by Sanitizer runtimes. Specific sanitizers may # support only subset of these (e.g. TSan works on x86_64 only). filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH Index: cmake/Modules/CompilerRTUtils.cmake =================================================================== --- cmake/Modules/CompilerRTUtils.cmake +++ cmake/Modules/CompilerRTUtils.cmake @@ -59,3 +59,18 @@ append_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list}) append_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list}) endmacro() + +# Appends -Dvalue=${value}/-Uvalue to all strings in ARGN +macro(def_undef_string condition) + if("${${condition}}" STREQUAL "") + foreach(str ${ARGN}) + set(${str} "${${str}} -U${condition}") + endforeach() + else() + foreach(str ${ARGN}) + set(${str} "${${str}} '-D${condition}=${${condition}}'") + endforeach() + endif() +endmacro() + + Index: cmake/Modules/FunctionExistsNotStub.cmake =================================================================== --- /dev/null +++ cmake/Modules/FunctionExistsNotStub.cmake @@ -0,0 +1,56 @@ +INCLUDE(CheckFunctionExists) + +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +# CMAKE_REQUIRED_FLAGS = string of compile command line flags +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +# CMAKE_REQUIRED_INCLUDES = list of include directories + +macro(CHECK_FUNCTION_EXISTS_NOT_STUB CSRC FUNCTION VARIABLE) + if(NOT DEFINED CHECKED_STUB_${VARIABLE}) + set(CHECKED_STUB_${VARIABLE} "done" CACHE INTERNAL "checked stub of ${FUNCTION}") + CHECK_FUNCTION_EXISTS("${FUNCTION}" "${VARIABLE}") + if(DEFINED ${VARIABLE}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for stubbed out ${FUNCTION}") + endif() + if(CMAKE_REQUIRED_INCLUDES) + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + else() + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES) + endif() + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_FLAGS ${CMAKE_REQUIRED_FLAGS}) + try_compile(${VARIABLE} + ${CMAKE_BINARY_DIR} + "${CSRC}" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS + "-DCOMPILE_DEFINITIONS:STRING=-DL_features_h -DL_AC_CHECK_FUNC=${FUNCTION} -DL_AC_CHECK_FUNC_stub='defined __stub_${FUNCTION} || defined __stub___${FUNCTION}'" + "${MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_FLAGS}" + "${MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES}" + OUTPUT_VARIABLE OUTPUT + ) + endif() + if(${VARIABLE}) + set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if function ${FUNCTION} is a stub " + "passed with the following output:\n" + "${OUTPUT}\n\n") + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for stubbed out ${FUNCTION} - no stub") + endif() + else() + set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if function ${FUNCTION} is a stub " + "failed with the following output:\n" + "${OUTPUT}\n\n") + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for stubbed out ${FUNCTION} - stub found") + endif() + endif() + endif() +endmacro() Index: lib/interception/interception_linux.h =================================================================== --- lib/interception/interception_linux.h +++ lib/interception/interception_linux.h @@ -25,7 +25,9 @@ // returns true if a function with the given name was found. bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, uptr real, uptr wrapper); +# ifdef HAVE_DLVSYM void *GetFuncAddrVer(const char *func_name, const char *ver); +# endif /* HAVE_DLVSYM */ } // namespace __interception #define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ @@ -43,5 +45,12 @@ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) #endif // !defined(__ANDROID__) +#ifndef HAVE_DLVSYM +/* Undo marketing crap above. Probe functionality, use result to decide. */ +# undef INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD +# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ + INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) +#endif + #endif // INTERCEPTION_LINUX_H #endif // __linux__ || __FreeBSD__ Index: lib/interception/interception_linux.cc =================================================================== --- lib/interception/interception_linux.cc +++ lib/interception/interception_linux.cc @@ -24,11 +24,13 @@ return real == wrapper; } +#ifdef HAVE_DLVSYM #if !defined(__ANDROID__) // android does not have dlvsym void *GetFuncAddrVer(const char *func_name, const char *ver) { return dlvsym(RTLD_NEXT, func_name, ver); } #endif // !defined(__ANDROID__) +#endif // HAVE_DLVSYM } // namespace __interception Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1273,33 +1273,43 @@ static THREADLOCAL __sanitizer_glob_t *pglob_copy; +#ifdef HAVE_GLOB_T_GL_CLOSEDIR static void wrapped_gl_closedir(void *dir) { COMMON_INTERCEPTOR_UNPOISON_PARAM(1); IndirectExternCall(pglob_copy->gl_closedir)(dir); } +#endif +#ifdef HAVE_GLOB_T_GL_READDIR static void *wrapped_gl_readdir(void *dir) { COMMON_INTERCEPTOR_UNPOISON_PARAM(1); return IndirectExternCall(pglob_copy->gl_readdir)(dir); } +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR static void *wrapped_gl_opendir(const char *s) { COMMON_INTERCEPTOR_UNPOISON_PARAM(1); COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); return IndirectExternCall(pglob_copy->gl_opendir)(s); } +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT static int wrapped_gl_lstat(const char *s, void *st) { COMMON_INTERCEPTOR_UNPOISON_PARAM(2); COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); return IndirectExternCall(pglob_copy->gl_lstat)(s, st); } +#endif +#ifdef HAVE_GLOB_T_GL_STAT static int wrapped_gl_stat(const char *s, void *st) { COMMON_INTERCEPTOR_UNPOISON_PARAM(2); COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); return IndirectExternCall(pglob_copy->gl_stat)(s, st); } +#endif INTERCEPTOR(int, glob, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), @@ -1307,24 +1317,64 @@ void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); __sanitizer_glob_t glob_copy = { - 0, 0, 0, - 0, wrapped_gl_closedir, wrapped_gl_readdir, - wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; + 0, + 0, + 0 +#ifdef HAVE_GLOB_T_GL_FLAGS + ,0 +#endif +#ifdef HAVE_GLOB_T_GL_CLOSEDIR + ,wrapped_gl_closedir +#endif +#ifdef HAVE_GLOB_T_GL_READDIR + ,wrapped_gl_readdir +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR + ,wrapped_gl_opendir +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT + ,wrapped_gl_lstat +#endif +#ifdef HAVE_GLOB_T_GL_STAT + ,wrapped_gl_stat +#endif + }; + if (flags & glob_altdirfunc) { +#ifdef HAVE_GLOB_T_GL_CLOSEDIR Swap(pglob->gl_closedir, glob_copy.gl_closedir); +#endif +#ifdef HAVE_GLOB_T_GL_READDIR Swap(pglob->gl_readdir, glob_copy.gl_readdir); +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR Swap(pglob->gl_opendir, glob_copy.gl_opendir); +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT Swap(pglob->gl_lstat, glob_copy.gl_lstat); +#endif +#ifdef HAVE_GLOB_T_GL_STAT Swap(pglob->gl_stat, glob_copy.gl_stat); +#endif pglob_copy = &glob_copy; } int res = REAL(glob)(pattern, flags, errfunc, pglob); if (flags & glob_altdirfunc) { +#ifdef HAVE_GLOB_T_GL_CLOSEDIR Swap(pglob->gl_closedir, glob_copy.gl_closedir); +#endif +#ifdef HAVE_GLOB_T_GL_READDIR Swap(pglob->gl_readdir, glob_copy.gl_readdir); +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR Swap(pglob->gl_opendir, glob_copy.gl_opendir); +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT Swap(pglob->gl_lstat, glob_copy.gl_lstat); +#endif +#ifdef HAVE_GLOB_T_GL_STAT Swap(pglob->gl_stat, glob_copy.gl_stat); +#endif } pglob_copy = 0; if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); @@ -1337,24 +1387,63 @@ void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); __sanitizer_glob_t glob_copy = { - 0, 0, 0, - 0, wrapped_gl_closedir, wrapped_gl_readdir, - wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; + 0, + 0, + 0 +#ifdef HAVE_GLOB_T_GL_FLAGS + ,0 +#endif +#ifdef HAVE_GLOB_T_GL_CLOSEDIR + ,wrapped_gl_closedir +#endif +#ifdef HAVE_GLOB_T_GL_READDIR + ,wrapped_gl_readdir +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR + ,wrapped_gl_opendir +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT + ,wrapped_gl_lstat +#endif +#ifdef HAVE_GLOB_T_GL_STAT + ,wrapped_gl_stat +#endif + }; if (flags & glob_altdirfunc) { +#ifdef HAVE_GLOB_T_GL_CLOSEDIR Swap(pglob->gl_closedir, glob_copy.gl_closedir); +#endif +#ifdef HAVE_GLOB_T_GL_READDIR Swap(pglob->gl_readdir, glob_copy.gl_readdir); +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR Swap(pglob->gl_opendir, glob_copy.gl_opendir); +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT Swap(pglob->gl_lstat, glob_copy.gl_lstat); +#endif +#ifdef HAVE_GLOB_T_GL_STAT Swap(pglob->gl_stat, glob_copy.gl_stat); +#endif pglob_copy = &glob_copy; } int res = REAL(glob64)(pattern, flags, errfunc, pglob); if (flags & glob_altdirfunc) { +#ifdef HAVE_GLOB_T_GL_CLOSEDIR Swap(pglob->gl_closedir, glob_copy.gl_closedir); +#endif +#ifdef HAVE_GLOB_T_GL_READDIR Swap(pglob->gl_readdir, glob_copy.gl_readdir); +#endif +#ifdef HAVE_GLOB_T_GL_OPENDIR Swap(pglob->gl_opendir, glob_copy.gl_opendir); +#endif +#ifdef HAVE_GLOB_T_GL_LSTAT Swap(pglob->gl_lstat, glob_copy.gl_lstat); +#endif +#ifdef HAVE_GLOB_T_GL_STAT Swap(pglob->gl_stat, glob_copy.gl_stat); +#endif } pglob_copy = 0; if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -150,7 +150,9 @@ #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS SI_NOT_WINDOWS #define SANITIZER_INTERCEPT_STATFS64 \ - (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID + SIZEOF_STRUCT_STATFS64 && ( \ + (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID \ + ) #define SANITIZER_INTERCEPT_STATVFS SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_INITGROUPS SI_NOT_WINDOWS Index: lib/sanitizer_common/sanitizer_platform_limits_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_linux.cc +++ lib/sanitizer_common/sanitizer_platform_limits_linux.cc @@ -61,7 +61,9 @@ #endif namespace __sanitizer { +#if SANITIZER_INTERCEPT_STATFS64 unsigned struct_statfs64_sz = sizeof(struct statfs64); +#endif } // namespace __sanitizer #if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__) Index: lib/sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -478,7 +478,8 @@ #elif SANITIZER_LINUX struct __sanitizer_sigset_t { // The size is determined by looking at sizeof of real sigset_t on linux. - uptr val[128 / sizeof(uptr)]; + /* .. except this should be * sizeof(uptr), not '/', no? */ + uptr val[SIZEOF_SIGSET_T / sizeof(uptr)]; }; #elif SANITIZER_FREEBSD struct __sanitizer_sigset_t { @@ -487,6 +488,17 @@ }; #endif +#if HAVE_STRUCT_SIGACTION_SA_MASK_LAST + struct __sanitizer_sigaction { + union { + void (*sigaction)(int sig, void *siginfo, void *uctx); + void (*handler)(int sig); + }; + STRUCT_SIGACTION_SA_FLAGS_TYPE sa_flags; + void (*sa_restorer)(); + __sanitizer_sigset_t sa_mask; + }; +#else // HAVE_STRUCT_SIGACTION_SA_MASK_LAST // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. struct __sanitizer_sigaction { union { @@ -504,6 +516,7 @@ void (*sa_restorer)(); #endif }; +#endif // HAVE_STRUCT_SIGACTION_SA_MASK_LAST #if SANITIZER_FREEBSD typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; @@ -588,13 +601,25 @@ uptr gl_pathc; char **gl_pathv; uptr gl_offs; +# ifdef HAVE_GLOB_T_GL_FLAGS int gl_flags; +# endif +# ifdef HAVE_GLOB_T_GL_CLOSEDIR void (*gl_closedir)(void *dirp); +# endif +# ifdef HAVE_GLOB_T_GL_READDIR void *(*gl_readdir)(void *dirp); +# endif +# ifdef HAVE_GLOB_T_GL_OPENDIR void *(*gl_opendir)(const char *); +# endif +# ifdef HAVE_GLOB_T_GL_LSTAT int (*gl_lstat)(const char *, void *); +# endif +# ifdef HAVE_GLOB_T_GL_STAT int (*gl_stat)(const char *, void *); +# endif }; # elif SANITIZER_FREEBSD struct __sanitizer_glob_t { Index: lib/sanitizer_common/sanitizer_platform_limits_posix.cc =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -103,14 +103,18 @@ #endif #if SANITIZER_LINUX || SANITIZER_FREEBSD +# ifdef HAVE_UTIME_H # include +# endif # include #endif #if !SANITIZER_ANDROID #include #include +# ifdef HAVE_WORDEXP_H #include +# endif #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -119,7 +123,9 @@ #include #include #include +# ifdef HAVE_NETROM_NETROM_H #include +# endif #include #include #include @@ -128,7 +134,9 @@ #include #include #include +# ifdef HAVE_SYS_USTAT_H #include +# endif #include #include #include @@ -215,12 +223,16 @@ #if SANITIZER_LINUX || SANITIZER_FREEBSD unsigned struct_rlimit_sz = sizeof(struct rlimit); unsigned struct_timespec_sz = sizeof(struct timespec); +# ifdef HAVE_UTIME_H unsigned struct_utimbuf_sz = sizeof(struct utimbuf); +# endif unsigned struct_itimerspec_sz = sizeof(struct itimerspec); #endif // SANITIZER_LINUX || SANITIZER_FREEBSD #if SANITIZER_LINUX && !SANITIZER_ANDROID +# ifdef HAVE_SYS_USTAT_H unsigned struct_ustat_sz = sizeof(struct ustat); +# endif unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID @@ -266,7 +278,9 @@ #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID int glob_nomatch = GLOB_NOMATCH; +# ifdef GLOB_ALTDIRFUNC int glob_altdirfunc = GLOB_ALTDIRFUNC; +# endif #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ @@ -370,7 +384,9 @@ unsigned struct_kbkeycode_sz = sizeof(struct kbkeycode); unsigned struct_kbsentry_sz = sizeof(struct kbsentry); unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo); +# ifdef HAVE_NETROM_NETROM_H unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct); +# endif unsigned struct_scc_modem_sz = sizeof(struct scc_modem); unsigned struct_scc_stat_sz = sizeof(struct scc_stat); unsigned struct_serial_multiport_struct_sz @@ -805,10 +821,18 @@ unsigned IOCTL_SIOCAX25SETPARMS = SIOCAX25SETPARMS; unsigned IOCTL_SIOCDEVPLIP = SIOCDEVPLIP; unsigned IOCTL_SIOCIPXCFGDATA = SIOCIPXCFGDATA; +# ifdef SIOCNRDECOBS unsigned IOCTL_SIOCNRDECOBS = SIOCNRDECOBS; +# endif +# ifdef SIOCNRGETPARMS unsigned IOCTL_SIOCNRGETPARMS = SIOCNRGETPARMS; +# endif +# ifdef SIOCNRRTCTL unsigned IOCTL_SIOCNRRTCTL = SIOCNRRTCTL; +# endif +# ifdef SIOCNRSETPARMS unsigned IOCTL_SIOCNRSETPARMS = SIOCNRSETPARMS; +# endif unsigned IOCTL_TIOCGSERIAL = TIOCGSERIAL; unsigned IOCTL_TIOCSERGETMULTI = TIOCSERGETMULTI; unsigned IOCTL_TIOCSERSETMULTI = TIOCSERSETMULTI; @@ -890,12 +914,24 @@ CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); CHECK_SIZE_AND_OFFSET(glob_t, gl_offs); +# ifdef HAVE_GLOB_T_GL_FLAGS CHECK_SIZE_AND_OFFSET(glob_t, gl_flags); +# endif +# ifdef HAVE_GLOB_T_GL_CLOSEDIR CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir); +# endif +# ifdef HAVE_GLOB_T_GL_READDIR CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir); +# endif +# ifdef HAVE_GLOB_T_GL_OPENDIR CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir); +# endif +# ifdef HAVE_GLOB_T_GL_LSTAT CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat); +# endif +# ifdef HAVE_GLOB_T_GL_STAT CHECK_SIZE_AND_OFFSET(glob_t, gl_stat); +# endif #endif CHECK_TYPE_SIZE(addrinfo); @@ -967,11 +1003,17 @@ COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction)); // Can't write checks for sa_handler and sa_sigaction due to them being // preprocessor macros. +#if HAVE_STRUCT_SIGACTION_SA_MASK_LAST +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); +#else // HAVE_STRUCT_SIGACTION_SA_MASK_LAST CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); #if SANITIZER_LINUX CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); #endif +#endif // HAVE_STRUCT_SIGACTION_SA_MASK_LAST #if SANITIZER_LINUX CHECK_TYPE_SIZE(__sysctl_args); @@ -991,7 +1033,7 @@ CHECK_TYPE_SIZE(__kernel_fd_set); #endif -#if !SANITIZER_ANDROID +#ifdef HAVE_WORDEXP_H CHECK_TYPE_SIZE(wordexp_t); CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc); CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv); Index: lib/sanitizer_common/sanitizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -73,7 +73,16 @@ } void SleepForMillis(int millis) { +#ifdef HAVE_NANOSLEEP + struct timespec ts; + ts.tv_sec = millis / 1000; + ts.tv_nsec = (millis % 1000) * 1000000; + nanosleep(&ts, NULL); /* could as well loop here */ +#elif defined HAVE_USLEEP usleep(millis * 1000); +# else + dunno how to SleepForMillis +#endif } void Abort() { Index: make/platform/clang_linux.mk =================================================================== --- make/platform/clang_linux.mk +++ make/platform/clang_linux.mk @@ -74,6 +74,185 @@ Arch.lsan-x86_64 := x86_64 endif +# TryCompile2 compiler source flags +# Returns exit code of running a compiler invocation. +# Same as TryCompile but in outer scope, don't want to touch the other one +TryCompile2 = \ + $(shell \ + cflags=""; \ + for flag in $(3); do \ + cflags="$$cflags $$flag"; \ + done; \ + $(1) $$cflags $(2) -o /dev/null > /dev/null 2> /dev/null ; \ + echo $$?) + +# our conftest.c +ct_c = $(ProjSrcRoot)/make/platform/clang_linux_test_libc.c + +HAVE_DLVSYM := 1 +HAVE_NETROM_NETROM_H := 1 +HAVE_GLOB_H := 1 +HAVE_NANOSLEEP := 1 +HAVE_GLOB_T_GL_CLOSEDIR := 1 +HAVE_GLOB_T_GL_FLAGS := 1 +HAVE_GLOB_T_GL_LSTAT := 1 +HAVE_GLOB_T_GL_OPENDIR := 1 +HAVE_GLOB_T_GL_READDIR := 1 +HAVE_GLOB_T_GL_STAT := 1 +HAVE_STRUCT_SIGACTION_SA_MASK_LAST := 0 +HAVE_SYS_USTAT_H := 1 +HAVE_USLEEP := 1 +HAVE_UTIME_H := 1 +HAVE_WORDEXP_H := 1 +SIZEOF_STRUCT_STATFS64 := 120 +SIZEOF_SIGSET_T := 128 +STRUCT_SIGACTION_SA_FLAGS_TYPE := int + +#ifneq ($(findstring -uclibc,$(CompilerTargetTriple)),) +# does not work, cross-compilation seems to be non-working? +ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_UCLIBC -DL_AC_CHECK_HEADER="",),0) + HAVE_DLVSYM := + HAVE_NETROM_NETROM_H := + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned long +ifneq ($(filter alpha%,$(CompilerTargetTriple)),) + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned +endif +ifneq ($(filter mips%,$(CompilerTargetTriple)),) + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned +endif + HAVE_STRUCT_SIGACTION_SA_MASK_LAST := 1 +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_HEADER="",),0) + HAVE_SYS_USTAT_H := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_HEADER="",),0) + HAVE_UTIME_H := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_HEADER="",),0) + HAVE_WORDEXP_H := +endif +glob_h := -DL_AC_CHECK_HEADER="" +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN $(glob_h),),0) + HAVE_GLOB_H := +endif +# check for struct glob members (check for GNU extensions) +glob_h += -DL_AC_STRUCT="glob_t" +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_flags,),0) + HAVE_GLOB_T_GL_FLAGS := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_closedir,),0) + HAVE_GLOB_T_GL_CLOSEDIR := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_readdir,),0) + HAVE_GLOB_T_GL_READDIR := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_opendir,),0) + HAVE_GLOB_T_GL_OPENDIR := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_lstat,),0) + HAVE_GLOB_T_GL_LSTAT := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h) -DL_AC_CHECK_STRUCT_MEMBER=gl_stat,),0) + HAVE_GLOB_T_GL_STAT := +endif +# check misc functions +# for __stub_* on glibc and uClibc including features.h is enough +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_features_h -DL_AC_CHECK_FUNC=nanosleep -DL_AC_CHECK_FUNC_stub="defined __stub_nanosleep || defined __stub___nanosleep",),0) + HAVE_NANOSLEEP := +endif +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_features_h -DL_AC_CHECK_FUNC=usleep -DL_AC_CHECK_FUNC_stub="defined __stub_usleep || defined __stub___usleep",),0) + HAVE_USLEEP := +endif + +# AC_CHECK_SIZEOF, in make +define ac_check_sizeof +$(shell \ +if test $$($(CC) $(1) -DL_AC_SIZEOF_GE=0 -o /dev/null > /dev/null 2> /dev/null; echo $$?) -eq 0; \ +then \ + ac_lo=0 ac_mid=0; \ + while :; \ + do \ + if test $$($(CC) $(1) -DL_AC_SIZEOF_LE=$$ac_mid -o /dev/null > /dev/null 2> /dev/null; echo $$?) -eq 0; then \ + ac_hi=$$ac_mid; \ + break; \ + else \ + ac_lo=$$(( $$ac_mid + 1 )); \ + if test $$ac_lo -le $$ac_mid; then ac_lo= ac_hi=; break; fi; \ + ac_mid=$$(( 2 * $$ac_mid + 1 )); \ + fi; \ + done; \ +else \ + if test $$($(CC) $(1) -DL_AC_SIZEOF_LT=0 -o /dev/null > /dev/null 2> /dev/null; echo $$?) -eq 0; then \ + ac_hi=-1 ac_mid=-1; \ + while :; \ + do \ + if test $$($(CC) $(1) -DL_AC_SIZEOF_GE=$$ac_mid -o /dev/null > /dev/null 2> /dev/null; echo $$?) -eq 0; then \ + ac_lo=$$ac_mid; \ + break; \ + else \ + ac_hi=$$(( ($$ac_mid) - 1 )); \ + if test $$ac_mid -le $$ac_hi; then ac_lo= ac_hi=; break; fi; \ + ac_mid=$$(( 2 * $$ac_mid )); \ + fi; \ + done; \ + else \ + ac_lo= ac_hi=; \ + fi; \ +fi; \ +while test "x$$ac_lo" != "x$$ac_hi"; \ +do \ + ac_mid=$$(( ($$ac_hi - $$ac_lo) / 2 + $$ac_lo )); \ + if test $$($(CC) $(1) -DL_AC_SIZEOF_LE=$$ac_mid -o /dev/null > /dev/null 2> /dev/null; echo $$?) -eq 0; then \ + ac_hi=$$ac_mid; \ + else \ + ac_lo=$$(( ($$ac_mid) + 1 )); \ + fi; \ +done; \ +echo $$(( $$ac_lo + 0 )); \ +) +endef + +# determine sizeof sigset_t +SIZEOF_SIGSET_T := $(call ac_check_sizeof,$(ct_c) -DL_AC_CHECK_HEADER="" -DL_AC_SIZEOF="sigset_t") + +# determine sizeof struct statfs64 +SIZEOF_STRUCT_STATFS64 := 0 +ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_HEADER="",),0) +SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c) -DL_AC_CHECK_HEADER="" -DL_AC_SIZEOF="struct statfs64") +else + ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_HEADER="",),0) + SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c) -DL_AC_CHECK_HEADER="" -DL_AC_SIZEOF="struct statfs64") + endif +endif +# end of -uclibc handling +endif + +define add_config_h_cppflag +ifeq ($($(1)),) +CONFIG_H_CPPFLAGS += -U$(1) +else +CONFIG_H_CPPFLAGS += '-D$(1)=$($(1))' +endif +endef + +CONFIG_H_CPPFLAGS := +$(eval $(call add_config_h_cppflag,HAVE_DLVSYM)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_H)) +$(eval $(call add_config_h_cppflag,HAVE_NANOSLEEP)) +$(eval $(call add_config_h_cppflag,HAVE_NETROM_NETROM_H)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_CLOSEDIR)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_FLAGS)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_LSTAT)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_OPENDIR)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_READDIR)) +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_STAT)) +$(eval $(call add_config_h_cppflag,HAVE_STRUCT_SIGACTION_SA_MASK_LAST)) +$(eval $(call add_config_h_cppflag,HAVE_SYS_USTAT_H)) +$(eval $(call add_config_h_cppflag,HAVE_USLEEP)) +$(eval $(call add_config_h_cppflag,HAVE_UTIME_H)) +$(eval $(call add_config_h_cppflag,HAVE_WORDEXP_H)) +$(eval $(call add_config_h_cppflag,SIZEOF_STRUCT_STATFS64)) +$(eval $(call add_config_h_cppflag,SIZEOF_SIGSET_T)) +$(eval $(call add_config_h_cppflag,STRUCT_SIGACTION_SA_FLAGS_TYPE)) endif ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),) @@ -87,6 +266,7 @@ CFLAGS := -Wall -Werror -O3 -fomit-frame-pointer SANITIZER_CFLAGS := -fPIE -fno-builtin -gline-tables-only +CFLAGS += $(CONFIG_H_CPPFLAGS) CFLAGS.full-i386 := $(CFLAGS) -m32 CFLAGS.full-x86_64 := $(CFLAGS) -m64 Index: make/platform/clang_linux_test_libc.c =================================================================== --- /dev/null +++ make/platform/clang_linux_test_libc.c @@ -0,0 +1,68 @@ +/* This file is used to check for libc characteristics and features */ +#ifdef L_features_h +# include +#endif + +#ifdef L_AC_CHECK_HEADER +/* compile-time check for availability of a header */ +# include L_AC_CHECK_HEADER +#endif + +#ifdef L_AC_CHECK_UCLIBC +# ifndef __UCLIBC__ +choke me /* not uClibc */ +# endif +#endif + +#ifdef L_MAIN +/* provide a dummy main for the linker */ +int main() +{ + return 0; +} +#endif + +#ifdef L_AC_CHECK_STRUCT_MEMBER +/* compile-time check for presence of struct member */ +int main() +{ + static L_AC_STRUCT ac_aggr; + if (ac_aggr.L_AC_CHECK_STRUCT_MEMBER) + return 0; + return 0; +} +#endif + +#ifdef L_AC_CHECK_FUNC +/* check if function (or macro) is available */ +# ifdef __cplusplus +extern "C" +# endif +# if L_AC_CHECK_FUNC_stub +choke me /* function 'L_AC_CHECK_FUNC' stubbed out! */ +# endif +char L_AC_CHECK_FUNC (); +int main () +{ + return L_AC_CHECK_FUNC (); +} +#endif + +#ifdef L_AC_SIZEOF +/* Determine sizeof expression */ +int main () +{ +# define s (long int) (sizeof (L_AC_SIZEOF)) +# if defined L_AC_SIZEOF_GE + static int test_array [1 - 2 * !((s) >= L_AC_SIZEOF_GE)]; +# elif defined L_AC_SIZEOF_LE + static int test_array [1 - 2 * !((s) <= L_AC_SIZEOF_LE)]; +# elif defined L_AC_SIZEOF_LT + static int test_array [1 - 2 * !((s) < L_AC_SIZEOF_LT)]; +# else +# error no such comparison operator +# endif + test_array [0] = 0; + return 0; +} +#endif