aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-error.c9
-rw-r--r--elf/dl-open.c8
-rw-r--r--elf/dlerror.c8
-rw-r--r--elf/rtld.c15
4 files changed, 31 insertions, 9 deletions
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 737bba7421..2eaa7e03d1 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -46,8 +46,13 @@ _dl_signal_error (int errcode,
if (catch)
{
- /* We are inside _dl_catch_error. Return to it. */
- catch->errstring = errstring;
+ /* We are inside _dl_catch_error. Return to it. We have to
+ duplicate the error string since it might be allocated on the
+ stack. */
+ size_t len = strlen (errstring) + 1;
+ catch->errstring = malloc (len);
+ if (catch->errstring != NULL)
+ memcpy (catch->errstring, errstring, len);
catch->objname = objname;
longjmp (catch->env, errcode ?: -1);
}
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 40b5224725..76f6329762 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -27,6 +27,11 @@ extern void _dl_start (void); weak_extern (_dl_start)
extern int __libc_multiple_libcs; /* Defined in init-first.c. */
+extern int __libc_argc;
+extern char **__libc_argv;
+extern char **__libc_envp;
+
+
size_t _dl_global_scope_alloc;
struct link_map *
@@ -136,7 +141,8 @@ _dl_open (const char *file, int mode)
/* Run the initializer functions of new objects. */
while (init = _dl_init_next (new))
- (*(void (*) (void)) init) ();
+ (*(void (*) (int, char **, char **)) init) (__libc_argc, __libc_argv,
+ __libc_envp);
if (dl_start_ptr == NULL)
/* We must be the static _dl_open in libc.a because ld.so.1 is not
diff --git a/elf/dlerror.c b/elf/dlerror.c
index 4ec5037de4..663207d708 100644
--- a/elf/dlerror.c
+++ b/elf/dlerror.c
@@ -1,5 +1,5 @@
/* dlerror -- Return error detail for failing <dlfcn.h> functions.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 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
@@ -58,6 +58,7 @@ dlerror (void)
? NULL : buf);
/* Reset the error indicator. */
+ free (last_errstring);
last_errstring = NULL;
return ret;
}
@@ -65,6 +66,11 @@ dlerror (void)
int
_dlerror_run (void (*operate) (void))
{
+ if (last_errstring != NULL)
+ /* Free the error string from the last failed command. This can
+ happen if `dlerror' was not run after an error was found. */
+ free (last_errstring);
+
last_errcode = _dl_catch_error (&last_errstring, &last_object_name,
operate);
return last_errstring != NULL;
diff --git a/elf/rtld.c b/elf/rtld.c
index 9f13124207..be71e88c3c 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -204,12 +204,15 @@ of this helper program; chances are you did not intend to run this program.\n",
{
l = _dl_map_object (NULL, _dl_argv[0], lt_library);
}
- const char *err_str = NULL;
+ char *err_str = NULL;
const char *obj_name __attribute__ ((unused));
(void) _dl_catch_error (&err_str, &obj_name, doit);
if (err_str != NULL)
- _exit (EXIT_FAILURE);
+ {
+ free (err_str);
+ _exit (EXIT_FAILURE);
+ }
}
else
l = _dl_map_object (NULL, _dl_argv[0], lt_library);
@@ -395,7 +398,8 @@ of this helper program; chances are you did not intend to run this program.\n",
const ElfW(Sym) *ref = NULL;
ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
&_dl_default_scope[2],
- "argument", 0);
+ "argument",
+ DL_LOOKUP_NOPLT);
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
@@ -488,8 +492,9 @@ of this helper program; chances are you did not intend to run this program.\n",
dynamic linker. There is no additional initialization
required for the ABI-compliant dynamic linker. */
- (*(void (*) (void)) (_dl_rtld_map.l_addr +
- _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
+ (*(void (*) (int, char **, char**))
+ (_dl_rtld_map.l_addr + _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr))
+ (0, NULL, NULL);
/* Clear the field so a future dlopen won't run it again. */
_dl_rtld_map.l_info[DT_INIT] = NULL;