1 1.1.1.2 christos # memchr.m4 serial 18 2 1.1.1.2 christos dnl Copyright (C) 2002-2004, 2009-2022 Free Software Foundation, Inc. 3 1.1 christos dnl This file is free software; the Free Software Foundation 4 1.1 christos dnl gives unlimited permission to copy and/or distribute it, 5 1.1 christos dnl with or without modifications, as long as this notice is preserved. 6 1.1 christos 7 1.1 christos AC_DEFUN_ONCE([gl_FUNC_MEMCHR], 8 1.1 christos [ 9 1.1 christos AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 10 1.1 christos 11 1.1 christos dnl Check for prerequisites for memory fence checks. 12 1.1 christos gl_FUNC_MMAP_ANON 13 1.1 christos AC_CHECK_HEADERS_ONCE([sys/mman.h]) 14 1.1 christos AC_CHECK_FUNCS_ONCE([mprotect]) 15 1.1 christos 16 1.1.1.2 christos AC_REQUIRE([gl_STRING_H_DEFAULTS]) 17 1.1.1.2 christos # Detect platform-specific bugs in some versions of glibc: 18 1.1.1.2 christos # memchr should not dereference anything with length 0 19 1.1.1.2 christos # https://bugzilla.redhat.com/show_bug.cgi?id=499689 20 1.1.1.2 christos # memchr should not dereference overestimated length after a match 21 1.1.1.2 christos # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 22 1.1.1.2 christos # https://sourceware.org/bugzilla/show_bug.cgi?id=10162 23 1.1.1.2 christos # memchr should cast the second argument to 'unsigned char'. 24 1.1.1.2 christos # This bug exists in Android 4.3. 25 1.1.1.2 christos # Assume that memchr works on platforms that lack mprotect. 26 1.1.1.2 christos AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], 27 1.1.1.2 christos [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ 28 1.1 christos #include <string.h> 29 1.1 christos #if HAVE_SYS_MMAN_H 30 1.1 christos # include <fcntl.h> 31 1.1 christos # include <unistd.h> 32 1.1 christos # include <sys/types.h> 33 1.1 christos # include <sys/mman.h> 34 1.1 christos # ifndef MAP_FILE 35 1.1 christos # define MAP_FILE 0 36 1.1 christos # endif 37 1.1 christos #endif 38 1.1 christos ]], [[ 39 1.1 christos int result = 0; 40 1.1 christos char *fence = NULL; 41 1.1 christos #if HAVE_SYS_MMAN_H && HAVE_MPROTECT 42 1.1 christos # if HAVE_MAP_ANONYMOUS 43 1.1 christos const int flags = MAP_ANONYMOUS | MAP_PRIVATE; 44 1.1 christos const int fd = -1; 45 1.1 christos # else /* !HAVE_MAP_ANONYMOUS */ 46 1.1 christos const int flags = MAP_FILE | MAP_PRIVATE; 47 1.1 christos int fd = open ("/dev/zero", O_RDONLY, 0666); 48 1.1 christos if (fd >= 0) 49 1.1 christos # endif 50 1.1 christos { 51 1.1 christos int pagesize = getpagesize (); 52 1.1 christos char *two_pages = 53 1.1 christos (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, 54 1.1 christos flags, fd, 0); 55 1.1 christos if (two_pages != (char *)(-1) 56 1.1 christos && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) 57 1.1 christos fence = two_pages + pagesize; 58 1.1 christos } 59 1.1 christos #endif 60 1.1 christos if (fence) 61 1.1 christos { 62 1.1.1.2 christos /* Test against bugs on glibc systems. */ 63 1.1 christos if (memchr (fence, 0, 0)) 64 1.1 christos result |= 1; 65 1.1 christos strcpy (fence - 9, "12345678"); 66 1.1 christos if (memchr (fence - 9, 0, 79) != fence - 1) 67 1.1 christos result |= 2; 68 1.1 christos if (memchr (fence - 1, 0, 3) != fence - 1) 69 1.1 christos result |= 4; 70 1.1.1.2 christos /* Test against bug on AIX 7.2. */ 71 1.1.1.2 christos if (memchr (fence - 4, '6', 16) != fence - 4) 72 1.1.1.2 christos result |= 8; 73 1.1 christos } 74 1.1 christos /* Test against bug on Android 4.3. */ 75 1.1 christos { 76 1.1 christos char input[3]; 77 1.1 christos input[0] = 'a'; 78 1.1 christos input[1] = 'b'; 79 1.1 christos input[2] = 'c'; 80 1.1 christos if (memchr (input, 0x789abc00 | 'b', 3) != input + 1) 81 1.1.1.2 christos result |= 16; 82 1.1 christos } 83 1.1 christos return result; 84 1.1 christos ]])], 85 1.1.1.2 christos [gl_cv_func_memchr_works=yes], 86 1.1.1.2 christos [gl_cv_func_memchr_works=no], 87 1.1.1.2 christos [case "$host_os" in 88 1.1.1.2 christos # Guess no on Android. 89 1.1.1.2 christos linux*-android*) gl_cv_func_memchr_works="guessing no" ;; 90 1.1.1.2 christos # Guess yes on native Windows. 91 1.1.1.2 christos mingw*) gl_cv_func_memchr_works="guessing yes" ;; 92 1.1.1.2 christos # If we don't know, obey --enable-cross-guesses. 93 1.1.1.2 christos *) gl_cv_func_memchr_works="$gl_cross_guess_normal" ;; 94 1.1.1.2 christos esac 95 1.1.1.2 christos ]) 96 1.1.1.2 christos ]) 97 1.1.1.2 christos case "$gl_cv_func_memchr_works" in 98 1.1.1.2 christos *yes) ;; 99 1.1.1.2 christos *) REPLACE_MEMCHR=1 ;; 100 1.1.1.2 christos esac 101 1.1 christos ]) 102 1.1 christos 103 1.1 christos # Prerequisites of lib/memchr.c. 104 1.1 christos AC_DEFUN([gl_PREREQ_MEMCHR], [ 105 1.1 christos AC_CHECK_HEADERS([bp-sym.h]) 106 1.1 christos ]) 107