diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-01-24 20:12:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-01-24 20:12:10 +0000 |
commit | bed12f78fab86b2349cab6e7f4c0e46bde5e9711 (patch) | |
tree | 5e98ba1f47f60b6e5cd4461c3fba7d01cd8add51 /elf/tst-dlmodcount.c | |
parent | e8648a5a87fd0c472cb6002df8111b9a8ec3fba6 (diff) | |
download | glibc-bed12f78fab86b2349cab6e7f4c0e46bde5e9711.tar.gz glibc-bed12f78fab86b2349cab6e7f4c0e46bde5e9711.tar.xz glibc-bed12f78fab86b2349cab6e7f4c0e46bde5e9711.zip |
Update.
2004-01-23 David Mosberger <davidm@hpl.hp.com> * sysdeps/generic/ldsodefs.h (struct rtld_global): Add members _dl_load_adds and _dl_load_subs. * elf/dl-support.c (_dl_load_adds): New variable. (_dl_load_subs): Likewise. * elf/dl-object.c (_dl_new_object): Increment dl_load_adds. * elf/dl-close.c (_dl_close): Increment dl_load_subs. * elf/link.h (struct dl_phdr_info): Add members dlpi_adds and dlpi_subs. * include/link.h: Likewise. * elf/dl-iteratephdr.c (__dl_iterate_phdr): Initialize dlpi_adds and dlpi_subs members. (dl_iterate_phdr): Likewise. * elf/tst-dlmodcount.c: New file. * elf/Makefile (distribute): Mention tst-dlmodcount.c. (tests): If build-shared, mention tst-dlmodcount. ($(objpfx)tst-dlmodcount): If build-shared, build and run tst-dlmodcount.
Diffstat (limited to 'elf/tst-dlmodcount.c')
-rw-r--r-- | elf/tst-dlmodcount.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/elf/tst-dlmodcount.c b/elf/tst-dlmodcount.c new file mode 100644 index 0000000000..b48ed0e2ae --- /dev/null +++ b/elf/tst-dlmodcount.c @@ -0,0 +1,107 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Mosberger <davidm@hpl.hp.com>, 2004. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <link.h> +#include <stdio.h> + +#define SET 0 +#define ADD 1 +#define REMOVE 2 + +#define leq(l,r) (((r) - (l)) <= ~0ULL / 2) + +static int +callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + static int last_adds = 0, last_subs = 0; + intptr_t cmd = (intptr_t) ptr; + + printf (" size = %Zu\n", size); + if (size < (offsetof (struct dl_phdr_info, dlpi_subs) + + sizeof (info->dlpi_subs))) + { + fprintf (stderr, "dl_iterate_phdr failed to pass dlpi_adds/dlpi_subs\n"); + exit (5); + } + + printf (" dlpi_adds = %Lu dlpi_subs = %Lu\n", + info->dlpi_adds, info->dlpi_subs); + + switch (cmd) + { + case SET: + break; + + case ADD: + if (leq (info->dlpi_adds, last_adds)) + { + fprintf (stderr, "dlpi_adds failed to get incremented!\n"); + exit (3); + } + break; + + case REMOVE: + if (leq (info->dlpi_subs, last_subs)) + { + fprintf (stderr, "dlpi_subs failed to get incremented!\n"); + exit (4); + } + break; + } + last_adds = info->dlpi_adds; + last_subs = info->dlpi_subs; + return -1; +} + +static void * +load (const char *path) +{ + void *handle; + + printf ("loading `%s'\n", path); + handle = dlopen (path, RTLD_LAZY); + if (!handle) + exit (1); + dl_iterate_phdr (callback, (void *)(intptr_t) ADD); + return handle; +} + +static void +unload (const char *path, void *handle) +{ + int ret; + + printf ("unloading `%s'\n", path); + if (dlclose (handle) < 0) + exit (2); + dl_iterate_phdr (callback, (void *)(intptr_t) REMOVE); +} + +int +main (int argc, char **argv) +{ + void *handle1, *handle2; + + dl_iterate_phdr (callback, (void *)(intptr_t) SET); + handle1 = load ("firstobj.so"); + handle2 = load ("globalmod1.so"); + unload ("firstobj.so", handle1); + unload ("globalmod1.so", handle2); + return 0; +} |