public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: libc-alpha@sourceware.org
Subject: [PATCH] elf: Replace memcmp with __memcmpeq for variable size
Date: Sun,  6 Feb 2022 13:09:14 -0800	[thread overview]
Message-ID: <20220206210914.1593336-1-hjl.tools@gmail.com> (raw)

Replace memcmp with __memcmpeq when a boolean return is all that is
needed.  __memcmpeq is an alias of memcmp by default and it can be
optimized by architectures.

Add <memcmp-eq.h> to define memcmp_eq which calls memcmp by default.

On x86-64, memcmp_eq calls __memcmpeq for variable size:

1. ld.so size
   text	   data	    bss	    dec	    hex	filename
 203170	  10984	    456	 214610	  34652	ld.so (before)
 204146	  10984	    456	 215586	  34a22	ld.so (after)
2. Cycles to run "sprof":

Before:

   1593248:
   1593248:	runtime linker statistics:
   1593248:	  total startup time in dynamic loader: 123726 cycles
   1593248:	            time needed for relocation: 36187 cycles (29.2%)
   1593248:	                 number of relocations: 103
   1593248:	      number of relocations from cache: 3
   1593248:	        number of relative relocations: 1355
   1593248:	           time needed to load objects: 34577 cycles (27.9%)
Try `sprof --help' or `sprof --usage' for more information.
   1593248:
   1593248:	runtime linker statistics:
   1593248:	           final number of relocations: 108
   1593248:	final number of relocations from cache: 3

After:

   1593300:
   1593300:	runtime linker statistics:
   1593300:	  total startup time in dynamic loader: 120229 cycles
   1593300:	            time needed for relocation: 33655 cycles (27.9%)
   1593300:	                 number of relocations: 103
   1593300:	      number of relocations from cache: 3
   1593300:	        number of relative relocations: 1355
   1593300:	           time needed to load objects: 32114 cycles (26.7%)
Try `sprof --help' or `sprof --usage' for more information.
   1593300:
   1593300:	runtime linker statistics:
   1593300:	           final number of relocations: 108
   1593300:	final number of relocations from cache: 3
---
 elf/cache.c                              | 20 ++++++------
 elf/dl-cache.c                           | 12 ++++----
 elf/dl-diagnostics.c                     |  2 +-
 elf/dl-hwcaps_split.c                    |  2 +-
 elf/dl-load.c                            | 25 ++++++++-------
 elf/dl-profile.c                         |  6 ++--
 elf/ldconfig.c                           |  5 +--
 elf/pldd.c                               |  2 +-
 elf/readelflib.c                         |  4 +--
 elf/readlib.c                            |  5 +--
 elf/rtld.c                               | 39 ++++++++++++------------
 elf/sprof.c                              | 12 ++++----
 include/string.h                         |  3 ++
 sysdeps/generic/memcmp-eq.h              | 24 +++++++++++++++
 sysdeps/x86_64/memcmp-eq.h               | 26 ++++++++++++++++
 sysdeps/x86_64/multiarch/memcmpeq-sse2.S |  4 ++-
 16 files changed, 127 insertions(+), 64 deletions(-)
 create mode 100644 sysdeps/generic/memcmp-eq.h
 create mode 100644 sysdeps/x86_64/memcmp-eq.h

diff --git a/elf/cache.c b/elf/cache.c
index dbf4c83a7a..810028b1bc 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -340,14 +340,15 @@ print_cache (const char *cache_name)
   const char *cache_data;
   int format = 0;
 
-  if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
+  if (memcmp_eq (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
     {
       /* This can only be the new format without the old one.  */
       cache_new = (struct cache_file_new *) cache;
 
-      if (memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)
-	  || memcmp (cache_new->version, CACHE_VERSION,
-		      sizeof CACHE_VERSION - 1))
+      if (memcmp_eq (cache_new->magic, CACHEMAGIC_NEW,
+		     sizeof CACHEMAGIC_NEW - 1)
+	  || memcmp_eq (cache_new->version, CACHE_VERSION,
+			sizeof CACHE_VERSION - 1))
 	error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
       check_new_cache (cache_new);
       format = 1;
@@ -374,10 +375,10 @@ print_cache (const char *cache_name)
 
 	  cache_new = (struct cache_file_new *) ((void *)cache + offset);
 
-	  if (memcmp (cache_new->magic, CACHEMAGIC_NEW,
-		      sizeof CACHEMAGIC_NEW - 1) == 0
-	      && memcmp (cache_new->version, CACHE_VERSION,
-			 sizeof CACHE_VERSION - 1) == 0)
+	  if (memcmp_eq (cache_new->magic, CACHEMAGIC_NEW,
+			 sizeof CACHEMAGIC_NEW - 1) == 0
+	      && memcmp_eq (cache_new->version, CACHE_VERSION,
+			    sizeof CACHE_VERSION - 1) == 0)
 	    {
 	      check_new_cache (cache_new);
 	      cache_data = (const char *) cache_new;
@@ -1030,7 +1031,8 @@ load_aux_cache (const char *aux_cache_name)
     = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (aux_cache == MAP_FAILED
       || aux_cache_size < sizeof (struct aux_cache_file)
-      || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
+      || memcmp_eq (aux_cache->magic, AUX_CACHEMAGIC,
+		    sizeof AUX_CACHEMAGIC - 1)
       || aux_cache_size != (sizeof (struct aux_cache_file)
 			    + aux_cache->nlibs * sizeof (struct aux_cache_file_entry)
 			    + aux_cache->len_strings))
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 88bf78ad7c..8574d4ded1 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -72,7 +72,7 @@ glibc_hwcaps_compare (uint32_t left_index, struct dl_hwcaps_priority *right)
     to_compare = left_name_length;
   else
     to_compare = right->name_length;
-  int cmp = memcmp (left_name, right->name, to_compare);
+  int cmp = memcmp_eq (left_name, right->name, to_compare);
   if (cmp != 0)
     return cmp;
   if (left_name_length < right->name_length)
@@ -420,8 +420,8 @@ _dl_load_cache_lookup (const char *name)
 	 - the old format with the new format in it
 	 The following checks if the cache contains any of these formats.  */
       if (file != MAP_FAILED && cachesize > sizeof *cache_new
-	  && memcmp (file, CACHEMAGIC_VERSION_NEW,
-		     sizeof CACHEMAGIC_VERSION_NEW - 1) == 0
+	  && memcmp_eq (file, CACHEMAGIC_VERSION_NEW,
+			sizeof CACHEMAGIC_VERSION_NEW - 1) == 0
 	  /* Check for corruption, avoiding overflow.  */
 	  && ((cachesize - sizeof *cache_new) / sizeof (struct file_entry_new)
 	      >= ((struct cache_file_new *) file)->nlibs))
@@ -435,7 +435,7 @@ _dl_load_cache_lookup (const char *name)
 	  cache = file;
 	}
       else if (file != MAP_FAILED && cachesize > sizeof *cache
-	       && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
+	       && memcmp_eq (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
 	       /* Check for corruption, avoiding overflow.  */
 	       && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
 		   >= ((struct cache_file *) file)->nlibs))
@@ -450,8 +450,8 @@ _dl_load_cache_lookup (const char *name)
 
 	  cache_new = (struct cache_file_new *) ((void *) cache + offset);
 	  if (cachesize < (offset + sizeof (struct cache_file_new))
-	      || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW,
-			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
+	      || memcmp_eq (cache_new->magic, CACHEMAGIC_VERSION_NEW,
+			    sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
 	      cache_new = (void *) -1;
 	  else
 	    {
diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c
index d29bdd6904..3181ef5ea8 100644
--- a/elf/dl-diagnostics.c
+++ b/elf/dl-diagnostics.c
@@ -170,7 +170,7 @@ unfiltered_envvar (const char *env, size_t *name_length)
     {
       size_t candidate_length = strlen (candidate);
       if (candidate_length == envname_length
-          && memcmp (candidate, env, candidate_length) == 0)
+          && memcmp_eq (candidate, env, candidate_length) == 0)
         return true;
       candidate += candidate_length + 1;
     }
diff --git a/elf/dl-hwcaps_split.c b/elf/dl-hwcaps_split.c
index 8f5d7a22b2..d69825bbcf 100644
--- a/elf/dl-hwcaps_split.c
+++ b/elf/dl-hwcaps_split.c
@@ -71,7 +71,7 @@ _dl_hwcaps_contains (const char *hwcaps, const char *name, size_t name_length)
   _dl_hwcaps_split_init (&split, hwcaps);
   while (_dl_hwcaps_split (&split))
     if (split.length == name_length
-        && memcmp (split.segment, name, name_length) == 0)
+        && memcmp_eq (split.segment, name, name_length) == 0)
       return true;
   return false;
 }
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 5b0ff41ee1..dd50f4457e 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -170,7 +170,7 @@ is_trusted_path_normalize (const char *path, size_t len)
   for (size_t idx = 0; idx < nsystem_dirs_len; ++idx)
     {
       if (wnp - npath >= system_dirs_len[idx]
-	  && memcmp (trun, npath, system_dirs_len[idx]) == 0)
+	  && memcmp_eq (trun, npath, system_dirs_len[idx]) == 0)
 	/* Found it.  */
 	return true;
 
@@ -507,7 +507,8 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
 
       /* See if this directory is already known.  */
       for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
-	if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
+	if (dirp->dirnamelen == len
+	    && memcmp_eq (cp, dirp->dirname, len) == 0)
 	  break;
 
       if (dirp != NULL)
@@ -884,7 +885,7 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
       /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */
       if (note->n_namesz == 4
 	  && note->n_type == NT_GNU_PROPERTY_TYPE_0
-	  && memcmp (note + 1, "GNU", 4) == 0)
+	  && memcmp_eq (note + 1, "GNU", 4) == 0)
 	{
 	  /* Check for invalid property.  */
 	  if (note->n_descsz < 8
@@ -1573,7 +1574,7 @@ open_verify (const char *name, int fd,
 #define ELF32_CLASS ELFCLASS32
 #define ELF64_CLASS ELFCLASS64
 #ifndef VALID_ELF_HEADER
-# define VALID_ELF_HEADER(hdr,exp,size)	(memcmp (hdr, exp, size) == 0)
+# define VALID_ELF_HEADER(hdr,exp,size)	(memcmp_eq (hdr, exp, size) == 0)
 # define VALID_ELF_OSABI(osabi)		(osabi == ELFOSABI_SYSV)
 # define VALID_ELF_ABIVERSION(osabi,ver) (ver == 0)
 #elif defined MORE_ELF_HEADER_DATA
@@ -1675,9 +1676,9 @@ open_verify (const char *name, int fd,
 						EI_ABIVERSION)
 			    || !VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI],
 						      ehdr->e_ident[EI_ABIVERSION])
-			    || memcmp (&ehdr->e_ident[EI_PAD],
-				       &expected[EI_PAD],
-				       EI_NIDENT - EI_PAD) != 0))
+			    || memcmp_eq (&ehdr->e_ident[EI_PAD],
+					  &expected[EI_PAD],
+					  EI_NIDENT - EI_PAD) != 0))
 	{
 	  /* Something is wrong.  */
 	  const Elf32_Word *magp = (const void *) ehdr->e_ident;
@@ -1720,8 +1721,8 @@ open_verify (const char *name, int fd,
 	  else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI],
 					  ehdr->e_ident[EI_ABIVERSION]))
 	    errstring = N_("ELF file ABI version invalid");
-	  else if (memcmp (&ehdr->e_ident[EI_PAD], &expected[EI_PAD],
-			   EI_NIDENT - EI_PAD) != 0)
+	  else if (memcmp_eq (&ehdr->e_ident[EI_PAD], &expected[EI_PAD],
+			       EI_NIDENT - EI_PAD) != 0)
 	    errstring = N_("nonzero padding in e_ident");
 	  else
 	    /* Otherwise we don't know what went wrong.  */
@@ -1802,7 +1803,8 @@ open_verify (const char *name, int fd,
 		  }
 	      }
 
-	    while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
+	    while (memcmp_eq (abi_note, &expected_note,
+			      sizeof (expected_note)))
 	      {
 		ElfW(Addr) note_size
 		  = ELF_NOTE_NEXT_OFFSET (abi_note[0], abi_note[1],
@@ -2193,7 +2195,8 @@ _dl_map_object (struct link_map *loader, const char *name,
 
 		  do
 		    {
-		      if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0)
+		      if (memcmp_eq (cached, dirp,
+				     system_dirs_len[cnt]) == 0)
 			{
 			  /* The prefix matches.  Don't use the entry.  */
 			  free (cached);
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 9359be7c33..7bfe558e66 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -416,10 +416,10 @@ _dl_start_profile (void)
   else
     {
       /* Test the signature in the file.  */
-      if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
+      if (memcmp_eq (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
 	  || *(uint32_t *) hist != GMON_TAG_TIME_HIST
-	  || memcmp (hist + sizeof (uint32_t), &hist_hdr,
-		     sizeof (struct gmon_hist_hdr)) != 0
+	  || memcmp_eq (hist + sizeof (uint32_t), &hist_hdr,
+			sizeof (struct gmon_hist_hdr)) != 0
 	  || narcsp[-1] != GMON_TAG_CG_ARC)
 	goto wrong_format;
     }
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 57bb95ebc3..94334af932 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -861,8 +861,9 @@ search_dir (const struct dir_entry *entry)
 		      ".#prelink#") == 0)
 	    continue;
 	  if (len >= sizeof (".#prelink#.XXXXXX") - 1
-	      && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
-			 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
+	      && memcmp_eq (direntry->d_name
+			    + len - sizeof (".#prelink#.XXXXXX") + 1,
+			    ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
 	    continue;
 	}
       len += strlen (entry->path) + 2;
diff --git a/elf/pldd.c b/elf/pldd.c
index f720b2c515..9fe80c874f 100644
--- a/elf/pldd.c
+++ b/elf/pldd.c
@@ -297,7 +297,7 @@ get_process_info (const char *exe, int dfd, long int pid)
 
   close (fd);
 
-  if (memcmp (e_ident, ELFMAG, SELFMAG) != 0)
+  if (memcmp_eq (e_ident, ELFMAG, SELFMAG) != 0)
     {
       error (0, 0, gettext ("process %lu is no ELF program"), pid);
       return EXIT_FAILURE;
diff --git a/elf/readelflib.c b/elf/readelflib.c
index e147416363..2e7cad7419 100644
--- a/elf/readelflib.c
+++ b/elf/readelflib.c
@@ -142,7 +142,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
 
 	      while (abi_note [0] != 4 || abi_note [1] != 16
 		     || abi_note [2] != 1
-		     || memcmp (abi_note + 3, "GNU", 4) != 0)
+		     || memcmp_eq (abi_note + 3, "GNU", 4) != 0)
 		{
 		  ElfW(Addr) note_size
 		    = ELF_NOTE_NEXT_OFFSET (abi_note[0], abi_note[1],
@@ -186,7 +186,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
 		  /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */
 		  if (note->n_namesz == 4
 		      && note->n_type == NT_GNU_PROPERTY_TYPE_0
-		      && memcmp (note + 1, "GNU", 4) == 0)
+		      && memcmp_eq (note + 1, "GNU", 4) == 0)
 		    {
 		      /* Check for invalid property.  */
 		      if (note->n_descsz < 8
diff --git a/elf/readlib.c b/elf/readlib.c
index 3651dcdd8e..4521fbd16d 100644
--- a/elf/readlib.c
+++ b/elf/readlib.c
@@ -115,7 +115,8 @@ process_file (const char *real_file_name, const char *file_name,
 	{
 	  char buf[SELFMAG];
 	  size_t n = MIN (statbuf.st_size, SELFMAG);
-	  if (fread (buf, n, 1, file) == 1 && memcmp (buf, ELFMAG, n) == 0)
+	  if (fread (buf, n, 1, file) == 1
+	      && memcmp_eq (buf, ELFMAG, n) == 0)
 	    error (0, 0, _("File %s is too small, not checked."), file_name);
 	}
       fclose (file);
@@ -156,7 +157,7 @@ process_file (const char *real_file_name, const char *file_name,
     }
 
   elf_header = (ElfW(Ehdr) *) file_contents;
-  if (memcmp (elf_header->e_ident, ELFMAG, SELFMAG) != 0)
+  if (memcmp_eq (elf_header->e_ident, ELFMAG, SELFMAG) != 0)
     {
       /* The file is neither ELF nor aout.  Check if it's a linker
 	 script, like libc.so - otherwise complain.  Only search the
diff --git a/elf/rtld.c b/elf/rtld.c
index 8dafaf61f4..abddf20fc7 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2619,7 +2619,7 @@ process_dl_debug (struct dl_main_state *state, const char *dl_debug)
 
 	  for (cnt = 0; cnt < ndebopts; ++cnt)
 	    if (debopts[cnt].len == len
-		&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
+		&& memcmp_eq (dl_debug, debopts[cnt].name, len) == 0)
 	      {
 		GLRO(dl_debug_mask) |= debopts[cnt].mask;
 		state->any_debug = true;
@@ -2697,49 +2697,50 @@ process_envvars (struct dl_main_state *state)
 	{
 	case 4:
 	  /* Warning level, verbose or not.  */
-	  if (memcmp (envline, "WARN", 4) == 0)
+	  if (memcmp_eq (envline, "WARN", 4) == 0)
 	    GLRO(dl_verbose) = envline[5] != '\0';
 	  break;
 
 	case 5:
 	  /* Debugging of the dynamic linker?  */
-	  if (memcmp (envline, "DEBUG", 5) == 0)
+	  if (memcmp_eq (envline, "DEBUG", 5) == 0)
 	    {
 	      process_dl_debug (state, &envline[6]);
 	      break;
 	    }
-	  if (memcmp (envline, "AUDIT", 5) == 0)
+	  if (memcmp_eq (envline, "AUDIT", 5) == 0)
 	    audit_list_add_string (&state->audit_list, &envline[6]);
 	  break;
 
 	case 7:
 	  /* Print information about versions.  */
-	  if (memcmp (envline, "VERBOSE", 7) == 0)
+	  if (memcmp_eq (envline, "VERBOSE", 7) == 0)
 	    {
 	      state->version_info = envline[8] != '\0';
 	      break;
 	    }
 
 	  /* List of objects to be preloaded.  */
-	  if (memcmp (envline, "PRELOAD", 7) == 0)
+	  if (memcmp_eq (envline, "PRELOAD", 7) == 0)
 	    {
 	      state->preloadlist = &envline[8];
 	      break;
 	    }
 
 	  /* Which shared object shall be profiled.  */
-	  if (memcmp (envline, "PROFILE", 7) == 0 && envline[8] != '\0')
+	  if (memcmp_eq (envline, "PROFILE", 7) == 0
+	      && envline[8] != '\0')
 	    GLRO(dl_profile) = &envline[8];
 	  break;
 
 	case 8:
 	  /* Do we bind early?  */
-	  if (memcmp (envline, "BIND_NOW", 8) == 0)
+	  if (memcmp_eq (envline, "BIND_NOW", 8) == 0)
 	    {
 	      GLRO(dl_lazy) = envline[9] == '\0';
 	      break;
 	    }
-	  if (memcmp (envline, "BIND_NOT", 8) == 0)
+	  if (memcmp_eq (envline, "BIND_NOT", 8) == 0)
 	    GLRO(dl_bind_not) = envline[9] != '\0';
 	  break;
 
@@ -2747,7 +2748,7 @@ process_envvars (struct dl_main_state *state)
 	  /* Test whether we want to see the content of the auxiliary
 	     array passed up from the kernel.  */
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "SHOW_AUXV", 9) == 0)
+	      && memcmp_eq (envline, "SHOW_AUXV", 9) == 0)
 	    _dl_show_auxv ();
 	  break;
 
@@ -2755,7 +2756,7 @@ process_envvars (struct dl_main_state *state)
 	case 10:
 	  /* Mask for the important hardware capabilities.  */
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "HWCAP_MASK", 10) == 0)
+	      && memcmp_eq (envline, "HWCAP_MASK", 10) == 0)
 	    GLRO(dl_hwcap_mask) = _dl_strtoul (&envline[11], NULL);
 	  break;
 #endif
@@ -2763,14 +2764,14 @@ process_envvars (struct dl_main_state *state)
 	case 11:
 	  /* Path where the binary is found.  */
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "ORIGIN_PATH", 11) == 0)
+	      && memcmp_eq (envline, "ORIGIN_PATH", 11) == 0)
 	    GLRO(dl_origin_path) = &envline[12];
 	  break;
 
 	case 12:
 	  /* The library search path.  */
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "LIBRARY_PATH", 12) == 0)
+	      && memcmp_eq (envline, "LIBRARY_PATH", 12) == 0)
 	    {
 	      state->library_path = &envline[13];
 	      state->library_path_source = "LD_LIBRARY_PATH";
@@ -2778,14 +2779,14 @@ process_envvars (struct dl_main_state *state)
 	    }
 
 	  /* Where to place the profiling data file.  */
-	  if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
+	  if (memcmp_eq (envline, "DEBUG_OUTPUT", 12) == 0)
 	    {
 	      debug_output = &envline[13];
 	      break;
 	    }
 
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
+	      && memcmp_eq (envline, "DYNAMIC_WEAK", 12) == 0)
 	    GLRO(dl_dynamic_weak) = 1;
 	  break;
 
@@ -2796,7 +2797,7 @@ process_envvars (struct dl_main_state *state)
 	  EXTRA_LD_ENVVARS_13
 #endif
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
+	      && memcmp_eq (envline, "USE_LOAD_BIAS", 13) == 0)
 	    {
 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
 	      break;
@@ -2806,14 +2807,14 @@ process_envvars (struct dl_main_state *state)
 	case 14:
 	  /* Where to place the profiling data file.  */
 	  if (!__libc_enable_secure
-	      && memcmp (envline, "PROFILE_OUTPUT", 14) == 0
+	      && memcmp_eq (envline, "PROFILE_OUTPUT", 14) == 0
 	      && envline[15] != '\0')
 	    GLRO(dl_profile_output) = &envline[15];
 	  break;
 
 	case 16:
 	  /* The mode of the dynamic linker can be set.  */
-	  if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
+	  if (memcmp_eq (envline, "TRACE_PRELINKING", 16) == 0)
 	    {
 	      state->mode = rtld_mode_trace;
 	      GLRO(dl_verbose) = 1;
@@ -2824,7 +2825,7 @@ process_envvars (struct dl_main_state *state)
 
 	case 20:
 	  /* The mode of the dynamic linker can be set.  */
-	  if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
+	  if (memcmp_eq (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
 	    state->mode = rtld_mode_trace;
 	  break;
 
diff --git a/elf/sprof.c b/elf/sprof.c
index 405fbcbf38..08afe170bd 100644
--- a/elf/sprof.c
+++ b/elf/sprof.c
@@ -889,22 +889,22 @@ load_profdata (const char *name, struct shobj *shobj)
   hist_hdr.dimen_abbrev = 's';
 
   /* Test whether the header of the profiling data is ok.  */
-  if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
+  if (memcmp_eq (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
       || *(uint32_t *) result->hist != GMON_TAG_TIME_HIST
-      || memcmp (result->hist_hdr, &hist_hdr,
-		 sizeof (struct gmon_hist_hdr)) != 0
+      || memcmp_eq (result->hist_hdr, &hist_hdr,
+		    sizeof (struct gmon_hist_hdr)) != 0
       || narcsp[-1] != GMON_TAG_CG_ARC)
     {
       error (0, 0, _("`%s' is no correct profile data file for `%s'"),
 	     name, shobj->name);
       if (do_test)
 	{
-	  if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0)
+	  if (memcmp_eq (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0)
 	    puts ("gmon_hdr differs");
 	  if (*(uint32_t *) result->hist != GMON_TAG_TIME_HIST)
 	    puts ("result->hist differs");
-	  if (memcmp (result->hist_hdr, &hist_hdr,
-		      sizeof (struct gmon_hist_hdr)) != 0)
+	  if (memcmp_eq (result->hist_hdr, &hist_hdr,
+			 sizeof (struct gmon_hist_hdr)) != 0)
 	    puts ("hist_hdr differs");
 	  if (narcsp[-1] != GMON_TAG_CG_ARC)
 	    puts ("narcsp[-1] differs");
diff --git a/include/string.h b/include/string.h
index 21f641a413..6a39fb1ec6 100644
--- a/include/string.h
+++ b/include/string.h
@@ -160,6 +160,7 @@ extern __typeof (__strsep_g) __strsep_g attribute_hidden;
 
 extern __typeof (memchr) memchr attribute_hidden;
 extern __typeof (memcmp) memcmp attribute_hidden;
+extern __typeof (__memcmpeq) __memcmpeq attribute_hidden;
 extern __typeof (memcpy) memcpy attribute_hidden;
 extern __typeof (memmove) memmove attribute_hidden;
 extern __typeof (memset) memset attribute_hidden;
@@ -172,6 +173,8 @@ extern __typeof (strnlen) strnlen attribute_hidden;
 extern __typeof (strsep) strsep attribute_hidden;
 #endif
 
+#include <memcmp-eq.h>
+
 #if (!IS_IN (libc) || !defined SHARED) \
   && !defined NO_MEMPCPY_STPCPY_REDIRECT
 /* Redirect calls to __builtin_mempcpy and __builtin_stpcpy to call
diff --git a/sysdeps/generic/memcmp-eq.h b/sysdeps/generic/memcmp-eq.h
new file mode 100644
index 0000000000..07e723fef5
--- /dev/null
+++ b/sysdeps/generic/memcmp-eq.h
@@ -0,0 +1,24 @@
+/* Function to compare byte sequences for equality.  Generic version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+
+static __always_inline int
+memcmp_eq (const void *s1, const void *s2, size_t n)
+{
+  return memcmp (s1, s2, n);
+}
diff --git a/sysdeps/x86_64/memcmp-eq.h b/sysdeps/x86_64/memcmp-eq.h
new file mode 100644
index 0000000000..3d907948f0
--- /dev/null
+++ b/sysdeps/x86_64/memcmp-eq.h
@@ -0,0 +1,26 @@
+/* Function to compare byte sequences for equality.  x86-64 version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+static __always_inline int
+memcmp_eq (const void *s1, const void *s2, size_t n)
+{
+  /* Compiler can better optimize the constant size.  */
+  if (__builtin_constant_p (n))
+    return memcmp (s1, s2, n);
+  return __memcmpeq (s1, s2, n);
+}
diff --git a/sysdeps/x86_64/multiarch/memcmpeq-sse2.S b/sysdeps/x86_64/multiarch/memcmpeq-sse2.S
index b80a29d4b0..de7f5a7525 100644
--- a/sysdeps/x86_64/multiarch/memcmpeq-sse2.S
+++ b/sysdeps/x86_64/multiarch/memcmpeq-sse2.S
@@ -16,8 +16,10 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef memcmp
+#if IS_IN (libc)
 # define memcmp	__memcmpeq_sse2
+#else
+# define memcmp	__memcmpeq
 #endif
 #define USE_AS_MEMCMPEQ	1
 #include "memcmp-sse2.S"
-- 
2.34.1


             reply	other threads:[~2022-02-06 21:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-06 21:09 H.J. Lu [this message]
2022-02-06 22:19 ` Florian Weimer
2022-02-07  0:20   ` H.J. Lu
2022-02-07 10:40     ` Florian Weimer
2022-02-07 13:13       ` H.J. Lu
2022-02-07 13:19         ` Florian Weimer
2022-02-07 13:27           ` H.J. Lu
2022-02-07 13:30             ` Adhemerval Zanella
2022-02-07 14:00               ` H.J. Lu
2022-02-07 20:35 ` Joseph Myers
2022-02-08 22:30 Wilco Dijkstra
2022-02-08 23:00 ` Adhemerval Zanella
2022-02-09  0:07   ` Noah Goldstein
2022-02-09  1:42     ` Wilco Dijkstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220206210914.1593336-1-hjl.tools@gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).