Hi, If you are trying to modify the libsanitizer files, please read here: https://code.google.com/p/address-sanitizer/wiki/HowToContribute
--kcc On Thu, Apr 17, 2014 at 5:49 PM, Bernhard Reutner-Fischer <rep.dot....@gmail.com> wrote: > Conditionalize usage of dlvsym(), nanosleep(), usleep(); > Conditionalize layout of struct sigaction and type of it's member > sa_flags. > Conditionalize glob_t members gl_closedir, gl_readdir, gl_opendir, > gl_flags, gl_lstat, gl_stat. > Check for availability of glob.h for use with above members. > Check for availability of netrom/netrom.h, sys/ustat.h (for obsolete > ustat() function), utime.h (for obsolete utime() function), wordexp.h. > Determine size of sigset_t instead of hardcoding it. > Determine size of struct statfs64, if available. > > Leave defaults to match what glibc expects but probe them for uClibc. > > Signed-off-by: Bernhard Reutner-Fischer <rep.dot....@gmail.com> > --- > CMakeLists.txt | 58 +++++++ > cmake/Modules/CompilerRTUtils.cmake | 15 ++ > cmake/Modules/FunctionExistsNotStub.cmake | 56 +++++++ > lib/interception/interception_linux.cc | 2 + > lib/interception/interception_linux.h | 9 ++ > .../sanitizer_common_interceptors.inc | 101 +++++++++++- > .../sanitizer_platform_limits_posix.cc | 44 ++++- > .../sanitizer_platform_limits_posix.h | 27 +++- > lib/sanitizer_common/sanitizer_posix_libcdep.cc | 9 ++ > make/platform/clang_linux.mk | 180 > +++++++++++++++++++++ > make/platform/clang_linux_test_libc.c | 68 ++++++++ > 11 files changed, 561 insertions(+), 8 deletions(-) > create mode 100644 cmake/Modules/FunctionExistsNotStub.cmake > create mode 100644 make/platform/clang_linux_test_libc.c > > diff --git a/CMakeLists.txt b/CMakeLists.txt > index e1a7a1f..af8073e 100644 > --- a/CMakeLists.txt > +++ b/CMakeLists.txt > @@ -330,6 +330,64 @@ if(APPLE) > -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 > diff --git a/cmake/Modules/CompilerRTUtils.cmake > b/cmake/Modules/CompilerRTUtils.cmake > index e22e775..3a0beec 100644 > --- a/cmake/Modules/CompilerRTUtils.cmake > +++ b/cmake/Modules/CompilerRTUtils.cmake > @@ -59,3 +59,18 @@ macro(append_no_rtti_flag list) > 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() > + > + > diff --git a/cmake/Modules/FunctionExistsNotStub.cmake > b/cmake/Modules/FunctionExistsNotStub.cmake > new file mode 100644 > index 0000000..9f944dd > --- /dev/null > +++ b/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() > diff --git a/lib/interception/interception_linux.cc > b/lib/interception/interception_linux.cc > index 6e908ac..c9b4a6e 100644 > --- a/lib/interception/interception_linux.cc > +++ b/lib/interception/interception_linux.cc > @@ -24,11 +24,13 @@ bool GetRealFunctionAddress(const char *func_name, uptr > *func_addr, > 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 > > diff --git a/lib/interception/interception_linux.h > b/lib/interception/interception_linux.h > index d3f774b..4802fe5 100644 > --- a/lib/interception/interception_linux.h > +++ b/lib/interception/interception_linux.h > @@ -25,7 +25,9 @@ namespace __interception { > // 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 @@ void *GetFuncAddrVer(const char *func_name, const char > *ver); > 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__ > diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc > b/lib/sanitizer_common/sanitizer_common_interceptors.inc > index 0d076a0..0a767d4 100644 > --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc > +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc > @@ -1273,33 +1273,43 @@ static void unpoison_glob_t(void *ctx, > __sanitizer_glob_t *pglob) { > > 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 @@ INTERCEPTOR(int, glob, const char *pattern, int flags, > 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 @@ INTERCEPTOR(int, glob64, const char *pattern, int > flags, > 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); > diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc > b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc > index 9ae4870..645777f 100644 > --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc > +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc > @@ -103,14 +103,18 @@ > #endif > > #if SANITIZER_LINUX || SANITIZER_FREEBSD > +# ifdef HAVE_UTIME_H > # include <utime.h> > +# endif > # include <sys/ptrace.h> > #endif > > #if !SANITIZER_ANDROID > #include <ifaddrs.h> > #include <sys/ucontext.h> > +# ifdef HAVE_WORDEXP_H > #include <wordexp.h> > +# endif > #endif > > #if SANITIZER_LINUX && !SANITIZER_ANDROID > @@ -119,7 +123,9 @@ > #include <net/if_ppp.h> > #include <netax25/ax25.h> > #include <netipx/ipx.h> > +# ifdef HAVE_NETROM_NETROM_H > #include <netrom/netrom.h> > +# endif > #include <rpc/xdr.h> > #include <scsi/scsi.h> > #include <sys/mtio.h> > @@ -128,7 +134,9 @@ > #include <sys/statvfs.h> > #include <sys/timex.h> > #include <sys/user.h> > +# ifdef HAVE_SYS_USTAT_H > #include <sys/ustat.h> > +# endif > #include <linux/cyclades.h> > #include <linux/if_eql.h> > #include <linux/if_plip.h> > @@ -215,12 +223,16 @@ namespace __sanitizer { > #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 @@ namespace __sanitizer { > > #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 @@ namespace __sanitizer { > 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 @@ namespace __sanitizer { > 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_TYPE_SIZE(glob_t); > 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 @@ CHECK_TYPE_SIZE(sigset_t); > 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_loff_t); > 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); > diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h > b/lib/sanitizer_common/sanitizer_platform_limits_posix.h > index a780ee2..04c6a96 100644 > --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h > +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h > @@ -478,7 +478,8 @@ namespace __sanitizer { > #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 @@ namespace __sanitizer { > }; > #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 @@ namespace __sanitizer { > 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 @@ namespace __sanitizer { > 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 { > diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc > b/lib/sanitizer_common/sanitizer_posix_libcdep.cc > index bb6e587..973f698 100644 > --- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc > +++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc > @@ -73,7 +73,16 @@ void SleepForSeconds(int seconds) { > } > > 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() { > diff --git a/make/platform/clang_linux.mk b/make/platform/clang_linux.mk > index c6921ea..5ce1567 100644 > --- a/make/platform/clang_linux.mk > +++ b/make/platform/clang_linux.mk > @@ -74,6 +74,185 @@ Arch.dfsan-x86_64 := x86_64 > 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="<stdio.h>",),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="<sys/ustat.h>",),0) > + HAVE_SYS_USTAT_H := > +endif > +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN > -DL_AC_CHECK_HEADER="<utime.h>",),0) > + HAVE_UTIME_H := > +endif > +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN > -DL_AC_CHECK_HEADER="<wordexp.h>",),0) > + HAVE_WORDEXP_H := > +endif > +glob_h := -DL_AC_CHECK_HEADER="<glob.h>" > +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="<signal.h>" -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="<sys/statfs.h>",),0) > +SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c) > -DL_AC_CHECK_HEADER="<sys/statfs.h>" -DL_AC_SIZEOF="struct statfs64") > +else > + ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN > -DL_AC_CHECK_HEADER="<sys/vfs.h>",),0) > + SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c) > -DL_AC_CHECK_HEADER="<sys/vfs.h>" -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 @@ endif > > 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 > diff --git a/make/platform/clang_linux_test_libc.c > b/make/platform/clang_linux_test_libc.c > new file mode 100644 > index 0000000..2f9bba8 > --- /dev/null > +++ b/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 <features.h> > +#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 > -- > 1.9.1 >