mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
ld.so: Introduce struct dl_exception
This commit separates allocating and raising exceptions. This simplifies catching and re-raising them because it is no longer necessary to make a temporary, on-stack copy of the exception message.
This commit is contained in:
parent
f87cc2bfba
commit
2449ae7b2d
60
ChangeLog
60
ChangeLog
@ -1,3 +1,63 @@
|
||||
2017-08-10 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
Introduce ld.so exceptions.
|
||||
* sysdeps/generic/ldsodefs.h (struct dl_exception): Define.
|
||||
(_dl_exception_create, _dl_exception_create_format)
|
||||
(_dl_exception_free, _dl_signal_exception, _dl_signal_cexception)
|
||||
(_dl_catch_exception): Declare.
|
||||
(_dl_catch_error): Update comment.
|
||||
* elf/dl-error-skeleton.c (struct catch): Replace objname,
|
||||
errstring, malloced members with exception member.
|
||||
(_dl_out_of_memory): Remove.
|
||||
(fatal_error): New function, extracted from _dl_signal_error.
|
||||
(_dl_signal_exception, _dl_signal_cexception): New functions.
|
||||
(_dl_signal_error): Call _dl_exception_create to allocate an
|
||||
exception object.
|
||||
(_dl_catch_exception): New function, based on _dl_catch_error.
|
||||
(_dl_catch_error): Implement using _dl_catch_exception.
|
||||
* elf/dl-exception.c: New file.
|
||||
* elf/Makefile (dl-routines): Add dl-exception.
|
||||
(elide-routines.os): Likewise.
|
||||
* elf/Version (ld/GLIBC_PRIVATE): Add _dl_exception_create,
|
||||
_dl_exception_create_format, _dl_exception_free.
|
||||
* elf/dl-deps.c (_dl_map_object_deps): Use _dl_catch_exception and
|
||||
_dl_signal_exception.
|
||||
* elf/dl-lookup.c (make_string): Remove.
|
||||
(_dl_lookup_symbol_x): Use _dl_exception_create_format,
|
||||
_dl_signal_cexception, _dl_exception_free.
|
||||
* elf/dl-open.c (_dl_open): Use _dl_catch_exception and
|
||||
_dl_signal_exception.
|
||||
* elf/dl-sym.c (do_sym): Likewise.
|
||||
* elf/dl-version.c (make_string): Remove.
|
||||
(match_symbol): Use _dl_exception_create_format,
|
||||
_dl_signal_cexception, _dl_exception_free.
|
||||
(_dl_check_map_versions): Likewise.
|
||||
* sysdeps/generic/localplt.data (ld.so): Add _dl_signal_exception,
|
||||
_dl_catch_exception.
|
||||
* sysdeps/unix/sysv/linux/aarch64/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/alpha/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/arm/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/m68k/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/microblaze/localplt.data (ld.so):
|
||||
Likewise.
|
||||
* sysdeps/unix/sysv/linux/nios2/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
|
||||
(ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
|
||||
(ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data (ld.so):
|
||||
Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sh/localplt.data (ld.so): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data (ld.so):
|
||||
Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data (ld.so):
|
||||
Likewise.
|
||||
* sysdeps/x86_64/localplt.data (ld.so): Likewise.
|
||||
|
||||
2017-08-10 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* inet/net-internal.h (__inet6_scopeid_pton): Remove
|
||||
|
@ -31,7 +31,8 @@ routines = $(all-dl-routines) dl-support dl-iteratephdr \
|
||||
dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
|
||||
runtime init fini debug misc \
|
||||
version profile tls origin scope \
|
||||
execstack caller open close trampoline)
|
||||
execstack caller open close trampoline \
|
||||
exception)
|
||||
ifeq (yes,$(use-ldconfig))
|
||||
dl-routines += dl-cache
|
||||
endif
|
||||
@ -51,7 +52,7 @@ endif
|
||||
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
|
||||
# But they are absent from the shared libc, because that code is in ld.so.
|
||||
elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
|
||||
dl-sysdep
|
||||
dl-sysdep dl-exception
|
||||
shared-only-routines += dl-caller
|
||||
|
||||
# ld.so uses those routines, plus some special stuff for being the program
|
||||
|
@ -28,6 +28,7 @@ libc {
|
||||
__libc_dlclose; __libc_dlopen_mode; __libc_dlsym;
|
||||
|
||||
# Internal error handling support. Interposes the functions in ld.so.
|
||||
_dl_signal_exception; _dl_catch_exception;
|
||||
_dl_signal_error; _dl_catch_error;
|
||||
}
|
||||
}
|
||||
@ -68,7 +69,11 @@ ld {
|
||||
# Pointer protection.
|
||||
__pointer_chk_guard;
|
||||
|
||||
# Internal error handling support.
|
||||
_dl_exception_create; _dl_exception_create_format; _dl_exception_free;
|
||||
|
||||
# Internal error handling support. Interposed by libc.so.
|
||||
_dl_signal_exception; _dl_catch_exception;
|
||||
_dl_signal_error; _dl_catch_error;
|
||||
|
||||
# Set value of a tunable.
|
||||
|
@ -165,8 +165,7 @@ _dl_map_object_deps (struct link_map *map,
|
||||
const char *name;
|
||||
int errno_saved;
|
||||
int errno_reason;
|
||||
const char *errstring;
|
||||
const char *objname;
|
||||
struct dl_exception exception;
|
||||
|
||||
/* No loaded object so far. */
|
||||
nlist = 0;
|
||||
@ -200,7 +199,6 @@ _dl_map_object_deps (struct link_map *map,
|
||||
alloca means we cannot use recursive function calls. */
|
||||
errno_saved = errno;
|
||||
errno_reason = 0;
|
||||
errstring = NULL;
|
||||
errno = 0;
|
||||
name = NULL;
|
||||
for (runp = known; runp; )
|
||||
@ -250,17 +248,9 @@ _dl_map_object_deps (struct link_map *map,
|
||||
/* Store the tag in the argument structure. */
|
||||
args.name = name;
|
||||
|
||||
bool malloced;
|
||||
int err = _dl_catch_error (&objname, &errstring, &malloced,
|
||||
openaux, &args);
|
||||
if (__glibc_unlikely (errstring != NULL))
|
||||
int err = _dl_catch_exception (&exception, openaux, &args);
|
||||
if (__glibc_unlikely (exception.errstring != NULL))
|
||||
{
|
||||
char *new_errstring = strdupa (errstring);
|
||||
objname = strdupa (objname);
|
||||
if (malloced)
|
||||
free ((char *) errstring);
|
||||
errstring = new_errstring;
|
||||
|
||||
if (err)
|
||||
errno_reason = err;
|
||||
else
|
||||
@ -313,31 +303,18 @@ _dl_map_object_deps (struct link_map *map,
|
||||
/* We must be prepared that the addressed shared
|
||||
object is not available. For filter objects the dependency
|
||||
must be available. */
|
||||
bool malloced;
|
||||
int err = _dl_catch_error (&objname, &errstring, &malloced,
|
||||
openaux, &args);
|
||||
|
||||
if (__glibc_unlikely (errstring != NULL))
|
||||
int err = _dl_catch_exception (&exception, openaux, &args);
|
||||
if (__glibc_unlikely (exception.errstring != NULL))
|
||||
{
|
||||
if (d->d_tag == DT_AUXILIARY)
|
||||
{
|
||||
/* We are not interested in the error message. */
|
||||
assert (errstring != NULL);
|
||||
if (malloced)
|
||||
free ((char *) errstring);
|
||||
|
||||
_dl_exception_free (&exception);
|
||||
/* Simply ignore this error and continue the work. */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
char *new_errstring = strdupa (errstring);
|
||||
objname = strdupa (objname);
|
||||
if (malloced)
|
||||
free ((char *) errstring);
|
||||
errstring = new_errstring;
|
||||
|
||||
if (err)
|
||||
errno_reason = err;
|
||||
else
|
||||
@ -683,6 +660,6 @@ Filters not supported with LD_TRACE_PRELINKING"));
|
||||
_dl_scope_free (old_l_initfini);
|
||||
|
||||
if (errno_reason)
|
||||
_dl_signal_error (errno_reason == -1 ? 0 : errno_reason, objname,
|
||||
NULL, errstring);
|
||||
_dl_signal_exception (errno_reason == -1 ? 0 : errno_reason,
|
||||
&exception, NULL);
|
||||
}
|
||||
|
@ -39,10 +39,7 @@
|
||||
_dl_signal_error. */
|
||||
struct catch
|
||||
{
|
||||
const char **objname; /* Object/File name. */
|
||||
const char **errstring; /* Error detail filled in here. */
|
||||
bool *malloced; /* Nonzero if the string is malloced
|
||||
by the libc malloc. */
|
||||
struct dl_exception *exception; /* The exception data is stored there. */
|
||||
volatile int *errcode; /* Return value of _dl_signal_error. */
|
||||
jmp_buf env; /* longjmp here on error. */
|
||||
};
|
||||
@ -60,11 +57,6 @@ static __thread struct catch *catch_hook attribute_tls_model_ie;
|
||||
static struct catch *catch_hook;
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
static const char _dl_out_of_memory[] = "out of memory";
|
||||
|
||||
#if DL_ERROR_BOOTSTRAP
|
||||
/* This points to a function which is called when an continuable error is
|
||||
received. Unlike the handling of `catch' this function may return.
|
||||
@ -76,6 +68,41 @@ static const char _dl_out_of_memory[] = "out of memory";
|
||||
static receiver_fct receiver;
|
||||
#endif /* DL_ERROR_BOOTSTRAP */
|
||||
|
||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||
static void
|
||||
__attribute__ ((noreturn))
|
||||
fatal_error (int errcode, const char *objname, const char *occasion,
|
||||
const char *errstring)
|
||||
{
|
||||
char buffer[1024];
|
||||
_dl_fatal_printf ("%s: %s: %s%s%s%s%s\n",
|
||||
RTLD_PROGNAME,
|
||||
occasion ?: N_("error while loading shared libraries"),
|
||||
objname, *objname ? ": " : "",
|
||||
errstring, errcode ? ": " : "",
|
||||
(errcode
|
||||
? __strerror_r (errcode, buffer, sizeof buffer)
|
||||
: ""));
|
||||
}
|
||||
|
||||
void
|
||||
_dl_signal_exception (int errcode, struct dl_exception *exception,
|
||||
const char *occasion)
|
||||
{
|
||||
struct catch *lcatch = catch_hook;
|
||||
if (lcatch != NULL)
|
||||
{
|
||||
*lcatch->exception = *exception;
|
||||
*lcatch->errcode = errcode;
|
||||
|
||||
/* We do not restore the signal mask because none was saved. */
|
||||
__longjmp (lcatch->env[0].__jmpbuf, 1);
|
||||
}
|
||||
else
|
||||
fatal_error (errcode, exception->objname, occasion, exception->errstring);
|
||||
}
|
||||
libc_hidden_def (_dl_signal_exception)
|
||||
|
||||
void
|
||||
internal_function
|
||||
_dl_signal_error (int errcode, const char *objname, const char *occation,
|
||||
@ -86,65 +113,42 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
|
||||
if (! errstring)
|
||||
errstring = N_("DYNAMIC LINKER BUG!!!");
|
||||
|
||||
if (objname == NULL)
|
||||
objname = "";
|
||||
if (lcatch != NULL)
|
||||
{
|
||||
/* We are inside _dl_catch_error. Return to it. We have to
|
||||
duplicate the error string since it might be allocated on the
|
||||
stack. The object name is always a string constant. */
|
||||
size_t len_objname = strlen (objname) + 1;
|
||||
size_t len_errstring = strlen (errstring) + 1;
|
||||
|
||||
char *errstring_copy = malloc (len_objname + len_errstring);
|
||||
if (errstring_copy != NULL)
|
||||
{
|
||||
/* Make a copy of the object file name and the error string. */
|
||||
*lcatch->objname = memcpy (__mempcpy (errstring_copy,
|
||||
errstring, len_errstring),
|
||||
objname, len_objname);
|
||||
*lcatch->errstring = errstring_copy;
|
||||
|
||||
/* If the main executable is relocated it means the libc's malloc
|
||||
is used. */
|
||||
bool malloced = true;
|
||||
#ifdef SHARED
|
||||
malloced = (GL(dl_ns)[LM_ID_BASE]._ns_loaded != NULL
|
||||
&& (GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_relocated != 0));
|
||||
#endif
|
||||
*lcatch->malloced = malloced;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is better than nothing. */
|
||||
*lcatch->objname = "";
|
||||
*lcatch->errstring = _dl_out_of_memory;
|
||||
*lcatch->malloced = false;
|
||||
}
|
||||
|
||||
_dl_exception_create (lcatch->exception, objname, errstring);
|
||||
*lcatch->errcode = errcode;
|
||||
|
||||
/* We do not restore the signal mask because none was saved. */
|
||||
__longjmp (lcatch->env[0].__jmpbuf, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||
char buffer[1024];
|
||||
_dl_fatal_printf ("%s: %s: %s%s%s%s%s\n",
|
||||
RTLD_PROGNAME,
|
||||
occation ?: N_("error while loading shared libraries"),
|
||||
objname, *objname ? ": " : "",
|
||||
errstring, errcode ? ": " : "",
|
||||
(errcode
|
||||
? __strerror_r (errcode, buffer, sizeof buffer)
|
||||
: ""));
|
||||
}
|
||||
fatal_error (errcode, objname, occation, errstring);
|
||||
}
|
||||
libc_hidden_def (_dl_signal_error)
|
||||
|
||||
|
||||
#if DL_ERROR_BOOTSTRAP
|
||||
void
|
||||
_dl_signal_cexception (int errcode, struct dl_exception *exception,
|
||||
const char *occasion)
|
||||
{
|
||||
if (__builtin_expect (GLRO(dl_debug_mask)
|
||||
& ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
|
||||
_dl_debug_printf ("%s: error: %s: %s (%s)\n",
|
||||
exception->objname, occasion,
|
||||
exception->errstring, receiver ? "continued" : "fatal");
|
||||
|
||||
if (receiver)
|
||||
{
|
||||
/* We are inside _dl_receive_error. Call the user supplied
|
||||
handler and resume the work. The receiver will still be
|
||||
installed. */
|
||||
(*receiver) (errcode, exception->objname, exception->errstring);
|
||||
}
|
||||
else
|
||||
_dl_signal_exception (errcode, exception, occasion);
|
||||
}
|
||||
|
||||
void
|
||||
internal_function
|
||||
_dl_signal_cerror (int errcode, const char *objname, const char *occation,
|
||||
@ -167,11 +171,9 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
|
||||
}
|
||||
#endif /* DL_ERROR_BOOTSTRAP */
|
||||
|
||||
|
||||
int
|
||||
internal_function
|
||||
_dl_catch_error (const char **objname, const char **errstring,
|
||||
bool *mallocedp, void (*operate) (void *), void *args)
|
||||
_dl_catch_exception (struct dl_exception *exception,
|
||||
void (*operate) (void *), void *args)
|
||||
{
|
||||
/* We need not handle `receiver' since setting a `catch' is handled
|
||||
before it. */
|
||||
@ -184,9 +186,7 @@ _dl_catch_error (const char **objname, const char **errstring,
|
||||
|
||||
struct catch c;
|
||||
/* Don't use an initializer since we don't need to clear C.env. */
|
||||
c.objname = objname;
|
||||
c.errstring = errstring;
|
||||
c.malloced = mallocedp;
|
||||
c.exception = exception;
|
||||
c.errcode = &errcode;
|
||||
|
||||
struct catch *const old = catch_hook;
|
||||
@ -197,17 +197,30 @@ _dl_catch_error (const char **objname, const char **errstring,
|
||||
{
|
||||
(*operate) (args);
|
||||
catch_hook = old;
|
||||
*objname = NULL;
|
||||
*errstring = NULL;
|
||||
*mallocedp = false;
|
||||
*exception = (struct dl_exception) { NULL };
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We get here only if we longjmp'd out of OPERATE. _dl_signal_error has
|
||||
already stored values into *OBJNAME, *ERRSTRING, and *MALLOCEDP. */
|
||||
/* We get here only if we longjmp'd out of OPERATE.
|
||||
_dl_signal_exception has already stored values into
|
||||
*EXCEPTION. */
|
||||
catch_hook = old;
|
||||
return errcode;
|
||||
}
|
||||
libc_hidden_def (_dl_catch_exception)
|
||||
|
||||
int
|
||||
internal_function
|
||||
_dl_catch_error (const char **objname, const char **errstring,
|
||||
bool *mallocedp, void (*operate) (void *), void *args)
|
||||
{
|
||||
struct dl_exception exception;
|
||||
int errorcode = _dl_catch_exception (&exception, operate, args);
|
||||
*objname = exception.objname;
|
||||
*errstring = exception.errstring;
|
||||
*mallocedp = exception.message_buffer == exception.errstring;
|
||||
return errorcode;
|
||||
}
|
||||
libc_hidden_def (_dl_catch_error)
|
||||
|
||||
#if DL_ERROR_BOOTSTRAP
|
||||
|
202
elf/dl-exception.c
Normal file
202
elf/dl-exception.c
Normal file
@ -0,0 +1,202 @@
|
||||
/* ld.so error exception allocation and deallocation.
|
||||
Copyright (C) 1995-2017 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
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <ldsodefs.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* 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. */
|
||||
static const char _dl_out_of_memory[] = "out of memory";
|
||||
|
||||
/* Dummy allocation object used if allocating the message buffer
|
||||
fails. */
|
||||
static void
|
||||
oom_exception (struct dl_exception *exception)
|
||||
{
|
||||
exception->objname = "";
|
||||
exception->errstring = _dl_out_of_memory;
|
||||
exception->message_buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
__attribute__ ((noreturn))
|
||||
length_mismatch (void)
|
||||
{
|
||||
_dl_fatal_printf ("Fatal error: "
|
||||
"length accounting in _dl_exception_create_format\n");
|
||||
}
|
||||
|
||||
/* Adjust the message buffer to indicate whether it is possible to
|
||||
free it. EXCEPTION->errstring must be a potentially deallocatable
|
||||
pointer. */
|
||||
static void
|
||||
adjust_message_buffer (struct dl_exception *exception)
|
||||
{
|
||||
/* If the main executable is relocated it means the libc's malloc
|
||||
is used. */
|
||||
bool malloced = true;
|
||||
#ifdef SHARED
|
||||
malloced = (GL(dl_ns)[LM_ID_BASE]._ns_loaded != NULL
|
||||
&& (GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_relocated != 0));
|
||||
#endif
|
||||
if (malloced)
|
||||
exception->message_buffer = (char *) exception->errstring;
|
||||
else
|
||||
exception->message_buffer = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_dl_exception_create (struct dl_exception *exception, const char *objname,
|
||||
const char *errstring)
|
||||
{
|
||||
if (objname == NULL)
|
||||
objname = "";
|
||||
size_t len_objname = strlen (objname) + 1;
|
||||
size_t len_errstring = strlen (errstring) + 1;
|
||||
char *errstring_copy = malloc (len_objname + len_errstring);
|
||||
if (errstring_copy != NULL)
|
||||
{
|
||||
/* Make a copy of the object file name and the error string. */
|
||||
exception->objname = memcpy (__mempcpy (errstring_copy,
|
||||
errstring, len_errstring),
|
||||
objname, len_objname);
|
||||
exception->errstring = errstring_copy;
|
||||
adjust_message_buffer (exception);
|
||||
}
|
||||
else
|
||||
oom_exception (exception);
|
||||
}
|
||||
rtld_hidden_def (_dl_exception_create)
|
||||
|
||||
void
|
||||
_dl_exception_create_format (struct dl_exception *exception, const char *objname,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
if (objname == NULL)
|
||||
objname = "";
|
||||
size_t len_objname = strlen (objname) + 1;
|
||||
/* Compute the length of the result. Include room for two NUL
|
||||
bytes. */
|
||||
size_t length = len_objname + 1;
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
for (const char *p = fmt; *p != '\0'; ++p)
|
||||
if (*p == '%')
|
||||
{
|
||||
++p;
|
||||
switch (*p)
|
||||
{
|
||||
case 's':
|
||||
length += strlen (va_arg (ap, const char *));
|
||||
break;
|
||||
default:
|
||||
/* Assumed to be '%'. */
|
||||
++length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
++length;
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
if (length > PTRDIFF_MAX)
|
||||
{
|
||||
oom_exception (exception);
|
||||
return;
|
||||
}
|
||||
char *errstring = malloc (length);
|
||||
if (errstring == NULL)
|
||||
{
|
||||
oom_exception (exception);
|
||||
return;
|
||||
}
|
||||
exception->errstring = errstring;
|
||||
adjust_message_buffer (exception);
|
||||
|
||||
/* Copy the error message to errstring. */
|
||||
{
|
||||
/* Next byte to be written in errstring. */
|
||||
char *wptr = errstring;
|
||||
/* End of the allocated string. */
|
||||
char *const end = errstring + length;
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
|
||||
for (const char *p = fmt; *p != '\0'; ++p)
|
||||
if (*p == '%')
|
||||
{
|
||||
++p;
|
||||
switch (*p)
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
const char *ptr = va_arg (ap, const char *);
|
||||
size_t len_ptr = strlen (ptr);
|
||||
if (len_ptr > end - wptr)
|
||||
length_mismatch ();
|
||||
wptr = __mempcpy (wptr, ptr, len_ptr);
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
if (wptr == end)
|
||||
length_mismatch ();
|
||||
*wptr = '%';
|
||||
++wptr;
|
||||
break;
|
||||
default:
|
||||
_dl_fatal_printf ("Fatal error:"
|
||||
" invalid format in exception string\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wptr == end)
|
||||
length_mismatch ();
|
||||
*wptr = *p;
|
||||
++wptr;
|
||||
}
|
||||
|
||||
if (wptr == end)
|
||||
length_mismatch ();
|
||||
*wptr = '\0';
|
||||
++wptr;
|
||||
if (len_objname != end - wptr)
|
||||
length_mismatch ();
|
||||
exception->objname = memcpy (wptr, objname, len_objname);
|
||||
}
|
||||
}
|
||||
rtld_hidden_def (_dl_exception_create_format)
|
||||
|
||||
void
|
||||
_dl_exception_free (struct dl_exception *exception)
|
||||
{
|
||||
free (exception->message_buffer);
|
||||
exception->objname = NULL;
|
||||
exception->errstring = NULL;
|
||||
exception->message_buffer = NULL;
|
||||
}
|
||||
rtld_hidden_def (_dl_exception_free)
|
@ -47,23 +47,6 @@ struct sym_val
|
||||
};
|
||||
|
||||
|
||||
#define make_string(string, rest...) \
|
||||
({ \
|
||||
const char *all[] = { string, ## rest }; \
|
||||
size_t len, cnt; \
|
||||
char *result, *cp; \
|
||||
\
|
||||
len = 1; \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
len += strlen (all[cnt]); \
|
||||
\
|
||||
cp = result = alloca (len); \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
cp = __stpcpy (cp, all[cnt]); \
|
||||
\
|
||||
result; \
|
||||
})
|
||||
|
||||
/* Statistics function. */
|
||||
#ifdef SHARED
|
||||
# define bump_num_relocations() ++GL(dl_num_relocations)
|
||||
@ -843,17 +826,16 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
|
||||
for unversioned lookups. */
|
||||
assert (version != NULL);
|
||||
const char *reference_name = undef_map ? undef_map->l_name : "";
|
||||
|
||||
struct dl_exception exception;
|
||||
/* XXX We cannot translate the message. */
|
||||
_dl_signal_cerror (0, DSO_FILENAME (reference_name),
|
||||
N_("relocation error"),
|
||||
make_string ("symbol ", undef_name, ", version ",
|
||||
version->name,
|
||||
" not defined in file ",
|
||||
version->filename,
|
||||
" with link time reference",
|
||||
res == -2
|
||||
? " (no version symbols)" : ""));
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (reference_name),
|
||||
"symbol %s version %s not defined in file %s"
|
||||
" with link time reference%s",
|
||||
undef_name, version->name, version->filename,
|
||||
res == -2 ? " (no version symbols)" : "");
|
||||
_dl_signal_cexception (0, &exception, N_("relocation error"));
|
||||
_dl_exception_free (&exception);
|
||||
*ref = NULL;
|
||||
return 0;
|
||||
}
|
||||
@ -869,12 +851,14 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
|
||||
const char *versionstr = version ? ", version " : "";
|
||||
const char *versionname = (version && version->name
|
||||
? version->name : "");
|
||||
|
||||
struct dl_exception exception;
|
||||
/* XXX We cannot translate the message. */
|
||||
_dl_signal_cerror (0, DSO_FILENAME (reference_name),
|
||||
N_("symbol lookup error"),
|
||||
make_string ("undefined symbol: ", undef_name,
|
||||
versionstr, versionname));
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (reference_name),
|
||||
"undefined symbol: %s%s%s",
|
||||
undef_name, versionstr, versionname);
|
||||
_dl_signal_cexception (0, &exception, N_("symbol lookup error"));
|
||||
_dl_exception_free (&exception);
|
||||
}
|
||||
*ref = NULL;
|
||||
return 0;
|
||||
|
@ -643,11 +643,8 @@ no more namespaces available for dlmopen()"));
|
||||
args.argv = argv;
|
||||
args.env = env;
|
||||
|
||||
const char *objname;
|
||||
const char *errstring;
|
||||
bool malloced;
|
||||
int errcode = _dl_catch_error (&objname, &errstring, &malloced,
|
||||
dl_open_worker, &args);
|
||||
struct dl_exception exception;
|
||||
int errcode = _dl_catch_exception (&exception, dl_open_worker, &args);
|
||||
|
||||
#if defined USE_LDCONFIG && !defined MAP_COPY
|
||||
/* We must unmap the cache file. */
|
||||
@ -655,7 +652,7 @@ no more namespaces available for dlmopen()"));
|
||||
#endif
|
||||
|
||||
/* See if an error occurred during loading. */
|
||||
if (__glibc_unlikely (errstring != NULL))
|
||||
if (__glibc_unlikely (exception.errstring != NULL))
|
||||
{
|
||||
/* Remove the object from memory. It may be in an inconsistent
|
||||
state if relocation failed, for example. */
|
||||
@ -679,28 +676,8 @@ no more namespaces available for dlmopen()"));
|
||||
/* Release the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* Make a local copy of the error string so that we can release the
|
||||
memory allocated for it. */
|
||||
size_t len_errstring = strlen (errstring) + 1;
|
||||
char *local_errstring;
|
||||
if (objname == errstring + len_errstring)
|
||||
{
|
||||
size_t total_len = len_errstring + strlen (objname) + 1;
|
||||
local_errstring = alloca (total_len);
|
||||
memcpy (local_errstring, errstring, total_len);
|
||||
objname = local_errstring + len_errstring;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_errstring = alloca (len_errstring);
|
||||
memcpy (local_errstring, errstring, len_errstring);
|
||||
}
|
||||
|
||||
if (malloced)
|
||||
free ((char *) errstring);
|
||||
|
||||
/* Reraise the error. */
|
||||
_dl_signal_error (errcode, objname, NULL, local_errstring);
|
||||
_dl_signal_exception (errcode, &exception, NULL);
|
||||
}
|
||||
|
||||
assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
|
||||
|
23
elf/dl-sym.c
23
elf/dl-sym.c
@ -119,26 +119,11 @@ do_sym (void *handle, const char *name, void *who,
|
||||
args.refp = &ref;
|
||||
|
||||
THREAD_GSCOPE_SET_FLAG ();
|
||||
|
||||
const char *objname;
|
||||
const char *errstring = NULL;
|
||||
bool malloced;
|
||||
int err = _dl_catch_error (&objname, &errstring, &malloced,
|
||||
call_dl_lookup, &args);
|
||||
|
||||
struct dl_exception exception;
|
||||
int err = _dl_catch_exception (&exception, call_dl_lookup, &args);
|
||||
THREAD_GSCOPE_RESET_FLAG ();
|
||||
|
||||
if (__glibc_unlikely (errstring != NULL))
|
||||
{
|
||||
/* The lookup was unsuccessful. Rethrow the error. */
|
||||
char *errstring_dup = strdupa (errstring);
|
||||
char *objname_dup = strdupa (objname);
|
||||
if (malloced)
|
||||
free ((char *) errstring);
|
||||
|
||||
_dl_signal_error (err, objname_dup, NULL, errstring_dup);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (__glibc_unlikely (exception.errstring != NULL))
|
||||
_dl_signal_exception (err, &exception, NULL);
|
||||
|
||||
result = args.map;
|
||||
}
|
||||
|
@ -27,25 +27,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define make_string(string, rest...) \
|
||||
({ \
|
||||
const char *all[] = { string, ## rest }; \
|
||||
size_t len, cnt; \
|
||||
char *result, *cp; \
|
||||
\
|
||||
len = 1; \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
len += strlen (all[cnt]); \
|
||||
\
|
||||
cp = result = alloca (len); \
|
||||
for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
|
||||
cp = __stpcpy (cp, all[cnt]); \
|
||||
\
|
||||
result; \
|
||||
})
|
||||
|
||||
|
||||
static inline struct link_map *
|
||||
__attribute ((always_inline))
|
||||
find_needed (const char *name, struct link_map *map)
|
||||
@ -78,8 +59,8 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
|
||||
ElfW(Addr) def_offset;
|
||||
ElfW(Verdef) *def;
|
||||
/* Initialize to make the compiler happy. */
|
||||
const char *errstring = NULL;
|
||||
int result = 0;
|
||||
struct dl_exception exception;
|
||||
|
||||
/* Display information about what we are doing while debugging. */
|
||||
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
|
||||
@ -96,8 +77,9 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
|
||||
if (verbose)
|
||||
{
|
||||
/* XXX We cannot translate the messages. */
|
||||
errstring = make_string ("\
|
||||
no version information available (required by ", name, ")");
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
"no version information available (required by %s)", name);
|
||||
goto call_cerror;
|
||||
}
|
||||
return 0;
|
||||
@ -116,10 +98,10 @@ no version information available (required by ", name, ")");
|
||||
char buf[20];
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
/* XXX We cannot translate the message. */
|
||||
errstring = make_string ("unsupported version ",
|
||||
_itoa (def->vd_version,
|
||||
&buf[sizeof (buf) - 1], 10, 0),
|
||||
" of Verdef record");
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
"unsupported version %s of Verdef record",
|
||||
_itoa (def->vd_version, &buf[sizeof (buf) - 1], 10, 0));
|
||||
result = 1;
|
||||
goto call_cerror;
|
||||
}
|
||||
@ -150,20 +132,22 @@ no version information available (required by ", name, ")");
|
||||
if (verbose)
|
||||
{
|
||||
/* XXX We cannot translate the message. */
|
||||
errstring = make_string ("weak version `", string,
|
||||
"' not found (required by ", name, ")");
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
"weak version `%s' not found (required by %s)", string, name);
|
||||
goto call_cerror;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX We cannot translate the message. */
|
||||
errstring = make_string ("version `", string, "' not found (required by ",
|
||||
name, ")");
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
"version `%s' not found (required by %s)", string, name);
|
||||
result = 1;
|
||||
call_cerror:
|
||||
_dl_signal_cerror (0, DSO_FILENAME (map->l_name),
|
||||
N_("version lookup error"), errstring);
|
||||
_dl_signal_cexception (0, &exception, N_("version lookup error"));
|
||||
_dl_exception_free (&exception);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -181,8 +165,8 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
|
||||
/* We need to find out which is the highest version index used
|
||||
in a dependecy. */
|
||||
unsigned int ndx_high = 0;
|
||||
struct dl_exception exception;
|
||||
/* Initialize to make the compiler happy. */
|
||||
const char *errstring = NULL;
|
||||
int errval = 0;
|
||||
|
||||
/* If we don't have a string table, we must be ok. */
|
||||
@ -205,13 +189,12 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
|
||||
char buf[20];
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
/* XXX We cannot translate the message. */
|
||||
errstring = make_string ("unsupported version ",
|
||||
_itoa (ent->vn_version,
|
||||
&buf[sizeof (buf) - 1], 10, 0),
|
||||
" of Verneed record\n");
|
||||
_dl_exception_create_format
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
"unsupported version %s of Verneed record",
|
||||
_itoa (ent->vn_version, &buf[sizeof (buf) - 1], 10, 0));
|
||||
call_error:
|
||||
_dl_signal_error (errval, DSO_FILENAME (map->l_name),
|
||||
NULL, errstring);
|
||||
_dl_signal_exception (errval, &exception, NULL);
|
||||
}
|
||||
|
||||
while (1)
|
||||
@ -293,7 +276,9 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
|
||||
calloc (ndx_high + 1, sizeof (*map->l_versions));
|
||||
if (__glibc_unlikely (map->l_versions == NULL))
|
||||
{
|
||||
errstring = N_("cannot allocate version reference table");
|
||||
_dl_exception_create
|
||||
(&exception, DSO_FILENAME (map->l_name),
|
||||
N_("cannot allocate version reference table"));
|
||||
errval = ENOMEM;
|
||||
goto call_error;
|
||||
}
|
||||
|
@ -732,31 +732,88 @@ _dl_dprintf (int fd, const char *fmt, ...)
|
||||
while (1)
|
||||
|
||||
|
||||
/* This function is called by all the internal dynamic linker functions
|
||||
when they encounter an error. ERRCODE is either an `errno' code or
|
||||
zero; OBJECT is the name of the problematical shared object, or null if
|
||||
it is a general problem; ERRSTRING is a string describing the specific
|
||||
problem. */
|
||||
/* An exception raised by the _dl_signal_error function family and
|
||||
caught by _dl_catch_error function family. Exceptions themselves
|
||||
are copied as part of the raise operation, but the strings are
|
||||
not. */
|
||||
struct dl_exception
|
||||
{
|
||||
const char *objname;
|
||||
const char *errstring;
|
||||
|
||||
/* This buffer typically stores both objname and errstring
|
||||
above. */
|
||||
char *message_buffer;
|
||||
};
|
||||
|
||||
/* Creates a new exception. This calls malloc; if allocation fails,
|
||||
dummy values are inserted. OBJECT is the name of the problematical
|
||||
shared object, or null if its a general problem. ERRSTRING is a
|
||||
string describing the specific problem. */
|
||||
void _dl_exception_create (struct dl_exception *, const char *object,
|
||||
const char *errstring)
|
||||
__attribute__ ((nonnull (1, 3)));
|
||||
rtld_hidden_proto (_dl_exception_create)
|
||||
|
||||
/* Like _dl_exception_create, but create errstring from a format
|
||||
string FMT. Currently, only "%s" and "%%" are supported as format
|
||||
directives. */
|
||||
void _dl_exception_create_format (struct dl_exception *, const char *objname,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((nonnull (1, 3), format (printf, 3, 4)));
|
||||
rtld_hidden_proto (_dl_exception_create_format)
|
||||
|
||||
/* Deallocate the exception, freeing allocated buffers (if
|
||||
possible). */
|
||||
void _dl_exception_free (struct dl_exception *)
|
||||
__attribute__ ((nonnull (1)));
|
||||
rtld_hidden_proto (_dl_exception_free)
|
||||
|
||||
/* This function is called by all the internal dynamic linker
|
||||
functions when they encounter an error. ERRCODE is either an
|
||||
`errno' code or zero; it specifies the return value of
|
||||
_dl_catch_error. OCCASION is included in the error message if the
|
||||
process is terminated immediately. */
|
||||
void _dl_signal_exception (int errcode, struct dl_exception *,
|
||||
const char *occasion)
|
||||
__attribute__ ((__noreturn__));
|
||||
libc_hidden_proto (_dl_signal_exception)
|
||||
|
||||
/* Like _dl_signal_exception, but creates the exception first. */
|
||||
extern void _dl_signal_error (int errcode, const char *object,
|
||||
const char *occurred, const char *errstring)
|
||||
const char *occasion, const char *errstring)
|
||||
internal_function __attribute__ ((__noreturn__));
|
||||
libc_hidden_proto (_dl_signal_error)
|
||||
|
||||
/* Like _dl_signal_error, but may return when called in the context of
|
||||
_dl_receive_error. This is only used during ld.so bootstrap. In
|
||||
static and profiled builds, this is equivalent to
|
||||
_dl_signal_error. */
|
||||
/* Like _dl_signal_exception, but may return when called in the
|
||||
context of _dl_receive_error. This is only used during ld.so
|
||||
bootstrap. In static and profiled builds, this is equivalent to
|
||||
_dl_signal_exception. */
|
||||
#if IS_IN (rtld)
|
||||
extern void _dl_signal_cexception (int errcode, struct dl_exception *,
|
||||
const char *occasion) attribute_hidden;
|
||||
#else
|
||||
__attribute__ ((always_inline))
|
||||
static inline void
|
||||
_dl_signal_cexception (int errcode, struct dl_exception *exception,
|
||||
const char *occasion)
|
||||
{
|
||||
_dl_signal_exception (errcode, exception, occasion);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* See _dl_signal_cexception above. */
|
||||
#if IS_IN (rtld)
|
||||
extern void _dl_signal_cerror (int errcode, const char *object,
|
||||
const char *occation, const char *errstring)
|
||||
const char *occasion, const char *errstring)
|
||||
internal_function attribute_hidden;
|
||||
#else
|
||||
__attribute__ ((always_inline))
|
||||
static inline void
|
||||
_dl_signal_cerror (int errcode, const char *object,
|
||||
const char *occation, const char *errstring)
|
||||
const char *occasion, const char *errstring)
|
||||
{
|
||||
_dl_signal_error (errcode, object, occation, errstring);
|
||||
_dl_signal_error (errcode, object, occasion, errstring);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -768,20 +825,28 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
|
||||
void *args)
|
||||
internal_function attribute_hidden;
|
||||
|
||||
/* Call OPERATE, catching errors from `dl_signal_error'. If there is no
|
||||
error, *ERRSTRING is set to null. If there is an error, *ERRSTRING is
|
||||
set to a string constructed from the strings passed to _dl_signal_error,
|
||||
and the error code passed is the return value and *OBJNAME is set to
|
||||
the object name which experienced the problems. ERRSTRING if nonzero
|
||||
points to a malloc'ed string which the caller has to free after use.
|
||||
ARGS is passed as argument to OPERATE. MALLOCEDP is set to true only
|
||||
if the returned string is allocated using the libc's malloc. */
|
||||
/* Call OPERATE, catching errors from `_dl_signal_error' and related
|
||||
functions. If there is no error, *ERRSTRING is set to null. If
|
||||
there is an error, *ERRSTRING is set to a string constructed from
|
||||
the strings passed to _dl_signal_error, and the error code passed
|
||||
is the return value and *OBJNAME is set to the object name which
|
||||
experienced the problems. ERRSTRING if nonzero points to a
|
||||
malloc'ed string which the caller has to free after use. ARGS is
|
||||
passed as argument to OPERATE. MALLOCEDP is set to true only if
|
||||
the returned string is allocated using the libc's malloc. */
|
||||
extern int _dl_catch_error (const char **objname, const char **errstring,
|
||||
bool *mallocedp, void (*operate) (void *),
|
||||
void *args)
|
||||
internal_function;
|
||||
libc_hidden_proto (_dl_catch_error)
|
||||
|
||||
/* Call OPERATE (ARGS). If no error occurs, set *EXCEPTION to zero.
|
||||
Otherwise, store a copy of the raised exception in *EXCEPTION,
|
||||
which has to be freed by _dl_exception_free. */
|
||||
int _dl_catch_exception (struct dl_exception *exception,
|
||||
void (*operate) (void *), void *args);
|
||||
libc_hidden_proto (_dl_catch_exception)
|
||||
|
||||
/* Open the shared object NAME and map in its segments.
|
||||
LOADER's DT_RPATH is used in searching for NAME.
|
||||
If the object is already opened, returns its existing map. */
|
||||
|
@ -16,3 +16,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -18,3 +18,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -35,3 +35,5 @@ ld.so: free + RELA R_ALPHA_GLOB_DAT
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error + RELA R_ALPHA_GLOB_DAT
|
||||
ld.so: _dl_catch_error + RELA R_ALPHA_GLOB_DAT
|
||||
ld.so: _dl_signal_exception + RELA R_ALPHA_GLOB_DAT
|
||||
ld.so: _dl_catch_exception + RELA R_ALPHA_GLOB_DAT
|
||||
|
@ -17,3 +17,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -21,3 +21,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -16,3 +16,5 @@ ld.so: free + REL R_386_GLOB_DAT
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error + REL R_386_GLOB_DAT
|
||||
ld.so: _dl_catch_error + REL R_386_GLOB_DAT
|
||||
ld.so: _dl_signal_exception + REL R_386_GLOB_DAT
|
||||
ld.so: _dl_catch_exception + REL R_386_GLOB_DAT
|
||||
|
@ -15,3 +15,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -15,3 +15,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -16,3 +16,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -36,3 +36,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -14,3 +14,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -44,3 +44,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -13,3 +13,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -14,3 +14,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -19,3 +19,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -26,3 +26,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -27,3 +27,5 @@ ld.so: free
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error
|
||||
ld.so: _dl_catch_error
|
||||
ld.so: _dl_signal_exception
|
||||
ld.so: _dl_catch_exception
|
||||
|
@ -18,3 +18,5 @@ ld.so: free + RELA R_X86_64_GLOB_DAT
|
||||
# The TLS-enabled version of these functions is interposed from libc.so.
|
||||
ld.so: _dl_signal_error + RELA R_X86_64_GLOB_DAT
|
||||
ld.so: _dl_catch_error + RELA R_X86_64_GLOB_DAT
|
||||
ld.so: _dl_signal_exception + RELA R_X86_64_GLOB_DAT
|
||||
ld.so: _dl_catch_exception + RELA R_X86_64_GLOB_DAT
|
||||
|
Loading…
Reference in New Issue
Block a user