mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 19:00:07 +00:00
Update.
1999-07-24 Ulrich Drepper <drepper@cygnus.com> * elf/dl-fini.c: Handle DT_FINI_ARRAY. * elf/link.h (struct link_map): Remove l_init_running. Add l_runcount and l_initcount. * elf/dl-init.c: Handle DT_INIT_ARRAY. * elf/dynamic-link.h: Change parameters. Now only get link_map pointer. Calculate l_initcount. * elf/link.h (struct link_map): Add l_runpath_dirs. * elf/dynamic-link.h: If RUNPATH is given, set RPATH to NULL. * elf/dl-load.c: Pretty print. (decompose_rpath): Take new parameter with info from where the path comes. Pass it the fillin_rpath. (_dl_init_paths): Initialize l_runpath_dirs. (_dl_map_object): Don't search using RPATHs if object has RUNPATH. Search using RUNPATH after LD_LIBRARY_PATH. * elf/dl-support.c: Adjust comment. * elf/rtld.c: Adjust help message.
This commit is contained in:
parent
3f38221989
commit
fcf70d4114
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
|||||||
|
1999-07-24 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* elf/dl-fini.c: Handle DT_FINI_ARRAY.
|
||||||
|
* elf/link.h (struct link_map): Remove l_init_running. Add l_runcount
|
||||||
|
and l_initcount.
|
||||||
|
* elf/dl-init.c: Handle DT_INIT_ARRAY.
|
||||||
|
* elf/dynamic-link.h: Change parameters. Now only get link_map
|
||||||
|
pointer. Calculate l_initcount.
|
||||||
|
|
||||||
|
* elf/link.h (struct link_map): Add l_runpath_dirs.
|
||||||
|
* elf/dynamic-link.h: If RUNPATH is given, set RPATH to NULL.
|
||||||
|
* elf/dl-load.c: Pretty print.
|
||||||
|
(decompose_rpath): Take new parameter with info from where the path
|
||||||
|
comes. Pass it the fillin_rpath.
|
||||||
|
(_dl_init_paths): Initialize l_runpath_dirs.
|
||||||
|
(_dl_map_object): Don't search using RPATHs if object has RUNPATH.
|
||||||
|
Search using RUNPATH after LD_LIBRARY_PATH.
|
||||||
|
* elf/dl-support.c: Adjust comment.
|
||||||
|
* elf/rtld.c: Adjust help message.
|
||||||
|
|
||||||
1999-07-24 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
1999-07-24 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||||
|
|
||||||
* elf/rtld.c (dl_main): Adopt to changed _dl_lookup_symbol
|
* elf/rtld.c (dl_main): Adopt to changed _dl_lookup_symbol
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Call the termination functions of loaded shared objects.
|
/* Call the termination functions of loaded shared objects.
|
||||||
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -28,18 +28,48 @@ _dl_fini (void)
|
|||||||
for (l = _dl_loaded; l; l = l->l_next)
|
for (l = _dl_loaded; l; l = l->l_next)
|
||||||
if (l->l_init_called)
|
if (l->l_init_called)
|
||||||
{
|
{
|
||||||
if (l->l_info[DT_FINI] &&
|
int first = 1;
|
||||||
!(l->l_name[0] == '\0' && l->l_type == lt_executable))
|
|
||||||
|
/* Make sure nothing happens if we are called twice. */
|
||||||
|
l->l_init_called = 0;
|
||||||
|
|
||||||
|
/* Don't call the destructors for objects we are not supposed to. */
|
||||||
|
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* First see whether an array is given. */
|
||||||
|
if (l->l_info[DT_FINI_ARRAY] != NULL)
|
||||||
|
{
|
||||||
|
ElfW(Addr) *array =
|
||||||
|
(ElfW(Addr) *) (l->l_addr
|
||||||
|
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||||
|
unsigned int sz = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||||
|
/ sizeof (ElfW(Addr)));
|
||||||
|
unsigned int cnt;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < sz; ++cnt)
|
||||||
{
|
{
|
||||||
/* When debugging print a message first. */
|
/* When debugging print a message first. */
|
||||||
if (_dl_debug_impcalls)
|
if (_dl_debug_impcalls && first)
|
||||||
|
_dl_debug_message (1, "\ncalling fini: ",
|
||||||
|
l->l_name[0] ? l->l_name : _dl_argv[0],
|
||||||
|
"\n\n", NULL);
|
||||||
|
first = 0;
|
||||||
|
|
||||||
|
(*(void (*) (void)) (l->l_addr + array[cnt])) ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next try the old-style destructor. */
|
||||||
|
if (l->l_info[DT_FINI])
|
||||||
|
{
|
||||||
|
/* When debugging print a message first. */
|
||||||
|
if (_dl_debug_impcalls && first)
|
||||||
_dl_debug_message (1, "\ncalling fini: ",
|
_dl_debug_message (1, "\ncalling fini: ",
|
||||||
l->l_name[0] ? l->l_name : _dl_argv[0],
|
l->l_name[0] ? l->l_name : _dl_argv[0],
|
||||||
"\n\n", NULL);
|
"\n\n", NULL);
|
||||||
|
|
||||||
(*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
(*(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Return the next shared object initializer function not yet run.
|
/* Return the next shared object initializer function not yet run.
|
||||||
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -38,27 +38,28 @@ _dl_init_next (struct r_scope_elem *searchlist)
|
|||||||
while (i-- > 0)
|
while (i-- > 0)
|
||||||
{
|
{
|
||||||
struct link_map *l = searchlist->r_list[i];
|
struct link_map *l = searchlist->r_list[i];
|
||||||
|
ElfW(Addr) *array;
|
||||||
|
|
||||||
if (l->l_init_called)
|
if (l->l_init_called)
|
||||||
/* This object is all done. */
|
/* This object is all done. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (l->l_init_running)
|
/* Check for object which constructors we do not run here.
|
||||||
|
XXX Maybe this should be pre-computed, but where? */
|
||||||
|
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||||
{
|
{
|
||||||
/* This object's initializer was just running.
|
|
||||||
Now mark it as having run, so this object
|
|
||||||
will be skipped in the future. */
|
|
||||||
l->l_init_running = 0;
|
|
||||||
l->l_init_called = 1;
|
l->l_init_called = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->l_info[DT_INIT]
|
/* Account for running next constructor. */
|
||||||
&& (l->l_name[0] != '\0' || l->l_type != lt_executable))
|
++l->l_runcount;
|
||||||
{
|
|
||||||
/* Run this object's initializer. */
|
|
||||||
l->l_init_running = 1;
|
|
||||||
|
|
||||||
|
if (l->l_runcount == 1)
|
||||||
|
{
|
||||||
|
/* Try running the DT_INIT constructor. */
|
||||||
|
if (l->l_info[DT_INIT])
|
||||||
|
{
|
||||||
/* Print a debug message if wanted. */
|
/* Print a debug message if wanted. */
|
||||||
if (_dl_debug_impcalls)
|
if (_dl_debug_impcalls)
|
||||||
_dl_debug_message (1, "\ncalling init: ",
|
_dl_debug_message (1, "\ncalling init: ",
|
||||||
@ -68,9 +69,28 @@ _dl_init_next (struct r_scope_elem *searchlist)
|
|||||||
return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
|
return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No initializer for this object.
|
/* No DT_INIT, so go on with the array. */
|
||||||
Mark it so we will skip it in the future. */
|
++l->l_runcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->l_runcount > l->l_initcount)
|
||||||
|
{
|
||||||
|
/* That were all of the constructors. */
|
||||||
|
l->l_runcount = 0;
|
||||||
l->l_init_called = 1;
|
l->l_init_called = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a debug message if wanted. */
|
||||||
|
if (_dl_debug_impcalls && l->l_info[DT_INIT] == NULL
|
||||||
|
&& l->l_runcount == 2)
|
||||||
|
_dl_debug_message (1, "\ncalling init: ",
|
||||||
|
l->l_name[0] ? l->l_name : _dl_argv[0],
|
||||||
|
"\n\n", NULL);
|
||||||
|
|
||||||
|
array = (ElfW(Addr) *) l->l_info[DT_INIT_ARRAY]->d_un.d_ptr;
|
||||||
|
return l->l_addr + array[l->l_runcount - 2];
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
/* On some systems, no flag bits are given to specify file mapping. */
|
/* On some systems, no flag bits are given to specify file mapping. */
|
||||||
#ifndef MAP_FILE
|
#ifndef MAP_FILE
|
||||||
#define MAP_FILE 0
|
# define MAP_FILE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The right way to map in the shared library files is MAP_COPY, which
|
/* The right way to map in the shared library files is MAP_COPY, which
|
||||||
@ -46,7 +46,7 @@
|
|||||||
means if the file is overwritten, we may at some point get some pages
|
means if the file is overwritten, we may at some point get some pages
|
||||||
from the new version after starting with pages from the old version. */
|
from the new version after starting with pages from the old version. */
|
||||||
#ifndef MAP_COPY
|
#ifndef MAP_COPY
|
||||||
#define MAP_COPY MAP_PRIVATE
|
# define MAP_COPY MAP_PRIVATE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some systems link their relocatable objects for another base address
|
/* Some systems link their relocatable objects for another base address
|
||||||
@ -55,30 +55,30 @@
|
|||||||
This results in a more efficient address space usage. Defaults to
|
This results in a more efficient address space usage. Defaults to
|
||||||
zero for almost all systems. */
|
zero for almost all systems. */
|
||||||
#ifndef MAP_BASE_ADDR
|
#ifndef MAP_BASE_ADDR
|
||||||
#define MAP_BASE_ADDR(l) 0
|
# define MAP_BASE_ADDR(l) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
#define byteorder ELFDATA2MSB
|
# define byteorder ELFDATA2MSB
|
||||||
#define byteorder_name "big-endian"
|
# define byteorder_name "big-endian"
|
||||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||||
#define byteorder ELFDATA2LSB
|
# define byteorder ELFDATA2LSB
|
||||||
#define byteorder_name "little-endian"
|
# define byteorder_name "little-endian"
|
||||||
#else
|
#else
|
||||||
#error "Unknown BYTE_ORDER " BYTE_ORDER
|
# error "Unknown BYTE_ORDER " BYTE_ORDER
|
||||||
#define byteorder ELFDATANONE
|
# define byteorder ELFDATANONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STRING(x) __STRING (x)
|
#define STRING(x) __STRING (x)
|
||||||
|
|
||||||
#ifdef MAP_ANON
|
#ifdef MAP_ANON
|
||||||
/* The fd is not examined when using MAP_ANON. */
|
/* The fd is not examined when using MAP_ANON. */
|
||||||
#define ANONFD -1
|
# define ANONFD -1
|
||||||
#else
|
#else
|
||||||
int _dl_zerofd = -1;
|
int _dl_zerofd = -1;
|
||||||
#define ANONFD _dl_zerofd
|
# define ANONFD _dl_zerofd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Handle situations where we have a preferred location in memory for
|
/* Handle situations where we have a preferred location in memory for
|
||||||
@ -87,10 +87,10 @@ int _dl_zerofd = -1;
|
|||||||
ELF_PREFERRED_ADDRESS_DATA;
|
ELF_PREFERRED_ADDRESS_DATA;
|
||||||
#endif
|
#endif
|
||||||
#ifndef ELF_PREFERRED_ADDRESS
|
#ifndef ELF_PREFERRED_ADDRESS
|
||||||
#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
|
# define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
|
||||||
#endif
|
#endif
|
||||||
#ifndef ELF_FIXED_ADDRESS
|
#ifndef ELF_FIXED_ADDRESS
|
||||||
#define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
|
# define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t _dl_pagesize;
|
size_t _dl_pagesize;
|
||||||
@ -436,7 +436,7 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
|||||||
|
|
||||||
static struct r_search_path_elem **
|
static struct r_search_path_elem **
|
||||||
internal_function
|
internal_function
|
||||||
decompose_rpath (const char *rpath, struct link_map *l)
|
decompose_rpath (const char *rpath, struct link_map *l, const char *what)
|
||||||
{
|
{
|
||||||
/* Make a copy we can work with. */
|
/* Make a copy we can work with. */
|
||||||
const char *where = l->l_name;
|
const char *where = l->l_name;
|
||||||
@ -445,7 +445,8 @@ decompose_rpath (const char *rpath, struct link_map *l)
|
|||||||
struct r_search_path_elem **result;
|
struct r_search_path_elem **result;
|
||||||
size_t nelems;
|
size_t nelems;
|
||||||
|
|
||||||
/* First see whether we must forget the RPATH from this object. */
|
/* First see whether we must forget the RUNPATH and RPATH from this
|
||||||
|
object. */
|
||||||
if (_dl_inhibit_rpath != NULL && !__libc_enable_secure)
|
if (_dl_inhibit_rpath != NULL && !__libc_enable_secure)
|
||||||
{
|
{
|
||||||
const char *found = strstr (_dl_inhibit_rpath, where);
|
const char *found = strstr (_dl_inhibit_rpath, where);
|
||||||
@ -455,8 +456,8 @@ decompose_rpath (const char *rpath, struct link_map *l)
|
|||||||
if ((found == _dl_inhibit_rpath || found[-1] == ':')
|
if ((found == _dl_inhibit_rpath || found[-1] == ':')
|
||||||
&& (found[len] == '\0' || found[len] == ':'))
|
&& (found[len] == '\0' || found[len] == ':'))
|
||||||
{
|
{
|
||||||
/* This object is on the list of objects for which the RPATH
|
/* This object is on the list of objects for which the
|
||||||
must not be used. */
|
RUNPATH and RPATH must not be used. */
|
||||||
result = (struct r_search_path_elem **)
|
result = (struct r_search_path_elem **)
|
||||||
malloc (sizeof (*result));
|
malloc (sizeof (*result));
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
@ -473,7 +474,7 @@ decompose_rpath (const char *rpath, struct link_map *l)
|
|||||||
string tokens. */
|
string tokens. */
|
||||||
copy = expand_dynamic_string_token (l, rpath);
|
copy = expand_dynamic_string_token (l, rpath);
|
||||||
if (copy == NULL)
|
if (copy == NULL)
|
||||||
_dl_signal_error (ENOMEM, NULL, "cannot create RPATH copy");
|
_dl_signal_error (ENOMEM, NULL, "cannot create RUNPATH/RPATH copy");
|
||||||
|
|
||||||
/* Count the number of necessary elements in the result array. */
|
/* Count the number of necessary elements in the result array. */
|
||||||
nelems = 0;
|
nelems = 0;
|
||||||
@ -488,7 +489,7 @@ decompose_rpath (const char *rpath, struct link_map *l)
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
_dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
|
_dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
|
||||||
|
|
||||||
return fillin_rpath (copy, result, ":", 0, "RPATH", where);
|
return fillin_rpath (copy, result, ":", 0, what, where);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -570,16 +571,33 @@ _dl_init_paths (const char *llp)
|
|||||||
{
|
{
|
||||||
assert (l->l_type != lt_loaded);
|
assert (l->l_type != lt_loaded);
|
||||||
|
|
||||||
|
if (l->l_info[DT_RUNPATH])
|
||||||
|
{
|
||||||
|
/* Allocate room for the search path and fill in information
|
||||||
|
from RUNPATH. */
|
||||||
|
l->l_runpath_dirs =
|
||||||
|
decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
|
+ l->l_info[DT_RUNPATH]->d_un.d_val),
|
||||||
|
l, "RUNPATH");
|
||||||
|
|
||||||
|
/* The RPATH is ignored. */
|
||||||
|
l->l_rpath_dirs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l->l_runpath_dirs = NULL;
|
||||||
|
|
||||||
if (l->l_info[DT_RPATH])
|
if (l->l_info[DT_RPATH])
|
||||||
/* Allocate room for the search path and fill in information
|
/* Allocate room for the search path and fill in information
|
||||||
from RPATH. */
|
from RPATH. */
|
||||||
l->l_rpath_dirs =
|
l->l_rpath_dirs =
|
||||||
decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
|
decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
+ l->l_info[DT_RPATH]->d_un.d_val),
|
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||||
l);
|
l, "RPATH");
|
||||||
else
|
else
|
||||||
l->l_rpath_dirs = NULL;
|
l->l_rpath_dirs = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* PIC */
|
#endif /* PIC */
|
||||||
|
|
||||||
if (llp != NULL && *llp != '\0')
|
if (llp != NULL && *llp != '\0')
|
||||||
@ -1036,7 +1054,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
|
|||||||
" phnum: ", buf3, "\n\n", NULL);
|
" phnum: ", buf3, "\n\n", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_get_dynamic_info (l->l_ld, l->l_addr, l->l_info);
|
elf_get_dynamic_info (l);
|
||||||
if (l->l_info[DT_HASH])
|
if (l->l_info[DT_HASH])
|
||||||
_dl_setup_hash (l);
|
_dl_setup_hash (l);
|
||||||
|
|
||||||
@ -1292,6 +1310,10 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
|||||||
|
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
|
/* When the object has the RUNPATH information we don't use any
|
||||||
|
RPATHs. */
|
||||||
|
if (loader != NULL && loader->l_info[DT_RUNPATH] == NULL)
|
||||||
|
{
|
||||||
/* First try the DT_RPATH of the dependent object that caused NAME
|
/* First try the DT_RPATH of the dependent object that caused NAME
|
||||||
to be loaded. Then that object's dependent, and on up. */
|
to be loaded. Then that object's dependent, and on up. */
|
||||||
for (l = loader; fd == -1 && l; l = l->l_loader)
|
for (l = loader; fd == -1 && l; l = l->l_loader)
|
||||||
@ -1303,7 +1325,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
|||||||
size_t ptrval = (l->l_info[DT_STRTAB]->d_un.d_ptr
|
size_t ptrval = (l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
+ l->l_info[DT_RPATH]->d_un.d_val);
|
+ l->l_info[DT_RPATH]->d_un.d_val);
|
||||||
l->l_rpath_dirs =
|
l->l_rpath_dirs =
|
||||||
decompose_rpath ((const char *) ptrval, l);
|
decompose_rpath ((const char *) ptrval, l, "RPATH");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->l_rpath_dirs != NULL)
|
if (l->l_rpath_dirs != NULL)
|
||||||
@ -1311,16 +1333,36 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
|||||||
&realname);
|
&realname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If dynamically linked, try the DT_RPATH of the executable itself. */
|
/* If dynamically linked, try the DT_RPATH of the executable
|
||||||
|
itself. */
|
||||||
l = _dl_loaded;
|
l = _dl_loaded;
|
||||||
if (fd == -1 && l && l->l_type != lt_loaded && l != loader
|
if (fd == -1 && l && l->l_type != lt_loaded && l != loader
|
||||||
&& l->l_rpath_dirs != NULL)
|
&& l->l_rpath_dirs != NULL)
|
||||||
fd = open_path (name, namelen, preloaded, l->l_rpath_dirs, &realname);
|
fd = open_path (name, namelen, preloaded, l->l_rpath_dirs,
|
||||||
|
&realname);
|
||||||
|
}
|
||||||
|
|
||||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||||
if (fd == -1 && env_path_list != NULL)
|
if (fd == -1 && env_path_list != NULL)
|
||||||
fd = open_path (name, namelen, preloaded, env_path_list, &realname);
|
fd = open_path (name, namelen, preloaded, env_path_list, &realname);
|
||||||
|
|
||||||
|
/* Look at the RUNPATH informaiton for this binary. */
|
||||||
|
if (loader != NULL && loader->l_info[DT_RUNPATH])
|
||||||
|
{
|
||||||
|
/* Make sure the cache information is available. */
|
||||||
|
if (loader->l_runpath_dirs == NULL)
|
||||||
|
{
|
||||||
|
size_t ptrval = (loader->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
|
+ loader->l_info[DT_RUNPATH]->d_un.d_val);
|
||||||
|
loader->l_runpath_dirs =
|
||||||
|
decompose_rpath ((const char *) ptrval, loader, "RUNPATH");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loader->l_runpath_dirs != NULL)
|
||||||
|
fd = open_path (name, namelen, preloaded, loader->l_runpath_dirs,
|
||||||
|
&realname);
|
||||||
|
}
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
/* Check the list of libraries in the file /etc/ld.so.cache,
|
/* Check the list of libraries in the file /etc/ld.so.cache,
|
||||||
|
@ -51,7 +51,8 @@ struct r_search_path *_dl_search_paths;
|
|||||||
/* We never do profiling. */
|
/* We never do profiling. */
|
||||||
const char *_dl_profile;
|
const char *_dl_profile;
|
||||||
|
|
||||||
/* Names of shared object for which the RPATHs should be ignored. */
|
/* Names of shared object for which the RUNPATHs and RPATHs should be
|
||||||
|
ignored. */
|
||||||
const char *_dl_inhibit_rpath;
|
const char *_dl_inhibit_rpath;
|
||||||
|
|
||||||
/* The map for the object we will profile. */
|
/* The map for the object we will profile. */
|
||||||
|
@ -34,13 +34,18 @@ extern int _dl_verbose __attribute__ ((unused));
|
|||||||
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
||||||
|
|
||||||
static inline void __attribute__ ((unused))
|
static inline void __attribute__ ((unused))
|
||||||
elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
|
elf_get_dynamic_info (struct link_map *l)
|
||||||
ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM
|
|
||||||
+ DT_EXTRANUM])
|
|
||||||
{
|
{
|
||||||
|
ElfW(Dyn) *dyn = l->l_ld;
|
||||||
|
ElfW(Addr) l_addr;
|
||||||
|
ElfW(Dyn) **info;
|
||||||
|
|
||||||
if (! dyn)
|
if (! dyn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
l_addr = l->l_addr;
|
||||||
|
info = l->l_info;
|
||||||
|
|
||||||
while (dyn->d_tag != DT_NULL)
|
while (dyn->d_tag != DT_NULL)
|
||||||
{
|
{
|
||||||
if (dyn->d_tag < DT_NUM)
|
if (dyn->d_tag < DT_NUM)
|
||||||
@ -106,6 +111,16 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
|
|||||||
if (flags & DF_BIND_NOW)
|
if (flags & DF_BIND_NOW)
|
||||||
info[DT_BIND_NOW] = info[DT_FLAGS];
|
info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||||
}
|
}
|
||||||
|
/* Determine how many constructors there are. */
|
||||||
|
if (info[DT_INIT_ARRAY] != NULL)
|
||||||
|
info[DT_INIT_ARRAY]->d_un.d_ptr += l_addr;
|
||||||
|
l->l_initcount = 1 + (info[DT_INIT_ARRAY]
|
||||||
|
? (info[DT_INIT_ARRAYSZ]->d_un.d_val
|
||||||
|
/ sizeof (ElfW(Addr)))
|
||||||
|
: 0);
|
||||||
|
if (info[DT_RUNPATH] != NULL)
|
||||||
|
/* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||||
|
info[DT_RPATH] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RESOLVE
|
#ifdef RESOLVE
|
||||||
|
11
elf/link.h
11
elf/link.h
@ -163,7 +163,6 @@ struct link_map
|
|||||||
} l_type:2;
|
} l_type:2;
|
||||||
unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
|
unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
|
||||||
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
|
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
|
||||||
unsigned int l_init_running:1; /* Nonzero while DT_INIT function runs. */
|
|
||||||
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
|
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
|
||||||
unsigned int l_reserved:2; /* Reserved for internal use. */
|
unsigned int l_reserved:2; /* Reserved for internal use. */
|
||||||
|
|
||||||
@ -202,6 +201,16 @@ struct link_map
|
|||||||
|
|
||||||
/* Nonzero if the data structure pointed to by `l_phdr' is allocated. */
|
/* Nonzero if the data structure pointed to by `l_phdr' is allocated. */
|
||||||
int l_phdr_allocated;
|
int l_phdr_allocated;
|
||||||
|
|
||||||
|
/* Counter for running constructors and destructors. */
|
||||||
|
unsigned int l_runcount;
|
||||||
|
|
||||||
|
/* Number of constructors. We compute this during loading to avoid
|
||||||
|
duplication of this during the possibly many calls to _dl_init_next. */
|
||||||
|
unsigned int l_initcount;
|
||||||
|
|
||||||
|
/* Collected information about own RUNPATH directories. */
|
||||||
|
struct r_search_path_elem **l_runpath_dirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* link.h */
|
#endif /* link.h */
|
||||||
|
@ -448,7 +448,8 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
object we get handle\n\
|
object we get handle\n\
|
||||||
--library-path PATH use given PATH instead of content of the environment\n\
|
--library-path PATH use given PATH instead of content of the environment\n\
|
||||||
variable LD_LIBRARY_PATH\n\
|
variable LD_LIBRARY_PATH\n\
|
||||||
--inhibit-rpath LIST ignore RPATH information in object names in LIST\n",
|
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
|
||||||
|
in LIST\n",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
++_dl_skip_args;
|
++_dl_skip_args;
|
||||||
|
Loading…
Reference in New Issue
Block a user