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