This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[patch] Variable page size support for MIPS/Linux
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- To: libc-alpha at sources dot redhat dot com
- Cc: Ralf Baechle <ralf at linux-mips dot org>
- Date: Mon, 22 Dec 2003 19:27:18 +0100 (CET)
- Subject: [patch] Variable page size support for MIPS/Linux
- Organization: Technical University of Gdansk
Hello,
Recently the MIPS/Linux kernel has been modified to support a
configurable page size if underlying hardware supports it. Currently page
sizes of 4kB, 16kB and 64kB are supported. This requires changes to glibc
not to hardcode the page size using the PAGE_SIZE macro and determine the
current setting at the run time.
Here is an appropriate update. As my version of gcc does not permit
building the current version, the update was developed and tested at the
run time with 2.2.5. It was then trivially updated by changing references
to _dl_pagesize with references to GL(dl_pagesize) and updating
configuration bits. It applies cleanly both to 2.3.2 and the trunk.
2003-12-22 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* sysdeps/unix/sysv/linux/mips/dl-static.c: New file to support
variable page size for MIPS.
* sysdeps/unix/sysv/linux/mips/getpagesize.c: Likewise.
* sysdeps/unix/sysv/linux/mips/ldsodefs.h: Likewise.
* sysdeps/unix/sysv/linux/mips/Dist: Add dl-static.c.
* sysdeps/unix/sysv/linux/mips/Makefile: Build dl-static in elf.
* sysdeps/unix/sysv/linux/mips/Versions: Add _dl_var_init.
The changes are based on the IA64 implementation with necessary changes
and a fix I'm sending in a separate mail.
Please apply.
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
glibc-2.3.2-mips-page-size.patch
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Dist glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Dist
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Dist 2002-08-27 16:05:52.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Dist 2003-12-21 12:36:03.000000000 +0000
@@ -1,5 +1,6 @@
_test_and_set.c
clone.S
+dl-static.c
entry.h
ipc_priv.h
kernel_sigaction.h
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Makefile glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Makefile
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Makefile 2002-03-28 23:41:51.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Makefile 2003-12-21 12:36:03.000000000 +0000
@@ -9,3 +9,11 @@ sysdep_routines += cachectl cacheflush s
sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
endif
+
+ifeq ($(subdir),elf)
+ifeq ($(build-shared),yes)
+# This is needed for DSO loading from static binaries.
+sysdep_routines += dl-static
+sysdep-rtld-routines += dl-static
+endif
+endif
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Versions glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Versions
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/Versions 2002-11-06 18:22:35.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/Versions 2003-12-21 12:36:03.000000000 +0000
@@ -1,3 +1,9 @@
+ld {
+ GLIBC_PRIVATE {
+ # used for loading by static libraries
+ _dl_var_init;
+ }
+}
libc {
# The comment lines with "#errlist-compat" are magic; see errlist-compat.awk.
# When you get an error from errlist-compat.awk, you need to add a new
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/dl-static.c glibc-2.3.2/sysdeps/unix/sysv/linux/mips/dl-static.c
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/dl-static.c 1970-01-01 00:00:00.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/dl-static.c 2003-12-19 15:52:41.000000000 +0000
@@ -0,0 +1,66 @@
+/* Variable initialization. MIPS version.
+ Copyright (C) 2001, 2002, 2003 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
+ 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 <ldsodefs.h>
+
+#ifdef SHARED
+
+void
+_dl_var_init (void *array[])
+{
+ /* It has to match "variables" below. */
+ enum
+ {
+ DL_PAGESIZE = 0
+ };
+
+ GL(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
+}
+
+#else
+#include <bits/libc-lock.h>
+
+__libc_lock_define_initialized_recursive (static, _dl_static_lock)
+
+static void *variables[] =
+{
+ &GL(dl_pagesize)
+};
+
+void
+_dl_static_init (struct link_map *map)
+{
+ const ElfW(Sym) *ref = NULL;
+ lookup_t loadbase;
+ void (*f) (void *[]);
+
+ __libc_lock_lock_recursive (_dl_static_lock);
+
+ loadbase = _dl_lookup_symbol ("_dl_var_init", map, &ref,
+ map->l_local_scope, 0, 1);
+ if (ref != NULL)
+ {
+ f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
+ f (variables);
+ }
+
+ __libc_lock_unlock_recursive (_dl_static_lock);
+}
+
+#endif
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/getpagesize.c glibc-2.3.2/sysdeps/unix/sysv/linux/mips/getpagesize.c
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/getpagesize.c 1970-01-01 00:00:00.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/getpagesize.c 2002-08-02 21:46:59.000000000 +0000
@@ -0,0 +1,39 @@
+/* Copyright (C) 1999, 2000, 2001, 2002 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
+ 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 <assert.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include <ldsodefs.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Return the system page size. The return value will depend on how
+ the kernel is configured. A program must use this call to
+ determine the page size to ensure proper alignment for calls such
+ as mmap and friends. --davidm 99/11/30 */
+
+int
+__getpagesize ()
+{
+ assert (GL(dl_pagesize) != 0);
+ return GL(dl_pagesize);
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff -up --recursive --new-file glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/ldsodefs.h glibc-2.3.2/sysdeps/unix/sysv/linux/mips/ldsodefs.h
--- glibc-2.3.2.macro/sysdeps/unix/sysv/linux/mips/ldsodefs.h 1970-01-01 00:00:00.000000000 +0000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/mips/ldsodefs.h 2003-12-18 17:56:43.000000000 +0000
@@ -0,0 +1,33 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects. MIPS.
+ Copyright (C) 2001, 2003 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
+ 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. */
+
+#ifndef _LDSODEFS_H
+
+/* Get the real definitions. */
+#include_next <ldsodefs.h>
+
+/* Now define our stuff. */
+
+/* We need special support to initialize DSO loaded for statically linked
+ binaries. */
+extern void _dl_static_init (struct link_map *map);
+#undef DL_STATIC_INIT
+#define DL_STATIC_INIT(map) _dl_static_init (map)
+
+#endif /* ldsodefs.h */