glibc/elf/tst-dlclose-lazy.c
Florian Weimer d0f07f7df8 elf: Make more functions available for binding during dlclose (bug 30425)
Previously, after destructors for a DSO have been invoked, ld.so refused
to bind against that DSO in all cases.  Relax this restriction somewhat
if the referencing object is itself a DSO that is being unloaded.  This
assumes that the symbol reference is not going to be stored anywhere.

The situation in the test case can arise fairly easily with C++ and
objects that are built with different optimization levels and therefore
define different functions with vague linkage.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-05-30 13:25:50 +02:00

48 lines
1.9 KiB
C

/* Test lazy binding during dlclose (bug 30425).
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This test re-creates a situation that can arise naturally for C++
applications due to the use of vague linkage and differences in the
set of compiler-emitted functions. A function in
tst-dlclose-lazy-mod1.so (exported_function) interposes a function
in tst-dlclose-lazy-mod2.so. This function is called from the
destructor in tst-dlclose-lazy-mod2.so, after the destructor for
tst-dlclose-lazy-mod1.so has already completed. Prior to the fix
for bug 30425, this would lead to a lazy binding failure in
tst-dlclose-lazy-mod1.so because dlclose had already marked the DSO
as unavailable for binding (by setting l_removed). */
#include <dlfcn.h>
#include <support/xdlfcn.h>
#include <support/check.h>
int
main (void)
{
/* Load tst-dlclose-lazy-mod1.so, indirectly loading
tst-dlclose-lazy-mod2.so. */
void *handle = xdlopen ("tst-dlclose-lazy-mod1.so", RTLD_GLOBAL | RTLD_LAZY);
/* Invoke the destructor of tst-dlclose-lazy-mod2.so, which calls
into tst-dlclose-lazy-mod1.so after its destructor has been
called. */
xdlclose (handle);
return 0;
}