mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 07:10:06 +00:00
Tue Nov 7 12:29:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/linux-compat.c: New file. * elf/Makefile (distribute): Add linux-compat.c. (generated): Add librtld.so. [$(config-os)=linux*] (extra-objs): Add linux-compat.so. [$(config-os)=linux*] (extra-objs): Add ld-linux.so.1. (librtld.so): New target. (ld.so, ld-linux.so.1): Make from librtld.so. * elf/rtld.c (dl_main): Instead of weak call to _dl_compat_init, call our own DT_INIT if we have one (and then clear it). (__dgettext): New weak function. * intl/localealias.c (read_alias_file): Avoid sprintf; use memcpy by hand instead. * sysdeps/generic/_strerror.c (_strerror_internal): Use _itoa instead of snprintf. * sysdeps/mach/_strerror.c (_strerror_internal): Don't write BUF[BUFLEN]. * elf/rtld.c (rtld_map): New static variable. (_dl_start): Use a differently named local BOOTSTRAP_MAP for the bootstrapping. Then copy data into `rtld_map'. (dl_main): Finish filling in rtld_map and link it into the chain, instead of allocating a new structure. (dl_main): Call _dl_compat_init if it is defined (use weak ref). * elf/dlsym.c: Fix last change: move REF out of `doit'. control. using it. and cwdir ports. functions. these. $(libdir)(rtld-installed-name). leading zeroes. in the rhs. pattern rule. never know. (fork): Use symbol_set_* macros for _hurd_fork_locks. * sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error): instead of unix/sysv. -dynamic-linker. (__printf_fp): Last arg ARGS is now `const void **const'; locale/C-ctype.c. * sysdeps/mach/hurd/sigsuspend.c: Likewise. * sysdeps/mach/hurd/mips/sigreturn.c: Likewise. alias gethostname. setitmr setpgrp (_S_msg_get_exec_flags, _S_msg_set_exec_flags, (abort_thread, abort_rpcs): Take same new arg and pass it through.
This commit is contained in:
parent
51093422b2
commit
86d2c878ac
32
ChangeLog
32
ChangeLog
@ -1,3 +1,35 @@
|
||||
Tue Nov 7 12:29:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* elf/linux-compat.c: New file.
|
||||
* elf/Makefile (distribute): Add linux-compat.c.
|
||||
(generated): Add librtld.so.
|
||||
[$(config-os)=linux*] (extra-objs): Add linux-compat.so.
|
||||
[$(config-os)=linux*] (extra-objs): Add ld-linux.so.1.
|
||||
(librtld.so): New target.
|
||||
(ld.so, ld-linux.so.1): Make from librtld.so.
|
||||
|
||||
* elf/rtld.c (dl_main): Instead of weak call to _dl_compat_init,
|
||||
call our own DT_INIT if we have one (and then clear it).
|
||||
(__dgettext): New weak function.
|
||||
|
||||
* intl/localealias.c (read_alias_file): Avoid sprintf; use memcpy
|
||||
by hand instead.
|
||||
|
||||
* sysdeps/generic/_strerror.c (_strerror_internal): Use _itoa
|
||||
instead of snprintf.
|
||||
|
||||
* sysdeps/mach/_strerror.c (_strerror_internal): Don't write
|
||||
BUF[BUFLEN].
|
||||
|
||||
* elf/rtld.c (rtld_map): New static variable.
|
||||
(_dl_start): Use a differently named local BOOTSTRAP_MAP for the
|
||||
bootstrapping. Then copy data into `rtld_map'.
|
||||
(dl_main): Finish filling in rtld_map and link it into the chain,
|
||||
instead of allocating a new structure.
|
||||
(dl_main): Call _dl_compat_init if it is defined (use weak ref).
|
||||
|
||||
* elf/dlsym.c: Fix last change: move REF out of `doit'.
|
||||
|
||||
Mon Nov 6 16:20:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dlsym.c: Return the proper value, not just the defining
|
||||
|
24
elf/Makefile
24
elf/Makefile
@ -31,24 +31,42 @@ libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared.
|
||||
rtld-routines := rtld $(addprefix dl-,load lookup object reloc \
|
||||
runtime sysdep error init fini)
|
||||
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h \
|
||||
soinit.c sofini.c ldd.sh.in
|
||||
soinit.c sofini.c ldd.sh.in linux-compat.c
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
extra-objs = $(rtld-routines:=.so) soinit.so sofini.so
|
||||
generated = librtld.so
|
||||
install-others = $(libdir)/$(rtld-installed-name)
|
||||
install-bin = ldd
|
||||
|
||||
ifneq (,$(filter linux%,$(config-os)))
|
||||
extra-objs += linux-compat.so
|
||||
install-lib += ld-linux.so.1
|
||||
endif
|
||||
endif
|
||||
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)ld.so: $(rtld-routines:%=$(objpfx)%.so) \
|
||||
|
||||
# Link together the dynamic linker into a single relocatable object.
|
||||
# We use this to produce both the ABI-compliant and Linux-compatible
|
||||
# dynamic linker shared objects below.
|
||||
$(objpfx)librtld.so: $(rtld-routines:%=$(objpfx)%.so) \
|
||||
$(patsubst %,$(common-objpfx)lib%_pic.a,\
|
||||
elf c $(LDLIBS-c.so:-l%=%))
|
||||
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
|
||||
$(LINK.o) -nostdlib -nostartfiles -r -o $@ \
|
||||
'-Wl,-(' $^ -lgcc '-Wl,-)'
|
||||
|
||||
$(objpfx)ld.so $(objpfx)ld-linux.so.1: $(objpfx)librtld.so
|
||||
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ $^
|
||||
|
||||
# The Linux-compatible dynamic linker shared object is just the same
|
||||
# with one object file of compatibility initialization code added.
|
||||
$(objpfx)ld-linux.so.1: $(objpfx)linux-compat.so
|
||||
|
||||
|
||||
$(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so
|
||||
$(patsubst %/,cd %;,$(objpfx)) \
|
||||
$(LINK.o) -shared -o $(@:$(objpfx)%=%) \
|
||||
|
@ -29,10 +29,10 @@ dlsym (void *handle, const char *name)
|
||||
struct link_map *map = handle;
|
||||
struct link_map *real_next;
|
||||
Elf32_Addr loadbase;
|
||||
const Elf32_Sym *ref = NULL;
|
||||
int lose;
|
||||
void doit (void)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
loadbase = _dl_lookup_symbol (name, &ref, map, map->l_name, 1);
|
||||
}
|
||||
|
||||
|
40
elf/linux-compat.c
Normal file
40
elf/linux-compat.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* Initializer for Linux-compatible dynamic linker `/lib/ld-linux.so.1'.
|
||||
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 <link.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This function will be the DT_INIT initializer for the ld-linux.so.1
|
||||
shared object. This is called from rtld.c before shlib initializers.
|
||||
|
||||
The old Linux ELF startup code expects the dynamic linker to magically
|
||||
call atexit to arrange for shared object finalizers to run. (The
|
||||
ABI-compliant startup code does this itself.) We build a compatible
|
||||
version of the dynamic linker to install as /lib/ld-linux.so.1, the
|
||||
name old Linux ELF binaries use. */
|
||||
|
||||
void
|
||||
_init (void)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, _dl_loaded,
|
||||
"<ld-linux.so.1 initialization>",
|
||||
1);
|
||||
(*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini);
|
||||
}
|
70
elf/rtld.c
70
elf/rtld.c
@ -50,22 +50,24 @@ static void dl_main (const Elf32_Phdr *phdr,
|
||||
Elf32_Word phent,
|
||||
Elf32_Addr *user_entry);
|
||||
|
||||
static struct link_map rtld_map;
|
||||
|
||||
Elf32_Addr
|
||||
_dl_start (void *arg)
|
||||
{
|
||||
struct link_map rtld_map;
|
||||
struct link_map bootstrap_map;
|
||||
|
||||
/* Figure out the run-time load address of the dynamic linker itself. */
|
||||
rtld_map.l_addr = elf_machine_load_address ();
|
||||
bootstrap_map.l_addr = elf_machine_load_address ();
|
||||
|
||||
/* Read our own dynamic section and fill in the info array.
|
||||
Conveniently, the first element of the GOT contains the
|
||||
offset of _DYNAMIC relative to the run-time load address. */
|
||||
rtld_map.l_ld = (void *) rtld_map.l_addr + *elf_machine_got ();
|
||||
elf_get_dynamic_info (rtld_map.l_ld, rtld_map.l_info);
|
||||
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + *elf_machine_got ();
|
||||
elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_info);
|
||||
|
||||
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||
ELF_MACHINE_BEFORE_RTLD_RELOC (rtld_map.l_info);
|
||||
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
|
||||
#endif
|
||||
|
||||
/* Relocate ourselves so we can do normal function calls and
|
||||
@ -77,8 +79,8 @@ _dl_start (void *arg)
|
||||
bootstrapping, so it must anti-perform each bootstrapping relocation
|
||||
before applying the final relocation when ld.so is linked in as
|
||||
normal a shared library. */
|
||||
rtld_map.l_type = lt_library;
|
||||
ELF_DYNAMIC_RELOCATE (&rtld_map, 0, NULL);
|
||||
bootstrap_map.l_type = lt_library;
|
||||
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, NULL);
|
||||
|
||||
|
||||
/* Now life is sane; we can call functions and access global data.
|
||||
@ -86,7 +88,12 @@ _dl_start (void *arg)
|
||||
the operating system's program loader where to find the program
|
||||
header table in core. */
|
||||
|
||||
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
|
||||
|
||||
/* Transfer data about ourselves to the permanent link_map structure. */
|
||||
rtld_map.l_addr = bootstrap_map.l_addr;
|
||||
rtld_map.l_ld = bootstrap_map.l_ld;
|
||||
memcpy (rtld_map.l_info, bootstrap_map.l_info, sizeof rtld_map.l_info);
|
||||
|
||||
|
||||
/* Call the OS-dependent function to set up life so we can do things like
|
||||
file access. It will call `dl_main' (below) to do all the real work
|
||||
@ -228,8 +235,14 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
will set up later to communicate with the debugger. */
|
||||
l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
|
||||
|
||||
l = _dl_new_object ((char *) interpreter_name, interpreter_name,
|
||||
lt_interpreter);
|
||||
/* Put the link_map for ourselves on the chain so it can be found by
|
||||
name. */
|
||||
rtld_map.l_name = (char *) rtld_map.l_libname = interpreter_name;
|
||||
rtld_map.l_type = lt_interpreter;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
l->l_next = &rtld_map;
|
||||
rtld_map.l_prev = l;
|
||||
|
||||
/* Now process all the DT_NEEDED entries and map in the objects.
|
||||
Each new link_map will go on the end of the chain, so we will
|
||||
@ -248,16 +261,13 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
l->l_deps_loaded = 1;
|
||||
}
|
||||
|
||||
l = _dl_loaded->l_next;
|
||||
while (l->l_type != lt_interpreter)
|
||||
l = l->l_next;
|
||||
if (l->l_opencount == 0)
|
||||
if (rtld_map.l_opencount == 0)
|
||||
{
|
||||
/* No DT_NEEDED entry referred to the interpreter object itself.
|
||||
Remove it from the maps we will use for symbol resolution. */
|
||||
l->l_prev->l_next = l->l_next;
|
||||
if (l->l_next)
|
||||
l->l_next->l_prev = l->l_prev;
|
||||
rtld_map.l_prev->l_next = rtld_map.l_next;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = rtld_map.l_prev;
|
||||
}
|
||||
|
||||
lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
||||
@ -276,6 +286,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
|
||||
dl_r_debug.r_map = _dl_loaded;
|
||||
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
|
||||
|
||||
@ -301,6 +312,19 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
if (rtld_map.l_info[DT_INIT])
|
||||
{
|
||||
/* Call the initializer for the compatibility version of the
|
||||
dynamic linker. There is no additional initialization
|
||||
required for the ABI-compliant dynamic linker. */
|
||||
|
||||
(*(void (*) (void)) (rtld_map.l_addr +
|
||||
rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
|
||||
|
||||
/* Clear the field so a future dlopen won't run it again. */
|
||||
rtld_map.l_info[DT_INIT] = NULL;
|
||||
}
|
||||
}
|
||||
const char *errstring;
|
||||
const char *errobj;
|
||||
@ -325,6 +349,18 @@ _dl_r_debug_state (void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define our own stub for the localization function used by strerror.
|
||||
English-only in the dynamic linker keeps it smaller. */
|
||||
|
||||
char *
|
||||
__dgettext (const char *domainname, const char *msgid)
|
||||
{
|
||||
assert (domainname == _libc_intl_domainname);
|
||||
return (char *) msgid;
|
||||
}
|
||||
weak_symbol (__dgettext)
|
||||
weak_alias (__dgettext, dgettext)
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/* Define (weakly) our own assert failure function which doesn't use stdio.
|
||||
|
@ -150,9 +150,11 @@ read_alias_file (fname, fname_len)
|
||||
FILE *fp;
|
||||
char *full_fname;
|
||||
size_t added;
|
||||
static const char aliasfile[] = "/locale.alias";
|
||||
|
||||
full_fname = (char *) alloca (fname_len + sizeof ("/locale.alias"));
|
||||
sprintf (full_fname, "%.*s/locale.alias", fname_len, fname);
|
||||
full_fname = (char *) alloca (fname_len + sizeof aliasfile);
|
||||
memcpy (full_fname, fname, fname_len);
|
||||
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
|
||||
|
||||
fp = fopen (full_fname, "r");
|
||||
if (fp == NULL)
|
||||
|
@ -18,6 +18,7 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../stdio-common/_itoa.h"
|
||||
|
||||
#ifndef HAVE_GNU_LD
|
||||
#define _sys_errlist sys_errlist
|
||||
@ -31,13 +32,14 @@ _strerror_internal (errnum, buf, buflen)
|
||||
char *buf;
|
||||
size_t buflen;
|
||||
{
|
||||
if (errnum < 0 || errnum > _sys_nerr)
|
||||
if (errnum < 0 || errnum >= _sys_nerr)
|
||||
{
|
||||
int len = __snprintf (buf, buflen, _("Unknown error %d"), errnum);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
buf[len - 1] = '\0';
|
||||
return buf;
|
||||
const char *unk = _("Unknown error ");
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p = buf + buflen;
|
||||
*--p = '\0';
|
||||
p = _itoa (errnum, p, 10, 0);
|
||||
return memcpy (p - unklen, unk, unklen);
|
||||
}
|
||||
|
||||
return (char *) _(_sys_errlist[errnum]);
|
||||
|
@ -43,7 +43,7 @@ _strerror_internal (int errnum, char *buf, size_t buflen)
|
||||
const char *unk = _("Error in unknown error system: ");
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p = buf + buflen;
|
||||
*p-- = '\0';
|
||||
*--p = '\0';
|
||||
p = _itoa (errnum, p, 16, 1);
|
||||
return memcpy (p - unklen, unk, unklen);
|
||||
}
|
||||
@ -59,7 +59,7 @@ _strerror_internal (int errnum, char *buf, size_t buflen)
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p = buf + buflen;
|
||||
size_t len = strlen (es->subsystem[sub].subsys_name);
|
||||
*p-- = '\0';
|
||||
*--p = '\0';
|
||||
p = _itoa (errnum, p, 16, 1);
|
||||
*p-- = ' ';
|
||||
p = memcpy (p - len, es->subsystem[sub].subsys_name, len);
|
||||
|
Loading…
Reference in New Issue
Block a user