diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | dlfcn/dlerror.c | 16 | ||||
-rw-r--r-- | elf/Versions | 3 | ||||
-rw-r--r-- | elf/dl-deps.c | 3 | ||||
-rw-r--r-- | elf/dl-error.c | 8 | ||||
-rw-r--r-- | elf/dl-libc.c | 2 | ||||
-rw-r--r-- | elf/dl-open.c | 3 | ||||
-rw-r--r-- | elf/rtld.c | 3 | ||||
-rw-r--r-- | iconv/loop.c | 2 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 3 |
10 files changed, 50 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog index 570150c3da..f175d84f2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2000-07-13 Ulrich Drepper <drepper@redhat.com> + * elf/Versions (ld): Export _dl_out_of_memory for GLIBC_2.2. + * dlfcn/dlerror.c (dlerror): Don't free the error string if it is the + report that we are out of memory. + * elf/dl-deps.c (_dl_map_object_deps): Likewise. + * elf/dl-libc.c (dlerror_run): Likewise. + * elf/dl-open.c (_dl_open): Likewise. + * elf/rtld.c (dl_main): Likewise. + * elf/dl-error.c: Define _dl_out_of_memory. + (_dl_signal_error): Return _dl_signal_error if we cannot duplicate + the error string. + * sysdeps/generic/ldsodefs.h: Declare _dl_out_of_memory. + + * dlfcn/dlerror.c (free_key_mem): Also free error string. + + * iconv/loop.c: Fix comment. + * malloc/mtrace.c (tr_freehook): Return immediately if ptr is NULL. 2000-07-13 Andreas Jaeger <aj@suse.de> diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c index 34ea82907e..1650eca729 100644 --- a/dlfcn/dlerror.c +++ b/dlfcn/dlerror.c @@ -35,7 +35,6 @@ struct dl_action_result static struct dl_action_result last_result; static struct dl_action_result *static_buf; - /* This is the key for the thread specific memory. */ static __libc_key_t key; @@ -61,7 +60,8 @@ dlerror (void) /* We can now free the string. */ if (result->errstring != NULL) { - free ((char *) result->errstring); + if (strcmp (result->errstring, "out of memory") != 0) + free ((char *) result->errstring); result->errstring = NULL; } buf = NULL; @@ -75,7 +75,8 @@ dlerror (void) strerror (result->errcode)) != -1) { /* We don't need the error string anymore. */ - free ((char *) result->errstring); + if (strcmp (result->errstring, "out of memory") != 0) + free ((char *) result->errstring); result->errstring = buf; } @@ -123,7 +124,8 @@ _dlerror_run (void (*operate) (void *), void *args) { /* Free the error string from the last failed command. This can happen if `dlerror' was not run after an error was found. */ - free ((char *) result->errstring); + if (strcmp (result->errstring, "out of memory") != 0) + free ((char *) result->errstring); result->errstring = NULL; } @@ -153,6 +155,12 @@ init (void) static void free_key_mem (void *mem) { + struct dl_action_result *result = (struct dl_action_result *) mem; + + if (result->errstring != NULL + && strcmp (result->errstring, "out of memory") != 0) + free (result->errstring); + free (mem); __libc_setspecific (key, NULL); } diff --git a/elf/Versions b/elf/Versions index a7c5a780f6..bb8b5f5982 100644 --- a/elf/Versions +++ b/elf/Versions @@ -56,5 +56,8 @@ ld { # this is defined in ld.so and overridden by libc _dl_init_first; + + # variables used elsewhere + _dl_out_of_memory; } } diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 7c7b4b6672..1d3779f822 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -295,7 +295,8 @@ _dl_map_object_deps (struct link_map *map, { /* We are not interested in the error message. */ assert (errstring != NULL); - free ((char *) errstring); + if (errstring != _dl_out_of_memory) + free ((char *) errstring); /* Simply ignore this error and continue the work. */ continue; diff --git a/elf/dl-error.c b/elf/dl-error.c index 88ab8e9519..959e1de202 100644 --- a/elf/dl-error.c +++ b/elf/dl-error.c @@ -45,6 +45,12 @@ __libc_tsd_define (static, DL_ERROR) #define tsd_setspecific(data) __libc_tsd_set (DL_ERROR, (data)) +/* This message we return as a last resort. We define the string in a + variable since we have to avoid freeing it and so have to enable + a pointer comparison. See below and in dlfcn/dlerror.c. */ +const char _dl_out_of_memory[] = "out of memory"; + + /* This points to a function which is called when an continuable error is received. Unlike the handling of `catch' this function may return. The arguments will be the `errstring' and `objname'. @@ -72,6 +78,8 @@ _dl_signal_error (int errcode, const char *objname, const char *errstring) stack. The object name is always a string constant. */ lcatch->objname = objname; lcatch->errstring = strdup (errstring); + if (lcatch->errstring == NULL) + lcatch->errstring = _dl_out_of_memory; longjmp (lcatch->env, errcode ?: -1); } else diff --git a/elf/dl-libc.c b/elf/dl-libc.c index 38774e50a0..992a52e699 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -42,7 +42,7 @@ dlerror_run (void (*operate) (void *), void *args) (void) _dl_catch_error (&objname, &last_errstring, operate, args); result = last_errstring != NULL; - if (result) + if (result && last_errstring != _dl_out_of_memory) free ((char *) last_errstring); return result; diff --git a/elf/dl-open.c b/elf/dl-open.c index e5628b6f06..680377be0a 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -329,7 +329,8 @@ _dl_open (const char *file, int mode, const void *caller) /* Make a local copy of the error string so that we can release the memory allocated for it. */ local_errstring = strdupa (errstring); - free ((char *) errstring); + if (errstring != _dl_out_of_memory) + free ((char *) errstring); /* Reraise the error. */ _dl_signal_error (errcode, objname, local_errstring); diff --git a/elf/rtld.c b/elf/rtld.c index 68c516d4bc..1db96999ea 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -506,7 +506,8 @@ of this helper program; chances are you did not intend to run this program.\n\ (void) _dl_catch_error (&objname, &err_str, map_doit, &args); if (__builtin_expect (err_str != NULL, 0)) { - free ((char *) err_str); + if (err_str != _dl_out_of_memory) + free ((char *) err_str); _exit (EXIT_FAILURE); } } diff --git a/iconv/loop.c b/iconv/loop.c index 04ae50b974..b8e798682e 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -233,7 +233,7 @@ FCTNAME (LOOPFCT) (struct __gconv_step *step, while (inptr != inend) { /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the - compiler generating better code. It will optimized away + compiler generating better code. They will be optimized away since MIN_NEEDED_OUTPUT is always a constant. */ if ((MIN_NEEDED_OUTPUT != 1 && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0)) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index bba91cacd0..fc9a9d1120 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -192,6 +192,9 @@ extern const char *_dl_inhibit_rpath; /* Nonzero if references should be treated as weak during runtime linking. */ extern int _dl_dynamic_weak; +/* The array with message we print as a last resort. */ +extern const char _dl_out_of_memory[]; + /* OS-dependent function to open the zero-fill device. */ extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ |