This patch adds support for dynamic PAGE_SIZE values to 'dietlibc'. It is a
little bit invasive in several aspects:
it modifies the startup code. We need to know the position of the elf-info
auxilary table which is located after 'environ'. We can not use
'environ' directly because it might be modified by the application.
Hence, an additional __elfinfo variable is placed into .bss and filled in
the startup code. Depending on platform, this adds 1-3 instructions and
an additional pointer to .bss.
I tested only the i386 and x86_64 modifications; it would be nice when
people with corresponding hardware would test the other ones. I am
especially uncertain regarding the parisc changes.
The elf-info stuff (which might be interesting e.g. for dynamic linking or
sysconf(_SC_CLK_TCK)) can be enabled without the dynamic pagesize too.
it removes the 'PAGE_SIZE' macro from <sys/shm.h>; this will break
compilation of existing userspace application which are using this
deprecated macro
I added a new internal 'dietpagesize.h' header which defines
| __DIET_PAGE_SIZE | __DIET_PAGE_SHIFT
macros. These return either builtin constants (when WANT_DYN_PAGESIZE is
not selected), or values derived from __libc_getpagesize().
Every usage of PAGE_SIZE in dietlibc code was replaced by these macros.
due to the previous point, the internal 'struct __dirstream' was modified.
I replaced
| getdents64(d->fd,(struct dirent64*)d->buf, sizeof (d->buf)-1);
with
| getdents64(d->fd,(struct dirent64*)d->buf, __DIRSTREAM_BUF_SIZE-1);
literally but I am not sure where the '-1' is coming from. There is one
hunk, where this '-1' is missing so I think the '-1' should be removed
from all calls to getdents64().
changes affect the *alloc() functions too; on x86_64 around 64 bytes where
added to .text of alloc.o
the new testprogramm requires a 'getconf' binary which returns the correct
values for PAGE_SIZE and CLK_TCK
This commit is contained in:
parent
6cd264d613
commit
5ce1baa9fa
1 changed files with 742 additions and 0 deletions
742
dietlibc-0.31-pagesize.patch
Normal file
742
dietlibc-0.31-pagesize.patch
Normal file
|
|
@ -0,0 +1,742 @@
|
|||
diff -up dietlibc-0.31.20080409/lib/mmap64.c.pagesize dietlibc-0.31.20080409/lib/mmap64.c
|
||||
--- dietlibc-0.31.20080409/lib/mmap64.c.pagesize 2004-12-13 11:21:31.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/lib/mmap64.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -4,16 +4,18 @@
|
||||
#include <syscalls.h>
|
||||
#include <errno.h>
|
||||
|
||||
+#include "../dietpagesize.h"
|
||||
+
|
||||
#ifdef __NR_mmap2
|
||||
void*__mmap2(void*start,size_t length,int prot,int flags,int fd,off_t pgoffset);
|
||||
|
||||
void*__libc_mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset);
|
||||
void*__libc_mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset) {
|
||||
- if (offset&(PAGE_SIZE-1)) {
|
||||
+ if (offset&(__DIET_PAGE_SIZE)) {
|
||||
errno=-EINVAL;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
- return __mmap2(addr,len,prot,flags,fd,offset>>PAGE_SHIFT);
|
||||
+ return __mmap2(addr,len,prot,flags,fd,offset>>__DIET_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
void*mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset)
|
||||
diff -up dietlibc-0.31.20080409/lib/readdir64.c.pagesize dietlibc-0.31.20080409/lib/readdir64.c
|
||||
--- dietlibc-0.31.20080409/lib/readdir64.c.pagesize 2004-03-02 22:27:19.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/lib/readdir64.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -14,7 +14,7 @@
|
||||
#ifndef WANT_LARGEFILE_BACKCOMPAT
|
||||
struct dirent64* readdir64(DIR *d) {
|
||||
if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
|
||||
- int res=getdents64(d->fd,(struct dirent64*)d->buf, sizeof (d->buf)-1);
|
||||
+ int res=getdents64(d->fd,(struct dirent64*)d->buf, __DIRSTREAM_BUF_SIZE-1);
|
||||
if (res<=0) return 0;
|
||||
d->num=res; d->cur=0;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ again:
|
||||
if (!trygetdents64) {
|
||||
#endif
|
||||
if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) {
|
||||
- int res=getdents(d->fd,(struct dirent*)d->buf, sizeof (d->buf)-1);
|
||||
+ int res=getdents(d->fd,(struct dirent*)d->buf, __DIRSTREAM_BUF_SIZE-1);
|
||||
if (res<=0) return 0;
|
||||
d->num=res; d->cur=0;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ again:
|
||||
#ifdef __NR_getdents64
|
||||
}
|
||||
if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
|
||||
- int res=getdents64(d->fd,(struct dirent64*)d->buf,sizeof (d->buf));
|
||||
+ int res=getdents64(d->fd,(struct dirent64*)d->buf,__DIRSTREAM_BUF_SIZE);
|
||||
if (res<=0) {
|
||||
if (errno==ENOSYS) {
|
||||
trygetdents64=0;
|
||||
diff -up dietlibc-0.31.20080409/lib/opendir.c.pagesize dietlibc-0.31.20080409/lib/opendir.c
|
||||
--- dietlibc-0.31.20080409/lib/opendir.c.pagesize 2002-07-03 22:33:38.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/lib/opendir.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
+#include "../dietpagesize.h"
|
||||
+
|
||||
DIR* opendir ( const char* name ) {
|
||||
int fd = open (name, O_RDONLY | O_DIRECTORY);
|
||||
DIR* t = NULL;
|
||||
@@ -12,7 +14,7 @@ DIR* opendir ( const char* name ) {
|
||||
if ( fd >= 0 ) {
|
||||
if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
|
||||
goto lose;
|
||||
- t = (DIR *) mmap (NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
+ t = (DIR *) mmap (NULL, __DIET_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (t == MAP_FAILED)
|
||||
lose:
|
||||
diff -up dietlibc-0.31.20080409/lib/readdir.c.pagesize dietlibc-0.31.20080409/lib/readdir.c
|
||||
--- dietlibc-0.31.20080409/lib/readdir.c.pagesize 2002-07-03 22:33:38.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/lib/readdir.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
struct dirent* readdir(DIR *d) {
|
||||
if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) {
|
||||
- int res=getdents(d->fd,(struct dirent*)d->buf,sizeof (d->buf)-1);
|
||||
+ int res=getdents(d->fd,(struct dirent*)d->buf,__DIRSTREAM_BUF_SIZE-1);
|
||||
if (res<=0) return 0;
|
||||
d->num=res; d->cur=0;
|
||||
}
|
||||
diff -up dietlibc-0.31.20080409/lib/closedir.c.pagesize dietlibc-0.31.20080409/lib/closedir.c
|
||||
--- dietlibc-0.31.20080409/lib/closedir.c.pagesize 2002-07-03 22:33:37.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/lib/closedir.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -4,8 +4,10 @@
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
+#include "../dietpagesize.h"
|
||||
+
|
||||
int closedir (DIR* d) {
|
||||
int res=close(d->fd);
|
||||
- munmap (d, PAGE_SIZE);
|
||||
+ munmap (d, __DIET_PAGE_SIZE);
|
||||
return res;
|
||||
}
|
||||
diff -up dietlibc-0.31.20080409/lib/alloc.c.pagesize dietlibc-0.31.20080409/lib/alloc.c
|
||||
--- dietlibc-0.31.20080409/lib/alloc.c.pagesize 2007-08-03 22:58:33.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/lib/alloc.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -18,8 +18,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
-#include <sys/shm.h> /* for PAGE_SIZE */
|
||||
-
|
||||
+#include "../dietpagesize.h"
|
||||
|
||||
/* -- HELPER CODE --------------------------------------------------------- */
|
||||
|
||||
@@ -39,7 +38,7 @@ typedef struct {
|
||||
#define BLOCK_START(b) (((void*)(b))-sizeof(__alloc_t))
|
||||
#define BLOCK_RET(b) (((void*)(b))+sizeof(__alloc_t))
|
||||
|
||||
-#define MEM_BLOCK_SIZE PAGE_SIZE
|
||||
+#define MEM_BLOCK_SIZE __DIET_PAGE_SIZE
|
||||
#define PAGE_ALIGN(s) (((s)+MEM_BLOCK_SIZE-1)&(unsigned long)(~(MEM_BLOCK_SIZE-1)))
|
||||
|
||||
/* a simple mmap :) */
|
||||
diff -up dietlibc-0.31.20080409/ppc/start.S.pagesize dietlibc-0.31.20080409/ppc/start.S
|
||||
--- dietlibc-0.31.20080409/ppc/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/ppc/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -31,6 +31,12 @@ _start:
|
||||
lis 14,environ@ha
|
||||
stw 5,environ@l(14)
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ /* TODO: can we really assume that environ and __elfinfo are on the
|
||||
+ same 16 bit page? */
|
||||
+ stw 5,__elfinfo@l(14)
|
||||
+#endif
|
||||
+
|
||||
#ifdef WANT_DYNAMIC
|
||||
mr 6,7
|
||||
bl _dyn_start
|
||||
diff -up dietlibc-0.31.20080409/dietfeatures.h.pagesize dietlibc-0.31.20080409/dietfeatures.h
|
||||
--- dietlibc-0.31.20080409/dietfeatures.h.pagesize 2007-10-09 01:15:27.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/dietfeatures.h 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -126,6 +126,16 @@
|
||||
/* #define WANT_SSP_XOR */
|
||||
|
||||
|
||||
+/* Some platforms like x86_64, ppc* or mips do not have a fixed PAGE_SIZE.
|
||||
+ * Select WANT_DYN_PAGESIZE to detect the current PAGE_SIZE at runtime. Else,
|
||||
+ * define WANT_STATIC_PAGESIZE to a proper value (must be a power of 2)
|
||||
+ * matching the configured pagesize of the kernel where your binaries are
|
||||
+ * running on.
|
||||
+ *
|
||||
+ * Selecting WANT_DYN_PAGESIZE enlarges the startup code by around 1-3
|
||||
+ * instructions and might add an additional __elfinfo symbol */
|
||||
+#define WANT_DYN_PAGESIZE
|
||||
+/* #define WANT_STATIC_PAGESIZE 0x10000UL */
|
||||
|
||||
|
||||
/* stop uncommenting here ;-) */
|
||||
@@ -157,4 +167,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#ifdef WANT_DYN_PAGESIZE
|
||||
+#define WANT_ELFINFO
|
||||
+#endif
|
||||
+
|
||||
#endif
|
||||
diff -up dietlibc-0.31.20080409/test/Makefile.pagesize dietlibc-0.31.20080409/test/Makefile
|
||||
--- dietlibc-0.31.20080409/test/Makefile.pagesize 2008-02-23 01:02:19.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/test/Makefile 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -14,7 +14,7 @@ glob grent hasmntopt hello iconv if_name
|
||||
memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest \
|
||||
protoent prototypes putenv pwent rand48 read1 readdir regex select sendfile servent siglist \
|
||||
speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr \
|
||||
-strstr strtol sysenter ungetc waitpid
|
||||
+strstr strtol sysconf sysenter ungetc waitpid
|
||||
|
||||
test: $(TESTPROGRAMS)
|
||||
|
||||
diff -up /dev/null dietlibc-0.31.20080409/test/sysconf.c
|
||||
--- /dev/null 2008-03-18 07:40:22.289057188 +0100
|
||||
+++ dietlibc-0.31.20080409/test/sysconf.c 2008-04-12 20:19:28.000000000 +0200
|
||||
@@ -0,0 +1,80 @@
|
||||
+#include <unistd.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <assert.h>
|
||||
+#include <sys/wait.h>
|
||||
+
|
||||
+#include "../dietpagesize.h"
|
||||
+
|
||||
+static long exec_getconf(char const *var)
|
||||
+{
|
||||
+ char buf[128];
|
||||
+ pid_t pid;
|
||||
+ int fd[2];
|
||||
+ int status;
|
||||
+ ssize_t l;
|
||||
+
|
||||
+ if (pipe(fd)<0 || (pid = fork())<0)
|
||||
+ abort();
|
||||
+
|
||||
+ if (pid==0) {
|
||||
+ close(fd[0]);
|
||||
+
|
||||
+ if (fd[1]!=1) {
|
||||
+ dup2(fd[1], 1);
|
||||
+ close(fd[1]);
|
||||
+ }
|
||||
+
|
||||
+ execlp("getconf", "getconf", var, NULL);
|
||||
+ _exit(1);
|
||||
+ }
|
||||
+
|
||||
+ close(fd[1]);
|
||||
+ l = read(fd[0], buf, sizeof(buf)-1);
|
||||
+ if (l<0) {
|
||||
+ perror("read()");
|
||||
+ goto err;
|
||||
+ } else if (l==sizeof(buf)-1)
|
||||
+ goto err;
|
||||
+ close(fd[0]);
|
||||
+
|
||||
+ buf[l] = '\0';
|
||||
+
|
||||
+ if (waitpid(pid, &status, 0)<0)
|
||||
+ goto err;
|
||||
+
|
||||
+ if (!WIFEXITED(status) || WEXITSTATUS(status)!=0)
|
||||
+ goto err;
|
||||
+
|
||||
+ return strtol(buf, NULL, 10);
|
||||
+
|
||||
+err:
|
||||
+ kill(pid, SIGKILL);
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static unsigned int do_check(char const *var, long exp)
|
||||
+{
|
||||
+ long cur = exec_getconf(var);
|
||||
+
|
||||
+ if (cur!=exp) {
|
||||
+ fprintf(stderr, "%s mismatch: got %ld, expected %ld\n",
|
||||
+ cur, exp);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ unsigned int err = 0;
|
||||
+
|
||||
+ assert(sysconf(_SC_PAGESIZE) == __DIET_PAGE_SIZE);
|
||||
+ assert(__DIET_PAGE_SIZE == (1<<__DIET_PAGE_SHIFT));
|
||||
+
|
||||
+ err += do_check("PAGE_SIZE", sysconf(_SC_PAGESIZE));
|
||||
+ err += do_check("CLK_TCK", sysconf(_SC_CLK_TCK));
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
diff -up dietlibc-0.31.20080409/test/runtests.sh.pagesize dietlibc-0.31.20080409/test/runtests.sh
|
||||
--- dietlibc-0.31.20080409/test/runtests.sh.pagesize 2008-02-23 01:02:19.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/test/runtests.sh 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -1,6 +1,6 @@
|
||||
SUBDIRS="dirent inet stdio string stdlib time"
|
||||
|
||||
-TESTPROGRAMS="adjtime argv atexit bsearch byteswap calloc confstr empty flush fputc ffs fnmatch ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent siglist speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysenter ungetc waitpid"
|
||||
+TESTPROGRAMS="adjtime argv atexit bsearch byteswap calloc confstr empty flush fputc ffs fnmatch ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent siglist speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysconf sysenter ungetc waitpid"
|
||||
|
||||
STDIN="read1"
|
||||
PASS="getpass"
|
||||
diff -up dietlibc-0.31.20080409/sparc64/start.S.pagesize dietlibc-0.31.20080409/sparc64/start.S
|
||||
--- dietlibc-0.31.20080409/sparc64/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/sparc64/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -25,6 +25,11 @@ _start:
|
||||
or %o3, %lo(environ), %o3
|
||||
stx %o2, [%o3]
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ add %o3, %o3, 8
|
||||
+ stx %o2, [%o3]
|
||||
+#endif
|
||||
+
|
||||
/* When starting a binary via the dynamic linker, %g1 contains the
|
||||
address of the shared library termination function, which will be
|
||||
registered with atexit(). If we are statically linked, this will
|
||||
diff -up dietlibc-0.31.20080409/libcruft/sysconf.c.pagesize dietlibc-0.31.20080409/libcruft/sysconf.c
|
||||
--- dietlibc-0.31.20080409/libcruft/sysconf.c.pagesize 2002-12-20 14:32:37.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/libcruft/sysconf.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <limits.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
+#include "dietelfinfo.h"
|
||||
+
|
||||
extern int __sc_nr_cpus();
|
||||
|
||||
long sysconf(int name)
|
||||
@@ -16,6 +18,14 @@ long sysconf(int name)
|
||||
return limit.rlim_cur;
|
||||
}
|
||||
case _SC_CLK_TCK:
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ {
|
||||
+ elf_addr_t *v = __get_elf_aux_value(AT_CLKTCK);
|
||||
+ if (v)
|
||||
+ return *v;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
#ifdef __alpha__
|
||||
return 1024;
|
||||
#else
|
||||
@@ -23,11 +33,7 @@ long sysconf(int name)
|
||||
#endif
|
||||
|
||||
case _SC_PAGESIZE:
|
||||
-#if ( defined(__alpha__) || defined(__sparc__) )
|
||||
- return 8192;
|
||||
-#else
|
||||
- return 4096;
|
||||
-#endif
|
||||
+ return __libc_getpagesize();
|
||||
|
||||
case _SC_ARG_MAX:
|
||||
return ARG_MAX;
|
||||
diff -up /dev/null dietlibc-0.31.20080409/libcruft/__get_elf_aux_value.c
|
||||
--- /dev/null 2008-03-18 07:40:22.289057188 +0100
|
||||
+++ dietlibc-0.31.20080409/libcruft/__get_elf_aux_value.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -0,0 +1,25 @@
|
||||
+#include <stdlib.h>
|
||||
+#include "../dietelfinfo.h"
|
||||
+
|
||||
+elf_addr_t *__get_elf_aux_value(unsigned int tag)
|
||||
+{
|
||||
+ extern char ** __elfinfo;
|
||||
+ elf_addr_t *aux_ptr;
|
||||
+ char ** tmp;
|
||||
+
|
||||
+ /* External symbol points to 'environ' after startup. Now, go the end
|
||||
+ * of 'environ'; the auxiliary ELF table is located immediately after
|
||||
+ * this position */
|
||||
+
|
||||
+ /* operate on tmp instead of __elfinfo to be thread safe */
|
||||
+ tmp = __elfinfo;
|
||||
+ while (*tmp)
|
||||
+ ++tmp;
|
||||
+ __elfinfo = tmp;
|
||||
+
|
||||
+ for (aux_ptr = (elf_addr_t *)(tmp+1); aux_ptr[0]!=AT_NULL; aux_ptr += 2)
|
||||
+ if (aux_ptr[0]==tag)
|
||||
+ return aux_ptr+1;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
diff -up dietlibc-0.31.20080409/libcruft/getpagesize.c.pagesize dietlibc-0.31.20080409/libcruft/getpagesize.c
|
||||
--- dietlibc-0.31.20080409/libcruft/getpagesize.c.pagesize 2002-02-23 23:18:42.000000000 +0100
|
||||
+++ dietlibc-0.31.20080409/libcruft/getpagesize.c 2008-04-12 20:15:33.000000000 +0200
|
||||
@@ -2,14 +2,25 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
-#ifndef PAGE_SIZE
|
||||
-#define PAGE_SIZE 4096
|
||||
-#endif
|
||||
+#include "../dietelfinfo.h"
|
||||
+#include "../dietpagesize.h"
|
||||
|
||||
-size_t __libc_getpagesize(void);
|
||||
size_t __libc_getpagesize(void) {
|
||||
- return PAGE_SIZE;
|
||||
+#ifdef WANT_DYN_PAGESIZE
|
||||
+ static size_t pgsz;
|
||||
+
|
||||
+ if (__unlikely(pgsz==0)) {
|
||||
+ elf_addr_t *v = __get_elf_aux_value(AT_PAGESZ);
|
||||
+ if (__likely(v))
|
||||
+ pgsz = *v;
|
||||
+ else
|
||||
+ pgsz = __DIET_PAGE_SIZE_PREDEF;
|
||||
+ }
|
||||
+
|
||||
+ return pgsz;
|
||||
+#else
|
||||
+ return __DIET_PAGE_SIZE_PREDEF;
|
||||
+#endif
|
||||
}
|
||||
|
||||
size_t getpagesize(void) __attribute__((weak,alias("__libc_getpagesize")));
|
||||
-
|
||||
diff -up /dev/null dietlibc-0.31.20080409/dietpagesize.h
|
||||
--- /dev/null 2008-03-18 07:40:22.289057188 +0100
|
||||
+++ dietlibc-0.31.20080409/dietpagesize.h 2008-04-12 20:22:45.000000000 +0200
|
||||
@@ -0,0 +1,31 @@
|
||||
+#ifndef H_DIETLIBC_DIETPAGESIZE_H
|
||||
+#define H_DIETLIBC_DIETPAGESIZE_H
|
||||
+
|
||||
+#include <strings.h>
|
||||
+#include "dietfeatures.h"
|
||||
+
|
||||
+extern size_t __libc_getpagesize(void) __attribute__((__const__)) __pure;
|
||||
+
|
||||
+#if defined(WANT_STATIC_PAGESIZE)
|
||||
+# define __DIET_PAGE_SIZE_PREDEF (WANT_STATIC_PAGESIZE)
|
||||
+# define __DIET_PAGE_SHIFT_PREDEF (ffs(__DIET_PAGE_SIZE_PREDEF)-1)
|
||||
+#elif defined(__alpha__) || defined(__sparc__)
|
||||
+# define __DIET_PAGE_SIZE_PREDEF (8192UL)
|
||||
+# define __DIET_PAGE_SHIFT_PREDEF (13)
|
||||
+#elif defined(__powerpc64__)
|
||||
+# define __DIET_PAGE_SIZE_PREDEF (65536UL)
|
||||
+# define __DIET_PAGE_SHIFT_PREDEF (16)
|
||||
+#else
|
||||
+# define __DIET_PAGE_SIZE_PREDEF (4096UL)
|
||||
+# define __DIET_PAGE_SHIFT_PREDEF (12)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef WANT_DYN_PAGESIZE
|
||||
+# define __DIET_PAGE_SIZE (__libc_getpagesize())
|
||||
+# define __DIET_PAGE_SHIFT (ffs(__DIET_PAGE_SIZE)-1)
|
||||
+#else
|
||||
+# define __DIET_PAGE_SIZE __DIET_PAGE_SIZE_PREDEF
|
||||
+# define __DIET_PAGE_SHIFT __DIET_PAGE_SHIFT_PREDEF
|
||||
+#endif
|
||||
+
|
||||
+#endif /* H_DIETLIBC_DIETPAGESIZE_H */
|
||||
diff -up dietlibc-0.31.20080409/s390x/start.S.pagesize dietlibc-0.31.20080409/s390x/start.S
|
||||
--- dietlibc-0.31.20080409/s390x/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/s390x/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -26,6 +26,11 @@ _start:
|
||||
larl %r13,environ
|
||||
stg %r4,0(%r13)
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ ahi %r13, 8 /* TODO: does it really point to __elfinfo? */
|
||||
+ stg %r4,0(%r13)
|
||||
+#endif
|
||||
+
|
||||
/* call main or _dyn_start */
|
||||
#ifdef WANT_DYNAMIC
|
||||
brasl %r14,_dyn_start
|
||||
diff -up /dev/null dietlibc-0.31.20080409/dietelfinfo.h
|
||||
--- /dev/null 2008-03-18 07:40:22.289057188 +0100
|
||||
+++ dietlibc-0.31.20080409/dietelfinfo.h 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -0,0 +1,9 @@
|
||||
+#include "dietfeatures.h"
|
||||
+
|
||||
+#ifdef WANT_ELFINFO
|
||||
+#include <linux/auxvec.h>
|
||||
+#include <linux/elf.h>
|
||||
+
|
||||
+elf_addr_t * __get_elf_aux_value(unsigned int tag)
|
||||
+ __attribute__((__visibility__("hidden"),__const__));
|
||||
+#endif
|
||||
diff -up dietlibc-0.31.20080409/ia64/start.S.pagesize dietlibc-0.31.20080409/ia64/start.S
|
||||
--- dietlibc-0.31.20080409/ia64/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/ia64/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -40,6 +40,11 @@ _start:
|
||||
;;
|
||||
st8 [r14] = out2 /* store envp in environ */
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ adds r14 = 8, r14 /* __elfinfo = environ + 8 */
|
||||
+ st8 [r14] = out2 /* store envp in __elfinfo */
|
||||
+#endif
|
||||
+
|
||||
#ifdef WANT_DYNAMIC
|
||||
/* FIXME: dl_init parameter ??? */
|
||||
br.call.sptk.few rp = _dyn_start
|
||||
diff -up dietlibc-0.31.20080409/i386/start.S.pagesize dietlibc-0.31.20080409/i386/start.S
|
||||
--- dietlibc-0.31.20080409/i386/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/i386/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -25,6 +25,10 @@ _start:
|
||||
PIC_INIT /* non-PIC: this is an empty line */
|
||||
PUT_VAR %eax, environ, %ecx /* non-PIC: movl %eax,environ */
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ PUT_VAR %eax, __elfinfo, %ecx
|
||||
+#endif
|
||||
+
|
||||
#ifdef PROFILING
|
||||
pushl $_etext
|
||||
pushl $.text
|
||||
diff -up dietlibc-0.31.20080409/dietdirent.h.pagesize dietlibc-0.31.20080409/dietdirent.h
|
||||
--- dietlibc-0.31.20080409/dietdirent.h.pagesize 2002-07-03 22:33:37.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/dietdirent.h 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -1,8 +1,12 @@
|
||||
#include <sys/shm.h>
|
||||
|
||||
+#include "dietpagesize.h"
|
||||
+
|
||||
struct __dirstream {
|
||||
int fd;
|
||||
- char buf[PAGE_SIZE-(sizeof (int)*3)];
|
||||
unsigned int num;
|
||||
unsigned int cur;
|
||||
+ char buf[];
|
||||
}; /* stream data from opendir() */
|
||||
+
|
||||
+#define __DIRSTREAM_BUF_SIZE (__DIET_PAGE_SIZE - offsetof(struct __dirstream, buf))
|
||||
diff -up dietlibc-0.31.20080409/alpha/start.S.pagesize dietlibc-0.31.20080409/alpha/start.S
|
||||
--- dietlibc-0.31.20080409/alpha/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/alpha/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -24,6 +24,10 @@ _start:
|
||||
|
||||
stq $18, environ
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ stq $18, __elfinfo
|
||||
+#endif
|
||||
+
|
||||
#ifdef WANT_DYNAMIC
|
||||
/* in v0 ($0) is the ld.so _fini pointer */
|
||||
mov $0, $19 /* mov v0(dynload) to a3 */
|
||||
diff -up dietlibc-0.31.20080409/syscalls.s/environ.S.pagesize dietlibc-0.31.20080409/syscalls.s/environ.S
|
||||
--- dietlibc-0.31.20080409/syscalls.s/environ.S.pagesize 2004-09-28 02:01:30.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/syscalls.s/environ.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -1,6 +1,7 @@
|
||||
.section ".bss"
|
||||
.align 8
|
||||
#include <endian.h>
|
||||
+#include <dietfeatures.h>
|
||||
|
||||
.type environ,object
|
||||
.weak environ
|
||||
@@ -15,3 +16,22 @@ environ:
|
||||
#endif
|
||||
.size environ,.-environ
|
||||
.size __environ,.-__environ
|
||||
+
|
||||
+/* __elfinfo will be a copy of __environ after startup. Later, it will be
|
||||
+ updated by __get_elf_aux_value() to point to the terminating NULL of the
|
||||
+ environment.
|
||||
+
|
||||
+ Startup code assumes that __elfinfo is located immediately after
|
||||
+ __environ. */
|
||||
+
|
||||
+#ifdef WANT_ELFINFO
|
||||
+.type __elfinfo,object
|
||||
+.weak __elfinfo
|
||||
+__elfinfo:
|
||||
+#if __WORDSIZE == 64
|
||||
+ .quad 0
|
||||
+#else
|
||||
+ .long 0
|
||||
+#endif
|
||||
+.size __elfinfo,.-__elfinfo
|
||||
+#endif
|
||||
diff -up dietlibc-0.31.20080409/arm/start.S.pagesize dietlibc-0.31.20080409/arm/start.S
|
||||
--- dietlibc-0.31.20080409/arm/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/arm/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -23,11 +23,15 @@ _start:
|
||||
#ifdef __DYN_LIB
|
||||
ldr sl, .L4
|
||||
1: add sl, pc, sl
|
||||
- str a3, [sl, ip] @ environ = envp
|
||||
+ str a3, [ip, sl]! @ environ = envp; ip = GOT(environ)
|
||||
#else
|
||||
str a3, [ip, #0] @ environ = envp
|
||||
#endif
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ str a3, [ip, #4] @ __elfinfo = envp
|
||||
+#endif
|
||||
+
|
||||
#ifdef PROFILING
|
||||
stmdb sp!, { r0 - r3 }
|
||||
ldr r0, .L5
|
||||
@@ -70,6 +74,3 @@ _exit:
|
||||
.L5: .word .text
|
||||
.L6: .word _etext
|
||||
#endif
|
||||
-
|
||||
-
|
||||
-
|
||||
diff -up dietlibc-0.31.20080409/parisc/start.S.pagesize dietlibc-0.31.20080409/parisc/start.S
|
||||
--- dietlibc-0.31.20080409/parisc/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/parisc/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -34,6 +34,11 @@ _start:
|
||||
ldil LP%environ, %r19
|
||||
ldo RP%environ(%r19), %r19
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ ldil LP%__elfinfo, %r19
|
||||
+ ldo RP%__elfinfo(%r19), %r19
|
||||
+#endif
|
||||
+
|
||||
/* Expand the stack to store the 5th through 7th args */
|
||||
ldo 64(%sp), %sp
|
||||
|
||||
diff -up dietlibc-0.31.20080409/include/sys/shm.h.pagesize dietlibc-0.31.20080409/include/sys/shm.h
|
||||
--- dietlibc-0.31.20080409/include/sys/shm.h.pagesize 2005-09-21 09:33:08.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/include/sys/shm.h 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -60,15 +60,6 @@ struct shm_info {
|
||||
unsigned long swap_successes;
|
||||
};
|
||||
|
||||
-#if defined(__i386__) || defined(__mips__) || defined(__arm__) || defined(__powerpc__) || defined (__powerpc64__) || defined(__s390__) || defined(__hppa__) || defined(__x86_64__) || defined(__ia64__)
|
||||
-#define PAGE_SIZE 4096UL
|
||||
-#define PAGE_SHIFT 12
|
||||
-#elif defined(__alpha__) || defined(__sparc__)
|
||||
-/* sun4* has 4k except sun4 architecture, sparc64 has 8k */
|
||||
-#define PAGE_SIZE 8192UL
|
||||
-#define PAGE_SHIFT 13
|
||||
-#endif
|
||||
-
|
||||
extern int shmget(key_t key, int size, int shmflg) __THROW;
|
||||
extern void *shmat(int shmid, const void *shmaddr, int shmflg) __THROW;
|
||||
extern int shmdt (const void *shmaddr) __THROW;
|
||||
diff -up dietlibc-0.31.20080409/sparc/start.S.pagesize dietlibc-0.31.20080409/sparc/start.S
|
||||
--- dietlibc-0.31.20080409/sparc/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/sparc/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -25,6 +25,11 @@ _start:
|
||||
or %o3, %lo(environ), %o3
|
||||
st %o2, [%o3]
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ add %o3, %o3, 4
|
||||
+ st %o2, [%o3]
|
||||
+#endif
|
||||
+
|
||||
/* When starting a binary via the dynamic linker, %g1 contains the
|
||||
address of the shared library termination function, which will be
|
||||
registered with atexit(). If we are statically linked, this will
|
||||
diff -up dietlibc-0.31.20080409/sparc/shmat.c.pagesize dietlibc-0.31.20080409/sparc/shmat.c
|
||||
--- dietlibc-0.31.20080409/sparc/shmat.c.pagesize 2001-06-16 19:48:57.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/sparc/shmat.c 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -3,17 +3,15 @@
|
||||
#include <sys/shm.h>
|
||||
#include <unistd.h>
|
||||
|
||||
-extern void* __ipc();
|
||||
+#include "../dietpagesize.h"
|
||||
|
||||
-#ifndef PAGE_SIZE
|
||||
-#define PAGE_SIZE 4096
|
||||
-#endif
|
||||
+extern void* __ipc();
|
||||
|
||||
void* shmat(int shmid,const void* shmaddr,int shmflg) {
|
||||
void* raddr;
|
||||
register void* result;
|
||||
result=__ipc(SHMAT,shmid,shmflg,&raddr,shmaddr);
|
||||
- if ((unsigned long)result <= -(unsigned long)PAGE_SIZE)
|
||||
+ if ((unsigned long)result <= -(unsigned long)__DIET_PAGE_SIZE)
|
||||
result=raddr;
|
||||
return result;
|
||||
}
|
||||
diff -up dietlibc-0.31.20080409/ppc64/start.S.pagesize dietlibc-0.31.20080409/ppc64/start.S
|
||||
--- dietlibc-0.31.20080409/ppc64/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/ppc64/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -58,6 +58,12 @@ _start:
|
||||
oris 14,14,environ@ha
|
||||
std 5,environ@l(14)
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ /* TODO: can we really assume that environ and __elfinfo are on the
|
||||
+ same 16 bit page? */
|
||||
+ std 5,__elfinfo@l(14)
|
||||
+#endif
|
||||
+
|
||||
#ifdef WANT_DYNAMIC
|
||||
/* #warning dynamic */
|
||||
mr 6,7
|
||||
diff -up dietlibc-0.31.20080409/x86_64/start.S.pagesize dietlibc-0.31.20080409/x86_64/start.S
|
||||
--- dietlibc-0.31.20080409/x86_64/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/x86_64/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -12,12 +12,23 @@ _start:
|
||||
|
||||
leaq 8(%rsi,%rdi,8),%rdx /* %rdx = envp = (8*rdi)+%rsi+8 */
|
||||
|
||||
+
|
||||
+#ifdef WANT_ELFINFO
|
||||
+#ifdef __DYN_LIB
|
||||
+ movq environ@GOTPCREL(%rip), %rax
|
||||
+#else
|
||||
+ leaq environ(%rip), %rax
|
||||
+#endif
|
||||
+ movq %rdx, (%rax) /* environ */
|
||||
+ movq %rdx, 8(%rax) /* __elfinfo */
|
||||
+#else
|
||||
#ifdef __DYN_LIB
|
||||
movq environ@GOTPCREL(%rip), %rax
|
||||
movq %rdx, (%rax)
|
||||
#else
|
||||
movq %rdx, environ(%rip)
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
#ifdef PROFILING
|
||||
pushq %rdi /* save reg args */
|
||||
diff -up dietlibc-0.31.20080409/s390/start.S.pagesize dietlibc-0.31.20080409/s390/start.S
|
||||
--- dietlibc-0.31.20080409/s390/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/s390/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -30,6 +30,11 @@ _start:
|
||||
l %r1,8(%r13)
|
||||
st %r4,0(%r1)
|
||||
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ ahi %r1, 4 # TODO: does it really point to __elfinfo now?
|
||||
+ st %r4,0(%r1)
|
||||
+#endif
|
||||
+
|
||||
/* call main or _dyn_start */
|
||||
l %r1,0(%r13)
|
||||
basr %r14,%r1
|
||||
diff -up dietlibc-0.31.20080409/dynlinker/ldso_start.S.pagesize dietlibc-0.31.20080409/dynlinker/ldso_start.S
|
||||
--- dietlibc-0.31.20080409/dynlinker/ldso_start.S.pagesize 2006-10-13 22:11:13.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/dynlinker/ldso_start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -86,6 +86,15 @@ __environ:
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
+/* __elfinfo must follow __environ immediately */
|
||||
+.global __elfinfo
|
||||
+__elfinfo:
|
||||
+#if __WORDSIZE == 64
|
||||
+ .quad 0
|
||||
+#else
|
||||
+ .long 0
|
||||
+#endif
|
||||
+
|
||||
.global fini_entry
|
||||
fini_entry:
|
||||
.long 0
|
||||
diff -up dietlibc-0.31.20080409/mips/start.S.pagesize dietlibc-0.31.20080409/mips/start.S
|
||||
--- dietlibc-0.31.20080409/mips/start.S.pagesize 2006-04-04 07:35:14.000000000 +0200
|
||||
+++ dietlibc-0.31.20080409/mips/start.S 2008-04-12 20:13:10.000000000 +0200
|
||||
@@ -47,6 +47,9 @@ __start:
|
||||
#endif
|
||||
add $a2, $a2, $a1
|
||||
sw $a2, environ
|
||||
+#ifdef WANT_ELFINFO
|
||||
+ sw $a2, __elfinfo
|
||||
+#endif
|
||||
jalr $25
|
||||
la $25, exit
|
||||
move $4,$2
|
||||
Loading…
Add table
Add a link
Reference in a new issue