support configurable page size on mips, powerpc and microblaze
authorSzabolcs Nagy <nsz@port70.net>
Sun, 15 Sep 2013 02:00:32 +0000 (02:00 +0000)
committerSzabolcs Nagy <nsz@port70.net>
Sun, 15 Sep 2013 02:00:32 +0000 (02:00 +0000)
PAGE_SIZE was hardcoded to 4096, which is historically what most
systems use, but on several archs it is a kernel config parameter,
user space can only know it at execution time from the aux vector.

PAGE_SIZE and PAGESIZE are not defined on archs where page size is
a runtime parameter, applications should use sysconf(_SC_PAGE_SIZE)
to query it. Internally libc code defines PAGE_SIZE to libc.page_size,
which is set to aux[AT_PAGESZ] in __init_libc and early in __dynlink
as well. (Note that libc.page_size can be accessed without GOT, ie.
before relocations are done)

Some fpathconf settings are hardcoded to 4096, these should be actually
queried from the filesystem using statfs.

19 files changed:
arch/microblaze/bits/limits.h
arch/microblaze/reloc.h
arch/mips/bits/limits.h
arch/mips/reloc.h
arch/powerpc/bits/limits.h
arch/powerpc/reloc.h
include/limits.h
src/aio/aio_readwrite.c
src/aio/lio_listio.c
src/conf/fpathconf.c
src/conf/sysconf.c
src/env/__libc_start_main.c
src/internal/libc.h
src/ldso/dynlink.c
src/legacy/getpagesize.c
src/legacy/valloc.c
src/mman/mprotect.c
src/thread/pthread_create.c
src/thread/pthread_getattr_np.c

index 65a3dd6477bce24af82e092e9172fbcf18829e46..fbc6d238dc89b91dbe94af93ea60e862c67ac154 100644 (file)
@@ -1,6 +1,5 @@
 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define PAGE_SIZE 4096
 #define LONG_BIT 32
 #endif
 
index 60f742251bd79ebc4eeb1f4593ece671f69f4c78..7bf3a5b053e9b4207fb607011100b179ae59de83 100644 (file)
@@ -49,7 +49,7 @@ void __reloc_self(int c, size_t *a, size_t *dynv)
        for (a+=c+1; *a; a++);
        for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
        base = (char *)t[AT_BASE];
-       if (!base) base = (char *)(t[AT_PHDR] & -4096);
+       if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
        for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1];
        n = t[DT_RELASZ];
        for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12)
index 65a3dd6477bce24af82e092e9172fbcf18829e46..fbc6d238dc89b91dbe94af93ea60e862c67ac154 100644 (file)
@@ -1,6 +1,5 @@
 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define PAGE_SIZE 4096
 #define LONG_BIT 32
 #endif
 
index 4c035f3276cc97f540b928b0da353851b5fa4347..07fa10a7e8ec2879e9427d0f94e3cd58f7c802bc 100644 (file)
@@ -51,7 +51,7 @@ void __reloc_self(int c, size_t *a, size_t *dynv, size_t *got)
        for (a+=c+1; *a; a++);
        for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
        base = (char *)t[AT_BASE];
-       if (!base) base = (char *)(t[AT_PHDR] & -4096);
+       if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
        for (a=dynv; *a; a+=2) if (*a-0x70000000UL<20) t[*a&31] = a[1];
        n = t[DT_MIPS_LOCAL_GOTNO - 0x70000000];
        for (a=got; n; a++, n--) *a += (size_t)base;
index 65a3dd6477bce24af82e092e9172fbcf18829e46..fbc6d238dc89b91dbe94af93ea60e862c67ac154 100644 (file)
@@ -1,6 +1,5 @@
 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define PAGE_SIZE 4096
 #define LONG_BIT 32
 #endif
 
index 2877ce2a3cc7698daa0a751475d0234ce63b3575..38034c5642b6d684759a68262bb0dd3e5a2953e6 100644 (file)
@@ -46,7 +46,7 @@ void __reloc_self(int c, size_t *a, size_t *dynv)
        for (a+=c+1; *a; a++);
        for (a++; *a; a+=2) if (*a<20) t[*a] = a[1];
        base = (char *)t[AT_BASE];
-       if (!base) base = (char *)(t[AT_PHDR] & -4096);
+       if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]);
        for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1];
        n = t[DT_RELASZ];
        for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12)
index 54d1940b439c77f40f2282682e2a3b05683dc688..a8460cc8379fff1aa4c849491f6b4a48ee892426 100644 (file)
@@ -40,7 +40,9 @@
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 
 #define PIPE_BUF 4096
+#ifdef PAGE_SIZE
 #define PAGESIZE PAGE_SIZE
+#endif
 #define FILESIZEBITS 64
 #define NAME_MAX 255
 #define SYMLINK_MAX 255
index 666372db7b7da3c40ca3f46c955c9e10c1637ac6..0de3d4fb7ec762aaded69a52a8c4da2dfd5620a2 100644 (file)
@@ -2,8 +2,8 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
-#include <limits.h>
 #include "pthread_impl.h"
+#include "libc.h"
 
 static void dummy(void)
 {
index 07145dd41656f85592954384a6c1d5252b2218f8..61d7f20ef06cfab2f932a10b365412b924c216d3 100644 (file)
@@ -1,9 +1,9 @@
 #include <aio.h>
 #include <errno.h>
-#include <limits.h>
 #include <unistd.h>
 #include <string.h>
 #include "pthread_impl.h"
+#include "libc.h"
 
 struct lio_state {
        struct sigevent *sev;
index bfbb27426755c328d4a712abbb924785c1b07e82..28c4345c2e9888333449b35ce3bc03dc966fe27e 100644 (file)
@@ -19,11 +19,11 @@ long fpathconf(int fd, int name)
                [_PC_PRIO_IO] = -1,
                [_PC_SOCK_MAXBUF] = -1,
                [_PC_FILESIZEBITS] = FILESIZEBITS,
-               [_PC_REC_INCR_XFER_SIZE] = PAGE_SIZE,
-               [_PC_REC_MAX_XFER_SIZE] = PAGE_SIZE,
-               [_PC_REC_MIN_XFER_SIZE] = PAGE_SIZE,
-               [_PC_REC_XFER_ALIGN] = PAGE_SIZE,
-               [_PC_ALLOC_SIZE_MIN] = PAGE_SIZE,
+               [_PC_REC_INCR_XFER_SIZE] = 4096,
+               [_PC_REC_MAX_XFER_SIZE] = 4096,
+               [_PC_REC_MIN_XFER_SIZE] = 4096,
+               [_PC_REC_XFER_ALIGN] = 4096,
+               [_PC_ALLOC_SIZE_MIN] = 4096,
                [_PC_SYMLINK_MAX] = SYMLINK_MAX,
                [_PC_2_SYMLINKS] = 1
        };
index 5dc1e453aecf93d5815b0f3067374bc3a83cf296..97fd4fadfd07eb20c2fb1fa34df955c9d5898ee3 100644 (file)
@@ -3,6 +3,7 @@
 #include <errno.h>
 #include <sys/resource.h>
 #include "syscall.h"
+#include "libc.h"
 
 #define VER (-2)
 #define OFLOW (-3)
@@ -42,7 +43,7 @@ long sysconf(int name)
                [_SC_MQ_OPEN_MAX] = -1,
                [_SC_MQ_PRIO_MAX] = OFLOW,
                [_SC_VERSION] = VER,
-               [_SC_PAGE_SIZE] = PAGE_SIZE,
+               [_SC_PAGE_SIZE] = OFLOW,
                [_SC_RTSIG_MAX] = 63, /* ?? */
                [_SC_SEM_NSEMS_MAX] = SEM_NSEMS_MAX,
                [_SC_SEM_VALUE_MAX] = OFLOW,
@@ -222,6 +223,8 @@ long sysconf(int name)
                if (name == _SC_ARG_MAX) return ARG_MAX;
                if (name == _SC_SEM_VALUE_MAX) return SEM_VALUE_MAX;
                if (name == _SC_MQ_PRIO_MAX) return MQ_PRIO_MAX;
+               /* name == _SC_PAGE_SIZE */
+               return PAGE_SIZE;
        } else if (values[name] == CPUCNT) {
                unsigned char set[128] = {1};
                int i, cnt;
index 2a8698bb19439809a7acc469caa6e2656c90a58c..73d4932788d4a6a33396d887912e753699b83b69 100644 (file)
@@ -26,6 +26,7 @@ void __init_libc(char **envp, char *pn)
        for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
        __hwcap = aux[AT_HWCAP];
        __sysinfo = aux[AT_SYSINFO];
+       libc.page_size = aux[AT_PAGESZ];
 
        if (pn) {
                __progname = __progname_full = pn;
index c8fbe3fdc901c61638baeac06dae3e51d1a268a2..3350b3d1f064420482fce4dd60ad9a3806760d61 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <limits.h>
 
 struct __libc {
        void *main_thread;
@@ -14,10 +15,15 @@ struct __libc {
        FILE *ofl_head;
        int ofl_lock[2];
        size_t tls_size;
+       size_t page_size;
 };
 
 extern size_t __hwcap;
 
+#ifndef PAGE_SIZE
+#define PAGE_SIZE libc.page_size
+#endif
+
 #if !defined(__PIC__) || (100*__GNUC__+__GNUC_MINOR__ >= 303 && !defined(__PCC__))
 
 #ifdef __PIC__
index a89e74320048162048b77fa50ad0e17ab263ccd7..a525b3d8fa837b5cbc573f874d6e75a3ce2b0109 100644 (file)
@@ -980,6 +980,7 @@ void *__dynlink(int argc, char **argv)
                env_preload = 0;
                libc.secure = 1;
        }
+       libc.page_size = aux[AT_PAGESZ];
 
        /* If the dynamic linker was invoked as a program itself, AT_BASE
         * will not be set. In that case, we assume the base address is
index 5ede652b054e712009504845227e40a9fbdd7b09..a47995cb69df7f922699b1c719ba51cba16ffa80 100644 (file)
@@ -1,5 +1,5 @@
 #include <unistd.h>
-#include <limits.h>
+#include "libc.h"
 
 int getpagesize(void)
 {
index e48cf2146c9ba65ad9c0e0805bf147d87c1cdf48..5af2256a478ac5ce34a70184f38ef9dd371a5d3d 100644 (file)
@@ -1,6 +1,6 @@
 #define _BSD_SOURCE
 #include <stdlib.h>
-#include <limits.h>
+#include "libc.h"
 
 void *valloc(size_t size)
 {
index 5ab2d8b0278896ace8109eed8251a3e72abe8c47..f488486db6e2d8fe4f7f3b200a0af81a6396451b 100644 (file)
@@ -1,5 +1,5 @@
 #include <sys/mman.h>
-#include <limits.h>
+#include "libc.h"
 #include "syscall.h"
 
 int mprotect(void *addr, size_t len, int prot)
index 6c841be799b1632917c4b318dc0fa8faf4bd3e3a..d26f252ee1dd879ea41afa54e02c47526adefdb7 100644 (file)
@@ -1,5 +1,6 @@
 #include "pthread_impl.h"
 #include "stdio_impl.h"
+#include "libc.h"
 #include <sys/mman.h>
 
 static void dummy_0()
index 86df1defed80bb70780df4bda1fa920e8a7d09c3..10ea512733fad390ac5cc699438cf1e4c02f06a2 100644 (file)
@@ -1,5 +1,6 @@
 #define _GNU_SOURCE
 #include "pthread_impl.h"
+#include "libc.h"
 #include <sys/mman.h>
 
 int pthread_getattr_np(pthread_t t, pthread_attr_t *a)