diff --git a/ChangeLog b/ChangeLog index be4fe225b7..78a3ea78b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +Thu Jun 13 00:02:25 1996 Roland McGrath + + * elf/dl-lookup.c (_dl_lookup_symbol): If no value and *REF is + null, consider it a strong reference and give the error. + +Wed Jun 12 15:52:46 1996 Roland McGrath + + * elf/dl-open.c (_dl_open): Correctly terminate relocating loop + after relocating NEW when it's the only new object. + + * elf/dl-init.c (_dl_init_next): When out of initializers, set + _r_debug.r_state to RT_CONSISTENT and call _dl_debug_state just + before return. + + * elf/rtld.c (dl_main): Move _dl_debug_initialize call after + relocation. Call it unconditionally and only fill in DT_DEBUG + if it's present. Then call _dl_debug_state with r_state RT_ADD + before running initializers. + + * elf/dl-open.c (_dl_open): Call _dl_debug_initialize and then call + _dl_debug_state with r_state RT_ADD before running initializers + * elf/dl-close.c (_dl_close): Call _dl_debug_state with r_state + RT_DELETE before running finalizers and with RT_CONSISTENT just + before return. + + * elf/Makefile (dl-routines): Add dl-debug. + * elf/dl-debug.c: New file. + * elf/rtld.c (_dl_r_debug): Rename to _r_debug and move to dl-debug.c. + (_dl_r_debug_state): Rename to _dl_debug_state and likewise move. + (dl_main): Use _dl_debug_initialize. + * elf/link.h: Fix name to _dl_debug_state in decl. + (_dl_debug_initialize): Declare new function from dl-debug.c. + (_r_debug): Declare it. + + * Makerules (distinfo-vars): Add install-{lib,data,bin,sbin,others}. + In distinfo set $(subdir)-VAR and then set VAR to $($(subdir)-VAR). + + * Makeconfig (rpath-link): New variable; add $(elfobjdir). + (default-rpath): Use it. + (built-program-cmd): Use it in LD_LIBRARY_PATH. + + * Makeconfig (sysdep-configures): Prepend $(sysdep_dir) to names tried. + + * sysdeps/unix/Dist: Add make-syscalls.sh. + + * misc/Makefile (headers): Add sys/swap.h. + * posix/unistd.h: Remove decls for swapon, swapoff. + * sysdeps/generic/sys/swap.h: New file. + * sysdeps/unix/sysv/linux/sys/swap.h: New file. + + * sysdeps/unix/sysv/linux/gnu/types.h: Remove temporary hack #define + of __kernel_fsid_t. It is correctly defines in now. + Tue Jun 11 23:23:30 1996 Roland McGrath * Makerules (LDFLAGS-c.so): Use __libc_main instead of diff --git a/Makeconfig b/Makeconfig index 0bb64bc288..1d534580b1 100644 --- a/Makeconfig +++ b/Makeconfig @@ -88,11 +88,12 @@ $(common-objpfx)config.make: $(common-objpfx)config.status $(..)config.h.in # Find all the sysdeps configure fragments, to make sure we re-run # configure when any of them changes. -sysdep-configures = $(foreach dir,$(config-sysdirs),\ - $(patsubst %.in,%,\ - $(firstword $(wildcard \ - $(dir)/configure \ - $(dir)/configure.in)))) +sysdep-configures = \ + $(foreach dir,$(config-sysdirs),\ + $(patsubst %.in,%,\ + $(firstword $(wildcard \ + $(sysdep_dir)/$(dir)/configure \ + $(sysdep_dir)/$(dir)/configure.in)))) # Force the user to configure before making. $(common-objpfx)config.status: $(..)configure $(sysdep-configures) @@ -312,7 +313,7 @@ ifeq (yes,$(build-shared)) # We need the versioned name of libc.so in the deps of $(others) et al # so that the symlink to libc.so is created before anything tries to # run the linked programs. -link-libc = -Wl,-rpath-link=$(common-objdir):$(elfobjdir) \ +link-libc = -Wl,-rpath-link=$(rpath-link) \ $(common-objpfx)libc.so$(libc.so-version) \ $(elfobjdir)/$(rtld-installed-name) \ $(common-objpfx)libc.a $(gnulib) @@ -323,6 +324,8 @@ default-rpath = $(slibdir):$(libdir) else default-rpath = $(libdir) endif +# This is how to find at build-time things that will be installed there. +rpath-link = $(common-objdir):$(elfobjdir) else link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a endif @@ -356,9 +359,9 @@ built-program-cmd = $(built-program-file) else comma = , define built-program-cmd -LD_LIBRARY_PATH=$(common-objdir)$(patsubst -Wl$(comma)-rpath-link=%,:%,\ - $(filter -Wl$(comma)-rpath-link=%,\ - $(sysdep-LDFLAGS))) \ +LD_LIBRARY_PATH=$(rpath-link)$(patsubst -Wl$(comma)-rpath-link=%,:%,\ + $(filter -Wl$(comma)-rpath-link=%,\ + $(sysdep-LDFLAGS))) \ $(elf-objpfx)ld.so $(built-program-file) endef endif diff --git a/Makerules b/Makerules index 412b217184..4ea38edd34 100644 --- a/Makerules +++ b/Makerules @@ -420,10 +420,15 @@ endif define o-iterator-doit $(common-objpfx)$(patsubst %,$(libtype$o),c)($(ar-symtab-name)): \ $(common-objpfx)$(patsubst %,$(libtype$o),c)(\ - $(patsubst $(objpfx)%,%,$(o-objects))) \ - $(filter subdir_lib,$(firstword $(subdir) subdir_lib)); \ + $(patsubst $(objpfx)%,%,$(o-objects))) $(subdirs-stamp-o); \ $$(RANLIB) $$(common-objpfx)$$(patsubst %,$$(libtype$o),c) endef +ifndef subdir +subdirs-stamps := $(foreach d,$(subdirs),\ + $(firstword $(objdir) $(subdir))/stamp%-$d) +subdirs-stamp-o = $(subst %,$o,$(subdirs-stamps)) +$(subdirs-stamps): subdir_lib; +endif object-suffixes-left = $(object-suffixes) include $(o-iterator) @@ -810,8 +815,10 @@ define distinfo-vars rm -f $@.new $(foreach var,subdir subdir-dirs sources elided-routines sysdep_routines \ headers sysdep_headers distribute dont_distribute generated \ - others tests extra-libs $(extra-libs:%=%-routines), -echo >> $@.new '$(var) := $($(var))') + others tests extra-libs $(extra-libs:%=%-routines) \ + $(addprefix install-,lib data bin sbin others), +echo >> $@.new '$(subdir)-$(var) := $($(var))' +echo >> $@.new '$(var) = $$($(subdir)-$(var))') endef ifneq (,$(strip $(gpl2lgpl))) diff --git a/elf/Makefile b/elf/Makefile index 07ffbd8788..be7604de8e 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -26,7 +26,7 @@ routines = $(dl-routines) dl-open dl-close dl-symbol dl-support # The core dynamic linking functions are in libc for the static and # profiled libraries. dl-routines = $(addprefix dl-,load lookup object reloc deps \ - runtime error init fini) + runtime error init fini debug) # But they are absent from the shared libc, because that code is in ld.so. elide-routines.so = $(dl-routines) dl-support diff --git a/elf/dl-close.c b/elf/dl-close.c index 70d7ab4083..184d38298e 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -41,6 +41,10 @@ _dl_close (struct link_map *map) /* There are still references to this object. Do nothing more. */ return; + /* Notify the debugger we are about to remove some loaded objects. */ + _r_debug.r_state = RT_DELETE; + _dl_debug_state (); + list = map->l_searchlist; /* The search list contains a counted reference to each object it @@ -105,4 +109,8 @@ _dl_close (struct link_map *map) } free (list); + + /* Notify the debugger those objects are finalized and gone. */ + _r_debug.r_state = RT_CONSISTENT; + _dl_debug_state (); } diff --git a/elf/dl-debug.c b/elf/dl-debug.c new file mode 100644 index 0000000000..861e0019e8 --- /dev/null +++ b/elf/dl-debug.c @@ -0,0 +1,56 @@ +/* Communicate dynamic linker state to the debugger at runtime. +Copyright (C) 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include + +/* This structure communicates dl state to the debugger. The debugger + normally finds it via the DT_DEBUG entry in the dynamic section, but in + a statically-linked program there is no dynamic section for the debugger + to examine and it looks for this particular symbol name. */ +struct r_debug _r_debug; + + +/* Initialize _r_debug if it has not already been done. The argument is + the run-time load address of the dynamic linker, to be put in + _r_debug.r_ldbase. Returns the address of _r_debug. */ + +struct r_debug * +_dl_debug_initialize (ElfW(Addr) ldbase) +{ + if (_r_debug.r_brk == 0) + { + /* Tell the debugger where to find the map of loaded objects. */ + _r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; + _r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */ + _r_debug.r_map = _dl_loaded; + _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state; + } + + return &_r_debug; +} + + +/* This function exists solely to have a breakpoint set on it by the + debugger. The debugger is supposed to find this function's address by + examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks + for this particular symbol name in the PT_INTERP file. */ +void +_dl_debug_state (void) +{ +} diff --git a/elf/dl-init.c b/elf/dl-init.c index 66ef83e28b..6259c35235 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -65,5 +65,10 @@ _dl_init_next (struct link_map *map) l->l_init_called = 1; } + + /* Notify the debugger all new objects are now ready to go. */ + _r_debug.r_state = RT_CONSISTENT; + _dl_debug_state (); + return 0; } diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index bbccbc01ef..7ceffa23e1 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -129,7 +129,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, } } - if (weak_value.s == NULL && ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) + if (weak_value.s == NULL && + !*ref || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) { /* We could find no value for a strong reference. */ const char msg[] = "undefined symbol: "; diff --git a/elf/dl-open.c b/elf/dl-open.c index 9389303b90..373d32dd79 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -29,6 +29,7 @@ _dl_open (struct link_map *parent, const char *file, int mode) { struct link_map *new, *l; ElfW(Addr) init; + struct r_debug *r; /* Load the named object. */ @@ -47,7 +48,7 @@ _dl_open (struct link_map *parent, const char *file, int mode) l = new; while (l->l_next) l = l->l_next; - do + while (1) { if (! l->l_relocated) { @@ -56,8 +57,10 @@ _dl_open (struct link_map *parent, const char *file, int mode) *_dl_global_scope_end = NULL; } + if (l == new) + break; l = l->l_prev; - } while (l != new); + } new->l_global = (mode & RTLD_GLOBAL); if (new->l_global) @@ -108,6 +111,14 @@ _dl_open (struct link_map *parent, const char *file, int mode) } } + + /* Notify the debugger we have added some objects. We need to call + _dl_debug_initialize in a static program in case dynamic linking has + not been used before. */ + r = _dl_debug_initialize (0); + r->r_state = RT_ADD; + _dl_debug_state (); + /* Run the initializer functions of new objects. */ while (init = _dl_init_next (new)) (*(void (*) (void)) init) (); diff --git a/elf/link.h b/elf/link.h index 6910445095..f43ec411f8 100644 --- a/elf/link.h +++ b/elf/link.h @@ -62,6 +62,9 @@ struct r_debug ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */ }; +/* This is the instance of that structure used by the dynamic linker. */ +extern struct r_debug _r_debug; + /* This symbol refers to the "dynamic structure" in the `.dynamic' section of whatever module refers to `_DYNAMIC'. So, to find its own `struct r_debug', a program could do: @@ -291,7 +294,12 @@ extern void _dl_fini (void); any shared object mappings. The `r_state' member of `struct r_debug' says what change is taking place. This function's address is the value of the `r_brk' member. */ -extern void _dl_r_debug_state (void); +extern void _dl_debug_state (void); + +/* Initialize `struct r_debug' if it has not already been done. The + argument is the run-time load address of the dynamic linker, to be put + in the `r_ldbase' member. Returns the address of the structure. */ +extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase); #endif /* link.h */ diff --git a/elf/rtld.c b/elf/rtld.c index c9ddfb5c63..7befc0a82f 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -46,8 +46,6 @@ int _dl_argc; char **_dl_argv; const char *_dl_rpath; -struct r_debug _dl_r_debug; - static void dl_main (const ElfW(Phdr) *phdr, ElfW(Half) phent, ElfW(Addr) *user_entry); @@ -229,12 +227,6 @@ of this helper program; chances are you did not intend to run this program.\n", /* Set up our cache of pointers into the hash table. */ _dl_setup_hash (l); - if (l->l_info[DT_DEBUG]) - /* There is a DT_DEBUG entry in the dynamic section. Fill it in - with the run-time address of the r_debug structure, which we - will set up later to communicate with the debugger. */ - l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &_dl_r_debug; - /* Put the link_map for ourselves on the chain so it can be found by name. */ _dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname = interpreter_name; @@ -343,11 +335,20 @@ of this helper program; chances are you did not intend to run this program.\n", _dl_relocate_object (&_dl_rtld_map, &_dl_default_scope[2], 0); } - /* Tell the debugger where to find the map of loaded objects. */ - _dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; - _dl_r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */ - _dl_r_debug.r_map = _dl_loaded; - _dl_r_debug.r_brk = (ElfW(Addr)) &_dl_r_debug_state; + { + /* Initialize _r_debug. */ + struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr); + + l = _dl_loaded; + if (l->l_info[DT_DEBUG]) + /* There is a DT_DEBUG entry in the dynamic section. Fill it in + with the run-time address of the r_debug structure */ + l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r; + + /* Notify the debugger that all objects are now mapped in. */ + r->r_state = RT_ADD; + _dl_debug_state (); + } if (_dl_rtld_map.l_info[DT_INIT]) { @@ -365,10 +366,3 @@ of this helper program; chances are you did not intend to run this program.\n", /* Once we return, _dl_sysdep_start will invoke the DT_INIT functions and then *USER_ENTRY. */ } - -/* This function exists solely to have a breakpoint set on it by the - debugger. */ -void -_dl_r_debug_state (void) -{ -} diff --git a/misc/Makefile b/misc/Makefile index 741b04cb6f..3dff4ae0e4 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -27,7 +27,7 @@ headers := sys/uio.h iovec.h sys/ioctl.h ioctls.h ioctl-types.h \ a.out.h nlist.h stab.h stab.def sgtty.h sys/dir.h sys/cdefs.h \ ttyent.h syslog.h sys/syslog.h paths.h sys/reboot.h \ sys/mman.h sys/param.h fstab.h mntent.h search.h err.h error.h\ - sys/queue.h sysexits.h syscall.h sys/syscall.h + sys/queue.h sysexits.h syscall.h sys/syscall.h sys/swap.h routines := brk sbrk sstk ioctl \ readv writev \ diff --git a/posix/unistd.h b/posix/unistd.h index 72ecd96023..8c8a48842b 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -662,13 +662,6 @@ extern int acct __P ((__const char *__name)); This call is restricted to the super-user. */ extern int chroot __P ((__const char *__path)); -/* Make the block special device PATH available to the system for swapping. - This call is restricted to the super-user. */ -extern int swapon __P ((__const char *__path)); - -/* Stop using block special device PATH for swapping. */ -extern int swapoff __P ((__const char *__path)); - /* Successive calls return the shells listed in `/etc/shells'. */ extern char *getusershell __P ((void)); diff --git a/sysdeps/generic/sys/swap.h b/sysdeps/generic/sys/swap.h new file mode 100644 index 0000000000..17003a8d8e --- /dev/null +++ b/sysdeps/generic/sys/swap.h @@ -0,0 +1,33 @@ +/* Calls to enable and disable swapping on specified locations. Unix version. +Copyright (C) 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef __SYS_SWAP_H + +#define __SYS_SWAP_H 1 +#include + + +/* Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user. */ +extern int swapon __P ((__const char *__path)); + +/* Stop using block special device PATH for swapping. */ +extern int swapoff __P ((__const char *__path)); + +#endif /* sys/swap.h */ diff --git a/sysdeps/unix/Dist b/sysdeps/unix/Dist index f3b02e6c60..9f4ecc4ffe 100644 --- a/sysdeps/unix/Dist +++ b/sysdeps/unix/Dist @@ -3,3 +3,4 @@ ioctls-tmpl.c ioctls.awk snarf-ioctls make_errlist.c mk-local_lim.c s-proto.S +make-syscalls.sh diff --git a/sysdeps/unix/sysv/linux/gnu/types.h b/sysdeps/unix/sysv/linux/gnu/types.h index 719d136e16..402df2aa4c 100644 --- a/sysdeps/unix/sysv/linux/gnu/types.h +++ b/sysdeps/unix/sysv/linux/gnu/types.h @@ -54,7 +54,6 @@ typedef __kernel_nlink_t __nlink_t; /* Type of file link counts. */ typedef __kernel_off_t __off_t; /* Type of file sizes and offsets. */ typedef __kernel_pid_t __pid_t; /* Type of process identifications. */ typedef __kernel_ssize_t __ssize_t; /* Type of a byte count, or error. */ -#define __kernel_fsid_t long long /* XXX */ typedef __kernel_fsid_t __fsid_t; /* Type of file system IDs. */ /* Everythin' else. */ diff --git a/sysdeps/unix/sysv/linux/sys/swap.h b/sysdeps/unix/sysv/linux/sys/swap.h new file mode 100644 index 0000000000..f454c8c9f0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sys/swap.h @@ -0,0 +1,37 @@ +/* Calls to enable and disable swapping on specified locations. Linux version. +Copyright (C) 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef __SYS_SWAP_H + +#define __SYS_SWAP_H 1 +#include + +/* Get constants from kernel headers. */ +#include + + +/* Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user. */ +extern int swapon __P ((__const char *__path, int __flags)); + +/* Stop using block special device PATH for swapping. */ +extern int swapoff __P ((__const char *__path)); + + +#endif /* sys/swap.h */