aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--elf/dl-dst.h4
-rw-r--r--elf/dl-load.c123
3 files changed, 71 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 4d054b0894..ae7e9b391a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2001-03-17 Bruno Haible <haible@clisp.cons.org>
* intl/loadmsgcat.c (_nl_load_domain) [!_LIBC]: Use fstat, not fstat64.
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');