+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
#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
/* 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;
/* 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";
}
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;
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
__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_")))
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();
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;
}
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;
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
/* 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
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;
}
/* 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) \
{ \
/* 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) \
{ \
} \
\
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; \
}