mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
Update.
* elf/elf.h: Add various DF_1_*, DTF_1_*, and DF_P1_* entries. * elf/dl-close.c (_dl_close): Don't close an object if it is marked with nodelete. * elf/dl-open.c (dl_open_worker): Pass RTLD_NOLOAD as new parameter to _dl_map_object. Return immediately if no object loaded. Set DF_1_NODELETE bit in l_flags_1 if RTLD_NODELETE was passed. * elf/dynamic-link.h (elf_get_dynamic_info): Copy DT_FLAGS_1 entry if it exists into l_flags_1 word. * elf/dl-load.c (_dl_map_object_from_fd): Take no parameter and use it to determine whether loading is wanted or not. (_dl_map_object): Likewise. Call _dl_map_object_from_fd with new parameter. * sysdeps/generic/ldsodefs.h: Update prototype. * elf/dl-deps.c: Add new parameter to _dl_map_object calls. * elf/rtld.c: Likewise. * elf/Makefile (tests): Add noload. Add rules to generate noload. * elf/noload.c: New file. * include/link.h (struct link_map): Add l_feature_1 and l_flags_1. * sysdeps/generic/bits/dlfcn.h: Define RTLD_NOLOAD and RTLD_NODELETE. * sysdeps/mips/bits/dlfcn.h: Likewise.
This commit is contained in:
parent
5e61ef8848
commit
bf8b3e74bf
21
ChangeLog
21
ChangeLog
@ -1,5 +1,26 @@
|
||||
2000-07-20 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/elf.h: Add various DF_1_*, DTF_1_*, and DF_P1_* entries.
|
||||
* elf/dl-close.c (_dl_close): Don't close an object if it is marked
|
||||
with nodelete.
|
||||
* elf/dl-open.c (dl_open_worker): Pass RTLD_NOLOAD as new parameter
|
||||
to _dl_map_object. Return immediately if no object loaded.
|
||||
Set DF_1_NODELETE bit in l_flags_1 if RTLD_NODELETE was passed.
|
||||
* elf/dynamic-link.h (elf_get_dynamic_info): Copy DT_FLAGS_1 entry
|
||||
if it exists into l_flags_1 word.
|
||||
* elf/dl-load.c (_dl_map_object_from_fd): Take no parameter and use
|
||||
it to determine whether loading is wanted or not.
|
||||
(_dl_map_object): Likewise.
|
||||
Call _dl_map_object_from_fd with new parameter.
|
||||
* sysdeps/generic/ldsodefs.h: Update prototype.
|
||||
* elf/dl-deps.c: Add new parameter to _dl_map_object calls.
|
||||
* elf/rtld.c: Likewise.
|
||||
* elf/Makefile (tests): Add noload. Add rules to generate noload.
|
||||
* elf/noload.c: New file.
|
||||
* include/link.h (struct link_map): Add l_feature_1 and l_flags_1.
|
||||
* sysdeps/generic/bits/dlfcn.h: Define RTLD_NOLOAD and RTLD_NODELETE.
|
||||
* sysdeps/mips/bits/dlfcn.h: Likewise.
|
||||
|
||||
* libio/Makefile (tests): Add tst_wprintf2.
|
||||
(tst_wprintf2-ARGS): Define.
|
||||
* libio/tst_wprintf2.c: New file.
|
||||
|
12
bits/dlfcn.h
12
bits/dlfcn.h
@ -22,20 +22,24 @@
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x100
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
|
@ -48,6 +48,11 @@ _dl_close (void *_map)
|
||||
unsigned int nrellist;
|
||||
unsigned int i;
|
||||
|
||||
/* First see whether we can remove the object at all. */
|
||||
if (map->l_flags_1 & DF_1_NODELETE)
|
||||
/* Nope. Do nothing. */
|
||||
return;
|
||||
|
||||
if (map->l_opencount == 0)
|
||||
_dl_signal_error (0, map->l_name, N_("shared object not open"));
|
||||
|
||||
@ -112,7 +117,8 @@ _dl_close (void *_map)
|
||||
points to, the 0th elt being MAP itself. Decrement the reference
|
||||
counts on all the objects MAP depends on. */
|
||||
for (i = 0; i < nsearchlist; ++i)
|
||||
--list[i]->l_opencount;
|
||||
if (! (list[i]->l_flags_1 & DF_1_NODELETE))
|
||||
--list[i]->l_opencount;
|
||||
|
||||
/* Check each element of the search list to see if all references to
|
||||
it are gone. */
|
||||
|
@ -67,7 +67,7 @@ openaux (void *a)
|
||||
args->aux = _dl_map_object (args->map, args->name, 0,
|
||||
(args->map->l_type == lt_executable
|
||||
? lt_library : args->map->l_type),
|
||||
args->trace_mode);
|
||||
args->trace_mode, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -232,7 +232,7 @@ _dl_map_object_deps (struct link_map *map,
|
||||
|
||||
dep = _dl_map_object (l, name, 0,
|
||||
l->l_type == lt_executable ? lt_library :
|
||||
l->l_type, trace_mode);
|
||||
l->l_type, trace_mode, 0);
|
||||
|
||||
/* Add it in any case to the duplicate list. */
|
||||
newp = alloca (sizeof (struct list));
|
||||
@ -316,7 +316,7 @@ _dl_map_object_deps (struct link_map *map,
|
||||
args.aux = _dl_map_object (l, name, 0,
|
||||
(l->l_type == lt_executable
|
||||
? lt_library : l->l_type),
|
||||
trace_mode);
|
||||
trace_mode, 0);
|
||||
}
|
||||
|
||||
/* The auxiliary object is actually available.
|
||||
|
@ -688,7 +688,7 @@ static
|
||||
#endif
|
||||
struct link_map *
|
||||
_dl_map_object_from_fd (const char *name, int fd, char *realname,
|
||||
struct link_map *loader, int l_type)
|
||||
struct link_map *loader, int l_type, int noload)
|
||||
{
|
||||
/* This is the expected ELF header. */
|
||||
#define ELF32_CLASS ELFCLASS32
|
||||
@ -752,6 +752,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
|
||||
return l;
|
||||
}
|
||||
|
||||
if (noload)
|
||||
/* We are not supposed to load the object unless it is already
|
||||
loaded. So return now. */
|
||||
return NULL;
|
||||
|
||||
/* Print debugging message. */
|
||||
if (__builtin_expect (_dl_debug_files, 0))
|
||||
_dl_debug_message (1, "file=", name, "; generating link map\n", NULL);
|
||||
@ -1301,7 +1306,7 @@ open_path (const char *name, size_t namelen, int preloaded,
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
int type, int trace_mode)
|
||||
int type, int trace_mode, int noload)
|
||||
{
|
||||
int fd;
|
||||
char *realname;
|
||||
@ -1501,5 +1506,5 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
_dl_signal_error (errno, name, N_("cannot open shared object file"));
|
||||
}
|
||||
|
||||
return _dl_map_object_from_fd (name, fd, realname, loader, type);
|
||||
return _dl_map_object_from_fd (name, fd, realname, loader, type, noload);
|
||||
}
|
||||
|
@ -144,7 +144,17 @@ dl_open_worker (void *a)
|
||||
}
|
||||
|
||||
/* Load the named object. */
|
||||
args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0);
|
||||
args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0,
|
||||
mode & RTLD_NOLOAD);
|
||||
|
||||
/* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
|
||||
set and the object is not already loaded. */
|
||||
if (new == NULL)
|
||||
{
|
||||
assert (mode & RTLD_NOLOAD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (new->l_searchlist.r_list)
|
||||
/* It was already open. */
|
||||
return;
|
||||
@ -279,6 +289,11 @@ dl_open_worker (void *a)
|
||||
/* XXX Do we have to add something to r_dupsearchlist??? --drepper */
|
||||
}
|
||||
|
||||
/* Mark the object as not deletable if the RTLD_NODELETE flags was
|
||||
passed. */
|
||||
if (__builtin_expect (mode & RTLD_NODELETE, 0))
|
||||
new->l_flags_1 |= DF_1_NODELETE;
|
||||
|
||||
if (_dl_sysdep_start == NULL)
|
||||
/* We must be the static _dl_open in libc.a. A static program that
|
||||
has loaded a dynamic object now has competition. */
|
||||
|
@ -114,6 +114,8 @@ elf_get_dynamic_info (struct link_map *l)
|
||||
if (flags & DF_BIND_NOW)
|
||||
info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||
}
|
||||
if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
|
||||
l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||
if (info[DT_RUNPATH] != NULL)
|
||||
/* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||
info[DT_RPATH] = NULL;
|
||||
|
19
elf/elf.h
19
elf/elf.h
@ -622,7 +622,7 @@ typedef struct
|
||||
#define DT_PLTPADSZ 0x6ffffdf9
|
||||
#define DT_MOVEENT 0x6ffffdfa
|
||||
#define DT_MOVESZ 0x6ffffdfb
|
||||
#define DT_FEATURE_1 0x6ffffdfc
|
||||
#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
|
||||
#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
|
||||
the following DT_* entry. */
|
||||
#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
|
||||
@ -678,6 +678,23 @@ typedef struct
|
||||
#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
|
||||
#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
|
||||
#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
|
||||
#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
|
||||
#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
|
||||
#define DF_1_TRANS 0x00000200
|
||||
#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
|
||||
#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
|
||||
#define DF_1_NODUMP 0x00001000
|
||||
#define DF_1_CONFALT 0x00002000
|
||||
#define DF_1_ENDFILTEE 0x00004000
|
||||
|
||||
/* Flags for the feature selection in DT_FEATURE_1. */
|
||||
#define DTF_1_PARINIT 0x00000001
|
||||
#define DTF_1_CONFEXP 0x00000002
|
||||
|
||||
/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
|
||||
#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
|
||||
#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
|
||||
generally available. */
|
||||
|
||||
/* Version definition sections. */
|
||||
|
||||
|
70
elf/noload.c
Normal file
70
elf/noload.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/* First try to load an object which is a dependency. This should
|
||||
succeed. */
|
||||
if (dlopen ("testobj1.so", RTLD_LAZY | RTLD_NOLOAD) == NULL)
|
||||
{
|
||||
printf ("cannot open \"testobj1.so\": %s\n", dlerror ());
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
puts ("loading \"testobj1.so\" succeeded, OK");
|
||||
|
||||
/* Now try loading an object which is not already loaded. */
|
||||
if (dlopen ("testobj5.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
|
||||
{
|
||||
puts ("succeeded in loading \"testobj5.so\"");
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load the object and run the same test again. */
|
||||
void *p;
|
||||
|
||||
puts ("\"testobj5.so\" wasn't loaded and RTLD_NOLOAD prevented it, OK");
|
||||
|
||||
p = dlopen ("testobj5.so", RTLD_LAZY);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
printf ("cannot open \"testobj5.so\" without RTLD_NOLOAD: %s\n",
|
||||
dlerror ());
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
puts ("loading \"testobj5.so\" succeeded, OK");
|
||||
|
||||
if (dlopen ("testobj5.so", RTLD_LAZY | RTLD_NOLOAD) == NULL)
|
||||
{
|
||||
printf ("cannot open \"testobj5.so\": %s\n", dlerror ());
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
puts ("loading \"testobj5.so\" with RTLD_NOLOAD succeeded, OK");
|
||||
|
||||
if (dlclose (p) != 0)
|
||||
{
|
||||
printf ("cannot close \"testobj5.so\": %s\n", dlerror ());
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
puts ("closing \"testobj5.so\" succeeded, OK");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return 42 + a;
|
||||
}
|
10
elf/rtld.c
10
elf/rtld.c
@ -313,7 +313,7 @@ static void
|
||||
map_doit (void *a)
|
||||
{
|
||||
struct map_args *args = (struct map_args *) a;
|
||||
args->main_map = _dl_map_object (NULL, args->str, 0, lt_library, 0);
|
||||
args->main_map = _dl_map_object (NULL, args->str, 0, lt_library, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -514,7 +514,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
else
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
_dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
|
||||
_dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0, 0);
|
||||
HP_TIMING_NOW (stop);
|
||||
|
||||
HP_TIMING_DIFF (load_time, start, stop);
|
||||
@ -694,7 +694,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
|| strchr (p, '/') == NULL))
|
||||
{
|
||||
struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
|
||||
lt_library, 0);
|
||||
lt_library, 0, 0);
|
||||
if (new_map->l_opencount == 1)
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
@ -762,7 +762,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
if (p[0] != '\0')
|
||||
{
|
||||
struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
|
||||
lt_library, 0);
|
||||
lt_library, 0, 0);
|
||||
if (new_map->l_opencount == 1)
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
@ -773,7 +773,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
{
|
||||
char *p = strndupa (problem, file_size - (problem - file));
|
||||
struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
|
||||
lt_library, 0);
|
||||
lt_library, 0, 0);
|
||||
if (new_map->l_opencount == 1)
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
|
@ -214,6 +214,10 @@ struct link_map
|
||||
unsigned int l_reldepsmax;
|
||||
unsigned int l_reldepsact;
|
||||
struct link_map **l_reldeps;
|
||||
|
||||
/* Various flag words. */
|
||||
ElfW(Word) l_feature_1;
|
||||
ElfW(Word) l_flags_1;
|
||||
};
|
||||
|
||||
#endif /* link.h */
|
||||
|
@ -22,20 +22,24 @@
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x100
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
|
@ -271,7 +271,7 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
|
||||
value to allow additional security checks. */
|
||||
extern struct link_map *_dl_map_object (struct link_map *loader,
|
||||
const char *name, int preloaded,
|
||||
int type, int trace_mode)
|
||||
int type, int trace_mode, int noload)
|
||||
internal_function;
|
||||
|
||||
/* Call _dl_map_object on the dependencies of MAP, and set up
|
||||
|
@ -22,20 +22,24 @@
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_LAZY 0x0001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x0002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00008 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x004
|
||||
#define RTLD_GLOBAL 0x0004
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
|
Loading…
Reference in New Issue
Block a user