diff --git a/ChangeLog b/ChangeLog index 4d054b0894..ae7e9b391a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2001-03-19 Ulrich Drepper + + * 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 * 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. + /* $ORIGIN is not expanded for SUID/GUID programs and it must + always appear first in path. - 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)))) + 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; + const char *repl = NULL; + size_t len = 1; - /* 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)))) + /* 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 (__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 - { - /* 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 (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');