فهرست منبع

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

Eric Andersen 21 سال پیش
والد
کامیت
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);
+