[PATCH 3/3] [LLVM] [sanitizer] add conditionals for libc

Konstantin Serebryany konstantin.s.serebryany at gmail.com
Thu Apr 17 07:51:03 PDT 2014


On Thu, Apr 17, 2014 at 6:27 PM, Bernhard Reutner-Fischer
<rep.dot.nop at gmail.com> wrote:
> On 17 April 2014 16:07, Konstantin Serebryany
> <konstantin.s.serebryany at gmail.com> wrote:
>> Hi,
>>
>> If you are trying to modify the libsanitizer files, please read here:
>> https://code.google.com/p/address-sanitizer/wiki/HowToContribute
>
> I read that, thanks. Patch 3/3 is for current compiler-rt git repo,
> please install it there, i do not have write access to the LLVM nor
> compiler-rt trees.

I can commit your patch to llvm tree only after you follow the process
described on that page.
Sorry, this is a hard rule.

--kcc

> TIA,
>>
>> --kcc
>>
>> On Thu, Apr 17, 2014 at 5:49 PM, Bernhard Reutner-Fischer
>> <rep.dot.nop at 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.nop at 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
>>>



More information about the llvm-commits mailing list