diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | Makeconfig | 9 | ||||
-rw-r--r-- | elf/Makefile | 13 | ||||
-rw-r--r-- | elf/dl-load.c | 5 | ||||
-rw-r--r-- | elf/rtld.c | 51 | ||||
-rw-r--r-- | sysdeps/generic/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/generic/make_siglist.c | 11 | ||||
-rw-r--r-- | sysdeps/mach/hurd/dl-sysdep.c | 23 |
8 files changed, 111 insertions, 34 deletions
@@ -1,3 +1,34 @@ +Thu Nov 16 06:07:49 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_start_cleanup): New + function. + (_dl_sysdep_start): Move cleanup code there. + + * Makeconfig (default-rpath): New variable. + (link-libc): Use it. + * elf/Makefile (ld.so): Pass -rpath=$(default-rpath). + * elf/rtld.c (_dl_rpath): New variable. + (_dl_start): Set it from rtld_map's DT_RPATH. + Call _dl_setup_hash on rtld_map. + (dl_main): Cache address of _exit in variable before relocating, + and use that in later calls. Call _dl_sysdep_start_cleanup before + relocating. Keep track of dependency order while loading; remove + rtld_map from chain, and reinsert in proper order if there is a + dependency on it. + + * sysdeps/generic/Makefile (make_siglist): Pass + -DSIGNUM_H=... with config's signum.h location. + * sysdeps/generic/make_siglist.c: Include SIGNUM_H to define + signal numbers. + (HAVE_STRSIGNAL, HAVE_PSIGNAL): Define these before including signame.c + (main): Deansideclize output. + + * elf/dl-load.c (_dl_map_object): Use _dl_rpath variable in place + of DEFAULT_RPATH macro. + * elf/Makefile: Undo last change. + + * sysdeps/mach/hurd/dl-sysdep.c (free): Don't abort, just nop. + Wed Nov 15 19:22:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * elf/dl-lookup.c (_dl_lookup_symbol): Undefined symbol is no diff --git a/Makeconfig b/Makeconfig index e716776cb9..a610d057f5 100644 --- a/Makeconfig +++ b/Makeconfig @@ -291,8 +291,15 @@ endif endif ifndef link-libc ifeq (yes,$(build-shared)) -link-libc = -Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(libdir) \ +link-libc = -Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(default-rpath) \ $(common-objpfx)libc.so $(gnulib) +# Choose the default search path for the dynamic linker based on +# where we will install libraries. +ifneq ($(libdir),$(slibdir)) +default-rpath = $(slibdir):$(libdir) +else +default-rpath = $(libdir) +endif else link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a endif diff --git a/elf/Makefile b/elf/Makefile index a37e95d2c5..4a1adb8b59 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -50,16 +50,6 @@ endif include ../Rules -# Choose the default search path for the dynamic linker based on -# where we will install libraries. -ifneq ($(libdir),$(slibdir)) -default-rpath = $(slibdir):$(libdir) -else -default-rpath = $(libdir) -endif -CPPFLAGS += -DDEFAULT_RPATH='"$(default-rpath)"' - - # Link together the dynamic linker into a single relocatable object. # We use this to produce both the ABI-compliant and Linux-compatible # dynamic linker shared objects below. @@ -70,7 +60,8 @@ $(objpfx)librtld.so: $(rtld-routines:%=$(objpfx)%.so) \ '-Wl,-(' $^ -lgcc '-Wl,-)' $(objpfx)ld.so $(objpfx)ld-linux.so.1: $(objpfx)librtld.so - $(LINK.o) -nostdlib -nostartfiles -shared -o $@ $^ + $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ + -Wl,-rpath=$(default-rpath) $^ # The Linux-compatible dynamic linker shared object is just the same # with one object file of compatibility initialization code added. diff --git a/elf/dl-load.c b/elf/dl-load.c index 126d6aab5c..88ee318aad 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -139,7 +139,10 @@ _dl_map_object (struct link_map *loader, const char *name) if (fd == -1 && ! _dl_secure) trypath (getenv ("LD_LIBRARY_PATH")); if (fd == -1) - trypath (DEFAULT_RPATH); + { + extern const char *_dl_rpath; /* Set in rtld.c. */ + trypath (_dl_rpath); + } } else { diff --git a/elf/rtld.c b/elf/rtld.c index 88f0d6d804..d0c25b4db4 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -39,10 +39,12 @@ extern Elf32_Addr _dl_sysdep_start (void **start_argptr, void (*dl_main) (const Elf32_Phdr *phdr, Elf32_Word phent, Elf32_Addr *user_entry)); +extern void _dl_sysdep_start_cleanup (void); int _dl_secure; int _dl_argc; char **_dl_argv; +const char *_dl_rpath; struct r_debug dl_r_debug; @@ -93,7 +95,13 @@ _dl_start (void *arg) rtld_map.l_addr = bootstrap_map.l_addr; rtld_map.l_ld = bootstrap_map.l_ld; memcpy (rtld_map.l_info, bootstrap_map.l_info, sizeof rtld_map.l_info); + _dl_setup_hash (&rtld_map); + /* Cache the DT_RPATH stored in ld.so itself; this will be + the default search path. */ + _dl_rpath = (void *) (rtld_map.l_addr + + rtld_map.l_info[DT_STRTAB]->d_un.d_ptr + + rtld_map.l_info[DT_RPATH]->d_un.d_val); /* Call the OS-dependent function to set up life so we can do things like file access. It will call `dl_main' (below) to do all the real work @@ -118,10 +126,11 @@ dl_main (const Elf32_Phdr *phdr, void doit (void) { const Elf32_Phdr *ph; - struct link_map *l; + struct link_map *l, *last, *before_rtld; const char *interpreter_name; int lazy; int list_only = 0; + __typeof (_exit) *volatile exitfn; if (*user_entry == (Elf32_Addr) &_start) { @@ -248,6 +257,7 @@ of this helper program; chances are you did not intend to run this program.\n", /* Now process all the DT_NEEDED entries and map in the objects. Each new link_map will go on the end of the chain, so we will come across it later in the loop to map in its dependencies. */ + before_rtld = NULL; for (l = _dl_loaded; l; l = l->l_next) { if (l->l_info[DT_NEEDED]) @@ -255,24 +265,47 @@ of this helper program; chances are you did not intend to run this program.\n", const char *strtab = (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr; const Elf32_Dyn *d; + last = l; for (d = l->l_ld; d->d_tag != DT_NULL; ++d) if (d->d_tag == DT_NEEDED) - _dl_map_object (l, strtab + d->d_un.d_val); + { + struct link_map *new; + new = _dl_map_object (l, strtab + d->d_un.d_val); + if (!before_rtld && new == &rtld_map) + before_rtld = last; + last = new; + } } l->l_deps_loaded = 1; } - if (rtld_map.l_opencount == 0) + /* If any DT_NEEDED entry referred to the interpreter object itself, + reorder the list so it appears after its dependent. If not, + remove it from the maps we will use for symbol resolution. */ + rtld_map.l_prev->l_next = rtld_map.l_next; + if (rtld_map.l_next) + rtld_map.l_next->l_prev = rtld_map.l_prev; + if (before_rtld) { - /* No DT_NEEDED entry referred to the interpreter object itself. - Remove it from the maps we will use for symbol resolution. */ - rtld_map.l_prev->l_next = rtld_map.l_next; + rtld_map.l_prev = before_rtld; + rtld_map.l_next = before_rtld->l_next; + before_rtld->l_next = &rtld_map; if (rtld_map.l_next) - rtld_map.l_next->l_prev = rtld_map.l_prev; + rtld_map.l_next->l_prev = &rtld_map; } lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0'; + /* Fetch this value now, before real relocation. For --list, it will + be called below, and the finally-linked version is not the right + one. */ + exitfn = &_exit; + + /* Do any necessary cleanups for the startup OS interface code. + We do these now so that no calls are made after real relocation + which might be resolved to different functions than we expect. */ + _dl_sysdep_start_cleanup (); + /* Now we have all the objects loaded. Relocate them all. We do this in reverse order so that copy relocs of earlier objects overwrite the data written by later objects. */ @@ -297,7 +330,7 @@ of this helper program; chances are you did not intend to run this program.\n", { _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n", NULL); - _exit (1); + (*exitfn) (1); } for (l = _dl_loaded->l_next; l; l = l->l_next) @@ -311,7 +344,7 @@ of this helper program; chances are you did not intend to run this program.\n", " (0x", bp, ")\n", NULL); } - _exit (0); + (*exitfn) (0); } if (rtld_map.l_info[DT_INIT]) diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile index 1315a26b95..dc31a50fcd 100644 --- a/sysdeps/generic/Makefile +++ b/sysdeps/generic/Makefile @@ -53,6 +53,8 @@ $(objpfx)siglist.c: $(objpfx)make_siglist $(objpfx)make_siglist: $(sysdep_dir)/generic/make_siglist.c $(native-compile) + -DSIGNUM_H=\"`cd $(dir $(firstword $(wildcard \ + $(+sysdep_dirs:%=%/signum.h)))); pwd`/signum.h\" generated := $(generated) make_siglist siglist.c endif diff --git a/sysdeps/generic/make_siglist.c b/sysdeps/generic/make_siglist.c index 34abf80513..a38ab6aa2e 100644 --- a/sysdeps/generic/make_siglist.c +++ b/sysdeps/generic/make_siglist.c @@ -15,14 +15,19 @@ You should have received a copy of the GNU General Public License along with the GNU C Library; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <signal.h> #include <stdio.h> +#include <signal.h> +/* Get this configuration's defns of the signal numbers. */ +#define _SIGNAL_H 1 +#include SIGNUM_H /* Make a definition for sys_siglist. */ #undef HAVE_SYS_SIGLIST +#define HAVE_STRSIGNAL +#define HAVE_PSIGNAL #define sys_siglist my_siglist /* Avoid clash with signal.h. */ #include "signame.c" @@ -35,11 +40,11 @@ main() signame_init (); - puts ("#include \"ansidecl.h\"\n#include <stddef.h>\n"); + puts ("#include <stddef.h>\n"); puts ("\n/* This is a list of all known signal numbers. */"); - puts ("\nCONST char *CONST _sys_siglist[] =\n {"); + puts ("\nconst char *const _sys_siglist[] =\n {"); for (i = 0; i < NSIG; ++i) printf (" \"%s\",\n", sys_siglist[i]); diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 0144958766..f8997fe025 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -159,12 +159,6 @@ unfmh(); /* XXX */ _dl_hurd_data->phdrsz / sizeof (Elf32_Phdr), &_dl_hurd_data->user_entry); - /* Deallocate the reply port and task port rights acquired by - __mach_init. We are done with them now, and the user will - reacquire them for himself when he wants them. */ - __mig_dealloc_reply_port (MACH_PORT_NULL); - __mach_port_deallocate (__mach_task_self (), __mach_task_self_); - if (_dl_skip_args && _dl_argv[-_dl_skip_args] == (char *) p) { /* We are ignoring the first few arguments, but we have no Hurd @@ -198,6 +192,16 @@ fmh(); /* XXX */ LOSE; abort (); } + +void +_dl_sysdep_start_cleanup (void) +{ + /* Deallocate the reply port and task port rights acquired by + __mach_init. We are done with them now, and the user will + reacquire them for himself when he wants them. */ + __mig_dealloc_reply_port (MACH_PORT_NULL); + __mach_port_deallocate (__mach_task_self (), __mach_task_self_); +} int _dl_sysdep_open_zero_fill (void) @@ -567,13 +571,14 @@ malloc (size_t n) ptr += n; return block; } - weak_symbol (malloc) -/* These should never be called. */ +/* This should never be called. */ void *realloc (void *ptr, size_t n) { ptr += n; abort (); } -void free (void *ptr) { ptr = ptr; abort (); } weak_symbol (realloc) + +/* This will rarely be called. */ +void free (void *ptr) { ptr = ptr; } weak_symbol (free) /* Avoid signal frobnication in setjmp/longjmp. */ |