This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
>>>>> On Thu, 22 Jan 2004 07:29:45 +0100, Jakub Jelinek <jakub@redhat.com> said: Jakub> I'd make the counters unsigned long long instead to avoid Jakub> wrap around. Fine by me. Jakub> Also, could you write a testcase for it? dl_iterate_phdr, Jakub> then dlopen some shlib in elf, then dl_iterate_phdr again, Jakub> check the counters, dlclose etc. Sure. Attached is an updated patch. "make check subdirs=elf" passes all tests (including the new tst-dlmodcount test). If it looks OK, please apply. --david ChangeLog 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. Index: elf/Makefile --- elf/Makefile +++ elf/Makefile @@ -80,7 +80,7 @@ reldep9.c reldep9mod1.c reldep9mod2.c reldep9mod3.c \ tst-array1.exp tst-array2.exp tst-array4.exp \ tst-array2dep.c \ - tst-execstack-mod.c \ + tst-execstack-mod.c tst-dlmodcount.c \ check-textrel.c dl-sysdep.h CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables @@ -151,7 +151,7 @@ restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \ - $(tests-execstack-$(have-z-execstack)) + $(tests-execstack-$(have-z-execstack)) tst-dlmodcount # reldep9 test-srcs = tst-pathopt tests-vis-yes = vismain @@ -713,4 +713,8 @@ $(sort $(wildcard $(common-objpfx)*/lib*.so \ $(common-objpfx)iconvdata/*.so)) > $@ generated += check-textrel check-textrel.out + +$(objpfx)tst-dlmodcount: $(libdl) +$(objpfx)tst-dlmodcount.out: $(test-modules) + endif Index: elf/dl-close.c --- elf/dl-close.c +++ elf/dl-close.c @@ -319,6 +319,7 @@ /* Notify the debugger we are about to remove some loaded objects. */ _r_debug.r_state = RT_DELETE; _dl_debug_state (); + ++GL(dl_load_subs); #ifdef USE_TLS size_t tls_free_start; Index: elf/dl-iteratephdr.c --- elf/dl-iteratephdr.c +++ elf/dl-iteratephdr.c @@ -48,6 +48,8 @@ info.dlpi_name = l->l_name; info.dlpi_phdr = l->l_phdr; info.dlpi_phnum = l->l_phnum; + info.dlpi_adds = GL(dl_load_adds); + info.dlpi_subs = GL(dl_load_subs); ret = callback (&info, sizeof (struct dl_phdr_info), data); if (ret) break; @@ -84,6 +86,8 @@ info.dlpi_name = ""; info.dlpi_phdr = _dl_phdr; info.dlpi_phnum = _dl_phnum; + info.dlpi_adds = GL(dl_load_adds); + info.dlpi_subs = GL(dl_load_subs); ret = (*callback) (&info, sizeof (struct dl_phdr_info), data); if (ret) return ret; Index: elf/dl-object.c --- elf/dl-object.c +++ elf/dl-object.c @@ -83,6 +83,7 @@ else GL(dl_loaded) = new; ++GL(dl_nloaded); + ++GL(dl_load_adds); /* If we have no loader the new object acts as it. */ if (loader == NULL) Index: elf/dl-support.c --- elf/dl-support.c +++ elf/dl-support.c @@ -71,6 +71,11 @@ /* Number of object in the _dl_loaded list. */ unsigned int _dl_nloaded; +/* Incremented whenever something may have been added to dl_loaded. */ +unsigned long long _dl_load_adds; +/* Incremented whenever something may have been removed from dl_loaded. */ +unsigned long long _dl_load_subs; + /* Fake scope. In dynamically linked binaries this is the scope of the main application but here we don't have something like this. So create a fake scope containing nothing. */ Index: elf/link.h --- elf/link.h +++ elf/link.h @@ -100,6 +100,12 @@ const char *dlpi_name; const ElfW(Phdr) *dlpi_phdr; ElfW(Half) dlpi_phnum; + + /* Note: older versions of libc do not provide the following + members. Check the SIZE argument pass to the dl_iterate_phdr() + callback to determine whether or not they areprovided. */ + unsigned long long dlpi_adds; /* incr. when phdrs may have been added */ + unsigned long long dlpi_subs; /* incr. when phdrs may have been removed */ }; __BEGIN_DECLS Index: elf/tst-dlmodcount.c --- /dev/null +++ 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; +} Index: include/link.h --- include/link.h +++ include/link.h @@ -293,6 +293,12 @@ const char *dlpi_name; const ElfW(Phdr) *dlpi_phdr; ElfW(Half) dlpi_phnum; + + /* Note: older versions of libc do not provide the following + members. Check the SIZE argument pass to the dl_iterate_phdr() + callback to determine whether or not they areprovided. */ + unsigned long long dlpi_adds; /* incr. when phdrs may have been added */ + unsigned long long dlpi_subs; /* incr. when phdrs may have been removed */ }; extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, Index: sysdeps/generic/ldsodefs.h --- sysdeps/generic/ldsodefs.h +++ sysdeps/generic/ldsodefs.h @@ -265,6 +265,11 @@ EXTERN const char *_dl_platform; EXTERN size_t _dl_platformlen; + /* Incremented whenever something may have been added to dl_loaded. */ + EXTERN unsigned long long _dl_load_adds; + /* Incremented whenever something may have been removed from dl_loaded. */ + EXTERN unsigned long long _dl_load_subs; + #ifndef MAP_ANON /* File descriptor referring to the zero-fill device. */ EXTERN int _dl_zerofd;
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |