On Fri, Mar 21, 2025 at 11:01 AM Iain Sandoe <iains....@gmail.com> wrote:
>
> 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?

OK.

Richard.

> 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)
>

Reply via email to