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