mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 23:10:06 +00:00
Update.
2000-12-30 Ulrich Drepper <drepper@redhat.com> * elf/dl-close.c (_dl_close): We can ignore the NODELETE flag if the object was not yet initialized. 2000-12-28 H.J. Lu <hjl@gnu.org> * elf/dl-deps.c (_dl_map_object_deps): Make sure the DSO state is always consistent even if its dependency is failed. * elf/dl-open.c (_dl_open): Increment the open count before calling _dl_close () in case of failure. * elf/neededtest4.c: New file. * elf/neededobj5.c: New file. * elf/neededobj6.c: New file. * elf/Makefile (distribute): Add neededobj5.c and neededobj6.c. (tests): Add neededtest4. (modules-names): Add neededobj5 and neededobj6. ($(objpfx)neededobj6.so): New target. ($(objpfx)neededtest4): New target. ($(objpfx)neededtest4.out): New target.
This commit is contained in:
parent
d9af88677f
commit
c77a447822
24
ChangeLog
24
ChangeLog
@ -1,3 +1,27 @@
|
|||||||
|
2000-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-close.c (_dl_close): We can ignore the NODELETE flag if the
|
||||||
|
object was not yet initialized.
|
||||||
|
|
||||||
|
2000-12-28 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
|
* elf/dl-deps.c (_dl_map_object_deps): Make sure the DSO state
|
||||||
|
is always consistent even if its dependency is failed.
|
||||||
|
|
||||||
|
* elf/dl-open.c (_dl_open): Increment the open count before
|
||||||
|
calling _dl_close () in case of failure.
|
||||||
|
|
||||||
|
* elf/neededtest4.c: New file.
|
||||||
|
* elf/neededobj5.c: New file.
|
||||||
|
* elf/neededobj6.c: New file.
|
||||||
|
|
||||||
|
* elf/Makefile (distribute): Add neededobj5.c and neededobj6.c.
|
||||||
|
(tests): Add neededtest4.
|
||||||
|
(modules-names): Add neededobj5 and neededobj6.
|
||||||
|
($(objpfx)neededobj6.so): New target.
|
||||||
|
($(objpfx)neededtest4): New target.
|
||||||
|
($(objpfx)neededtest4.out): New target.
|
||||||
|
|
||||||
2000-12-28 Joseph S. Myers <jsm28@cam.ac.uk>
|
2000-12-28 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||||
|
|
||||||
* misc/sys/cdefs.h (__attribute_format_strfmon__): Define.
|
* misc/sys/cdefs.h (__attribute_format_strfmon__): Define.
|
||||||
|
@ -55,6 +55,7 @@ distribute := $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
|||||||
reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \
|
reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \
|
||||||
nextmod1.c nextmod2.c pathoptobj.c tst-pathopt.sh \
|
nextmod1.c nextmod2.c pathoptobj.c tst-pathopt.sh \
|
||||||
neededobj1.c neededobj2.c neededobj3.c neededobj4.c \
|
neededobj1.c neededobj2.c neededobj3.c neededobj4.c \
|
||||||
|
neededobj5.c neededobj6.c \
|
||||||
unload2mod.c unload2dep.c ltglobmod1.c ltglobmod2.c \
|
unload2mod.c unload2dep.c ltglobmod1.c ltglobmod2.c \
|
||||||
testobj.h vismod.h
|
testobj.h vismod.h
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
|||||||
constload1 order $(tests-vis-$(have-protected)) noload filter unload \
|
constload1 order $(tests-vis-$(have-protected)) noload filter unload \
|
||||||
reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
|
reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
|
||||||
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
|
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
|
||||||
neededtest3 unload2 lateglobal
|
neededtest3 neededtest4 unload2 lateglobal
|
||||||
test-srcs = tst-pathopt
|
test-srcs = tst-pathopt
|
||||||
tests-vis-yes = vismain
|
tests-vis-yes = vismain
|
||||||
tests-nodelete-yes = nodelete
|
tests-nodelete-yes = nodelete
|
||||||
@ -113,6 +114,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
|||||||
$(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
|
$(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
|
||||||
reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
|
reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
|
||||||
neededobj1 neededobj2 neededobj3 neededobj4 \
|
neededobj1 neededobj2 neededobj3 neededobj4 \
|
||||||
|
neededobj5 neededobj6 \
|
||||||
unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj
|
unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj
|
||||||
modules-vis-yes = vismod1 vismod2 vismod3
|
modules-vis-yes = vismod1 vismod2 vismod3
|
||||||
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
|
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
|
||||||
@ -263,6 +265,7 @@ $(objpfx)neededobj2.so: $(objpfx)neededobj1.so $(libdl)
|
|||||||
$(objpfx)neededobj3.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so $(libdl)
|
$(objpfx)neededobj3.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so $(libdl)
|
||||||
$(objpfx)neededobj4.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
|
$(objpfx)neededobj4.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
|
||||||
$(objpfx)neededobj3.so $(libdl)
|
$(objpfx)neededobj3.so $(libdl)
|
||||||
|
$(objpfx)neededobj6.so: $(objpfx)neededobj5.so
|
||||||
$(objpfx)unload2mod.so: $(objpfx)unload2dep.so
|
$(objpfx)unload2mod.so: $(objpfx)unload2dep.so
|
||||||
$(objpfx)ltglobmod2.so: $(libdl)
|
$(objpfx)ltglobmod2.so: $(libdl)
|
||||||
|
|
||||||
@ -287,6 +290,10 @@ $(objpfx)neededtest3: $(libdl)
|
|||||||
$(objpfx)neededtest3.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
|
$(objpfx)neededtest3.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
|
||||||
$(objpfx)neededobj3.so $(objpfx)neededobj4.so
|
$(objpfx)neededobj3.so $(objpfx)neededobj4.so
|
||||||
|
|
||||||
|
neededtest4-ENV = LC_ALL=C LANGUAGE=C
|
||||||
|
$(objpfx)neededtest4: $(libdl) $(objpfx)neededobj1.so
|
||||||
|
$(objpfx)neededtest4.out: $(objpfx)neededobj5.so $(objpfx)neededobj6.so
|
||||||
|
|
||||||
$(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
|
$(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
|
||||||
LDFLAGS-restest1 = -rdynamic
|
LDFLAGS-restest1 = -rdynamic
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ _dl_close (void *_map)
|
|||||||
unsigned int *new_opencount;
|
unsigned int *new_opencount;
|
||||||
|
|
||||||
/* First see whether we can remove the object at all. */
|
/* First see whether we can remove the object at all. */
|
||||||
if (map->l_flags_1 & DF_1_NODELETE)
|
if ((map->l_flags_1 & DF_1_NODELETE) && map->l_init_called)
|
||||||
/* Nope. Do nothing. */
|
/* Nope. Do nothing. */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ _dl_close (void *_map)
|
|||||||
}
|
}
|
||||||
--new_opencount[0];
|
--new_opencount[0];
|
||||||
for (i = 1; list[i] != NULL; ++i)
|
for (i = 1; list[i] != NULL; ++i)
|
||||||
if (! (list[i]->l_flags_1 & DF_1_NODELETE)
|
if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called)
|
||||||
/* Decrement counter. */
|
/* Decrement counter. */
|
||||||
&& --new_opencount[i] == 0
|
&& --new_opencount[i] == 0
|
||||||
/* Test whether this object was also loaded directly. */
|
/* Test whether this object was also loaded directly. */
|
||||||
@ -113,7 +113,8 @@ _dl_close (void *_map)
|
|||||||
struct link_map **dep_list = list[i]->l_searchlist.r_list;
|
struct link_map **dep_list = list[i]->l_searchlist.r_list;
|
||||||
|
|
||||||
for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j)
|
for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j)
|
||||||
if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE))
|
if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE)
|
||||||
|
|| ! dep_list[j]->l_init_called)
|
||||||
{
|
{
|
||||||
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
|
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
|
||||||
--new_opencount[dep_list[j]->l_idx];
|
--new_opencount[dep_list[j]->l_idx];
|
||||||
@ -127,7 +128,7 @@ _dl_close (void *_map)
|
|||||||
struct link_map *imap = list[i];
|
struct link_map *imap = list[i];
|
||||||
if (new_opencount[i] == 0 && imap->l_type == lt_loaded
|
if (new_opencount[i] == 0 && imap->l_type == lt_loaded
|
||||||
&& (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY])
|
&& (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY])
|
||||||
&& ! (imap->l_flags_1 & DF_1_NODELETE)
|
&& (! (imap->l_flags_1 & DF_1_NODELETE) || ! imap->l_init_called)
|
||||||
/* Skip any half-cooked objects that were never initialized. */
|
/* Skip any half-cooked objects that were never initialized. */
|
||||||
&& imap->l_init_called)
|
&& imap->l_init_called)
|
||||||
{
|
{
|
||||||
|
@ -141,6 +141,10 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
struct list known[1 + npreloads + 1];
|
struct list known[1 + npreloads + 1];
|
||||||
struct list *runp, *utail, *dtail;
|
struct list *runp, *utail, *dtail;
|
||||||
unsigned int nlist, nduplist, i;
|
unsigned int nlist, nduplist, i;
|
||||||
|
/* Object name. */
|
||||||
|
const char *name;
|
||||||
|
int errno_saved;
|
||||||
|
int errno_reason;
|
||||||
|
|
||||||
auto inline void preload (struct link_map *map);
|
auto inline void preload (struct link_map *map);
|
||||||
|
|
||||||
@ -192,6 +196,10 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
The whole process is complicated by the fact that we better
|
The whole process is complicated by the fact that we better
|
||||||
should use alloca for the temporary list elements. But using
|
should use alloca for the temporary list elements. But using
|
||||||
alloca means we cannot use recursive function calls. */
|
alloca means we cannot use recursive function calls. */
|
||||||
|
errno_saved = errno;
|
||||||
|
errno_reason = 0;
|
||||||
|
errno = 0;
|
||||||
|
name = NULL;
|
||||||
for (runp = known; runp; )
|
for (runp = known; runp; )
|
||||||
{
|
{
|
||||||
struct link_map *l = runp->map;
|
struct link_map *l = runp->map;
|
||||||
@ -227,15 +235,24 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
struct link_map *dep;
|
struct link_map *dep;
|
||||||
/* Allocate new entry. */
|
/* Allocate new entry. */
|
||||||
struct list *newp;
|
struct list *newp;
|
||||||
/* Object name. */
|
const char *objname;
|
||||||
const char *name;
|
const char *errstring;
|
||||||
|
|
||||||
/* Recognize DSTs. */
|
/* Recognize DSTs. */
|
||||||
name = expand_dst (l, strtab + d->d_un.d_val, 0);
|
name = expand_dst (l, strtab + d->d_un.d_val, 0);
|
||||||
|
/* Store the tag in the argument structure. */
|
||||||
|
args.name = name;
|
||||||
|
|
||||||
dep = _dl_map_object (l, name, 0,
|
if (_dl_catch_error (&objname, &errstring, openaux, &args))
|
||||||
l->l_type == lt_executable ? lt_library :
|
{
|
||||||
l->l_type, trace_mode, 0);
|
if (errno)
|
||||||
|
errno_reason = errno;
|
||||||
|
else
|
||||||
|
errno_reason = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dep = args.aux;
|
||||||
|
|
||||||
/* Add it in any case to the duplicate list. */
|
/* Add it in any case to the duplicate list. */
|
||||||
newp = alloca (sizeof (struct list));
|
newp = alloca (sizeof (struct list));
|
||||||
@ -266,18 +283,15 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
const char *objname;
|
const char *objname;
|
||||||
const char *errstring;
|
const char *errstring;
|
||||||
struct list *newp;
|
struct list *newp;
|
||||||
/* Object name. */
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/* Recognize DSTs. */
|
/* Recognize DSTs. */
|
||||||
name = expand_dst (l, strtab + d->d_un.d_val,
|
name = expand_dst (l, strtab + d->d_un.d_val,
|
||||||
d->d_tag == DT_AUXILIARY);
|
d->d_tag == DT_AUXILIARY);
|
||||||
|
/* Store the tag in the argument structure. */
|
||||||
|
args.name = name;
|
||||||
|
|
||||||
if (d->d_tag == DT_AUXILIARY)
|
if (d->d_tag == DT_AUXILIARY)
|
||||||
{
|
{
|
||||||
/* Store the tag in the argument structure. */
|
|
||||||
args.name = name;
|
|
||||||
|
|
||||||
/* Say that we are about to load an auxiliary library. */
|
/* Say that we are about to load an auxiliary library. */
|
||||||
if (__builtin_expect (_dl_debug_libs, 0))
|
if (__builtin_expect (_dl_debug_libs, 0))
|
||||||
_dl_debug_message (1, "load auxiliary object=",
|
_dl_debug_message (1, "load auxiliary object=",
|
||||||
@ -310,10 +324,14 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
"\n", NULL);
|
"\n", NULL);
|
||||||
|
|
||||||
/* For filter objects the dependency must be available. */
|
/* For filter objects the dependency must be available. */
|
||||||
args.aux = _dl_map_object (l, name, 0,
|
if (_dl_catch_error (&objname, &errstring, openaux, &args))
|
||||||
(l->l_type == lt_executable
|
{
|
||||||
? lt_library : l->l_type),
|
if (errno)
|
||||||
trace_mode, 0);
|
errno_reason = errno;
|
||||||
|
else
|
||||||
|
errno_reason = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The auxiliary object is actually available.
|
/* The auxiliary object is actually available.
|
||||||
@ -460,6 +478,10 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
while (runp != NULL && runp->done);
|
while (runp != NULL && runp->done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (errno == 0 && errno_saved != 0)
|
||||||
|
__set_errno (errno_saved);
|
||||||
|
|
||||||
if (map->l_initfini != NULL && map->l_type == lt_loaded)
|
if (map->l_initfini != NULL && map->l_type == lt_loaded)
|
||||||
{
|
{
|
||||||
/* This object was previously loaded as a dependency and we have
|
/* This object was previously loaded as a dependency and we have
|
||||||
@ -558,4 +580,8 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
}
|
}
|
||||||
/* Terminate the list of dependencies. */
|
/* Terminate the list of dependencies. */
|
||||||
map->l_initfini[nlist] = NULL;
|
map->l_initfini[nlist] = NULL;
|
||||||
|
|
||||||
|
if (errno_reason)
|
||||||
|
_dl_signal_error (errno_reason == -1 ? 0 : errno_reason,
|
||||||
|
name ?: "", N_("cannot load shared object file"));
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,17 @@ _dl_open (const char *file, int mode, const void *caller)
|
|||||||
/* Remove the object from memory. It may be in an inconsistent
|
/* Remove the object from memory. It may be in an inconsistent
|
||||||
state if relocation failed, for example. */
|
state if relocation failed, for example. */
|
||||||
if (args.map)
|
if (args.map)
|
||||||
_dl_close (args.map);
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Increment open counters for all objects which did not get
|
||||||
|
correctly loaded. */
|
||||||
|
for (i = 0; i < args.map->l_searchlist.r_nlist; ++i)
|
||||||
|
if (args.map->l_searchlist.r_list[i]->l_opencount == 0)
|
||||||
|
args.map->l_searchlist.r_list[i]->l_opencount = 1;
|
||||||
|
|
||||||
|
_dl_close (args.map);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make a local copy of the error string so that we can release the
|
/* Make a local copy of the error string so that we can release the
|
||||||
memory allocated for it. */
|
memory allocated for it. */
|
||||||
|
5
elf/neededobj5.c
Normal file
5
elf/neededobj5.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extern void a1_function (void);
|
||||||
|
|
||||||
|
void a1_function (void)
|
||||||
|
{
|
||||||
|
}
|
7
elf/neededobj6.c
Normal file
7
elf/neededobj6.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
extern void a1_function (void);
|
||||||
|
extern void a2_function (void);
|
||||||
|
|
||||||
|
void a2_function (void)
|
||||||
|
{
|
||||||
|
a1_function ();
|
||||||
|
}
|
156
elf/neededtest4.c
Normal file
156
elf/neededtest4.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include <dlfcn.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <link.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_loaded_objects (const char **loaded)
|
||||||
|
{
|
||||||
|
struct link_map *lm;
|
||||||
|
int n;
|
||||||
|
int *found = NULL;
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (n = 0; loaded[n]; n++)
|
||||||
|
/* NOTHING */;
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
found = (int *) alloca (sizeof (int) * n);
|
||||||
|
memset (found, 0, sizeof (int) * n);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" Name\n");
|
||||||
|
printf(" --------------------------------------------------------\n");
|
||||||
|
for (lm = _r_debug.r_map; lm; lm = lm->l_next)
|
||||||
|
{
|
||||||
|
if (lm->l_name && lm->l_name[0])
|
||||||
|
printf(" %s, count = %d\n", lm->l_name, (int) lm->l_opencount);
|
||||||
|
if (lm->l_type == lt_loaded && lm->l_name)
|
||||||
|
{
|
||||||
|
int match = 0;
|
||||||
|
for (n = 0; loaded[n] != NULL; n++)
|
||||||
|
{
|
||||||
|
if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
|
||||||
|
{
|
||||||
|
found[n] = 1;
|
||||||
|
match = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match == 0)
|
||||||
|
{
|
||||||
|
++errors;
|
||||||
|
printf ("ERRORS: %s is not unloaded\n", lm->l_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0; loaded[n] != NULL; n++)
|
||||||
|
{
|
||||||
|
if (found[n] == 0)
|
||||||
|
{
|
||||||
|
++errors;
|
||||||
|
printf ("ERRORS: %s is not loaded\n", loaded[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void c_function (void);
|
||||||
|
extern char *dirname (__const char *__filename);
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
void *obj;
|
||||||
|
const char *loaded[] = { NULL, NULL, NULL};
|
||||||
|
int errors = 0;
|
||||||
|
void (*f) (void);
|
||||||
|
const char *dir = dirname (argv [0]);
|
||||||
|
char *oldfilename;
|
||||||
|
char *newfilename;
|
||||||
|
|
||||||
|
c_function ();
|
||||||
|
|
||||||
|
printf ("\nThis is what is in memory now:\n");
|
||||||
|
errors += check_loaded_objects (loaded);
|
||||||
|
|
||||||
|
printf( "Loading shared object neededobj6.so\n");
|
||||||
|
obj = dlopen( "neededobj6.so", RTLD_LAZY);
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
printf ("%s\n", dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
f = dlsym (obj, "a2_function");
|
||||||
|
if (f == NULL)
|
||||||
|
{
|
||||||
|
printf ("%s\n", dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
f ();
|
||||||
|
loaded[0] = "neededobj5.so";
|
||||||
|
loaded[1] = "neededobj6.so";
|
||||||
|
errors += check_loaded_objects (loaded);
|
||||||
|
|
||||||
|
printf ("Closing neededobj6.so\n");
|
||||||
|
dlclose (obj);
|
||||||
|
loaded[0] = NULL;
|
||||||
|
errors += check_loaded_objects (loaded);
|
||||||
|
|
||||||
|
printf ("Rename neededobj5.so\n");
|
||||||
|
oldfilename = alloca (strlen (dir) + 1 + sizeof ("neededobj5.so"));
|
||||||
|
strcpy (oldfilename, dir);
|
||||||
|
strcat (oldfilename, "/");
|
||||||
|
strcat (oldfilename, "neededobj5.so");
|
||||||
|
newfilename = alloca (strlen (oldfilename) + sizeof (".renamed"));
|
||||||
|
strcpy (newfilename, oldfilename);
|
||||||
|
strcat (newfilename, ".renamed");
|
||||||
|
if (rename (oldfilename, newfilename))
|
||||||
|
{
|
||||||
|
perror ("rename");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf( "Loading shared object neededobj6.so\n");
|
||||||
|
obj = dlopen( "neededobj6.so", RTLD_LAZY);
|
||||||
|
if (obj == NULL)
|
||||||
|
printf ("%s\n", dlerror ());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("neededobj6.so should fail to load\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf( "Loading shared object neededobj1.so\n");
|
||||||
|
obj = dlopen( "neededobj1.so", RTLD_LAZY);
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
printf ("%s\n", dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
errors += check_loaded_objects (loaded);
|
||||||
|
f = dlsym (obj, "c_function");
|
||||||
|
if (f == NULL)
|
||||||
|
{
|
||||||
|
printf ("%s\n", dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
f ();
|
||||||
|
|
||||||
|
printf ("Restore neededobj5.so\n");
|
||||||
|
if (rename (newfilename, oldfilename))
|
||||||
|
{
|
||||||
|
perror ("rename");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors != 0)
|
||||||
|
printf ("%d errors found\n", errors);
|
||||||
|
return errors;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user