diff options
author | Roland McGrath <roland@gnu.org> | 1996-07-14 06:04:09 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-07-14 06:04:09 +0000 |
commit | 2064087b5f1a0a3a189fcd6a3012376f5545be31 (patch) | |
tree | 6f02a4e4364004352f2d785146b5dc12444e83b9 /elf | |
parent | 842907c6f8e6022f443175072e65bc516eb0973b (diff) |
Sun Jul 14 01:51:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>cvs/libc-960714
* manual/Makefile (glibc-targets): Variable and targets removed.
Sat Jul 13 23:50:17 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* manual/Makefile (lib): New phony target. Depend on stamp files.
($(objpfx)stamp%-$(subdir)): New rule to create them when necessary.
1996-07-13 Paul Eggert <eggert@twinsun.com>
* time/strftime.c (strftime): Use space padding for %e, %k, %l,
to match Emacs format-time-string specification.
(DO_NUMBER_SPACEPAD): Renamed from DO_NUMBER_NOPAD.
Sat Jul 13 20:17:38 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* elf/dl-deps.c (_dl_map_object_deps): Take new args PRELOADS and
NPRELOADS, vector of `struct link_map *'s; add them to the searchlist
between MAP and its deps.
* elf/link.h: Fix decl.
* elf/rtld.c (dl_main): If not secure, parse LD_PRELOAD for
colon-separated list of names, map those and pass vector of ptrs as
PRELOADS list to _dl_map_object_deps.
* elf/dl-runtime.c (_dl_object_relocation_scope): Pass new args to
_dl_map_object_deps with empty preload list.
* elf/dl-open.c (_dl_open): Likewise.
* sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_open_zero_fill): Function
removed.
(__mmap): Pass MACH_PORT_NULL for memobj port when (flags & MAP_ANON).
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_open_zero_fill):
Conditionalize defn on [! MAP_ANON].
* elf/dl-minimal.c (malloc): Conditionalize use of _dl_zerofd
on [! MAP_ANON].
* elf/rtld.c (dl_main): Likewise.
* elf/dl-load.c (_dl_zerofd): Conditionalize defn on [! MAP_ANON].
(_dl_map_object_from_fd): Conditionalize initialization of _dl_zerofd.
* elf/dl-fini.c (_dl_fini): Skip finalizer for executable itself.
Sat Jul 13 02:47:53 1996 David Mosberger-Tang <davidm@azstarnet.com>
* stdlib/random.c (__random): Declare as int32_t to be in sync
with declaration.
* socket/Makefile (headers): Add socketbits.h.
* misc/mntent.c (endmntent): Allow for NULL stream. SunOS does
it that way.
* grp/initgroups.c (initgroups): Add groups that user is a member
of, not the ones he is _not_ a member of.
* nss/nsswitch.c (known_compare): Make known_compare() a static
instead of a local function. The latter are difficult to debug
and slow to execute on certain platforms.
* sysdeps/posix/ttyname_r.c (ttyname_r): Use sizeof (dev) - 1 in
place of sizeof (dev). The size of a literal string includes the
NUL byte.
* sysdeps/unix/getlogin.c (getlogin): Initialize ut_fd with -1.
Thu Jul 11 16:59:10 1996 David Mosberger-Tang <davidm@azstarnet.com>
* misc/mntent.c (addmntent): Seek to end of file before writing
entry. Return 1 on error, not -1.
Tue Jul 9 19:08:05 1996 David Mosberger-Tang <davidm@azstarnet.com>
* sysdeps/unix/sysv/linux/syscalls.list: Mark bdflush as EXTRA
syscall.
Fri Jul 5 18:44:55 1996 David Mosberger-Tang <davidm@azstarnet.com>
* sysdeps/unix/sysv/linux/alpha/ioperm.c (port_to_cpu_addr): Size
shift amount for Jensen must be 5 not 4.
Sat Jul 13 20:04:28 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* socket/sys/socket.h (struct osockaddr): New type.
Sat Jul 13 03:50:53 1996 Ulrich Drepper <drepper@cygnus.com>
* misc/Makefile (routines): Add qefgcvt and qefgcvt_r.
* misc/efgcvt.c, misc/efgcvt_r.c: Change code so that the `double'
and `long double' versions can be generated.
* misc/qefgcvt.c, misc/qefgcvt_r.c: New files. Define macros
so that included efgcvt{,_r}.c file generate `long double'
versions.
* stdlib/stdlib.h: Add prototypes for q[efg]cvt() and q[ef]cvt_r()
functions.
* manual/startup.texi: Document new getsubopt function.
* manual/examples/subopt.c: New example program for documenting
getsubopt function.
Fri Jul 12 23:58:37 1996 Ulrich Drepper <drepper@cygnus.com>
* stdlib/Makefile (routines): Add getsubopt.
* stdlib/stdlib.h: Add prototype for getsubopt.
* stdlib/getsubopt.c: New file. Implement getsubopt function
to handle suboption parsing.
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-deps.c | 23 | ||||
-rw-r--r-- | elf/dl-fini.c | 6 | ||||
-rw-r--r-- | elf/dl-load.c | 12 | ||||
-rw-r--r-- | elf/dl-minimal.c | 11 | ||||
-rw-r--r-- | elf/dl-open.c | 2 | ||||
-rw-r--r-- | elf/dl-runtime.c | 2 | ||||
-rw-r--r-- | elf/link.h | 10 | ||||
-rw-r--r-- | elf/rtld.c | 47 |
8 files changed, 93 insertions, 20 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 9fe974d982..28733ab60d 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -23,20 +23,29 @@ Cambridge, MA 02139, USA. */ #include <stdlib.h> void -_dl_map_object_deps (struct link_map *map) +_dl_map_object_deps (struct link_map *map, + struct link_map **preloads, unsigned int npreloads) { struct list { struct link_map *map; struct list *next; }; - struct list head, *tailp, *scanp; + struct list head[1 + npreloads], *tailp, *scanp; unsigned int nlist; /* Start the search list with one element: MAP itself. */ - head.map = map; - head.next = NULL; - nlist = 1; + head[0].map = map; + + /* Add the preloaded items after MAP but before any of its dependencies. */ + for (nlist = 0; nlist < npreloads; ++nlist) + { + head[nlist].next = &head[nlist + 1]; + head[nlist + 1].map = preloads[nlist]; + } + + /* Terminate the list. */ + head[nlist++].next = NULL; /* We use `l_reserved' as a mark bit to detect objects we have already put in the search list and avoid adding duplicate elements later in @@ -47,7 +56,7 @@ _dl_map_object_deps (struct link_map *map) dependencies and appending them to the list as we step through it. This produces a flat, ordered list that represents a breadth-first search of the dependency tree. */ - for (scanp = tailp = &head; scanp; scanp = scanp->next) + for (scanp = tailp = head; scanp; scanp = scanp->next) { struct link_map *l = scanp->map; @@ -91,7 +100,7 @@ _dl_map_object_deps (struct link_map *map) map->l_nsearchlist = nlist; nlist = 0; - for (scanp = &head; scanp; scanp = scanp->next) + for (scanp = head; scanp; scanp = scanp->next) { map->l_searchlist[nlist++] = scanp->map; diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 36b4390663..9f4233aca0 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -25,9 +25,11 @@ _dl_fini (void) struct link_map *l; for (l = _dl_loaded; l; l = l->l_next) - if (l->l_init_called && l->l_info[DT_FINI]) + if (l->l_init_called) { - (*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) (); + 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)) (); /* Make sure nothing happens if we are called twice. */ l->l_init_called = 0; } diff --git a/elf/dl-load.c b/elf/dl-load.c index ff7f5cf487..29ac0bfd87 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -59,7 +59,14 @@ Cambridge, MA 02139, USA. */ #define STRING(x) #x +#ifdef MAP_ANON +/* The fd is not examined when using MAP_ANON. */ +#define ANONFD -1 +#else int _dl_zerofd = -1; +#define ANONFD _dl_zerofd +#endif + size_t _dl_pagesize; @@ -176,6 +183,8 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, if (header->e_phentsize != sizeof (ElfW(Phdr))) LOSE ("ELF file's phentsize not the expected size"); +#ifndef MAP_ANON +#define MAP_ANON 0 if (_dl_zerofd == -1) { _dl_zerofd = _dl_sysdep_open_zero_fill (); @@ -185,6 +194,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, _dl_signal_error (errno, NULL, "cannot open zero fill device"); } } +#endif /* Enter the new object in the list of loaded objects. */ l = _dl_new_object (realname, name, l_type); @@ -329,7 +339,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, caddr_t mapat; mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED, - _dl_zerofd, 0); + ANONFD, 0); if (mapat == (caddr_t) -1) lose (errno, "cannot map zero-fill pages"); } diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c index fd7bf05497..61615cd9a9 100644 --- a/elf/dl-minimal.c +++ b/elf/dl-minimal.c @@ -33,13 +33,18 @@ static void *alloc_ptr, *alloc_end, *alloc_last_block; void * weak_function malloc (size_t n) { +#ifdef MAP_ANON +#define _dl_zerofd (-1) +#else extern int _dl_zerofd; - if (_dl_pagesize == 0) - _dl_pagesize = __getpagesize (); - if (_dl_zerofd == -1) _dl_zerofd = _dl_sysdep_open_zero_fill (); +#define MAP_ANON 0 +#endif + + if (_dl_pagesize == 0) + _dl_pagesize = __getpagesize (); if (alloc_end == 0) { diff --git a/elf/dl-open.c b/elf/dl-open.c index c24920f933..058c3e5a39 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -39,7 +39,7 @@ _dl_open (const char *file, int mode) return new; /* Load that object's dependencies. */ - _dl_map_object_deps (new); + _dl_map_object_deps (new, NULL, 0); /* Relocate the objects loaded. We do this in reverse order so that copy diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 8ad2c0ffa4..cdacd756ef 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -41,7 +41,7 @@ _dl_object_relocation_scope (struct link_map *l) if (! l->l_searchlist) /* We must construct the searchlist for this object. */ - _dl_map_object_deps (l); + _dl_map_object_deps (l, NULL, 0); /* The primary scope is this object itself and its dependencies. */ diff --git a/elf/link.h b/elf/link.h index 1e0104a4ea..fa96613478 100644 --- a/elf/link.h +++ b/elf/link.h @@ -196,9 +196,13 @@ extern int _dlerror_run (void (*operate) (void)); extern struct link_map *_dl_map_object (struct link_map *loader, const char *name, int type); -/* Call _dl_map_object on the dependencies of MAP, and - set up MAP->l_searchlist. */ -extern void _dl_map_object_deps (struct link_map *map); +/* Call _dl_map_object on the dependencies of MAP, and set up + MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously + loaded objects that will be inserted into MAP->l_searchlist after MAP + but before its dependencies. */ +extern void _dl_map_object_deps (struct link_map *map, + struct link_map **preloads, + unsigned int npreloads); /* Cache the locations of MAP's hash table. */ extern void _dl_setup_hash (struct link_map *map); diff --git a/elf/rtld.c b/elf/rtld.c index 6baa7a868a..2e23d9cb38 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -21,6 +21,7 @@ Cambridge, MA 02139, USA. */ #include <stddef.h> #include <stdlib.h> #include <unistd.h> +#include <sys/mman.h> /* Check if MAP_ANON is defined. */ #include "../stdio-common/_itoa.h" @@ -124,6 +125,8 @@ dl_main (const ElfW(Phdr) *phdr, struct link_map *l; int lazy; int list_only = 0; + struct link_map **preloads; + unsigned int npreloads; if (*user_entry == (ElfW(Addr)) &_start) { @@ -247,12 +250,52 @@ of this helper program; chances are you did not intend to run this program.\n", l->l_next = &_dl_rtld_map; _dl_rtld_map.l_prev = l; - /* Load all the libraries specified by DT_NEEDED entries. */ - _dl_map_object_deps (l); + preloads = NULL; + npreloads = 0; + if (! _dl_secure) + { + const char *preloadlist = getenv ("LD_PRELOAD"); + if (preloadlist) + { + /* The LD_PRELOAD environment variable gives a colon-separated + list of libraries that are loaded before the executable's + dependencies and prepended to the global scope list. */ + char *list = strdupa (preloadlist); + char *p; + while ((p = strsep (&list, ":")) != NULL) + { + (void) _dl_map_object (NULL, p, lt_library); + ++npreloads; + } + + if (npreloads != 0) + { + /* Set up PRELOADS with a vector of the preloaded libraries. */ + struct link_map *l; + unsigned int i; + preloads = __alloca (npreloads * sizeof preloads[0]); + l = _dl_rtld_map.l_next; /* End of the chain before preloads. */ + i = 0; + do + { + preloads[i++] = l; + l = l->l_next; + } while (l); + assert (i == npreloads); + } + } + } + + /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD + specified some libraries to load, these are inserted before the actual + dependencies in the executable's searchlist for symbol resolution. */ + _dl_map_object_deps (l, preloads, npreloads); +#ifndef MAP_ANON /* We are done mapping things, so close the zero-fill descriptor. */ __close (_dl_zerofd); _dl_zerofd = -1; +#endif /* Remove _dl_rtld_map from the chain. */ _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next; |