summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--dlfcn/Makefile5
-rw-r--r--elf/Versions3
-rw-r--r--elf/dl-misc.c241
-rw-r--r--sysdeps/generic/ldsodefs.h66
5 files changed, 257 insertions, 95 deletions
diff --git a/ChangeLog b/ChangeLog
index 68029ec06b..8cb5df8393 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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