glibc/elf/unload.c
Roland McGrath d78efd9f36 * elf/tst-tls-dlinfo.c: New file.
* elf/Makefile (tests): Add it.
	($(objpfx)tst-tls-dlinfo): Depend on $(libdl).
	($(objpfx)tst-tls-dlinfo.out): Depend on $(objpfx)tst-tlsmod2.so.

	* dlfcn/dlfcn.h (RTLD_DI_PROFILENAME, RTLD_DI_PROFILEOUT): New enum
	values, reserve unsupported requested names used on Solaris.
	(RTLD_DI_TLS_MODID, RTLD_DI_TLS_DATA): New enum values.
	(RTLD_DI_MAX): Likewise.
	* dlfcn/dlinfo.c (dlinfo_doit): Handle RTLD_DI_TLS_MODID and
	RTLD_DI_TLS_DATA.

	* elf/dl-tls.c (_dl_tls_get_addr_soft): New function.
	* sysdeps/generic/ldsodefs.h: Declare it.
	* elf/Versions (ld: GLIBC_PRIVATE): Add it.
	* elf/link.h (struct dl_phdr_info): New members dlpi_tls_modid,
	dlpi_tls_data.
	* elf/dl-iteratephdr.c (__dl_iterate_phdr): Fill them in.

	* include/link.h: Don't copy contents from elf/link.h.
	Instead, #include it while #define'ing around link_map.
	* elf/dl-debug.c (_dl_debug_initialize): Add a cast.
	Add bogus extern decl to verify link_map members.
	* elf/loadtest.c (MAPS): New macro, cast _r_debug._r_map.
	(OUT, main): Use it in place of _r_debug._r_map.
	* elf/unload.c: Likewise.
	* elf/unload2.c: Likewise.
	* elf/neededtest.c (check_loaded_objects): Likewise.
	* elf/neededtest2.c (check_loaded_objects): Likewise.
	* elf/neededtest3.c (check_loaded_objects): Likewise.
	* elf/neededtest4.c (check_loaded_objects): Likewise.
	* elf/circleload1.c (check_loaded_objects): Likewise.
2006-03-01 06:18:49 +00:00

92 lines
1.9 KiB
C

/* Test for unloading (really unmapping) of objects. By Franz Sirl.
This test does not have to passed in all dlopen() et.al. implementation
since it is not required the unloading actually happens. But we
require it for glibc. */
#include <dlfcn.h>
#include <link.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>
#define MAPS ((struct link_map *) _r_debug.r_map)
#define OUT \
for (map = MAPS; map != NULL; map = map->l_next) \
if (map->l_type == lt_loaded) \
printf ("name = \"%s\", direct_opencount = %d\n", \
map->l_name, (int) map->l_direct_opencount); \
fflush (stdout)
typedef struct
{
void *next;
} strct;
int
main (void)
{
void *sohandle;
strct *testdat;
int ret;
int result = 0;
struct link_map *map;
mtrace ();
puts ("\nBefore");
OUT;
sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
if (sohandle == NULL)
{
printf ("*** first dlopen failed: %s\n", dlerror ());
exit (1);
}
puts ("\nAfter loading unloadmod.so");
OUT;
testdat = dlsym (sohandle, "testdat");
testdat->next = (void *) -1;
ret = dlclose (sohandle);
if (ret != 0)
{
puts ("*** first dlclose failed");
result = 1;
}
puts ("\nAfter closing unloadmod.so");
OUT;
sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
if (sohandle == NULL)
{
printf ("*** second dlopen failed: %s\n", dlerror ());
exit (1);
}
puts ("\nAfter loading unloadmod.so the second time");
OUT;
testdat = dlsym (sohandle, "testdat");
if (testdat->next == (void *) -1)
{
puts ("*** testdat->next == (void *) -1");
result = 1;
}
ret = dlclose (sohandle);
if (ret != 0)
{
puts ("*** second dlclose failed");
result = 1;
}
puts ("\nAfter closing unloadmod.so again");
OUT;
return result;
}