From: David Mosberger <davidm@napali.hpl.hp.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: davidm@hpl.hp.com, Roland McGrath <roland@redhat.com>,
GNU libc hackers <libc-hacker@sources.redhat.com>
Subject: Re: enabling caching for dl_iterate_phdr()
Date: Sat, 24 Jan 2004 05:54:00 -0000 [thread overview]
Message-ID: <16402.2189.718828.875017@napali.hpl.hp.com> (raw)
In-Reply-To: <20040122062944.GC6811@sunsite.ms.mff.cuni.cz>
>>>>> 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;
next prev parent reply other threads:[~2004-01-24 5:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <16387.9755.753294.37588@napali.hpl.hp.com>
2004-01-17 0:57 ` Roland McGrath
2004-01-17 1:39 ` Jakub Jelinek
2004-01-17 1:40 ` Roland McGrath
2004-01-17 1:51 ` David Mosberger
2004-01-22 0:35 ` David Mosberger
2004-01-22 8:39 ` Jakub Jelinek
2004-01-24 5:54 ` David Mosberger [this message]
2004-01-24 20:27 ` Ulrich Drepper
2004-01-26 21:48 ` David Mosberger
2004-01-26 22:39 ` Ulrich Drepper
2004-01-26 22:58 ` Roland McGrath
2004-01-26 23:03 ` David Mosberger
2003-12-16 19:55 David Mosberger
2003-12-23 22:24 ` Roland McGrath
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16402.2189.718828.875017@napali.hpl.hp.com \
--to=davidm@napali.hpl.hp.com \
--cc=davidm@hpl.hp.com \
--cc=jakub@redhat.com \
--cc=libc-hacker@sources.redhat.com \
--cc=roland@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).