Remove the getpagesize system call from ia64
H . J . Lu
hjl@valinux.com
Wed Jan 10 17:35:00 GMT 2001
On Thu, Jan 11, 2001 at 12:05:52AM +0100, Jakub Jelinek wrote:
> On Wed, Jan 10, 2001 at 10:23:31AM -0800, H . J . Lu wrote:
> > AT_PAGESZ works on the current ia64 kernel.
>
> Unfortunately, not fully yet :(.
>
> Consider statically linked:
> #include <stdio.h>
> #include <pwd.h>
> #include <sys/types.h>
> #include <unistd.h>
>
> int main() {
> struct passwd *foo;
> foo=getpwuid(2166);
> printf("%d %d\n",foo->pw_uid,foo->pw_gid);
> }
> This will crash. Although _dl_pagesize is set properly in the main program,
> when it dlopens libnss_files.so.2 which in turn drags in libc.so.6.1 and
> ld-linux-ia64.so.2. Now when libnss_files.so.2 calls __getpagesize(), it
> uses _dl_pagesize variable present in ld-linux-ia64.so.2 which has not been
> initialized and thus it either crashes immediately or later on (if
> -DNDEBUG=1). At least I believe this is happening from what Bill Nottingham
> told me. I think one solution could be to have the getpagesize syscall for
> this case, another one would be to have a list of ld.so variables which need
> to be initialized to their static originals, like have something like:
> { "_dl_pagesize", &_dl_pagesize },
> and during dlopen #ifndef SHARED go through that list and copy the content.
>
> Jakub
Here is a patch to implement the second suggestion.
--
H.J. Lu (hjl@valinux.com)
---
2001-01-10 H.J. Lu <hjl@gnu.org>
* elf/dl-libc.c (do_dlopen): initialize _dl_pagesize and
_dl_clktck in DSOs.
Index: elf/dl-libc.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-libc.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 dl-libc.c
--- elf/dl-libc.c 2000/08/31 16:48:13 1.1.1.7
+++ elf/dl-libc.c 2001/01/11 01:31:05
@@ -18,6 +18,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <assert.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <ldsodefs.h>
@@ -70,12 +71,34 @@ struct do_dlsym_args
const ElfW(Sym) *ref;
};
+extern int _dl_clktck;
+
static void
do_dlopen (void *ptr)
{
+ const ElfW(Sym) *ref;
+ lookup_t loadbase;
+ size_t *pagesize;
+ int *clktck;
+
struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
/* Open and relocate the shared object. */
args->map = _dl_open (args->name, RTLD_LAZY, NULL);
+
+ /* We need to initialize _dl_pagesize and _dl_clktck which are
+ uninitialized in DSOs. */
+
+ loadbase = _dl_lookup_symbol ("_dl_pagesize", args->map, &ref,
+ args->map->l_local_scope, 0, 1);
+ assert (ref != NULL);
+ pagesize = (size_t *) DL_SYMBOL_ADDRESS (loadbase, ref);
+ *pagesize = _dl_pagesize;
+
+ loadbase = _dl_lookup_symbol ("_dl_clktck", args->map, &ref,
+ args->map->l_local_scope, 0, 1);
+ assert (ref != NULL);
+ clktck = (int *) DL_SYMBOL_ADDRESS (loadbase, ref);
+ *clktck = _dl_clktck;
}
static void
More information about the Libc-alpha
mailing list