Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Ulrich Drepper committed Dec 31, 2000
1 parent d9af886 commit c77a447
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 20 deletions.
24 changes: 24 additions & 0 deletions 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>

* misc/sys/cdefs.h (__attribute_format_strfmon__): Define.
Expand Down
9 changes: 8 additions & 1 deletion elf/Makefile
Expand Up @@ -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 \
nextmod1.c nextmod2.c pathoptobj.c tst-pathopt.sh \
neededobj1.c neededobj2.c neededobj3.c neededobj4.c \
neededobj5.c neededobj6.c \
unload2mod.c unload2dep.c ltglobmod1.c ltglobmod2.c \
testobj.h vismod.h

Expand Down Expand Up @@ -100,7 +101,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
constload1 order $(tests-vis-$(have-protected)) noload filter unload \
reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
neededtest3 unload2 lateglobal
neededtest3 neededtest4 unload2 lateglobal
test-srcs = tst-pathopt
tests-vis-yes = vismain
tests-nodelete-yes = nodelete
Expand All @@ -113,6 +114,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
$(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
neededobj1 neededobj2 neededobj3 neededobj4 \
neededobj5 neededobj6 \
unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj
modules-vis-yes = vismod1 vismod2 vismod3
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
Expand Down Expand Up @@ -263,6 +265,7 @@ $(objpfx)neededobj2.so: $(objpfx)neededobj1.so $(libdl)
$(objpfx)neededobj3.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so $(libdl)
$(objpfx)neededobj4.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
$(objpfx)neededobj3.so $(libdl)
$(objpfx)neededobj6.so: $(objpfx)neededobj5.so
$(objpfx)unload2mod.so: $(objpfx)unload2dep.so
$(objpfx)ltglobmod2.so: $(libdl)

Expand All @@ -287,6 +290,10 @@ $(objpfx)neededtest3: $(libdl)
$(objpfx)neededtest3.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.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)
LDFLAGS-restest1 = -rdynamic

Expand Down
9 changes: 5 additions & 4 deletions elf/dl-close.c
Expand Up @@ -55,7 +55,7 @@ _dl_close (void *_map)
unsigned int *new_opencount;

/* 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. */
return;

Expand Down Expand Up @@ -101,7 +101,7 @@ _dl_close (void *_map)
}
--new_opencount[0];
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. */
&& --new_opencount[i] == 0
/* Test whether this object was also loaded directly. */
Expand All @@ -113,7 +113,8 @@ _dl_close (void *_map)
struct link_map **dep_list = list[i]->l_searchlist.r_list;

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);
--new_opencount[dep_list[j]->l_idx];
Expand All @@ -127,7 +128,7 @@ _dl_close (void *_map)
struct link_map *imap = list[i];
if (new_opencount[i] == 0 && imap->l_type == lt_loaded
&& (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. */
&& imap->l_init_called)
{
Expand Down
54 changes: 40 additions & 14 deletions elf/dl-deps.c
Expand Up @@ -141,6 +141,10 @@ _dl_map_object_deps (struct link_map *map,
struct list known[1 + npreloads + 1];
struct list *runp, *utail, *dtail;
unsigned int nlist, nduplist, i;
/* Object name. */
const char *name;
int errno_saved;
int errno_reason;

auto inline void preload (struct link_map *map);

Expand Down Expand Up @@ -192,6 +196,10 @@ _dl_map_object_deps (struct link_map *map,
The whole process is complicated by the fact that we better
should use alloca for the temporary list elements. But using
alloca means we cannot use recursive function calls. */
errno_saved = errno;
errno_reason = 0;
errno = 0;
name = NULL;
for (runp = known; runp; )
{
struct link_map *l = runp->map;
Expand Down Expand Up @@ -227,15 +235,24 @@ _dl_map_object_deps (struct link_map *map,
struct link_map *dep;
/* Allocate new entry. */
struct list *newp;
/* Object name. */
const char *name;
const char *objname;
const char *errstring;

/* Recognize DSTs. */
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,
l->l_type == lt_executable ? lt_library :
l->l_type, trace_mode, 0);
if (_dl_catch_error (&objname, &errstring, openaux, &args))
{
if (errno)
errno_reason = errno;
else
errno_reason = -1;
goto out;
}
else
dep = args.aux;

/* Add it in any case to the duplicate list. */
newp = alloca (sizeof (struct list));
Expand Down Expand Up @@ -266,18 +283,15 @@ _dl_map_object_deps (struct link_map *map,
const char *objname;
const char *errstring;
struct list *newp;
/* Object name. */
const char *name;

/* Recognize DSTs. */
name = expand_dst (l, strtab + d->d_un.d_val,
d->d_tag == DT_AUXILIARY);
/* Store the tag in the argument structure. */
args.name = name;

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. */
if (__builtin_expect (_dl_debug_libs, 0))
_dl_debug_message (1, "load auxiliary object=",
Expand Down Expand Up @@ -310,10 +324,14 @@ _dl_map_object_deps (struct link_map *map,
"\n", NULL);

/* For filter objects the dependency must be available. */
args.aux = _dl_map_object (l, name, 0,
(l->l_type == lt_executable
? lt_library : l->l_type),
trace_mode, 0);
if (_dl_catch_error (&objname, &errstring, openaux, &args))
{
if (errno)
errno_reason = errno;
else
errno_reason = -1;
goto out;
}
}

/* The auxiliary object is actually available.
Expand Down Expand Up @@ -460,6 +478,10 @@ _dl_map_object_deps (struct link_map *map,
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)
{
/* This object was previously loaded as a dependency and we have
Expand Down Expand Up @@ -558,4 +580,8 @@ _dl_map_object_deps (struct link_map *map,
}
/* Terminate the list of dependencies. */
map->l_initfini[nlist] = NULL;

if (errno_reason)
_dl_signal_error (errno_reason == -1 ? 0 : errno_reason,
name ?: "", N_("cannot load shared object file"));
}
12 changes: 11 additions & 1 deletion elf/dl-open.c
Expand Up @@ -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
state if relocation failed, for example. */
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
memory allocated for it. */
Expand Down
5 changes: 5 additions & 0 deletions elf/neededobj5.c
@@ -0,0 +1,5 @@
extern void a1_function (void);

void a1_function (void)
{
}
7 changes: 7 additions & 0 deletions elf/neededobj6.c
@@ -0,0 +1,7 @@
extern void a1_function (void);
extern void a2_function (void);

void a2_function (void)
{
a1_function ();
}

0 comments on commit c77a447

Please sign in to comment.