From b20760c02318fa6da228587c401a8b2bb22a1aab Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sun, 15 Sep 2013 02:00:32 +0000 Subject: 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. --- src/aio/aio_readwrite.c | 2 +- src/aio/lio_listio.c | 2 +- src/conf/fpathconf.c | 10 +++++----- src/conf/sysconf.c | 5 ++++- src/env/__libc_start_main.c | 1 + src/internal/libc.h | 6 ++++++ src/ldso/dynlink.c | 1 + src/legacy/getpagesize.c | 2 +- src/legacy/valloc.c | 2 +- src/mman/mprotect.c | 2 +- src/thread/pthread_create.c | 1 + src/thread/pthread_getattr_np.c | 1 + 12 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src') 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 #include #include -#include #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 #include -#include #include #include #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 #include #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] #include +#include 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 -#include +#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 -#include +#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 -#include +#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 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 int pthread_getattr_np(pthread_t t, pthread_attr_t *a) -- cgit v1.2.1