소스 검색

make certain that getpagesize() returns correct the value for mips
by extracting the value from the ELF header.

Eric Andersen 20 년 전
부모
커밋
68c4b497dd
6개의 변경된 파일61개의 추가작업 그리고 28개의 파일을 삭제
  1. 1 0
      ldso/include/ldso.h
  2. 13 13
      ldso/ldso/dl-elf.c
  3. 4 1
      ldso/ldso/dl-startup.c
  4. 4 1
      ldso/ldso/ldso.c
  5. 25 3
      libc/misc/internals/__uClibc_main.c
  6. 14 10
      libc/sysdeps/linux/common/getpagesize.c

+ 1 - 0
ldso/include/ldso.h

@@ -45,6 +45,7 @@ extern unsigned char *_dl_mmap_zero;   /* Also used by _dl_malloc */
 extern unsigned long *_dl_brkp;        /* The end of the data segment for brk and sbrk */
 extern unsigned long *_dl_envp;        /* The environment address */
 extern int _dl_secure;                 /* Are we dealing with setuid stuff? */
+extern size_t _dl_pagesize;            /* Store the page size for use later */
 
 #ifdef __SUPPORT_LD_DEBUG__
 extern char *_dl_debug;

+ 13 - 13
ldso/ldso/dl-elf.c

@@ -444,7 +444,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		return NULL;
 	}
 
-	header = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
+	header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
 			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	if (_dl_mmap_check_error(header)) {
 		_dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
@@ -453,7 +453,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		return NULL;
 	};
 
-	_dl_read(infile, header, PAGE_SIZE);
+	_dl_read(infile, header, _dl_pagesize);
 	epnt = (ElfW(Ehdr) *) (intptr_t) header;
 	if (epnt->e_ident[0] != 0x7f ||
 			epnt->e_ident[1] != 'E' ||
@@ -464,7 +464,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 				libname);
 		_dl_internal_error_number = LD_ERROR_NOTELF;
 		_dl_close(infile);
-		_dl_munmap(header, PAGE_SIZE);
+		_dl_munmap(header, _dl_pagesize);
 		return NULL;
 	};
 
@@ -479,7 +479,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		_dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET
 				"\n", _dl_progname, libname);
 		_dl_close(infile);
-		_dl_munmap(header, PAGE_SIZE);
+		_dl_munmap(header, _dl_pagesize);
 		return NULL;
 	};
 
@@ -525,7 +525,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		_dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname);
 		_dl_internal_error_number = LD_ERROR_MMAP_FAILED;
 		_dl_close(infile);
-		_dl_munmap(header, PAGE_SIZE);
+		_dl_munmap(header, _dl_pagesize);
 		return NULL;
 	};
 	libaddr = (unsigned long) status;
@@ -560,7 +560,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 					_dl_internal_error_number = LD_ERROR_MMAP_FAILED;
 					_dl_munmap((char *) libaddr, maxvma - minvma);
 					_dl_close(infile);
-					_dl_munmap(header, PAGE_SIZE);
+					_dl_munmap(header, _dl_pagesize);
 					return NULL;
 				};
 
@@ -593,7 +593,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 				_dl_internal_error_number = LD_ERROR_MMAP_FAILED;
 				_dl_munmap((char *) libaddr, maxvma - minvma);
 				_dl_close(infile);
-				_dl_munmap(header, PAGE_SIZE);
+				_dl_munmap(header, _dl_pagesize);
 				return NULL;
 			};
 
@@ -622,7 +622,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		_dl_internal_error_number = LD_ERROR_NODYNAMIC;
 		_dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",
 				_dl_progname, libname);
-		_dl_munmap(header, PAGE_SIZE);
+		_dl_munmap(header, _dl_pagesize);
 		return NULL;
 	}
 
@@ -725,7 +725,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 	}
 #endif
-	_dl_munmap(header, PAGE_SIZE);
+	_dl_munmap(header, _dl_pagesize);
 
 	return tpnt;
 }
@@ -803,7 +803,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
 	char *start, *ptr, *string;
 	static char *buf;
 
-	buf = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
+	buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
 			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	if (_dl_mmap_check_error(buf)) {
 		_dl_write(fd, "mmap of a spare page failed!\n", 29);
@@ -815,7 +815,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
 	if (!fmt)
 		return;
 
-	if (_dl_strlen(fmt) >= (PAGE_SIZE - 1)) {
+	if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) {
 		_dl_write(fd, "overflow\n", 11);
 		_dl_exit(20);
 	}
@@ -873,7 +873,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
 			start = NULL;
 		}
 	}
-	_dl_munmap(buf, PAGE_SIZE);
+	_dl_munmap(buf, _dl_pagesize);
 	return;
 }
 
@@ -902,7 +902,7 @@ void *_dl_malloc(int size)
 	if (_dl_malloc_function)
 		return (*_dl_malloc_function) (size);
 
-	if (_dl_malloc_addr - _dl_mmap_zero + size > PAGE_SIZE) {
+	if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 		_dl_dprintf(2, "malloc: mmapping more memory\n");
 #endif

+ 4 - 1
ldso/ldso/dl-startup.c

@@ -133,12 +133,14 @@ DL_BOOT(unsigned long args)
 	Elf32_Dyn *dpnt;
 	unsigned long *hash_addr;
 	struct r_debug *debug_addr = NULL;
+	size_t _dl_pagesize;
 	int indx;
 #if defined(__i386__)
 	int status = 0;
 #endif
 
 
+
 	/* WARNING! -- we cannot make _any_ funtion calls until we have
 	 * taken care of fixing up our own relocations.  Making static
 	 * inline calls is ok, but _no_ function calls.  Not yet
@@ -288,7 +290,8 @@ found_got:
 
 	/* Call mmap to get a page of writable memory that can be used
 	 * for _dl_malloc throughout the shared lib loader. */
-	mmap_zero = malloc_buffer = _dl_mmap((void *) 0, PAGE_SIZE,
+	_dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : 4096;
+	mmap_zero = malloc_buffer = _dl_mmap((void *) 0, _dl_pagesize,
 			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	if (_dl_mmap_check_error(mmap_zero)) {
 		SEND_STDERR("dl_boot: mmap of a spare page failed!\n");

+ 4 - 1
ldso/ldso/ldso.c

@@ -46,6 +46,7 @@ unsigned char *_dl_mmap_zero   = 0;		/* Also used by _dl_malloc */
 unsigned long *_dl_brkp        = 0;		/* The end of the data segment for brk and sbrk */
 unsigned long *_dl_envp        = 0;		/* The environment address */
 int _dl_secure                 = 1;		/* Are we dealing with setuid stuff? */
+size_t _dl_pagesize            = 0;		/* Store the page size for use later */
 
 
 
@@ -102,7 +103,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
 #endif
 
-
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 	/* Wahoo!!! */
 	SEND_STDERR("Cool, we managed to make a function call.\n");
@@ -114,6 +114,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	_dl_malloc_addr = malloc_buffer;
 	_dl_mmap_zero = mmap_zero;
 
+	/* Store the page size for later use */
+	_dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : 4096;
+
 	/* Now we have done the mandatory linking of some things.  We are now
 	 * free to start using global variables, since these things have all been
 	 * fixed up by now.  Still no function calls outside of this library ,

+ 25 - 3
libc/misc/internals/__uClibc_main.c

@@ -1,6 +1,6 @@
 /*
  * Manuel Novoa III           Feb 2001
- * Erik Andersen              Mar 2002
+ * Erik Andersen              2002-2004
  *
  * __uClibc_main is the routine to be called by all the arch-specific
  * versions of crt0.S in uClibc.
@@ -15,6 +15,8 @@
 #include <features.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
+#include <elf.h>
 #ifdef __UCLIBC_PROPOLICE__
 extern void __guard_setup(void);
 #endif
@@ -44,6 +46,9 @@ extern void weak_function __pthread_initialize_minimal(void);
  * environ symbol is also included.
  */
 
+extern int _dl_secure;
+extern size_t _dl_pagesize;
+
 char **__environ = 0;
 const char *__progname = 0;
 weak_alias(__environ, environ);
@@ -116,6 +121,23 @@ void __attribute__ ((__noreturn__))
 __uClibc_start_main(int argc, char **argv, char **envp,
 	void (*app_init)(void), void (*app_fini)(void))
 {
+    unsigned long *aux_dat;
+    Elf32_auxv_t auxvt[AT_EGID + 1];
+
+    /* Pull stuff from the ELF header when possible */
+    aux_dat = (unsigned long*)envp;
+    while (*aux_dat) {
+	aux_dat++;
+    }
+    aux_dat++;
+    while (*aux_dat) {
+	Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
+	if (auxv_entry->a_type <= AT_EGID) {
+	    memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+	}
+	aux_dat += 2;
+    }
+    _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : 4096;
 
     /* If we are dynamically linked the shared lib loader already
      * did this for us.  But if we are statically linked, we need
@@ -134,7 +156,7 @@ __uClibc_start_main(int argc, char **argv, char **envp,
 
 #ifdef __UCLIBC_CTOR_DTOR__
     /* Arrange for the application's dtors to run before we exit.  */
-	__app_fini = app_fini;
+    __app_fini = app_fini;
 
     /* Run all the application's ctors now.  */
     if (app_init!=NULL) {
@@ -143,7 +165,7 @@ __uClibc_start_main(int argc, char **argv, char **envp,
 #endif
 
 #ifdef __UCLIBC_PROPOLICE__
-     __guard_setup ();
+    __guard_setup ();
 #endif
 
     /* Note: It is possible that any initialization done above could

+ 14 - 10
libc/sysdeps/linux/common/getpagesize.c

@@ -1,28 +1,32 @@
-/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1992,1995-1997,2000,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 Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   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 <unistd.h>
 #include <features.h>
 #include <sys/param.h>
+extern size_t _dl_pagesize;
 
 /* Return the system page size.  */
 int __getpagesize(void)
 {
+  if (_dl_pagesize != 0)
+    return _dl_pagesize;
+
 #ifdef	EXEC_PAGESIZE
   return EXEC_PAGESIZE;
 #else	/* No EXEC_PAGESIZE.  */
@@ -36,5 +40,5 @@ int __getpagesize(void)
 #endif	/* NBPG.  */
 #endif	/* EXEC_PAGESIZE.  */
 }
-
 weak_alias(__getpagesize, getpagesize);
+