summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-03-20 06:52:36 +0000
committerUlrich Drepper <drepper@redhat.com>2001-03-20 06:52:36 +0000
commit2541eda0d4528470d93c71be0a0b74b9dcae9b14 (patch)
treec443e4abef3ba88d93a1c2f19798966f9166387e /elf
parent4a4d50f3728ae901ad94e33ee53270906866371d (diff)
downloadglibc-2541eda0d4528470d93c71be0a0b74b9dcae9b14.tar.gz
glibc-2541eda0d4528470d93c71be0a0b74b9dcae9b14.tar.xz
glibc-2541eda0d4528470d93c71be0a0b74b9dcae9b14.zip
Update.
2001-03-19  Ulrich Drepper  <drepper@redhat.com>

	* elf/dl-dst.h (DL_DST_COUNT): Add __builtin_expect.

	* elf/dl-load.c (_dl_dst_count): Make DST recognition more robust.
	(_dl_dst_substitute): Likewise.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-dst.h4
-rw-r--r--elf/dl-load.c123
2 files changed, 64 insertions, 63 deletions
diff --git a/elf/dl-dst.h b/elf/dl-dst.h
index ca32e25104..5d19922e4c 100644
--- a/elf/dl-dst.h
+++ b/elf/dl-dst.h
@@ -1,5 +1,5 @@
 /* Handling of dynamic sring tokens.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001 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
@@ -24,7 +24,7 @@
     size_t __cnt = 0;							      \
     const char *__sf = strchr (name, '$');				      \
 									      \
-    if (__sf != NULL)							      \
+    if (__builtin_expect (__sf != NULL, 0))				      \
       __cnt = _dl_dst_count (__sf, is_path);				      \
 									      \
     __cnt; })
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 44efb11da0..6f56f9772d 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -180,26 +180,28 @@ _dl_dst_count (const char *name, int is_path)
     {
       size_t len = 1;
 
-      /* $ORIGIN is not expanded for SUID/GUID programs.
-
-	 Note that it is no bug that the strings in the first two `strncmp'
-	 calls are longer than the sequence which is actually tested.  */
-      if ((((strncmp (&name[1], "ORIGIN}", 6) == 0
-	     && (!__libc_enable_secure
-		 || ((name[7] == '\0' || (is_path && name[7] == ':'))
-		     && (name == start || (is_path && name[-1] == ':'))))
-	     && (len = 7) != 0)
-	    || (strncmp (&name[1], "PLATFORM}", 8) == 0 && (len = 9) != 0))
-	   && (name[len] == '\0' || name[len] == '/'
-	       || (is_path && name[len] == ':')))
-	  || (name[1] == '{'
-	      && ((strncmp (&name[2], "ORIGIN}", 7) == 0
-		   && (!__libc_enable_secure
-		       || ((name[9] == '\0' || (is_path && name[9] == ':'))
-			   && (name == start || (is_path && name[-1] == ':'))))
-		   && (len = 9) != 0)
-		  || (strncmp (&name[2], "PLATFORM}", 9) == 0
-		      && (len = 11) != 0))))
+      /* $ORIGIN is not expanded for SUID/GUID programs and it must
+	 always appear first in path.
+
+	 Note that it is no bug that the string in the second and
+	 fourth `strncmp' call is longer than the sequence which is
+	 actually tested.  */
+      if (((strncmp (&name[1], "{ORIGIN}", 8) == 0 && (len = 9) != 0)
+	   || (strncmp (&name[1], "{ORIGIN}" + 1, 6) == 0
+	       && (name[7] == '\0' || name[7] == '/'
+		   || (is_path && name[7] == ':'))
+	       && (len = 7) != 0)))
+	{
+	  if (__builtin_expect (!__libc_enable_secure, 1)
+	      && (name == start || (is_path && name[-1] == ':')))
+	    ++cnt;
+	}
+      else if ((strncmp (&name[1], "{PLATFORM}", 10) == 0
+		&& (len = 11) != 0)
+	       || (strncmp (&name[1], "{PLATFORM}" + 1, 8) == 0
+		   && (name[9] == '\0' || name[9] == '/'
+		       || (is_path && name[9] == ':'))
+		   && (len = 9) != 0))
 	++cnt;
 
       name = strchr (name + len, '$');
@@ -225,57 +227,56 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
 
   do
     {
-      if (*name == '$')
+      if (__builtin_expect (*name, 'a') == '$')
 	{
-	  const char *repl;
-	  size_t len;
-
-	  /* Note that it is no bug that the strings in the first two `strncmp'
-	     calls are longer than the sequence which is actually tested.  */
-	  if ((((strncmp (&name[1], "ORIGIN}", 6) == 0 && (len = 7) != 0)
-		|| (strncmp (&name[1], "PLATFORM}", 8) == 0 && (len = 9) != 0))
-	       && (name[len] == '\0' || name[len] == '/'
-		   || (is_path && name[len] == ':')))
-	      || (name[1] == '{'
-		  && ((strncmp (&name[2], "ORIGIN}", 7) == 0 && (len = 9) != 0)
-		      || (strncmp (&name[2], "PLATFORM}", 9) == 0
-			  && (len = 11) != 0))))
+	  const char *repl = NULL;
+	  size_t len = 1;
+
+	  /* Note that it is no bug that the string in the second and
+	     fourth `strncmp' call is longer than the sequence which
+	     is actually tested.  */
+	  if (((strncmp (&name[1], "{ORIGIN}", 8) == 0 && (len = 9) != 0)
+	       || (strncmp (&name[1], "{ORIGIN}" + 1, 6) == 0
+		   && (name[7] == '\0' || name[7] == '/'
+		       || (is_path && name[7] == ':'))
+		   && (len = 7) != 0)))
 	    {
-	      repl = ((len == 7 || name[2] == 'O')
-		      ? (__libc_enable_secure
-			 && ((name[len] != '\0'
-			      && (!is_path || name[len] != ':'))
-			     || (name != start
-				 && (!is_path || name[-1] != ':')))
-			 ? NULL : l->l_origin)
-		      : _dl_platform);
-
-	      if (repl != NULL && repl != (const char *) -1)
-		{
-		  wp = __stpcpy (wp, repl);
-		  name += len;
-		}
-	      else
-		{
-		  /* We cannot use this path element, the value of the
-		     replacement is unknown.  */
-		  wp = last_elem;
-		  name += len;
-		  while (*name != '\0' && (!is_path || *name != ':'))
-		    ++name;
-		}
+	      if (__builtin_expect (!__libc_enable_secure, 1)
+		  && (name == start || (is_path && name[-1] == ':')))
+		repl = l->l_origin;
+	    }
+	  else if ((strncmp (&name[1], "{PLATFORM}", 10) == 0
+		    && (len = 11) != 0)
+		   || (strncmp (&name[1], "{PLATFORM}" + 1, 8) == 0
+		       && (name[9] == '\0' || name[9] == '/' || name[9] == ':')
+		       && (len = 9) != 0))
+	    repl = _dl_platform;
+
+
+	  if (repl != NULL && repl != (const char *) -1)
+	    {
+	      wp = __stpcpy (wp, repl);
+	      name += len;
+	    }
+	  else if (len > 1)
+	    {
+	      /* We cannot use this path element, the value of the
+		 replacement is unknown.  */
+	      wp = last_elem;
+	      name += len;
+	      while (*name != '\0' && (!is_path || *name != ':'))
+		++name;
 	    }
 	  else
 	    /* No DST we recognize.  */
 	    *wp++ = *name++;
 	}
-      else if (is_path && *name == ':')
+      else
 	{
 	  *wp++ = *name++;
-	  last_elem = wp;
+	  if (is_path && *name == ':')
+	    last_elem = wp;
 	}
-      else
-	*wp++ = *name++;
     }
   while (*name != '\0');