summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--elf/dl-reloc.c2
-rw-r--r--elf/rtld.c62
-rw-r--r--malloc/malloc.c89
-rw-r--r--sysdeps/arm/dl-machine.h7
-rw-r--r--sysdeps/generic/dl-environ.c23
-rw-r--r--sysdeps/unix/sysv/linux/dl-librecon.h4
-rw-r--r--sysdeps/unix/sysv/linux/i386/dl-librecon.h8
8 files changed, 167 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fbb34f8c6..fdf3acccd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2001-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* malloc/malloc.c (ptmalloc_init): Don't call getenv five times.
+	Instead use new function next_env_entry which iterates over the
+	environment once.
+
+	* sysdeps/arm/dl-machine.h (elf_machine_runtime_setup): Only set
+	_dl_profile_map for the right object.
+
+	* elf/dl-reloc.c (_dl_relocate_object): Allocate l_reloc_result
+	only if consider_profiling is != 0, not if _dl_profile != NULL.
+
+	* sysdeps/generic/dl-environ.c (_dl_next_ld_env_entry): Optimize a bit.
+	Now returns pointer to first character set "LD_".
+	* elf/rtld.c (process_envvars): Adjust for change above.
+	* sysdeps/unix/sysv/linux/dl-librecon.h (EXTRA_LD_ENVVARS): Likewise.
+	* sysdeps/unix/sysv/linux/i386/dl-librecon.h (EXTRA_LD_ENVVARS):
+	Likewise.
+
+2001-08-10  Wolfram Gloger  <wg@malloc.de>
+
+	* malloc/malloc.c (grow_heap): Use mmap() rather than mprotect()
+	to allocate new memory, for better performance with Linux-2.4.x.
+
 2001-08-10  Ulrich Drepper  <drepper@redhat.com>
 
 	* posix/getopt_init.c (__getopt_clean_environment): Avoid making
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index c829de797f..dbbc19c233 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -91,7 +91,7 @@ cannot make segment writable for relocation"));
 #include "dynamic-link.h"
     ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
 
-    if (__builtin_expect (_dl_profile != NULL, 0))
+    if (__builtin_expect (consider_profiling, 0))
       {
 	/* Allocate the array which will contain the already found
 	   relocations.  If the shared object lacks a PLT (for example
diff --git a/elf/rtld.c b/elf/rtld.c
index 2eddb5a40a..b32de61888 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1282,10 +1282,12 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", startp);
 /* Process all environments variables the dynamic linker must recognize.
    Since all of them start with `LD_' we are a bit smarter while finding
    all the entries.  */
+extern char **_environ;
+
 static void
 process_envvars (enum mode *modep)
 {
-  char **runp = NULL;
+  char **runp = _environ;
   char *envline;
   enum mode mode = normal;
   char *debug_output = NULL;
@@ -1301,98 +1303,98 @@ process_envvars (enum mode *modep)
 	/* This is a "LD_" variable at the end of the string without
 	   a '=' character.  Ignore it since otherwise we will access
 	   invalid memory below.  */
-	break;
+	continue;
 
-      switch (len - 3)
+      switch (len)
 	{
 	case 4:
 	  /* Warning level, verbose or not.  */
-	  if (memcmp (&envline[3], "WARN", 4) == 0)
-	    _dl_verbose = envline[8] != '\0';
+	  if (memcmp (envline, "WARN", 4) == 0)
+	    _dl_verbose = envline[5] != '\0';
 	  break;
 
 	case 5:
 	  /* Debugging of the dynamic linker?  */
-	  if (memcmp (&envline[3], "DEBUG", 5) == 0)
-	    process_dl_debug (&envline[9]);
+	  if (memcmp (envline, "DEBUG", 5) == 0)
+	    process_dl_debug (&envline[6]);
 	  break;
 
 	case 7:
 	  /* Print information about versions.  */
-	  if (memcmp (&envline[3], "VERBOSE", 7) == 0)
+	  if (memcmp (envline, "VERBOSE", 7) == 0)
 	    {
-	      version_info = envline[11] != '\0';
+	      version_info = envline[8] != '\0';
 	      break;
 	    }
 
 	  /* List of objects to be preloaded.  */
-	  if (memcmp (&envline[3], "PRELOAD", 7) == 0)
+	  if (memcmp (envline, "PRELOAD", 7) == 0)
 	    {
-	      preloadlist = &envline[11];
+	      preloadlist = &envline[8];
 	      break;
 	    }
 
 	  /* Which shared object shall be profiled.  */
-	  if (memcmp (&envline[3], "PROFILE", 7) == 0)
-	    _dl_profile = &envline[11];
+	  if (memcmp (envline, "PROFILE", 7) == 0)
+	    _dl_profile = &envline[8];
 	  break;
 
 	case 8:
 	  /* Do we bind early?  */
-	  if (memcmp (&envline[3], "BIND_NOW", 8) == 0)
+	  if (memcmp (envline, "BIND_NOW", 8) == 0)
 	    {
-	      _dl_lazy = envline[12] == '\0';
+	      _dl_lazy = envline[9] == '\0';
 	      break;
 	    }
-	  if (memcmp (&envline[3], "BIND_NOT", 8) == 0)
-	    _dl_bind_not = envline[12] != '\0';
+	  if (memcmp (envline, "BIND_NOT", 8) == 0)
+	    _dl_bind_not = envline[9] != '\0';
 	  break;
 
 	case 9:
 	  /* Test whether we want to see the content of the auxiliary
 	     array passed up from the kernel.  */
-	  if (memcmp (&envline[3], "SHOW_AUXV", 9) == 0)
+	  if (memcmp (envline, "SHOW_AUXV", 9) == 0)
 	    _dl_show_auxv ();
 	  break;
 
 	case 10:
 	  /* Mask for the important hardware capabilities.  */
-	  if (memcmp (&envline[3], "HWCAP_MASK", 10) == 0)
-	    _dl_hwcap_mask = __strtoul_internal (&envline[14], NULL, 0, 0);
+	  if (memcmp (envline, "HWCAP_MASK", 10) == 0)
+	    _dl_hwcap_mask = __strtoul_internal (&envline[11], NULL, 0, 0);
 	  break;
 
 	case 11:
 	  /* Path where the binary is found.  */
 	  if (!__libc_enable_secure
-	      && memcmp (&envline[3], "ORIGIN_PATH", 11) == 0)
-	    _dl_origin_path = &envline[15];
+	      && memcmp (envline, "ORIGIN_PATH", 11) == 0)
+	    _dl_origin_path = &envline[12];
 	  break;
 
 	case 12:
 	  /* The library search path.  */
-	  if (memcmp (&envline[3], "LIBRARY_PATH", 12) == 0)
+	  if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
 	    {
-	      library_path = &envline[16];
+	      library_path = &envline[13];
 	      break;
 	    }
 
 	  /* Where to place the profiling data file.  */
-	  if (memcmp (&envline[3], "DEBUG_OUTPUT", 12) == 0)
+	  if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
 	    {
-	      debug_output = &envline[16];
+	      debug_output = &envline[13];
 	      break;
 	    }
 
-	  if (memcmp (&envline[3], "DYNAMIC_WEAK", 12) == 0)
+	  if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
 	    _dl_dynamic_weak = 1;
 	  break;
 
 	case 14:
 	  /* Where to place the profiling data file.  */
 	  if (!__libc_enable_secure
-	      && memcmp (&envline[3], "PROFILE_OUTPUT", 14) == 0)
+	      && memcmp (envline, "PROFILE_OUTPUT", 14) == 0)
 	    {
-	      _dl_profile_output = &envline[18];
+	      _dl_profile_output = &envline[15];
 	      if (*_dl_profile_output == '\0')
 		_dl_profile_output = "/var/tmp";
 	    }
@@ -1400,7 +1402,7 @@ process_envvars (enum mode *modep)
 
 	case 20:
 	  /* The mode of the dynamic linker can be set.  */
-	  if (memcmp (&envline[3], "TRACE_LOADED_OBJECTS", 20) == 0)
+	  if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
 	    mode = trace;
 	  break;
 
diff --git a/malloc/malloc.c b/malloc/malloc.c
index c3040f4627..92de6e44e9 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1680,6 +1680,42 @@ ptmalloc_init_all __MALLOC_P((void))
 static void ptmalloc_init __MALLOC_P ((void)) __attribute__ ((constructor));
 #endif
 
+#ifdef _LIBC
+#include <string.h>
+extern char **_environ;
+
+static char *
+internal_function
+next_env_entry (char ***position)
+{
+  char **current = *position;
+  char *result = NULL;
+
+  while (*current != NULL)
+    {
+      if (__builtin_expect ((*current)[0] == 'M', 0)
+	  && (*current)[1] == 'A'
+	  && (*current)[2] == 'L'
+	  && (*current)[3] == 'L'
+	  && (*current)[4] == 'O'
+	  && (*current)[5] == 'C'
+	  && (*current)[6] == '_')
+	{
+	  result = &(*current)[7];
+
+	  /* Save current position for next visit.  */
+	  *position = ++current;
+
+	  break;
+	}
+
+      ++current;
+    }
+
+  return result;
+}
+#endif
+
 static void
 ptmalloc_init __MALLOC_P((void))
 #else
@@ -1728,6 +1764,52 @@ ptmalloc_init __MALLOC_P((void))
   __free_hook = save_free_hook;
 #endif
   secure = __libc_enable_secure;
+#ifdef _LIBC
+  s = NULL;
+  {
+    char **runp = _environ;
+    char *envline;
+
+    while (__builtin_expect ((envline = next_env_entry (&runp)) != NULL,
+			     0))
+      {
+	size_t len = strcspn (envline, "=");
+
+	if (envline[len] != '=')
+	  /* This is a "MALLOC_" variable at the end of the string
+	     without a '=' character.  Ignore it since otherwise we
+	     will access invalid memory below.  */
+	  continue;
+
+	switch (len)
+	  {
+	  case 6:
+	    if (memcmp (envline, "CHECK_", 6) == 0)
+	      s = &envline[7];
+	    break;
+	  case 8:
+	    if (! secure && memcmp (envline, "TOP_PAD_", 8) == 0)
+	      mALLOPt(M_TOP_PAD, atoi(&envline[9]));
+	    break;
+	  case 9:
+	    if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0)
+	      mALLOPt(M_MMAP_MAX, atoi(&envline[10]));
+	    break;
+	  case 15:
+	    if (! secure)
+	      {
+		if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0)
+		  mALLOPt(M_TRIM_THRESHOLD, atoi(&envline[16]));
+		else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0)
+		  mALLOPt(M_MMAP_THRESHOLD, atoi(&envline[16]));
+	      }
+	    break;
+	  default:
+	    break;
+	  }
+      }
+  }
+#else
   if (! secure)
     {
       if((s = getenv("MALLOC_TRIM_THRESHOLD_")))
@@ -1740,6 +1822,7 @@ ptmalloc_init __MALLOC_P((void))
 	mALLOPt(M_MMAP_MAX, atoi(s));
     }
   s = getenv("MALLOC_CHECK_");
+#endif
   if(s) {
     if(s[0]) mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0'));
     __malloc_check_init();
@@ -2050,7 +2133,8 @@ new_heap(size) size_t size;
       return 0;
     }
   }
-  if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) {
+  if(MMAP(p2, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED)
+     == (char *) MAP_FAILED) {
     munmap(p2, HEAP_MAX_SIZE);
     return 0;
   }
@@ -2078,7 +2162,8 @@ grow_heap(h, diff) heap_info *h; long diff;
     new_size = (long)h->size + diff;
     if(new_size > HEAP_MAX_SIZE)
       return -1;
-    if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0)
+    if(MMAP((char *)h + h->size, diff, PROT_READ|PROT_WRITE,
+	    MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
       return -2;
   } else {
     new_size = (long)h->size + diff;
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index ba515ebec4..24fe366784 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -103,8 +103,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
       if (profile)
 	{
 	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
-	  /* Say that we really want profiling and the timers are started.  */
-	  _dl_profile_map = l;
+
+	  if (_dl_name_match_p (_dl_profile, l))
+	    /* Say that we really want profiling and the timers are
+	       started.  */
+	    _dl_profile_map = l;
 	}
       else
 	/* This function will get called to fix up the GOT entry indicated by
diff --git a/sysdeps/generic/dl-environ.c b/sysdeps/generic/dl-environ.c
index 26ddf922f3..9b317548ec 100644
--- a/sysdeps/generic/dl-environ.c
+++ b/sysdeps/generic/dl-environ.c
@@ -1,5 +1,5 @@
 /* Environment handling for dynamic loader.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000, 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
@@ -32,21 +32,22 @@ _dl_next_ld_env_entry (char ***position)
   char **current = *position;
   char *result = NULL;
 
-  if (current == NULL)
-    /* We start over.  */
-    current = _environ;
-
-  while (result == NULL && *current != NULL)
+  while (*current != NULL)
     {
-      if ((*current)[0] == 'L' && (*current)[1] == 'D' && (*current)[2] == '_')
-	result = *current;
+      if (__builtin_expect ((*current)[0] == 'L', 0)
+	  && (*current)[1] == 'D' && (*current)[2] == '_')
+	{
+	  result = &(*current)[3];
+
+	  /* Save current position for next visit.  */
+	  *position = ++current;
+
+	  break;
+	}
 
       ++current;
     }
 
-  /* Save current position for next visit.  */
-  *position = current;
-
   return result;
 }
 
diff --git a/sysdeps/unix/sysv/linux/dl-librecon.h b/sysdeps/unix/sysv/linux/dl-librecon.h
index b1052972f3..5c34d00edb 100644
--- a/sysdeps/unix/sysv/linux/dl-librecon.h
+++ b/sysdeps/unix/sysv/linux/dl-librecon.h
@@ -24,10 +24,10 @@
 /* Recognizing extra environment variables.  */
 #define EXTRA_LD_ENVVARS \
   case 13:								      \
-    if (memcmp (&envline[3], "ASSUME_KERNEL", 13) == 0)			      \
+    if (memcmp (envline, "ASSUME_KERNEL", 13) == 0)			      \
       {									      \
 	unsigned long int i, j, osversion = 0;				      \
-	char *p = &envline[17], *q;					      \
+	char *p = &envline[14], *q;					      \
 									      \
 	for (i = 0; i < 3; i++, p = q + 1)				      \
 	  {								      \
diff --git a/sysdeps/unix/sysv/linux/i386/dl-librecon.h b/sysdeps/unix/sysv/linux/i386/dl-librecon.h
index 627eecf62d..acff7fc14f 100644
--- a/sysdeps/unix/sysv/linux/i386/dl-librecon.h
+++ b/sysdeps/unix/sysv/linux/i386/dl-librecon.h
@@ -49,10 +49,10 @@
 /* Recognizing extra environment variables.  */
 #define EXTRA_LD_ENVVARS \
   case 13:								      \
-    if (memcmp (&envline[3], "ASSUME_KERNEL", 13) == 0)			      \
+    if (memcmp (envline, "ASSUME_KERNEL", 13) == 0)			      \
       {									      \
 	unsigned long int i, j, osversion = 0;				      \
-	char *p = &envline[17], *q;					      \
+	char *p = &envline[14], *q;					      \
 									      \
 	for (i = 0; i < 3; i++, p = q + 1)				      \
 	  {								      \
@@ -72,9 +72,9 @@
       }									      \
 									      \
   case 15:								      \
-    if (memcmp (&envline[3], "LIBRARY_VERSION", 15) == 0)		      \
+    if (memcmp (envline, "LIBRARY_VERSION", 15) == 0)		      \
       {									      \
-	_dl_correct_cache_id = envline[19] == '5' ? 2 : 3;		      \
+	_dl_correct_cache_id = envline[16] == '5' ? 2 : 3;		      \
 	break;								      \
       }