diff options
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | dlfcn/Makefile | 5 | ||||
-rw-r--r-- | elf/Versions | 3 | ||||
-rw-r--r-- | elf/dl-misc.c | 241 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 66 |
5 files changed, 257 insertions, 95 deletions
@@ -1,5 +1,42 @@ 2001-02-27 Ulrich Drepper <drepper@redhat.com> + * elf/Versions [ld]: Don't export _dl_debug_message anymore. Export + _dl_debug_printf. + * elf/dl-misc.c: Remove definition of _dl_sysdep_output and + _dl_debug_message. Define _dl_debug_vdprintf, _dl_debug_printf, + _dl_debug_printf_c, and _dl_printf. + * sysdeps/generic/ldsodefs.h: Don't declare _dl_sysdep_output, + _dl_debug_message, _dl_sysdep_message, _dl_sysdep_error, and + _dl_sysdep_fatal. Declare _dl_debug_printf, _dl_debug_printf_c, + _dl_printf, _dl_error_printf, and _dl_fatal_printf. + * elf/dl-close.c: Replace use of old output functions with the new + ones. + * elf/dl-deps.c: Likewise. + * elf/dl-error.c: Likewise. + * elf/dl-fini.c: Likewise. + * elf/dl-init.c: Likewise. + * elf/dl-load.c: Likewise. + * elf/dl-lookup.c: Likewise. + * elf/dl-minimal.c: Likewise. + * elf/dl-open.c: Likewise. + * elf/dl-profile.c: Likewise. + * elf/dl-reloc.c: Likewise. + * elf/dl-version.c: Likewise. + * elf/do-lookup.h: Likewise. + * elf/rtld.c: Likewise. + * sysdeps/generic/dl-cache.c: Likewise. + * sysdeps/generic/dl-sysdep.c: Likewise. + * sysdeps/generic/libc-start.c: Likewise. + * sysdeps/i386/dl-machine.h: Likewise. + * sysdeps/unix/sysv/linux/dl-osinfo.h: Likewise. + * sysdeps/unix/sysv/linux/i386/dl-librecon.h: Likewise. + * sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Likewise. + + * sysdeps/generic/ldsodefs.h: Remove _dl_secure declaration. + + * dlfcn/Makefile: Don't run tstatexit test unless .hidden is + supported by assembler. + * sysdeps/generic/ldsodefs.h: Remove commented-out variable declaractions. diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 87dc60a1b2..65694165e6 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -35,7 +35,10 @@ endif libdl-shared-only-routines += eval ifeq (yes,$(build-shared)) -tests = glrefmain failtest tst-dladdr default errmsg1 tstatexit tstcxaatexit +tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit +ifeq (yes,$(have-protected)) +tests += tstatexit +endif endif modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \ errmsg1mod modatexit modcxaatexit diff --git a/elf/Versions b/elf/Versions index 0ad831fe0d..b72cedbcef 100644 --- a/elf/Versions +++ b/elf/Versions @@ -30,7 +30,6 @@ ld { _dl_sysdep_start; _r_debug; _dl_global_scope; _dl_lookup_symbol_skip; _dl_lookup_versioned_symbol; _dl_lookup_versioned_symbol_skip; - _dl_debug_message; # Function from libc.so which must be shared with libc. calloc; free; malloc; realloc; @@ -62,6 +61,6 @@ ld { _dl_clktck; _dl_pagesize; } GLIBC_2.2.3 { - _dl_debug_mask; + _dl_debug_mask; _dl_debug_printf; } } diff --git a/elf/dl-misc.c b/elf/dl-misc.c index 5629c2aa82..69b714f76c 100644 --- a/elf/dl-misc.c +++ b/elf/dl-misc.c @@ -1,5 +1,5 @@ /* Miscellaneous support functions for dynamic linker - Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2001 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 @@ -20,12 +20,16 @@ #include <assert.h> #include <fcntl.h> #include <ldsodefs.h> +#include <limits.h> #include <link.h> #include <stdarg.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> +#include <sys/param.h> #include <sys/stat.h> +#include <sys/uio.h> #include <stdio-common/_itoa.h> #ifndef MAP_ANON @@ -82,71 +86,190 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) int _dl_debug_fd = 2; -void -_dl_sysdep_output (int fd, const char *msg, ...) +/* Bare-bone printf implementation. This function only knows about + the formats and flags needed and can handle only up to 64 stripes in + the output. */ +static void +_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) { - va_list ap; + const int niovmax = 64; + struct iovec iov[niovmax]; + int niov = 0; + pid_t pid = 0; + char pidbuf[7]; - va_start (ap, msg); - do + while (*fmt != '\0') { - size_t len = strlen (msg); - __libc_write (fd, msg, len); - msg = va_arg (ap, const char *); + const char *startp = fmt; + + if (tag_p > 0) + { + /* Generate the tag line once. It consists of the PID and a + colon followed by a tab. */ + if (pid == 0) + { + char *p; + pid = __getpid (); + assert (pid >= 0 && pid < 100000); + p = _itoa_word (pid, &pidbuf[5], 10, 0); + while (p > pidbuf) + *--p = '0'; + pidbuf[5] = ':'; + pidbuf[6] = '\t'; + } + + /* Append to the output. */ + assert (niov < niovmax); + iov[niov].iov_len = 7; + iov[niov++].iov_base = pidbuf; + + /* No more tags until we see the next newline. */ + tag_p = -1; + } + + /* Skip everything except % and \n (if tags are needed). */ + while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) + ++fmt; + + /* Append constant string. */ + assert (niov < niovmax); + if ((iov[niov].iov_len = fmt - startp) != 0) + iov[niov++].iov_base = (char *) startp; + + if (*fmt == '%') + { + /* It is a format specifier. */ + char fill = ' '; + int width = -1; +#if LONG_MAX != INT_MAX + int long_mod = 0; +#endif + + /* Recognize zero-digit fill flag. */ + if (*++fmt == '0') + { + fill = '0'; + ++fmt; + } + + /* See whether with comes from a parameter. Note that no other + way to specify the width is implemented. */ + if (*fmt == '*') + { + width = va_arg (arg, int); + ++fmt; + } + + /* Recognize the l modifier. It is only important on some + platforms where long and int have a different size. We + can use the same code for size_t. */ + if (*fmt == 'l' || *fmt == 'Z') + { +#if LONG_MAX != INT_MAX + long_mod = 1; +#endif + ++fmt; + } + + switch (*fmt) + { + /* Integer formatting. */ + case 'u': + case 'x': + { + /* We have to make a difference if long and int have a + different size. */ +#if LONG_MAX != INT_MAX + unsigned long int num = (long_mod + ? va_arg (arg, unsigned long int); + : va_arg (arg, unsigned int)); +#else + unsigned long int num = va_arg (arg, unsigned int); +#endif + /* We use alloca() to allocate the buffer with the most + pessimistic guess for the size. Using alloca() allows + having more than one integer formatting in a call. */ + char *buf = (char *) alloca (3 * sizeof (unsigned long int)); + char *endp = &buf[3 * sizeof (unsigned long int)]; + char *cp = _itoa_word (num, endp, *fmt == 'x' ? 16 : 10, 0); + + /* Pad to the width the user specified. */ + if (width != -1) + while (endp - cp < width) + *--cp = fill; + + iov[niov].iov_base = cp; + iov[niov].iov_len = endp - cp; + ++niov; + } + break; + + case 's': + /* Get the string argument. */ + iov[niov].iov_base = va_arg (arg, char *); + iov[niov].iov_len = strlen (iov[niov].iov_base); + ++niov; + break; + + default: + assert (! "invalid format specifier"); + } + ++fmt; + } + else if (*fmt == '\n') + { + /* See whether we have to print a single newline character. */ + if (fmt == startp) + { + iov[niov].iov_base = (char *) startp; + iov[niov++].iov_len = 1; + } + else + /* No, just add it to the rest of the string. */ + ++iov[niov - 1].iov_len; + + /* Next line, print a tag again. */ + tag_p = 1; + ++fmt; + } } - while (msg != NULL); - va_end (ap); + + /* Finally write the result. */ + __writev (fd, iov, niov); } +/* Write to debug file. */ void -_dl_debug_message (int new_line, const char *msg, ...) +_dl_debug_printf (const char *fmt, ...) { - /* We print the strings we get passed one after the other but start all - lines using the current PID. */ - int pid = 0; - va_list ap; - - va_start (ap, msg); - do - if (msg[0] == '\0') - /* Get the next argument. */ - msg = va_arg (ap, const char *); - else - { - const char *endp; - - /* We actually will print something in this line. So print the - PID now if needed. */ - if (new_line) - { - char buf[7]; - char *p; - if (pid == 0) - pid = __getpid (); - assert (pid >= 0 && pid < 100000); - p = _itoa_word (pid, &buf[5], 10, 0); - while (p > buf) - *--p = '0'; - buf[5] = ':'; - buf[6] = '\t'; - __libc_write (_dl_debug_fd, buf, 7); - new_line = 0; - } - - endp = msg + strcspn (msg, "\n"); - if (*endp == '\0') - { - __libc_write (_dl_debug_fd, msg, endp - msg); - msg = va_arg (ap, const char *); - } - else - { - __libc_write (_dl_debug_fd, msg, endp - msg + 1); - msg = endp + 1; - new_line = 1; - } - } - while (msg != NULL); - va_end (ap); + va_list arg; + + va_start (arg, fmt); + _dl_debug_vdprintf (_dl_debug_fd, 1, fmt, arg); + va_end (arg); +} + + +/* Write to debug file but don't start with a tag. */ +void +_dl_debug_printf_c (const char *fmt, ...) +{ + va_list arg; + + va_start (arg, fmt); + _dl_debug_vdprintf (_dl_debug_fd, -1, fmt, arg); + va_end (arg); +} + + +/* Write the given file descriptor. */ +void +_dl_dprintf (int fd, const char *fmt, ...) +{ + va_list arg; + + va_start (arg, fmt); + _dl_debug_vdprintf (fd, 0, fmt, arg); + va_end (arg); } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 699e490ece..0575eaf9a9 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -225,45 +225,45 @@ extern struct r_search_path_elem *_dl_init_all_dirs; /* OS-dependent function to open the zero-fill device. */ extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ -/* OS-dependent function to write a message on the specified - descriptor FD. All arguments are `const char *'; args until a null - pointer are concatenated to form the message to print. */ -extern void _dl_sysdep_output (int fd, const char *string, ...); - -/* OS-dependent function to write a debug message on the specified - descriptor for this. All arguments are `const char *'; args until - a null pointer are concatenated to form the message to print. If - NEW_LINE is nonzero it is assumed that the message starts on a new - line. */ -extern void _dl_debug_message (int new_line, const char *string, ...); - -/* OS-dependent function to write a message on the standard output. - All arguments are `const char *'; args until a null pointer - are concatenated to form the message to print. */ -#define _dl_sysdep_message(string, args...) \ - _dl_sysdep_output (STDOUT_FILENO, string, ##args) - -/* OS-dependent function to write a message on the standard error. - All arguments are `const char *'; args until a null pointer - are concatenated to form the message to print. */ -#define _dl_sysdep_error(string, args...) \ - _dl_sysdep_output (STDERR_FILENO, string, ##args) - -/* OS-dependent function to give a fatal error message and exit - when the dynamic linker fails before the program is fully linked. - All arguments are `const char *'; args until a null pointer - are concatenated to form the message to print. */ -#define _dl_sysdep_fatal(string, args...) \ + +/* Write message on the debug file descriptor. The parameters are + interpreted as for a `printf' call. All the lines start with a + tag showing the PID. */ +extern void _dl_debug_printf (const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + +/* Write message on the debug file descriptor. The parameters are + interpreted as for a `printf' call. All the lines buf the first + start with a tag showing the PID. */ +extern void _dl_debug_printf_c (const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + + +/* Write a message on the specified descriptor FD. The parameters are + interpreted as for a `printf' call. */ +extern void _dl_dprintf (int fd, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + +/* Write a message on the specified descriptor standard output. The + parameters are interpreted as for a `printf' call. */ +#define _dl_printf(fmt, args...) \ + _dl_dprintf (STDOUT_FILENO, fmt, ##args) + +/* Write a message on the specified descriptor standard error. The + parameters are interpreted as for a `printf' call. */ +#define _dl_error_printf(fmt, args...) \ + _dl_dprintf (STDERR_FILENO, fmt, ##args) + +/* Write a message on the specified descriptor standard error and exit + the program. The parameters are interpreted as for a `printf' call. */ +#define _dl_fatal_printf(fmt, args...) \ do \ { \ - _dl_sysdep_output (STDERR_FILENO, string, ##args); \ + _dl_dprintf (STDERR_FILENO, fmt, ##args); \ _exit (127); \ } \ while (1) -/* Nonzero if the program should be "secure" (i.e. it's setuid or somesuch). - This tells the dynamic linker to ignore environment variables. */ -extern int _dl_secure; /* This function is called by all the internal dynamic linker functions when they encounter an error. ERRCODE is either an `errno' code or |