summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2013-09-15 02:00:32 +0000
committerSzabolcs Nagy <nsz@port70.net>2013-09-15 02:00:32 +0000
commitb20760c02318fa6da228587c401a8b2bb22a1aab (patch)
treea9bf139467269eb8a87fa2bb3423259eb59903e3
parent7a34dd3495d4bcd3dadc8b9fe2c89f819c15e7fd (diff)
downloadmusl-b20760c02318fa6da228587c401a8b2bb22a1aab.tar.gz
musl-b20760c02318fa6da228587c401a8b2bb22a1aab.tar.bz2
musl-b20760c02318fa6da228587c401a8b2bb22a1aab.tar.xz
musl-b20760c02318fa6da228587c401a8b2bb22a1aab.zip
support configurable page size on mips, powerpc and microblaze
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.
-rw-r--r--arch/microblaze/bits/limits.h1
-rw-r--r--arch/microblaze/reloc.h2
-rw-r--r--arch/mips/bits/limits.h1
-rw-r--r--arch/mips/reloc.h2
-rw-r--r--arch/powerpc/bits/limits.h1
-rw-r--r--arch/powerpc/reloc.h2
-rw-r--r--include/limits.h2
-rw-r--r--src/aio/aio_readwrite.c2
-rw-r--r--src/aio/lio_listio.c2
-rw-r--r--src/conf/fpathconf.c10
-rw-r--r--src/conf/sysconf.c5
-rw-r--r--src/env/__libc_start_main.c1
-rw-r--r--src/internal/libc.h6
-rw-r--r--src/ldso/dynlink.c1
-rw-r--r--src/legacy/getpagesize.c2
-rw-r--r--src/legacy/valloc.c2
-rw-r--r--src/mman/mprotect.c2
-rw-r--r--src/thread/pthread_create.c1
-rw-r--r--src/thread/pthread_getattr_np.c1
19 files changed, 29 insertions, 17 deletions
diff --git a/arch/microblaze/bits/limits.h b/arch/microblaze/bits/limits.h
index 65a3dd64..fbc6d238 100644
--- a/arch/microblaze/bits/limits.h
+++ b/arch/microblaze/bits/limits.h
@@ -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
diff --git a/arch/microblaze/reloc.h b/arch/microblaze/reloc.h
index 60f74225..7bf3a5b0 100644
--- a/arch/microblaze/reloc.h
+++ b/arch/microblaze/reloc.h
@@ -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)
diff --git a/arch/mips/bits/limits.h b/arch/mips/bits/limits.h
index 65a3dd64..fbc6d238 100644
--- a/arch/mips/bits/limits.h
+++ b/arch/mips/bits/limits.h
@@ -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
diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
index 4c035f32..07fa10a7 100644
--- a/arch/mips/reloc.h
+++ b/arch/mips/reloc.h
@@ -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;
diff --git a/arch/powerpc/bits/limits.h b/arch/powerpc/bits/limits.h
index 65a3dd64..fbc6d238 100644
--- a/arch/powerpc/bits/limits.h
+++ b/arch/powerpc/bits/limits.h
@@ -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
diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h
index 2877ce2a..38034c56 100644
--- a/arch/powerpc/reloc.h
+++ b/arch/powerpc/reloc.h
@@ -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)
diff --git a/include/limits.h b/include/limits.h
index 54d1940b..a8460cc8 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -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
diff --git a/src/aio/aio_readwrite.c b/src/aio/aio_readwrite.c
index 666372db..0de3d4fb 100644
--- a/src/aio/aio_readwrite.c
+++ b/src/aio/aio_readwrite.c
@@ -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)
{
diff --git a/src/aio/lio_listio.c b/src/aio/lio_listio.c
index 07145dd4..61d7f20e 100644
--- a/src/aio/lio_listio.c
+++ b/src/aio/lio_listio.c
@@ -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;
diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
index bfbb2742..28c4345c 100644
--- a/src/conf/fpathconf.c
+++ b/src/conf/fpathconf.c
@@ -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
};
diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
index 5dc1e453..97fd4fad 100644
--- a/src/conf/sysconf.c
+++ b/src/conf/sysconf.c
@@ -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;
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index 2a8698bb..73d49327 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -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;
diff --git a/src/internal/libc.h b/src/internal/libc.h
index c8fbe3fd..3350b3d1 100644
--- a/src/internal/libc.h
+++ b/src/internal/libc.h
@@ -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__
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index a89e7432..a525b3d8 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -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
diff --git a/src/legacy/getpagesize.c b/src/legacy/getpagesize.c
index 5ede652b..a47995cb 100644
--- a/src/legacy/getpagesize.c
+++ b/src/legacy/getpagesize.c
@@ -1,5 +1,5 @@
#include <unistd.h>
-#include <limits.h>
+#include "libc.h"
int getpagesize(void)
{
diff --git a/src/legacy/valloc.c b/src/legacy/valloc.c
index e48cf214..5af2256a 100644
--- a/src/legacy/valloc.c
+++ b/src/legacy/valloc.c
@@ -1,6 +1,6 @@
#define _BSD_SOURCE
#include <stdlib.h>
-#include <limits.h>
+#include "libc.h"
void *valloc(size_t size)
{
diff --git a/src/mman/mprotect.c b/src/mman/mprotect.c
index 5ab2d8b0..f488486d 100644
--- a/src/mman/mprotect.c
+++ b/src/mman/mprotect.c
@@ -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)
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index 6c841be7..d26f252e 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -1,5 +1,6 @@
#include "pthread_impl.h"
#include "stdio_impl.h"
+#include "libc.h"
#include <sys/mman.h>
static void dummy_0()
diff --git a/src/thread/pthread_getattr_np.c b/src/thread/pthread_getattr_np.c
index 86df1def..10ea5127 100644
--- a/src/thread/pthread_getattr_np.c
+++ b/src/thread/pthread_getattr_np.c
@@ -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)