1998-03-06 17:04  Ulrich Drepper  <drepper@cygnus.com>

	* libc.map: Add _dl_debug_impcalls, _dl_debug_fd, _dl_sysdep_output,
	__libc_start_main.
	* csu/Makefile (routines): Add libc-start.
	* elf/dl-error.c: Remove declaration of _dl_argv.  Include <unitsd.h>.
	* elf/dl-lookup.c: Likewise.
	* elf/dl-version.c: Likewise.
	* sysdeps/i386/dl-machine.h: Likewise.
	* elf/link.h: Declare _dl_argv, _dl_debug_fd.
	Declare _dl_sysdep_output.  Make _dl_sysdep_fatal, _dl_sysdep_error and
	_dl_sysdep_message macros which use _dl_sysdep_output.
	* elf/dl-fini.c: Write out which destructor is called while debugging.
	* elf/dl-init.c: Likewise for constructor.
	* elf/dl-load.c: Use _dl_debug_message instead of _dl_sysdep_message.
	* elf/dl-misc.c: Remove _dl_sysdep_fatal, _dl_sysdep_error and
	_dl_sysdep_message.  Add _dl_sysdep_output.
	* elf/rtld.c: Recognize LD_DEBUG_OUTPUT.  Set _dl_debug_fd if
	this file can be opened.
	For LD_DEBUG=libs also set _dl_debug_impcalls.
	* sysdeps/generic/dl-cache.c: Include unistd.h.
	* sysdeps/generic/libc-start.c: New file.
	* sysdeps/i386/elf/start.S: Don't call main directly, call
	* sysdeps/unix/sysv/linux/libc-start.c: New file.
	__libc_start_main instead.

	* elf/Makefile ($(objpfx)ld.so): Add $(load-map-file) as dependency.
This commit is contained in:
Ulrich Drepper 1998-03-06 17:21:43 +00:00
parent 4b7814cf8a
commit 7dea968e78
18 changed files with 185 additions and 70 deletions

View File

@ -1,3 +1,31 @@
1998-03-06 17:04 Ulrich Drepper <drepper@cygnus.com>
* libc.map: Add _dl_debug_impcalls, _dl_debug_fd, _dl_sysdep_output,
__libc_start_main.
* csu/Makefile (routines): Add libc-start.
* elf/dl-error.c: Remove declaration of _dl_argv. Include <unitsd.h>.
* elf/dl-lookup.c: Likewise.
* elf/dl-version.c: Likewise.
* sysdeps/i386/dl-machine.h: Likewise.
* elf/link.h: Declare _dl_argv, _dl_debug_fd.
Declare _dl_sysdep_output. Make _dl_sysdep_fatal, _dl_sysdep_error and
_dl_sysdep_message macros which use _dl_sysdep_output.
* elf/dl-fini.c: Write out which destructor is called while debugging.
* elf/dl-init.c: Likewise for constructor.
* elf/dl-load.c: Use _dl_debug_message instead of _dl_sysdep_message.
* elf/dl-misc.c: Remove _dl_sysdep_fatal, _dl_sysdep_error and
_dl_sysdep_message. Add _dl_sysdep_output.
* elf/rtld.c: Recognize LD_DEBUG_OUTPUT. Set _dl_debug_fd if
this file can be opened.
For LD_DEBUG=libs also set _dl_debug_impcalls.
* sysdeps/generic/dl-cache.c: Include unistd.h.
* sysdeps/generic/libc-start.c: New file.
* sysdeps/i386/elf/start.S: Don't call main directly, call
* sysdeps/unix/sysv/linux/libc-start.c: New file.
__libc_start_main instead.
* elf/Makefile ($(objpfx)ld.so): Add $(load-map-file) as dependency.
1998-03-06 Ulrich Drepper <drepper@cygnus.com>
* nss/nsswitch.c (__nss_nscd_not_available): Removed.

View File

@ -27,7 +27,7 @@
subdir := csu
routines = init-first
routines = init-first libc-start
csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
extra-objs = start.o gmon-start.o \
$(start-installed-name) g$(start-installed-name) \

View File

@ -109,7 +109,7 @@ $(rtld-ldscript): $(rtld-ldscript-in) $(rtld-parms)
-e 's#@@rtld-base@@#$(rtld-base)#' $< >$@
endif
$(objpfx)ld.so: $(objpfx)librtld.os $(addprefix $(objpfx),$(rtld-ldscript))
$(objpfx)ld.so: $(objpfx)librtld.os $(addprefix $(objpfx),$(rtld-ldscript)) $(load-map-file)
$(rtld-link) -Wl,-soname=$(rtld-installed-name)
define rtld-link

View File

@ -1,5 +1,5 @@
/* Error handling for runtime dynamic linker.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998 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
@ -17,11 +17,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include <link.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* This is the internal function we use to generate the error string. */
extern char *_strerror_internal __P ((int, char *, size_t));
@ -76,7 +76,6 @@ _dl_signal_error (int errcode,
else
{
/* Lossage while resolving the program's own symbols is always fatal. */
extern char **_dl_argv; /* Set in rtld.c at startup. */
char buffer[1024];
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
": error in loading shared libraries: ",

View File

@ -1,5 +1,5 @@
/* Call the termination functions of loaded shared objects.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 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
@ -29,7 +29,15 @@ _dl_fini (void)
{
if (l->l_info[DT_FINI] &&
!(l->l_name[0] == '\0' && l->l_type == lt_executable))
(*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
{
/* When debugging print a message first. */
if (_dl_debug_impcalls)
_dl_debug_message ("\n\tcalling fini: ",
l->l_name[0] ? l->l_name : _dl_argv[0],
"\n", NULL);
(*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
}
/* Make sure nothing happens if we are called twice. */
l->l_init_called = 0;
}

View File

@ -1,5 +1,5 @@
/* Return the next shared object initializer function not yet run.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 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
@ -57,6 +57,13 @@ _dl_init_next (struct link_map *map)
{
/* Run this object's initializer. */
l->l_init_running = 1;
/* Print a debug message if wanted. */
if (_dl_debug_impcalls)
_dl_debug_message ("\tcalling init: ",
l->l_name[0] ? l->l_name : _dl_argv[0],
"\n\n", NULL);
return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
}

View File

@ -92,9 +92,6 @@ ELF_PREFERRED_ADDRESS_DATA;
size_t _dl_pagesize;
/* Arguments passed to the dynamic linker. */
extern char **_dl_argv;
extern const char *_dl_platform;
extern size_t _dl_platformlen;
@ -879,7 +876,7 @@ open_path (const char *name, size_t namelen, int preloaded,
/* Print name we try if this is wanted. */
if (_dl_debug_libs)
_dl_sysdep_message ("\t trying file=", buf, "\n", NULL);
_dl_debug_message ("\t trying file=", buf, "\n", NULL);
fd = __open (buf, O_RDONLY);
if (this_dir->machdirstatus == unknown)
@ -934,7 +931,7 @@ open_path (const char *name, size_t namelen, int preloaded,
/* Print name we try if this is wanted. */
if (_dl_debug_libs)
_dl_sysdep_message ("\t trying file=", buf, "\n", NULL);
_dl_debug_message ("\t trying file=", buf, "\n", NULL);
fd = __open (buf, O_RDONLY);
if (this_dir->dirstatus == unknown)
@ -1053,7 +1050,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
size_t namelen = strlen (name) + 1;
if (_dl_debug_libs)
_dl_sysdep_message ("\tfind library=", name, "; searching\n", NULL);
_dl_debug_message ("\tfind library=", name, "; searching\n", NULL);
fd = -1;
@ -1117,7 +1114,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
/* Add another newline when we a tracing the library loading. */
if (_dl_debug_libs)
_dl_sysdep_message ("\n", NULL);
_dl_debug_message ("\n", NULL);
}
else
{

View File

@ -280,7 +280,6 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
const struct r_found_version *version,
int reloc_type)
{
extern char **_dl_argv;
const unsigned long int hash = _dl_elf_hash (undef_name);
struct sym_val current_value = { 0, NULL };
struct link_map **scope;

View File

@ -74,8 +74,12 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
}
/* Descriptor to write debug messages to. */
int _dl_debug_fd;
void
_dl_sysdep_fatal (const char *msg, ...)
_dl_sysdep_output (int fd, const char *msg, ...)
{
va_list ap;
@ -83,41 +87,7 @@ _dl_sysdep_fatal (const char *msg, ...)
do
{
size_t len = strlen (msg);
__write (STDERR_FILENO, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);
_exit (127);
}
void
_dl_sysdep_error (const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
do
{
size_t len = strlen (msg);
__write (STDERR_FILENO, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);
}
void
_dl_sysdep_message (const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
do
{
size_t len = strlen (msg);
__write (STDOUT_FILENO, msg, len);
__write (fd, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);

View File

@ -1,5 +1,5 @@
/* Handle symbol and library versioning.
Copyright (C) 1997 Free Software Foundation, Inc.
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -28,9 +28,6 @@
#include <stdio-common/_itoa.h>
/* Set in rtld.c at startup. */
extern char **_dl_argv;
#define VERSTAG(tag) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))

View File

@ -231,6 +231,9 @@ typedef void (*receiver_fct) (int, const char *, const char *);
user interface to run-time dynamic linking. */
/* Parameters passed to te dynamic linker. */
extern char **_dl_argv;
/* Cached value of `getpagesize ()'. */
extern size_t _dl_pagesize;
@ -244,26 +247,48 @@ extern struct link_map *_dl_profile_map;
/* If nonzero the appropriate debug information if printed. */
extern int _dl_debug_libs;
extern int _dl_debug_impcalls;
/* File deccriptor to write debug messages to. */
extern int _dl_debug_fd;
/* 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. */
#define _dl_debug_message(string, args...) \
_dl_sysdep_output (_dl_debug_fd, string, ##args)
/* 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. */
extern void _dl_sysdep_message (const char *string, ...);
#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. */
extern void _dl_sysdep_error (const char *string, ...);
#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. */
extern void _dl_sysdep_fatal (const char *string, ...)
__attribute__ ((__noreturn__));
#define _dl_sysdep_fatal(string, args...) \
do \
{ \
_dl_sysdep_output (STDERR_FILENO, string, ##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. */

View File

@ -17,6 +17,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <fcntl.h>
#include <link.h>
#include <stddef.h>
#include <stdlib.h>
@ -74,6 +75,7 @@ const char *_dl_profile;
const char *_dl_profile_output;
struct link_map *_dl_profile_map;
int _dl_debug_libs;
int _dl_debug_impcalls;
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
@ -907,6 +909,9 @@ print_missing_version (int errcode __attribute__ ((unused)),
objname, ": ", errstring, "\n", NULL);
}
/* Nonzero if any of the debugging options is enabled. */
static int any_debug;
/* Process the string given as the parameter which explains which debugging
options are enabled. */
static void
@ -924,6 +929,8 @@ process_dl_debug (char *dl_debug)
&& (issep (dl_debug[4]) || dl_debug[4] == '\0'))
{
_dl_debug_libs = 1;
_dl_debug_impcalls = 1;
any_debug = 1;
dl_debug += 4;
}
else if (strncmp (dl_debug, "help", 4) == 0
@ -956,6 +963,7 @@ process_envvars (enum mode *modep, int *lazyp)
char *envline;
enum mode mode = normal;
int bind_now = 0;
char *debug_output = NULL;
/* This is the default place for profiling data file. */
_dl_profile_output = "/var/tmp";
@ -984,6 +992,16 @@ process_envvars (enum mode *modep, int *lazyp)
if (result < 0)
continue;
/* Where to place the profiling data file. */
result = strncmp (&envline[3], "DEBUG_OUTPUT=", 13);
if (result == 0)
{
debug_output = &envline[16];
continue;
}
if (result < 0)
continue;
/* Which shared object shall be profiled. */
result = strncmp (&envline[3], "PROFILE=", 8);
if (result == 0)
@ -1038,6 +1056,18 @@ process_envvars (enum mode *modep, int *lazyp)
}
}
/* If we have to run the dynamic linker in debugging mode and the
LD_DEBUG_OUTPUT environment variable is given, we write the debug
messages to this file. */
if (any_debug && debug_output != NULL)
{
_dl_debug_fd = __open (debug_output, O_WRONLY | O_APPEND | O_CREAT,
0666);
if (_dl_debug_fd == -1)
/* We use standard output if opening the file failed. */
_dl_debug_fd = STDOUT_FILENO;
}
/* LAZY is determined by the environment variable LD_WARN and
LD_BIND_NOW if we trace the binary. */
if (mode == trace)

View File

@ -11,7 +11,7 @@ GLIBC_2.0 {
__collate_element_strings; __collate_symbol_classes;
__collate_symbol_hash; __collate_symbol_strings;
_obstack;
__progname_full; __progname;
__progname_full; __progname; _dl_debug_impcalls; _dl_debug_fd;
_IO_list_all; _IO_stderr_; _IO_stdin_; _IO_stdout_;
@ -21,7 +21,7 @@ GLIBC_2.0 {
.div; .mul; .rem; .udiv; .umul; .urem;
# helper functions
__errno_location; __libc_init_first; __h_errno_location;
__errno_location; __libc_init_first; __h_errno_location; __libc_start_main;
# functions with special/multiple interfaces
__sigsetjmp; _setjmp; __sigaddset; __sigdelset; __sigismember;
@ -98,7 +98,7 @@ GLIBC_2.0 {
__vsscanf; __vfscanf; __vsnprintf;
_rpc_dtablesize; _null_auth; _seterr_reply;
__res_randomid; __getpid;
__strcasecmp; __write; _strerror_internal;
__strcasecmp; __write; _strerror_internal; _dl_sysdep_output;
# Exception handling support functions from libgcc
__register_frame; __register_frame_table; __deregister_frame;

View File

@ -18,7 +18,7 @@
Boston, MA 02111-1307, USA. */
#include <link.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/mman.h>
/* System-dependent function to read a file's whole contents

View File

@ -0,0 +1,24 @@
/* Copyright (C) 1998 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. */
int
__libc_start_main (int (*main) (int, char **, char **), int argc,
char **argv, char **envp)
{
return (*main) (argc, argv, envp);
}

View File

@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. i386 version.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998 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
@ -302,8 +302,6 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
#ifdef RESOLVE
extern char **_dl_argv;
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */

View File

@ -1,5 +1,5 @@
/* Startup code compliant to the ELF i386 ABI.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998 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
@ -88,9 +88,11 @@ _start:
call atexit
popl %eax
/* Call the user's main function, and exit with its value. */
call main
/* Call the user's main function, and exit with its value.
But let the libc call main. */
movl $main, %eax
pushl %eax
call __libc_start_main
call exit
hlt /* Crash if somehow `exit' does return. */

View File

@ -0,0 +1,31 @@
/* Copyright (C) 1998 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 <link.h>
int
__libc_start_main (int (*main) (int, char **, char **), int argc,
char **argv, char **envp)
{
#ifdef PIC
if (_dl_debug_impcalls)
_dl_debug_message ("\ttransferring control: ", argv[0], "\n\n", NULL);
#endif
return (*main) (argc, argv, envp);
}