diff options
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | Makerules | 23 | ||||
-rw-r--r-- | elf/Makefile | 5 | ||||
-rw-r--r-- | elf/sofini.c | 9 | ||||
-rw-r--r-- | elf/soinit.c | 38 | ||||
-rw-r--r-- | misc/syslog.c | 89 | ||||
-rw-r--r-- | sysdeps/i386/init-first.c | 45 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/init-first.c | 4 | ||||
-rw-r--r-- | sysdeps/stub/sys/ipc_buf.h | 3 | ||||
-rw-r--r-- | sysdeps/stub/sys/sem_buf.h | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/fpu_control.h | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/init-first.S | 84 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/init-first.c | 72 | ||||
-rw-r--r-- | sysvipc/sys/shm.h | 2 |
14 files changed, 260 insertions, 160 deletions
@@ -1,3 +1,36 @@ +Thu Sep 21 00:03:53 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/stub/sys/sem_buf.h (union semun): New type. + + * sysdeps/mach/hurd/i386/init-first.c (init1) [PIC]: Call + __libc_global_ctors. + * sysdeps/i386/init-first.c: Rewritten. + * sysdeps/unix/sysv/linux/i386/init-first.S: File removed. + * sysdeps/unix/sysv/linux/i386/init-first.c: New file. + + * sysdeps/unix/sysv/linux/i386/fpu_control.h: Fix name in decl of + ___fpu_control. + + * Makerules (build-shlib): New canned sequence, broken out of + lib%.so rule. Link in $^ instead of just $<. + (lib%.so: lib%_pic.a): Use it. + (libc.so): New target; use $(build-shlib) for cmds, but also depend + on soinit.so first and sofini.so last. + + * elf/soinit.c: New file. + * elf/sofini.c: New file. + * elf/Makefile (distribute): Add soinit.c and sofini.c. + (extra-objs): Add soinit.so and sofini.so. + + * sysvipc/sys/shm.h (shmat): Fix return type to char *. + * sysdeps/stub/sys/ipc_buf.h (key_t): Type removed. + + * misc/syslog.c (vsyslog): Rewritten using open_memstream to + dynamically allocate buffers. + + * Makerules (install-lib-nosubdir): Make this, rather than + install-no-libc.a, depend on the installed shared libraries. + Wed Sep 20 18:02:03 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * locale/locale.c: Include errno.h. @@ -476,7 +476,7 @@ install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so)) install-lib := $(filter-out %.so,$(install-lib)) ifeq (yes,$(build-shared)) install: $(libdir)/libc.so$(libc.so-version) -install-no-libc.a: $(foreach so,$(install-lib.so),\ +install-lib-nosubdir: $(foreach so,$(install-lib.so),\ $(libdir)/$(patsubst $(libprefix)lib%,lib$(libprefix)%,\ $(libprefix)$(so))$($(so)-version)) @@ -550,12 +550,15 @@ ifeq (yes,$(build-shared)) # build shared libraries in place from the installed *_pic.a files. # $(LDLIBS-%.so) may contain -l switches to generate run-time dependencies # on other shared objects. -lib%.so: lib%_pic.a - $(LINK.o) -shared -o $@ -Wl,-soname \ - -Wl,lib$(libprefix)$(notdir $*).so$($(@F)-version) \ - $(LDFLAGS.so) $(LDFLAGS-$(notdir $*).so) \ - -L$(firstword $(objdir) .) -L$(common-objpfx:%/=%) \ - $(LDLIBS-$(notdir $*).so) -Wl,--whole-archive $< \ +lib%.so: lib%_pic.a; $(build-shlib) + +define build-shlib +$(LINK.o) -shared -o $@ -Wl,-soname \ + -Wl,lib$(libprefix)$(notdir $*).so$($(@F)-version) \ + $(LDFLAGS.so) $(LDFLAGS-$(notdir $*).so) \ + -L$(firstword $(objdir) .) -L$(common-objpfx:%/=%) \ + -Wl,--whole-archive $^ $(LDLIBS-$(notdir $*).so) +endef # Don't try to use -lc when making libc.so itself. # Also omits crti.o and crtn.o, which we do not want @@ -563,6 +566,12 @@ lib%.so: lib%_pic.a LDFLAGS-c.so = -nostdlib -nostartfiles # Give libc.so an entry point and make it directly runnable itself. LDFLAGS-c.so += -Wl,-dynamic-linker -Wl,/lib/ld.so -e __libc_print_version +# Use our own special initializer and finalizer files for libc.so. +elfobjdir := $(firstword $(objdir) $(..)elf) +$(common-objpfx)libc.so: $(elfobjdir)/soinit.so \ + $(common-objpfx)libc_pic.a \ + $(elfobjdir)/sofini.so + $(build-shlib) endif diff --git a/elf/Makefile b/elf/Makefile index b0923b2..0065d2b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -31,12 +31,13 @@ LDFLAGS-dl.so := -e 0 # work around ld bug rtld-routines := rtld $(addprefix dl-,load lookup object reloc \ runtime sysdep error init fini) -distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h +distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h \ + soinit.c sofini.c include ../Makeconfig ifeq (yes,$(build-shared)) -extra-objs = $(rtld-routines:=.so) +extra-objs = $(rtld-routines:=.so) soinit.so sofini.so install-lib = ld.so endif diff --git a/elf/sofini.c b/elf/sofini.c new file mode 100644 index 0000000..e44041b --- /dev/null +++ b/elf/sofini.c @@ -0,0 +1,9 @@ +/* Finalizer module for ELF shared C library. This provides terminating + null pointer words in the `.ctors' and `.dtors' sections. */ + +static void (*const __CTOR_END__[1]) (void) + __attribute__ ((unused, section (".ctors"))) + = { 0 }; +static void (*const __DTOR_END__[1]) (void) + __attribute__ ((unused, section (".dtors"))) + = { 0 }; diff --git a/elf/soinit.c b/elf/soinit.c new file mode 100644 index 0000000..0310b74 --- /dev/null +++ b/elf/soinit.c @@ -0,0 +1,38 @@ +/* Initializer module for building the ELF shared C library. This file and + sofini.c do the work normally done by crtbeginS.o and crtendS.o, to wrap + the `.ctors' and `.dtors' sections so the lists are terminated, and + calling those lists of functions. */ + +static void (*const __CTOR_LIST__[1]) (void) + __attribute__ ((section (".ctors"))) + = { (void (*) (void)) -1 }; +static void (*const __DTOR_LIST__[1]) (void) + __attribute__ ((section (".dtors"))) + = { (void (*) (void)) -1 }; + +static inline void +run_hooks (void (*const list[]) (void)) +{ + while (*++list) + (**list) (); +} + + +/* This function will be called from _init in init-first.c. */ +void +__libc_global_ctors (void) +{ + /* Call constructor functions. */ + run_hooks (__CTOR_LIST__); +} + + +/* This function becomes the DT_FINI termination function + for the C library. */ +void _fini (void) __attribute__ ((section (".fini"))); /* Just for kicks. */ +void +_fini (void) +{ + /* Call destructor functions. */ + run_hooks (__DTOR_LIST__); +} diff --git a/misc/syslog.c b/misc/syslog.c index ba82e23..ba994ee 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -48,6 +48,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; #include <string.h> #include <time.h> #include <unistd.h> +#include <stdlib.h> #if __STDC__ #include <stdarg.h> @@ -94,11 +95,12 @@ vsyslog(pri, fmt, ap) register const char *fmt; va_list ap; { - register int cnt; - register char ch, *p, *t; time_t now; - int fd, saved_errno; - char *stdp, tbuf[2048], fmt_cpy[1024]; + int fd; + FILE *f; + char *buf = 0; + size_t bufsize = 0; + size_t prioff, msgoff; #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID /* Check for invalid bits. */ @@ -112,51 +114,42 @@ vsyslog(pri, fmt, ap) if (!LOG_MASK(LOG_PRI(pri)) & LogMask) return; - saved_errno = errno; - /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) pri |= LogFacility; - /* Build the message. */ - (void)time(&now); - p = tbuf + sprintf(tbuf, "<%d>", pri); - p += strftime(p, sizeof (tbuf) - (p - tbuf), "%h %e %T ", - localtime(&now)); - if (LogStat & LOG_PERROR) - stdp = p; + /* Build the message in a memory-buffer stream. */ + f = open_memstream (&buf, &bufsize); + prioff = fprintf (f, "<%d>", pri); + (void) time (&now); + f->__bufp += strftime (f->__bufp, f->__put_limit - f->__bufp, + "%h %e %T ", localtime (&now)); + msgoff = ftell (f); if (LogTag == NULL) - LogTag = __progname; + LogTag = __progname; if (LogTag != NULL) - p += sprintf(p, "%s", LogTag); + fputs (LogTag, f); if (LogStat & LOG_PID) - p += sprintf(p, "[%d]", getpid()); - if (LogTag != NULL) { - *p++ = ':'; - *p++ = ' '; - } + fprintf (f, "[%d]", getpid ()); + if (LogTag != NULL) + putc (':', f), putc (' ', f); - /* Substitute error message for %m. */ - for (t = fmt_cpy; ch = *fmt; ++fmt) - if (ch == '%' && fmt[1] == 'm') { - ++fmt; - t += sprintf(t, "%s", strerror(saved_errno)); - } else - *t++ = ch; - *t = '\0'; + /* We have the header. Print the user's format into the buffer. */ + vfprintf (f, fmt, ap); - p += vsprintf(p, fmt_cpy, ap); - cnt = p - tbuf; + /* Close the memory stream; this will finalize the data + into a malloc'd buffer in BUF. */ + fclose (f); /* Output to stderr if requested. */ if (LogStat & LOG_PERROR) { struct iovec iov[2]; register struct iovec *v = iov; - v->iov_base = stdp; - v->iov_len = cnt - (stdp - tbuf); + v->iov_base = buf + msgoff; + v->iov_len = bufsize - msgoff; ++v; - v->iov_base = "\n"; + v->iov_base = (char *) "\n"; v->iov_len = 1; (void)writev(STDERR_FILENO, iov, 2); } @@ -164,22 +157,22 @@ vsyslog(pri, fmt, ap) /* Get connected, output the message to the local logger. */ if (!connected) openlog(LogTag, LogStat | LOG_NDELAY, 0); - if (send(LogFile, tbuf, cnt, 0) >= 0) - return; - - /* - * Output the message to the console; don't worry about blocking, - * if console blocks everything will. Make sure the error reported - * is the one from the syslogd failure. - */ - if (LogStat & LOG_CONS && - (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { - (void)strcat(tbuf, "\r\n"); - cnt += 2; - p = index(tbuf, '>') + 1; - (void)write(fd, p, cnt - (p - tbuf)); + if (send(LogFile, buf, bufsize, 0) < 0) + { + /* + * Output the message to the console; don't worry about blocking, + * if console blocks everything will. Make sure the error reported + * is the one from the syslogd failure. + */ + if (LogStat & LOG_CONS && + (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) + { + dprintf (fd, "%s\r\n", buf + msgoff); (void)close(fd); - } + } + } + + free (buf); } static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ diff --git a/sysdeps/i386/init-first.c b/sysdeps/i386/init-first.c index aa36732..792702e 100644 --- a/sysdeps/i386/init-first.c +++ b/sysdeps/i386/init-first.c @@ -20,26 +20,45 @@ Cambridge, MA 02139, USA. */ #include <unistd.h> extern void __libc_init (int, char **, char **); +extern void __libc_global_ctors (void); + + +static void +init (int *data) +{ + int argc = *data; + char **argv = (void *) (data + 1); + char **envp = &argv[argc + 1]; + + __environ = envp; + __libc_init (argc, argv, envp); +} #ifdef PIC -static void soinit (int argc, char *arg0, ...) - __attribute__ ((unused, section (".init"))); +/* This function is called to initialize the shared C library. + It is called just before the user _start code from i386/elf/start.S, + with the stack set up as that code gets it. */ + +/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT + pointer in the dynamic section based solely on that. It is convention + for this function to be in the `.init' section, but the symbol name is + the only thing that really matters!! */ +/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ void -__libc_init_first (void) +_init (int argc, ...) { + init (&argc); + + __libc_global_ctors (); } #endif -#ifdef PIC -static void soinit -#else -void __libc_init_first -#endif -(int argc, char *arg0, ...) -{ - char **argv = &arg0, **envp = &argv[argc + 1]; - __environ = envp; - __libc_init (argc, argv, envp); +void +__libc_init_first (int argc __attribute__ ((unused)), ...) +{ +#ifndef PIC + init (&argc); +#endif } diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index a23d201..ba39a70 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -27,6 +27,7 @@ Cambridge, MA 02139, USA. */ extern void __mach_init (void); extern void __libc_init (int, char **, char **); +extern void __libc_global_ctors (void); void *(*_cthread_init_routine) (void); /* Returns new SP to use. */ void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__)); @@ -93,6 +94,9 @@ init1 (int argc, char *arg0, ...) d->intarray, d->intarraysize); __libc_init (argc, argv, __environ); +#ifdef PIC + __libc_global_ctors (); +#endif } static void diff --git a/sysdeps/stub/sys/ipc_buf.h b/sysdeps/stub/sys/ipc_buf.h index fc2ad03..d62d2c1 100644 --- a/sysdeps/stub/sys/ipc_buf.h +++ b/sysdeps/stub/sys/ipc_buf.h @@ -36,9 +36,6 @@ Boston, MA 02111-1307, USA. */ __BEGIN_DECLS -/* Data type for key value. */ -typedef int key_t; - /* Special key values. */ #define IPC_PRIVATE ((key_t) 0) /* private key */ diff --git a/sysdeps/stub/sys/sem_buf.h b/sysdeps/stub/sys/sem_buf.h index b301525..194eb14 100644 --- a/sysdeps/stub/sys/sem_buf.h +++ b/sysdeps/stub/sys/sem_buf.h @@ -47,6 +47,15 @@ struct semid_ds unsigned short int sem_nsems; /* number of semaphores in set */ }; +/* Union used for argument for `semctl'. */ +union semun +{ + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + unsigned short int *array; /* array for GETALL & SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ + }; + __END_DECLS #endif /* sys/sem_buf.h */ diff --git a/sysdeps/unix/sysv/linux/i386/fpu_control.h b/sysdeps/unix/sysv/linux/i386/fpu_control.h index 28f3eeb..470e960 100644 --- a/sysdeps/unix/sysv/linux/i386/fpu_control.h +++ b/sysdeps/unix/sysv/linux/i386/fpu_control.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Olaf Flebbe. @@ -88,7 +88,7 @@ Boston, MA 02111-1307, USA. */ #define _FPU_IEEE 0x137f /* private namespace. It should only be used in init-first.o. */ -extern unsigned short __fpu_control; +extern unsigned short ___fpu_control; __BEGIN_DECLS diff --git a/sysdeps/unix/sysv/linux/i386/init-first.S b/sysdeps/unix/sysv/linux/i386/init-first.S deleted file mode 100644 index 3c0c185..0000000 --- a/sysdeps/unix/sysv/linux/i386/init-first.S +++ /dev/null @@ -1,84 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. - For i386/Linux. -Copyright (C) 1995 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. */ - -#include <sysdep.h> - - .text - - /* Called from start.S. Not: there is no value in %ebx. */ - -ENTRY (__libc_init_first) - - /* Make sure we are not using iBSC2 personality. */ - movl $SYS_ify (personality), %eax - xorl %ebx, %ebx - int $0x80 - -#ifdef PIC - /* Set control work of FPU. */ - call .L0 -.L0: popl %ebx - addl $_GLOBAL_OFFSET_TABLE_+[.-.L0], %ebx - movzwl C_SYMBOL_NAME(___fpu_control@GOT)(%ebx), %eax -#else - movzwl ___fpu_control, %eax -#endif - pushl %eax - call JUMPTARGET(__setfpucw) - addl $4, %esp - - /* That is all for now. */ - ret - - - /* This is only a dummy function for the list below. */ - .type _dummy_exit, @function -C_LABEL(_dummy_exit) - ret - - - .section .init,"ax",@progbits - movl 16(%ebp), %edx /* envp */ - movl 12(%ebp), %ecx /* argv */ - movl 8(%ebp), %eax /* argc */ - pushl %edx - pushl %ecx - pushl %eax - - call JUMPTARGET(__libc_init) - - addl $12, %esp - - - /* Make sure __libc_subinit section is always present. */ - .section __libc_subinit, "a", @progbits - .align 4 - .type __elf_set___libc_subinit_element__dummy_exit__, @object - .size __elf_set___libc_subinit_element__dummy_exit__, 4 -__elf_set___libc_subinit_element__dummy_exit__: - .long _dummy_exit - - /* Make sure __libc_atexit section is always present. */ - .section __libc_atexit, "a", @progbits - .align 4 - .type __elf_set___libc_atexit_element__dummy_exit__, @object - .size __elf_set___libc_atexit_element__dummy_exit__, 4 -__elf_set___libc_atexit_element__dummy_exit__: - .long _dummy_exit diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c new file mode 100644 index 0000000..0177daa --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/init-first.c @@ -0,0 +1,72 @@ +/* Initialization code run first thing by the ELF startup code. i386/Linux +Copyright (C) 1995 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 <unistd.h> +#include "fpu_control.h" + +extern void __libc_init (int, char **, char **); +extern void __libc_global_ctors (void); + + +static void +init (int *data) +{ + int argc = *data; + char **argv = (void *) (data + 1); + char **envp = &argv[argc + 1]; + + /* Make sure we are not using iBSC2 personality. */ + asm ("int $0x80 # syscall no %0, arg %1" + : : "a" (SYS_ify (personality)), "b" (0)); + + /* Set the FPU control word to the proper default value. */ + __setfpucw (___fpu_control); + + __environ = envp; + __libc_init (argc, argv, envp); +} + +#ifdef PIC +/* This function is called to initialize the shared C library. + It is called just before the user _start code from i386/elf/start.S, + with the stack set up as that code gets it. */ + +/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT + pointer in the dynamic section based solely on that. It is convention + for this function to be in the `.init' section, but the symbol name is + the only thing that really matters!! */ +/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ + +void +_init (int argc, ...) +{ + init (&argc); + + __libc_global_ctors (); +} +#endif + + +void +__libc_init_first (int argc __attribute__ ((unused)), ...) +{ +#ifndef PIC + init (&argc); +#endif +} diff --git a/sysvipc/sys/shm.h b/sysvipc/sys/shm.h index 11f9e7a..9ee61e4 100644 --- a/sysvipc/sys/shm.h +++ b/sysvipc/sys/shm.h @@ -46,7 +46,7 @@ extern int shmctl __P ((int __shmid, int __cmd, struct shmid_ds *__buf)); extern int shmget __P ((key_t __key, int __size, int __shmflg)); /* Attach shared memory segment. */ -extern int shmat __P ((int __shmid, char *__shmaddr, int __shmflg)); +extern char *shmat __P ((int __shmid, char *__shmaddr, int __shmflg)); /* Detach shared memory segment. */ extern int shmdt __P ((char *__shmaddr)); |