diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-10-14 05:57:55 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2004-10-14 05:57:55 +0000 |
commit | 9869e6ec913e268748f510ab6ec64b8fd62531bc (patch) | |
tree | f3f8b9c049c73755d183cc1c1affd34ee8f9772b /sysdeps/generic | |
parent | 3ee87ca7d4c813087eeee8b9fd04b7836244a54a (diff) |
Updated to fedora-glibc-20041014T0548
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/dl-tls.c | 2 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 40 | ||||
-rw-r--r-- | sysdeps/generic/segfault.c | 88 |
3 files changed, 46 insertions, 84 deletions
diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 4fe67da4e1..bf3592e292 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -33,7 +33,7 @@ /* Amount of excess space to allocate in the static TLS area to allow dynamic loading of modules defining IE-model TLS data. */ -# define TLS_STATIC_SURPLUS 64 +# define TLS_STATIC_SURPLUS 64 + DL_NNS * 100 /* Value used for dtv entries for which the allocation is delayed. */ # define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 2b526867ad..f1062e7fa6 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -216,18 +216,27 @@ struct rtld_global /* Don't change the order of the following elements. 'dl_loaded' must remain the first element. Forever. */ - /* And a pointer to the map for the main map. */ - EXTERN struct link_map *_dl_loaded; - /* Number of object in the _dl_loaded list. */ - EXTERN unsigned int _dl_nloaded; - /* Array representing global scope. */ - EXTERN struct r_scope_elem *_dl_global_scope[2]; - /* Direct pointer to the searchlist of the main object. */ - EXTERN struct r_scope_elem *_dl_main_searchlist; - /* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ - EXTERN size_t _dl_global_scope_alloc; +/* Non-shared code has no support for multiple namespaces. */ +#ifdef SHARED +# define DL_NNS 16 +#else +# define DL_NNS 1 +#endif + EXTERN struct link_namespaces + { + /* And a pointer to the map for the main map. */ + struct link_map *_ns_loaded; + /* Number of object in the _dl_loaded list. */ + unsigned int _ns_nloaded; + /* Array representing global scope. */ + struct r_scope_elem *_ns_global_scope[2]; + /* Direct pointer to the searchlist of the main object. */ + struct r_scope_elem *_ns_main_searchlist; + /* This is zero at program start to signal that the global scope map is + allocated by rtld. Later it keeps the size of the map. It might be + reset if in _dl_close if the last global object is removed. */ + size_t _ns_global_scope_alloc; + } _dl_ns[DL_NNS]; /* During the program run we must not modify the global data of loaded shared object simultanously in two threads. Therefore we @@ -477,7 +486,7 @@ struct rtld_global_ro char *(*_dl_dst_substitute) (struct link_map *, const char *, char *, int); struct link_map *(internal_function *_dl_map_object) (struct link_map *, const char *, int, - int, int, int); + int, int, int, Lmid_t); void (internal_function *_dl_map_object_deps) (struct link_map *, struct link_map **, unsigned int, int, int); @@ -658,7 +667,8 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), value to allow additional security checks. */ extern struct link_map *_dl_map_object (struct link_map *loader, const char *name, int preloaded, - int type, int trace_mode, int mode) + int type, int trace_mode, int mode, + Lmid_t nsid) internal_function attribute_hidden; /* Call _dl_map_object on the dependencies of MAP, and set up @@ -723,7 +733,7 @@ extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) and enter it into the _dl_main_map list. */ extern struct link_map *_dl_new_object (char *realname, const char *libname, int type, struct link_map *loader, - int mode) + int mode, Lmid_t nsid) internal_function attribute_hidden; /* Relocate the given object (if it hasn't already been). diff --git a/sysdeps/generic/segfault.c b/sysdeps/generic/segfault.c index 47f2447169..f141fff661 100644 --- a/sysdeps/generic/segfault.c +++ b/sysdeps/generic/segfault.c @@ -19,11 +19,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <alloca.h> #include <ctype.h> #include <errno.h> #include <execinfo.h> #include <fcntl.h> #include <signal.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -33,9 +35,6 @@ #include <bp-checks.h> -/* Get the definition of "struct layout". */ -#include <frame.h> - /* This file defines macros to access the content of the sigcontext element passed up by the signal handler. */ #include <sigcontextinfo.h> @@ -43,35 +42,6 @@ /* Get code to possibly dump the content of all registers. */ #include <register-dump.h> -/* This implementation assumes a stack layout that matches the defaults - used by gcc's `__builtin_frame_address' and `__builtin_return_address' - (FP is the frame pointer register): - - +-----------------+ +-----------------+ - FP -> | previous FP --------> | previous FP ------>... - | | | | - | return address | | return address | - +-----------------+ +-----------------+ - - */ - -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#ifndef CURRENT_STACK_FRAME -# define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) -#endif - -/* By default we assume that the stack grows downward. */ -#ifndef INNER_THAN -# define INNER_THAN < -#endif - -/* By default assume the `next' pointer in struct layout points to the - next struct layout. */ -#ifndef ADVANCE_STACK_FRAME -# define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (next)) -#endif - /* We'll use tis a lot. */ #define WRITE_STRING(s) write (fd, s, strlen (s)) @@ -102,13 +72,10 @@ write_strsignal (int fd, int signal) static void catch_segfault (int signal, SIGCONTEXT ctx) { - struct layout *current; - void *__unbounded top_frame; - void *__unbounded top_stack; - int fd; + int fd, cnt, i; void **arr; - size_t cnt; struct sigaction sa; + uintptr_t pc; /* This is the name of the file we are writing to. If none is given or we cannot write to this file write to stderr. */ @@ -130,41 +97,26 @@ catch_segfault (int signal, SIGCONTEXT ctx) WRITE_STRING ("\nBacktrace:\n"); - top_frame = GET_FRAME (ctx); - top_stack = GET_STACK (ctx); + /* Get the backtrace. */ + arr = alloca (256 * sizeof (void *)); + cnt = backtrace (arr, 256); - /* First count how many entries we'll have. */ - cnt = 1; - current = BOUNDED_1 ((struct layout *) top_frame); - while (!((void *) current INNER_THAN top_stack - || !((void *) current INNER_THAN __libc_stack_end))) - { - ++cnt; - - current = ADVANCE_STACK_FRAME (current->next); - } - - arr = alloca (cnt * sizeof (void *)); - - /* First handle the program counter from the structure. */ - arr[0] = GET_PC (ctx); - - current = BOUNDED_1 ((struct layout *) top_frame); - cnt = 1; - while (!((void *) current INNER_THAN top_stack - || !((void *) current INNER_THAN __libc_stack_end))) - { - arr[cnt++] = current->return_address; - - current = ADVANCE_STACK_FRAME (current->next); - } + /* Now try to locate the PC from signal context in the backtrace. + Normally it will be found at arr[2], but it might appear later + if there were some signal handler wrappers. Allow a few bytes + difference to cope with as many arches as possible. */ + pc = (uintptr_t) GET_PC (ctx); + for (i = 0; i < cnt; ++i) + if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16) + break; - /* If the last return address was NULL, assume that it doesn't count. */ - if (arr[cnt-1] == NULL) - cnt--; + /* If we haven't found it, better dump full backtrace even including + the signal handler frames instead of not dumping anything. */ + if (i == cnt) + i = 0; /* Now generate nicely formatted output. */ - __backtrace_symbols_fd (arr, cnt, fd); + __backtrace_symbols_fd (arr + i, cnt - i, fd); #ifdef HAVE_PROC_SELF /* Now the link map. */ |