2002-02-02  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/generic/dl-environ.c (unsetenv): Optimize.  Don't use
	strncmp.
	* elf/dl-load.c (is_dst): Optimize.  Don't call strncmp twice.
	* elf/rtld.c (process_dl_debug): Optimize. Avoid calls to strncmp,
	strspn, and strcspn.
	(process_envvars): Don't use strcspn.

	* elf/dl-load.c (_dl_dst_count): Fix possible endless loop.
	(_dl_dst_substitute): Likewise.
This commit is contained in:
Ulrich Drepper 2002-02-02 09:49:35 +00:00
parent e0f4188600
commit 379d4ec497
4 changed files with 99 additions and 61 deletions

View File

@ -1,3 +1,15 @@
2002-02-02 Ulrich Drepper <drepper@redhat.com>
* sysdeps/generic/dl-environ.c (unsetenv): Optimize. Don't use
strncmp.
* elf/dl-load.c (is_dst): Optimize. Don't call strncmp twice.
* elf/rtld.c (process_dl_debug): Optimize. Avoid calls to strncmp,
strspn, and strcspn.
(process_envvars): Don't use strcspn.
* elf/dl-load.c (_dl_dst_count): Fix possible endless loop.
(_dl_dst_substitute): Likewise.
2002-02-01 Ulrich Drepper <drepper@redhat.com>
* elf/do-rel.h (elf_dynamic_do_rel): Help the compiler recognize

View File

@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <libintl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -147,22 +148,38 @@ local_strdup (const char *s)
static size_t
is_dst (const char *start, const char *name, const char *str, size_t cmplen,
is_dst (const char *start, const char *name, const char *str,
int is_path, int secure)
{
size_t len;
bool is_curly = false;
if (strncmp (name, str, cmplen) == 0)
len = cmplen + 1;
else if (strncmp (name, str + 1, cmplen - 2) == 0
&& (name[cmplen - 2] == '\0' || name[cmplen - 2] == '/'
|| (is_path && name[cmplen - 2] == ':')))
len = cmplen - 1;
else
if (name[0] == '{')
{
is_curly = true;
++name;
}
len = 0;
while (name[len] == str[len] && name[len] != '\0')
++len;
if (is_curly)
{
if (name[len] != '}')
return 0;
/* Point again at the beginning of the name. */
--name;
/* Skip over closing curly brace and adjust for the --name. */
len += 2;
}
else if (name[len] != '\0' && name[len] != '/'
&& (!is_path || name[len] != ':'))
return 0;
if (__builtin_expect (secure, 0)
&& ((name[len - 1] != '\0' && (!is_path || name[len - 1] != ':'))
&& ((name[len] != '\0' && (!is_path || name[len] != ':'))
|| (name != start + 1 && (!is_path || name[-2] != ':'))))
return 0;
@ -178,17 +195,14 @@ _dl_dst_count (const char *name, int is_path)
do
{
size_t len = 1;
size_t len;
/* $ORIGIN is not expanded for SUID/GUID programs (except if it
is $ORIGIN alone) 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 ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path,
is $ORIGIN alone) and it must always appear first in path. */
++name;
if ((len = is_dst (start, name, "ORIGIN", is_path,
__libc_enable_secure)) != 0
|| ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, 0))
|| ((len = is_dst (start, name, "PLATFORM", is_path, 0))
!= 0))
++cnt;
@ -218,15 +232,13 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
if (__builtin_expect (*name == '$', 0))
{
const char *repl = NULL;
size_t len = 1;
size_t len;
/* 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 ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path,
++name;
if ((len = is_dst (start, name, "ORIGIN", is_path,
__libc_enable_secure)) != 0)
repl = l->l_origin;
else if ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path,
else if ((len = is_dst (start, name, "PLATFORM", is_path,
0)) != 0)
repl = GL(dl_platform);
@ -246,7 +258,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
}
else
/* No DST we recognize. */
*wp++ = *name++;
*wp++ = '$';
}
else
{

View File

@ -1286,49 +1286,50 @@ process_dl_debug (const char *dl_debug)
is correctly handled in the LD_DEBUG_HELP code below. */
static const struct
{
const char name[11];
unsigned char len;
const char name[10];
const char helptext[41];
unsigned short int mask;
} debopts[] =
{
{ "libs", "display library search paths",
#define LEN_AND_STR(str) sizeof (str) - 1, str
{ LEN_AND_STR ("libs"), "display library search paths",
DL_DEBUG_LIBS | DL_DEBUG_IMPCALLS },
{ "reloc", "display relocation processing",
{ LEN_AND_STR ("reloc"), "display relocation processing",
DL_DEBUG_RELOC | DL_DEBUG_IMPCALLS },
{ "files", "display progress for input file",
{ LEN_AND_STR ("files"), "display progress for input file",
DL_DEBUG_FILES | DL_DEBUG_IMPCALLS },
{ "symbols", "display symbol table processing",
{ LEN_AND_STR ("symbols"), "display symbol table processing",
DL_DEBUG_SYMBOLS | DL_DEBUG_IMPCALLS },
{ "bindings", "display information about symbol binding",
{ LEN_AND_STR ("bindings"), "display information about symbol binding",
DL_DEBUG_BINDINGS | DL_DEBUG_IMPCALLS },
{ "versions", "display version dependencies",
{ LEN_AND_STR ("versions"), "display version dependencies",
DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
{ "all", "all previous options combined",
{ LEN_AND_STR ("all"), "all previous options combined",
DL_DEBUG_LIBS | DL_DEBUG_RELOC | DL_DEBUG_FILES | DL_DEBUG_SYMBOLS
| DL_DEBUG_BINDINGS | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
{ "statistics", "display relocation statistics",
{ LEN_AND_STR ("statistics"), "display relocation statistics",
DL_DEBUG_STATISTICS },
{ "help", "display this help message and exit",
{ LEN_AND_STR ("help"), "display this help message and exit",
DL_DEBUG_HELP },
};
#define ndebopts (sizeof (debopts) / sizeof (debopts[0]))
size_t len;
#define separators " ,:"
do
/* Skip separating white spaces and commas. */
while (*dl_debug != '\0')
{
len = 0;
/* Skip separating white spaces and commas. */
dl_debug += strspn (dl_debug, separators);
if (*dl_debug != '\0')
if (*dl_debug != ' ' && *dl_debug != ',' && *dl_debug != ':')
{
size_t cnt;
size_t len = 1;
len = strcspn (dl_debug, separators);
while (dl_debug[len] != '\0' && dl_debug[len] != ' '
&& dl_debug[len] != ',' && dl_debug[len] != ':')
++len;
for (cnt = 0; cnt < ndebopts; ++cnt)
if (strncmp (dl_debug, debopts[cnt].name, len) == 0
&& debopts[cnt].name[len] == '\0')
if (debopts[cnt].len == len
&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
{
GL(dl_debug_mask) |= debopts[cnt].mask;
any_debug = 1;
@ -1342,11 +1343,14 @@ process_dl_debug (const char *dl_debug)
char *copy = strndupa (dl_debug, len);
_dl_error_printf ("\
warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
break;
}
}
dl_debug += len;
continue;
}
++dl_debug;
}
while (*(dl_debug += len) != '\0');
if (GL(dl_debug_mask) & DL_DEBUG_HELP)
{
@ -1387,7 +1391,10 @@ process_envvars (enum mode *modep)
while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
{
size_t len = strcspn (envline, "=");
size_t len = 0;
while (envline[len] != '\0' && envline[len] != '=')
++len;
if (envline[len] != '=')
/* This is a "LD_" variable at the end of the string without

View File

@ -1,5 +1,5 @@
/* Environment handling for dynamic loader.
Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 1995-1998, 2000, 2001, 2002 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
@ -53,23 +53,30 @@ _dl_next_ld_env_entry (char ***position)
int
unsetenv (const char *name)
{
const size_t len = strlen (name);
char **ep;
ep = __environ;
while (*ep != NULL)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
{
size_t cnt;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
while ((*ep)[cnt] == name[cnt] && name[cnt] != '\0')
++cnt;
if ((*ep)[cnt] == '=')
{
/* Found it. Remove this pointer by moving later ones to
the front. */
char **dp = ep;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
}
return 0;
}