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.
This commit is contained in:
Ulrich Drepper 2004-01-24 20:12:10 +00:00
parent e8648a5a87
commit bed12f78fa
10 changed files with 166 additions and 6 deletions

View File

@ -1,3 +1,23 @@
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.
2004-01-22 Jakub Jelinek <jakub@redhat.com>
* elf/dl-reloc.c (_dl_relocate_object): Move PT_GNU_RELRO protection

View File

@ -80,7 +80,7 @@ distribute := rtld-Rules \
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 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
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 @@ $(objpfx)check-textrel.out: $(objpfx)check-textrel
$(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

View File

@ -1,5 +1,5 @@
/* Close a shared object opened by `_dl_open'.
Copyright (C) 1996-2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2002, 2003, 2004 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
@ -319,6 +319,7 @@ _dl_close (void *_map)
/* 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;

View File

@ -1,5 +1,5 @@
/* Get loaded objects program headers.
Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
@ -48,6 +48,8 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
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 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
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;

View File

@ -1,5 +1,5 @@
/* Storage management for the chain of loaded shared objects.
Copyright (C) 1995,96,97,98,99,2000,2001,2002 Free Software Foundation, Inc.
Copyright (C) 1995-2002, 2004 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
@ -83,6 +83,7 @@ _dl_new_object (char *realname, const char *libname, int type,
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)

View File

@ -71,6 +71,11 @@ struct link_map *_dl_loaded;
/* 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. */

View File

@ -1,6 +1,6 @@
/* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects.
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 1995-1999, 2000, 2001, 2004 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
@ -100,6 +100,16 @@ struct dl_phdr_info
const char *dlpi_name;
const ElfW(Phdr) *dlpi_phdr;
ElfW(Half) dlpi_phnum;
/* Note: the next two members were introduced after the first
version of this structure was available. Check the SIZE
argument pass to the dl_iterate_phdr() callback to determine
whether or not they are provided. */
/* Incremented when a new object may have been added. */
unsigned long long int dlpi_adds;
/* Incremented when an object may have been removed. */
unsigned long long int dlpi_subs;
};
__BEGIN_DECLS

107
elf/tst-dlmodcount.c Normal file
View File

@ -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;
}

View File

@ -293,6 +293,9 @@ struct dl_phdr_info
const char *dlpi_name;
const ElfW(Phdr) *dlpi_phdr;
ElfW(Half) dlpi_phnum;
unsigned long long int dlpi_adds;
unsigned long long int dlpi_subs;
};
extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,

View File

@ -265,6 +265,11 @@ struct rtld_global
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;