It seems that libiberty already has replacements for most of the mem* functions, but they are not published via include/libiberty.h.
Tested on x86_64 Linux, Darwin aarch64 Linux, OK for trunk? thanks, Iain --- 8< --- This adds an implementation of memrchr to libiberty and arranges to configure gcc to use it, if the host does not have it. gcc/ChangeLog: * config.in: Regenerate. * configure: Regenerate. * configure.ac: Check for host memrchr. include/ChangeLog: * libiberty.h (memrchr): New. libiberty/ChangeLog: * Makefile.in: Add memrchr build rules. * config.in: Regenerate. * configure: Regenerate. * configure.ac: Check for memrchr. * functions.texi: Document memrchr. * memrchr.c: New file. Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> --- gcc/config.in | 6 ++++++ gcc/configure | 2 +- gcc/configure.ac | 2 +- include/libiberty.h | 10 ++++++++++ libiberty/Makefile.in | 17 +++++++++++++---- libiberty/config.in | 3 +++ libiberty/configure | 5 +++-- libiberty/configure.ac | 5 +++-- libiberty/functions.texi | 14 ++++++++++++++ libiberty/memrchr.c | 33 +++++++++++++++++++++++++++++++++ 10 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 libiberty/memrchr.c diff --git a/gcc/config.in b/gcc/config.in index 0d8a6ba1808..7c89cab7717 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1960,6 +1960,12 @@ #endif +/* Define to 1 if you have the `memrchr' function. */ +#ifndef USED_FOR_TARGET +#undef HAVE_MEMRCHR +#endif + + /* Define to 1 if you have the `mmap' function. */ #ifndef USED_FOR_TARGET #undef HAVE_MMAP diff --git a/gcc/configure b/gcc/configure index 063b9ce6701..ab6bec1f0ae 100755 --- a/gcc/configure +++ b/gcc/configure @@ -10640,7 +10640,7 @@ for ac_func in times clock kill getrlimit setrlimit atoq \ popen sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \ clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked madvise mallinfo mallinfo2 fstatat getauxval \ - clock_gettime munmap msync get_current_dir_name + clock_gettime munmap msync get_current_dir_name memrchr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/gcc/configure.ac b/gcc/configure.ac index 3243472680c..fca0579574f 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1574,7 +1574,7 @@ AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoq \ popen sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \ gcc_UNLOCKED_FUNCS madvise mallinfo mallinfo2 fstatat getauxval \ - clock_gettime munmap msync get_current_dir_name) + clock_gettime munmap msync get_current_dir_name memrchr) # At least for glibc, clock_gettime is in librt. But don't pull that # in if it still doesn't give us the function we want. diff --git a/include/libiberty.h b/include/libiberty.h index f2e763a306a..d4e8791b14b 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -215,6 +215,16 @@ extern int ffs(int); extern int mkstemps(char *, int); #endif +#if defined (HAVE_DECL_MKSTEMPS) && !HAVE_DECL_MKSTEMPS +extern int mkstemps(char *, int); +#endif + +/* Make memrchr available on systems that do not have it. */ +#if !defined (__GNU_LIBRARY__ ) && !defined (__linux__) && \ + !defined (HAVE_MEMRCHR) +extern void *memrchr(const void *, int, size_t); +#endif + /* Get the working directory. The result is cached, so don't call chdir() between calls to getpwd(). */ diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 4870fa95f2f..ce54d88278d 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -139,8 +139,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ ldirname.c \ lrealpath.c \ make-relative-prefix.c \ - make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmem.c \ - memmove.c mempcpy.c memset.c mkstemps.c \ + make-temp-file.c md5.c memchr.c memrchr.c memcmp.c memcpy.c \ + memmem.c memmove.c mempcpy.c memset.c mkstemps.c \ objalloc.c obstack.c \ partition.c pexecute.c \ pex-common.c pex-djgpp.c pex-msdos.c pex-one.c \ @@ -213,8 +213,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext) \ ./getcwd.$(objext) ./getpagesize.$(objext) \ ./gettimeofday.$(objext) \ ./index.$(objext) ./insque.$(objext) \ - ./memchr.$(objext) ./memcmp.$(objext) ./memcpy.$(objext) \ - ./memmem.$(objext) ./memmove.$(objext) \ + ./memchr.$(objext) ./memrchr.$(objext) ./memcmp.$(objext) \ + ./memcpy.$(objext) ./memmem.$(objext) ./memmove.$(objext) \ ./mempcpy.$(objext) ./memset.$(objext) ./mkstemps.$(objext) \ ./pex-djgpp.$(objext) ./pex-msdos.$(objext) \ ./pex-unix.$(objext) ./pex-win32.$(objext) \ @@ -1025,6 +1025,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/memchr.c $(OUTPUT_OPTION) +./memrchr.$(objext): $(srcdir)/memrchr.c $(INCDIR)/ansidecl.h + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/memrchr.c -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/memrchr.c -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/memrchr.c $(OUTPUT_OPTION) + ./memcmp.$(objext): $(srcdir)/memcmp.c $(INCDIR)/ansidecl.h if [ x"$(PICFLAG)" != x ]; then \ $(COMPILE.c) $(PICFLAG) $(srcdir)/memcmp.c -o pic/$@; \ diff --git a/libiberty/config.in b/libiberty/config.in index b055150961c..3b8716511f0 100644 --- a/libiberty/config.in +++ b/libiberty/config.in @@ -186,6 +186,9 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `memrchr' function. */ +#undef HAVE_MEMRCHR + /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET diff --git a/libiberty/configure b/libiberty/configure index 347719c6262..02fbaabe89e 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -6210,6 +6210,7 @@ funcs="$funcs gettimeofday" funcs="$funcs index" funcs="$funcs insque" funcs="$funcs memchr" +funcs="$funcs memrchr" funcs="$funcs memcmp" funcs="$funcs memcpy" funcs="$funcs memmem" @@ -6276,7 +6277,7 @@ if test "x" = "y"; then ffs __fsetlocking \ getcwd getpagesize getrlimit getrusage getsysinfo gettimeofday \ index insque \ - memchr memcmp memcpy memmem memmove memset mkstemps \ + memchr memrchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ pipe2 posix_spawn posix_spawnp psignal \ pstat_getdynamic pstat_getstatic putenv \ @@ -6691,7 +6692,7 @@ esac for f in atexit basename bcmp bcopy bsearch bzero calloc clock ffs \ getcwd getpagesize getrusage gettimeofday \ - index insque memchr memcmp memcpy memmove memset psignal \ + index insque memchr memrchr memcmp memcpy memmove memset psignal \ putenv random rename rindex sbrk setenv stpcpy strcasecmp \ strchr strdup strerror strncasecmp strrchr strstr strtod \ strtol strtoul sysconf times tmpnam vfprintf vprintf \ diff --git a/libiberty/configure.ac b/libiberty/configure.ac index 5bad0f93692..3de5eca0df2 100644 --- a/libiberty/configure.ac +++ b/libiberty/configure.ac @@ -370,6 +370,7 @@ funcs="$funcs gettimeofday" funcs="$funcs index" funcs="$funcs insque" funcs="$funcs memchr" +funcs="$funcs memrchr" funcs="$funcs memcmp" funcs="$funcs memcpy" funcs="$funcs memmem" @@ -436,7 +437,7 @@ if test "x" = "y"; then ffs __fsetlocking \ getcwd getpagesize getrlimit getrusage getsysinfo gettimeofday \ index insque \ - memchr memcmp memcpy memmem memmove memset mkstemps \ + memchr memrchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ pipe2 posix_spawn posix_spawnp psignal \ pstat_getdynamic pstat_getstatic putenv \ @@ -555,7 +556,7 @@ if test -n "${with_target_subdir}"; then for f in atexit basename bcmp bcopy bsearch bzero calloc clock ffs \ getcwd getpagesize getrusage gettimeofday \ - index insque memchr memcmp memcpy memmove memset psignal \ + index insque memchr memrchr memcmp memcpy memmove memset psignal \ putenv random rename rindex sbrk setenv stpcpy strcasecmp \ strchr strdup strerror strncasecmp strrchr strstr strtod \ strtol strtoul sysconf times tmpnam vfprintf vprintf \ diff --git a/libiberty/functions.texi b/libiberty/functions.texi index b56b02e0686..7c7da1ba296 100644 --- a/libiberty/functions.texi +++ b/libiberty/functions.texi @@ -749,6 +749,20 @@ returned. @end deftypefn +@c memrchr.c:3 +@deftypefn Supplemental void* memrchr (const void *@var{s}, int @var{c}, @ + size_t @var{n}) + +This function searches memory for the character @var{c} in reverse order, +starting at @code{*@var{s}+@var{n}-1} . The search only ends with +the first occurrence of @var{c}, or when the start us reached; in particular, +a null character does not terminate the search. If the character @var{c} is +found within @var{length} characters of @code{*@var{s}}, a pointer +to the character is returned. If @var{c} is not found, then @code{NULL} is +returned. + +@end deftypefn + @c memcmp.c:6 @deftypefn Supplemental int memcmp (const void *@var{x}, const void *@var{y}, @ size_t @var{count}) diff --git a/libiberty/memrchr.c b/libiberty/memrchr.c new file mode 100644 index 00000000000..fe7713ecce5 --- /dev/null +++ b/libiberty/memrchr.c @@ -0,0 +1,33 @@ +/* + +@deftypefn Supplemental void* memrchr (const void *@var{s}, int @var{c}, @ + size_t @var{n}) + +This function searches memory for the character @var{c} in reverse order, +starting at @code{*@var{s}+@var{n}-1} . The search only ends with +the first occurrence of @var{c}, or when the start us reached; in particular, +a null character does not terminate the search. If the character @var{c} is +found within @var{length} characters of @code{*@var{s}}, a pointer +to the character is returned. If @var{c} is not found, then @code{NULL} is +returned. + +@end deftypefn + +*/ + +#include <ansidecl.h> +#include <stddef.h> + +void * +memrchr (const void *src_void, int c, size_t length) +{ + if (length == 0) + return NULL; + + const unsigned char *p = (const unsigned char*)src_void; + p += length; + while (*--p != (unsigned char)c) + if (src_void == p) + return NULL; + return (void *)p; +} -- 2.39.2 (Apple Git-143)