* 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.
This commit is contained in:
Ulrich Drepper 2001-02-28 06:24:03 +00:00
parent edd8e70fea
commit b5ba065963
5 changed files with 256 additions and 94 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}
}

View File

@ -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 *);
}
while (msg != NULL);
va_end (ap);
}
const char *startp = fmt;
void
_dl_debug_message (int new_line, const char *msg, ...)
{
/* 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)
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, &buf[5], 10, 0);
while (p > buf)
*--p = '0';
buf[5] = ':';
buf[6] = '\t';
__libc_write (_dl_debug_fd, buf, 7);
new_line = 0;
}
assert (pid >= 0 && pid < 100000);
p = _itoa_word (pid, &pidbuf[5], 10, 0);
while (p > pidbuf)
*--p = '0';
pidbuf[5] = ':';
pidbuf[6] = '\t';
}
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);
/* 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;
}
}
/* Finally write the result. */
__writev (fd, iov, niov);
}
/* Write to debug file. */
void
_dl_debug_printf (const char *fmt, ...)
{
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);
}

View File

@ -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, ...);
/* 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)));
/* 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)
/* 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)));
/* 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 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