summary refs log tree commit diff
path: root/elf/dl-version.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-version.c')
-rw-r--r--elf/dl-version.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/elf/dl-version.c b/elf/dl-version.c
index b47bd91727..cda0889209 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -214,12 +214,19 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	      while (1)
 		{
 		  /* Match the symbol.  */
+		  const char *string = strtab + aux->vna_name;
 		  result |= match_symbol (DSO_FILENAME (map->l_name),
 					  map->l_ns, aux->vna_hash,
-					  strtab + aux->vna_name,
-					  needed->l_real, verbose,
+					  string, needed->l_real, verbose,
 					  aux->vna_flags & VER_FLG_WEAK);
 
+		  /* 0xfd0e42: _dl_elf_hash ("GLIBC_ABI_DT_RELR").  */
+		  if (aux->vna_hash == 0xfd0e42
+		      && __glibc_likely (strcmp (string,
+						 "GLIBC_ABI_DT_RELR")
+					 == 0))
+		    map->l_dt_relr_ref = 1;
+
 		  /* Compare the version index.  */
 		  if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)
 		    ndx_high = aux->vna_other & 0x7fff;
@@ -352,6 +359,30 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	}
     }
 
+  /* When there is a DT_VERNEED entry with libc.so on DT_NEEDED, issue
+     an error if there is a DT_RELR entry without GLIBC_ABI_DT_RELR
+     dependency.  */
+  if (dyn != NULL
+      && map->l_info[DT_NEEDED] != NULL
+      && map->l_info[DT_RELR] != NULL
+      && __glibc_unlikely (!map->l_dt_relr_ref))
+    {
+      const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+      const ElfW(Dyn) *d;
+      for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
+	if (d->d_tag == DT_NEEDED)
+	  {
+	    const char *name = strtab + d->d_un.d_val;
+	    if (strncmp (name, "libc.so.", 8) == 0)
+	      {
+		_dl_exception_create
+		  (&exception, DSO_FILENAME (map->l_name),
+		   N_("DT_RELR without GLIBC_ABI_DT_RELR dependency"));
+		goto call_error;
+	      }
+	  }
+    }
+
   return result;
 }