mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 17:53:37 +08:00
Update.
* elf/link.h (link_map): Add l_dev and l_ino. * elf/dl-load.c (_dl_map_object_from_fd): Test dev/ino of newly loaded shared object with all laoded objects. Initialize l_ino and l_dev in case it's new. * elf/rtld.c (dl_main): Explain situation is l_dev/l_ino with main object. * elf/Makefile: Compile and run new test. * elf/multiload.c: New file.
This commit is contained in:
parent
1a989e004c
commit
61e0617ac3
@ -1,5 +1,14 @@
|
||||
1999-02-18 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* elf/link.h (link_map): Add l_dev and l_ino.
|
||||
* elf/dl-load.c (_dl_map_object_from_fd): Test dev/ino of newly
|
||||
loaded shared object with all laoded objects. Initialize l_ino
|
||||
and l_dev in case it's new.
|
||||
* elf/rtld.c (dl_main): Explain situation is l_dev/l_ino with main
|
||||
object.
|
||||
* elf/Makefile: Compile and run new test.
|
||||
* elf/multiload.c: New file.
|
||||
|
||||
* nss/nsswitch.h (service_user): Change name field from const char *
|
||||
to char[0].
|
||||
(name_database_entry): Likewise.
|
||||
|
10
elf/Makefile
10
elf/Makefile
@ -77,7 +77,7 @@ others += ldconfig
|
||||
install-rootsbin += ldconfig
|
||||
endif
|
||||
|
||||
tests = loadtest restest1 preloadtest loadfail
|
||||
tests = loadtest restest1 preloadtest loadfail multiload
|
||||
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
testobj1_1 failobj
|
||||
extra-objs += $(modules-names:=.os)
|
||||
@ -244,7 +244,13 @@ preloadtest-ENV = \
|
||||
$(objpfx)loadfail: $(libdl)
|
||||
LDFLAGS-loadfail = -rdynamic
|
||||
|
||||
$(objpfx)loadfile.out: $(objpfx)failobj.so
|
||||
$(objpfx)loadfail.out: $(objpfx)failobj.so
|
||||
|
||||
$(objpfx)multiload: $(libdl)
|
||||
LDFLAGS-multiload = -rdynamic
|
||||
CFLAGS-multiload.c = -DOBJDIR=\"$(objdir)/$(subdir)\"
|
||||
|
||||
$(objpfx)multiload.out: $(objpfx)testobj1.so
|
||||
|
||||
# muwahaha
|
||||
|
||||
|
@ -602,10 +602,15 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
|
||||
int type;
|
||||
char *readbuf;
|
||||
ssize_t readlength;
|
||||
struct stat st;
|
||||
|
||||
/* Get file information. */
|
||||
if (__fstat (fd, &st) < 0)
|
||||
lose (errno, "cannot stat shared object");
|
||||
|
||||
/* Look again to see if the real name matched another already loaded. */
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
if (! strcmp (realname, l->l_name))
|
||||
if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
|
||||
{
|
||||
/* The object is already loaded.
|
||||
Just bump its reference count and return it. */
|
||||
@ -961,6 +966,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
|
||||
l->l_scope[0] = &l->l_symbolic_searchlist;
|
||||
}
|
||||
|
||||
/* Finally the file information. */
|
||||
l->l_dev = st.st_dev;
|
||||
l->l_ino = st.st_ino;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Data structure for communication from the run-time dynamic linker for
|
||||
loaded ELF shared objects.
|
||||
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999 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
|
||||
@ -24,6 +24,7 @@
|
||||
#include <features.h>
|
||||
#include <elf.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* We use this macro to refer to ELF types independent of the native wordsize.
|
||||
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
|
||||
@ -193,6 +194,11 @@ struct link_map
|
||||
/* A similar array, this time only with the local scope. This is
|
||||
used occasionally. */
|
||||
struct r_scope_elem *l_local_scope[2];
|
||||
|
||||
/* This information is kept to check for sure whether a shared
|
||||
object is the same as one already loaded. */
|
||||
dev_t l_dev;
|
||||
ino_t l_ino;
|
||||
};
|
||||
|
||||
#endif /* link.h */
|
||||
|
78
elf/multiload.c
Normal file
78
elf/multiload.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
void *a;
|
||||
void *b;
|
||||
void *c;
|
||||
void *d;
|
||||
char *wd;
|
||||
char *base;
|
||||
char *buf;
|
||||
|
||||
/* Change to the binary directory. */
|
||||
if (chdir (OBJDIR) != 0)
|
||||
{
|
||||
printf ("cannot change to `%s': %m", OBJDIR);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
wd = getcwd (NULL, 0);
|
||||
base = basename (wd);
|
||||
buf = alloca (strlen (wd) + strlen (base) + 5 + sizeof "testobj1.so");
|
||||
|
||||
printf ("loading `%s'\n", "./testobj1.so");
|
||||
a = dlopen ("./testobj1.so", RTLD_NOW);
|
||||
if (a == NULL)
|
||||
{
|
||||
printf ("cannot load `./testobj1.so': %s\n", dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
stpcpy (stpcpy (stpcpy (buf, "../"), base), "/testobj1.so");
|
||||
printf ("loading `%s'\n", buf);
|
||||
b = dlopen (buf, RTLD_NOW);
|
||||
if (b == NULL)
|
||||
{
|
||||
printf ("cannot load `%s': %s\n", buf, dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
stpcpy (stpcpy (buf, wd), "/testobj1.so");
|
||||
printf ("loading `%s'\n", buf);
|
||||
c = dlopen (buf, RTLD_NOW);
|
||||
if (c == NULL)
|
||||
{
|
||||
printf ("cannot load `%s': %s\n", buf, dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
stpcpy (stpcpy (stpcpy (stpcpy (buf, wd), "/../"), base), "/testobj1.so");
|
||||
printf ("loading `%s'\n", buf);
|
||||
d = dlopen (buf, RTLD_NOW);
|
||||
if (d == NULL)
|
||||
{
|
||||
printf ("cannot load `%s': %s\n", buf, dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (a != b || b != c || c != d)
|
||||
{
|
||||
puts ("shared object loaded more than once");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return a;
|
||||
}
|
17
elf/rtld.c
17
elf/rtld.c
@ -461,7 +461,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
HP_TIMING_NOW (start);
|
||||
_dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
|
||||
HP_TIMING_NOW (stop);
|
||||
|
||||
|
||||
HP_TIMING_DIFF (load_time, start, stop);
|
||||
}
|
||||
|
||||
@ -486,6 +486,21 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
_dl_loaded->l_entry = *user_entry;
|
||||
_dl_loaded->l_opencount = 1;
|
||||
|
||||
/* At this point we are in a bit of trouble. We would have to
|
||||
fill in the values for l_dev and l_ino. But in general we
|
||||
do not know where the file is. We also do not handle AT_EXECFD
|
||||
even if it would be passed up.
|
||||
|
||||
We leave the values here defined to 0. This is normally no
|
||||
problem as the program code itself is normally no shared
|
||||
object and therefore cannot be loaded dynamically. Nothing
|
||||
prevent the use of dynamic binaries and in these situations
|
||||
we might get problems. We might not be able to find out
|
||||
whether the object is already loaded. But since there is no
|
||||
easy way out and because the dynamic binary must also not
|
||||
have an SONAME we ignore this program for now. If it becomes
|
||||
a problem we can force people using SONAMEs. */
|
||||
|
||||
/* We delay initializing the path structure until we got the dynamic
|
||||
information for the program. */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user