Explorar o código

Some more updates and explanation

Eric Andersen %!s(int64=23) %!d(string=hai) anos
pai
achega
fe59e88493
Modificáronse 5 ficheiros con 326 adicións e 315 borrados
  1. 98 105
      ldso/ldso/boot1.c
  2. 98 105
      ldso/ldso/ld-uClibc.c
  3. 16 0
      ldso/ldso/ld_string.h
  4. 98 105
      ldso/ldso/ldso.c
  5. 16 0
      ldso/ldso/string.h

+ 98 - 105
ldso/ldso/boot1.c

@@ -75,12 +75,11 @@
  * someone has alpha patches), so for now everything is loaded writable.
  *
  * We do not have access to malloc and friends at the initial stages of dynamic
- * linking, and it would be handy to have some scratchpad memory available
- * for use as we set things up.  It is a bit of a kluge, but we mmap /dev/zero
- * to get one page of scratchpad.  A simpleminded _dl_malloc is provided so
- * that we have some memory that can be used for this purpose.  Typically
- * we would not want to use the same memory pool as malloc anyway - the user
- * might want to redefine malloc for example.
+ * linking, and it would be handy to have some scratchpad memory available for
+ * use as we set things up.  We mmap one page of scratch space, and have a
+ * simple _dl_malloc that uses this memory.  This is a good thing, since we do
+ * not want to use the same memory pool as malloc anyway - esp if the user
+ * redefines malloc to do something funky.
  *
  * Our first task is to perform a minimal linking so that we can call other
  * portions of the dynamic linker.  Once we have done this, we then build
@@ -92,7 +91,6 @@
  * can transfer control to the user's application.
  */
 
-#include <sys/mman.h>			// For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
 #include "elf.h"
 #include "link.h"
@@ -100,31 +98,12 @@
 #include "hash.h"
 #include "syscall.h"
 #include "string.h"
-
 #include "../config.h"
 
 #define ALLOW_ZERO_PLTGOT
 
-static char *_dl_malloc_addr, *_dl_mmap_zero;
-char *_dl_library_path = 0;		/* Where we look for libraries */
-char *_dl_preload = 0;			/* Things to be loaded before the libs. */
-char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char *_dl_not_lazy = 0;
-static char *_dl_warn = 0;		/* Used by ldd */
-static char *_dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main) (int, char **, char **);
-
-static int (*_dl_elf_init) (void);
-
-void *(*_dl_malloc_function) (int size) = NULL;
-
-struct r_debug *_dl_debug_addr = NULL;
-
-unsigned long *_dl_brkp;
-
-unsigned long *_dl_envp;
-
-#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
+/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
+#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ;  REALIGN();
 /*
  * Make sure that the malloc buffer is aligned on 4 byte boundary.  For 64 bit
  * platforms we may need to increase this to 8, but this is good enough for
@@ -132,8 +111,6 @@ unsigned long *_dl_envp;
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-
-
 #define ELF_HASH(RESULT,NAME) { \
   unsigned long hash = 0; \
     unsigned long tmp;  \
@@ -145,25 +122,39 @@ unsigned long *_dl_envp;
   } \
   RESULT = hash; \
 }
-extern int _dl_linux_resolve(void);
-extern char *_dl_strdup(const char *);
-extern char *_dl_getenv(char *symbol, char **envp);
-extern void _dl_unsetenv(char *symbol, char **envp);
-extern int _dl_fixup(struct elf_resolve *tpnt);
 
-/*
- * This stub function is used by some debuggers.  The idea is that they
- * can set an internal breakpoint on it, so that we are notified when the
- * address mapping is changed in some way.
- */
-void _dl_debug_state()
-{
-	return;
-}
-
-void _dl_boot(unsigned long args)
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;		/* Where we look for libraries */
+char *_dl_preload = 0;			/* Things to be loaded before the libs. */
+char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;		/* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
+static int (*_dl_elf_init) (void);
+void *(*_dl_malloc_function) (int size) = NULL;
+struct r_debug *_dl_debug_addr = NULL;
+unsigned long *_dl_brkp;
+unsigned long *_dl_envp;
+char *_dl_getenv(char *symbol, char **envp);
+void _dl_unsetenv(char *symbol, char **envp);
+int _dl_fixup(struct elf_resolve *tpnt);
+void _dl_debug_state(void);
+
+
+/* When we enter this piece of code, the program stack looks like this:
+        argc            argument counter (integer)
+        argv[0]         program name (pointer)
+        argv[1...N]     program args (pointers)
+        argv[argc-1]    end of args (integer)
+	NULL
+        env[0...N]      environment variables (pointers)
+        NULL
+	auxv_t[0...N]   Auxiliary Vector Table elements (mixed types)
+*/
+void _dl_boot(unsigned int args)
 {
-	unsigned long argc;
+	unsigned int argc;
 	char **argv, **envp;
 	int status;
 
@@ -176,10 +167,10 @@ void _dl_boot(unsigned long args)
 	struct dyn_elf *rpnt;
 	struct elf_resolve *app_tpnt;
 	unsigned long brk_addr;
-	unsigned long dl_data[AT_EGID + 1];
+	Elf32_auxv_t auxv_t[AT_EGID + 1];
 	unsigned char *malloc_buffer, *mmap_zero;
 	int (*_dl_atexit) (void *);
-	unsigned long *lpnt;
+	int *lpnt;
 	Elf32_Dyn *dpnt;
 	unsigned long *hash_addr;
 	struct r_debug *debug_addr;
@@ -199,60 +190,48 @@ void _dl_boot(unsigned long args)
 	while (*aux_dat)
 		aux_dat++;			/* Skip over the envp pointers */
 	aux_dat++;				/* Skip over NULL at end of envp */
-	dl_data[AT_UID] = -1;			/* check later to see if it is changed */
+
+	/* Place -1 here as a checkpoint.  We check later to see if it got changed 
+	 * when we read in the auxv_t */
+	auxv_t[AT_UID].a_type = -1;
+	
+	/* The junk on the stack immediately following the environment is  
+	 * the Auxiliary Vector Table.  Read out the elements of the auxv_t,
+	 * sort and store them in auxv_t for later use. */
 	while (*aux_dat) 
 	{
-		unsigned long *ad1;
+		Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
-		ad1 = aux_dat + 1;
-		if (*aux_dat <= AT_EGID)
-			dl_data[*aux_dat] = *ad1;
+		if (auxv_entry->a_type <= AT_EGID) {
+			_dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+		}
 		aux_dat += 2;
 	}
 
 	/* Next, locate the GOT */
-
-	load_addr = dl_data[AT_BASE];
-
+	load_addr = auxv_t[AT_BASE].a_un.a_val;
 	GET_GOT(got);
 	dpnt = (Elf32_Dyn *) (*got + load_addr);
 
-	/* OK, time for another hack.  Now call mmap to get a page of writable
-	   memory that can be used for a temporary malloc.  We do not know brk
-	   yet, so we cannot use real malloc. */
-
-	{
-#define ZFILENO -1
-
-#ifndef MAP_ANONYMOUS
-#ifdef __sparc__
-#define MAP_ANONYMOUS 0x20
-#else
-#error MAP_ANONYMOUS not defined and suplementary value not known
-#endif
-#endif
-
-		/* See if we need to relocate this address */
-		mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
-			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-		if (_dl_mmap_check_error(mmap_zero)) {
-			SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-			_dl_exit(13);
-		}
+	
+	/* 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, 4096, 
+		PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(mmap_zero)) {
+	    SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
+	    _dl_exit(13);
 	}
 
 	tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(tpnt, 0, sizeof(*tpnt));
 	app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
 	/*
 	 * This is used by gdb to locate the chain of shared libraries that are currently loaded.
 	 */
 	debug_addr = DL_MALLOC(sizeof(struct r_debug));
-	REALIGN();
 	_dl_memset(debug_addr, 0, sizeof(*debug_addr));
 
 	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
@@ -269,8 +248,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++)
 			if (ppnt->p_type == PT_DYNAMIC) {
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				while (dpnt->d_tag) {
@@ -280,7 +259,7 @@ void _dl_boot(unsigned long args)
 					}
 					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
 					if (dpnt->d_tag == DT_DEBUG)
-						dpnt->d_un.d_val = (unsigned long) debug_addr;
+						dpnt->d_un.d_val = (int) debug_addr;
 					if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
 						app_tpnt->dynamic_info[DT_TEXTREL] = 1;
 					dpnt++;
@@ -308,8 +287,8 @@ void _dl_boot(unsigned long args)
 
 		/* First cover the shared library/dynamic linker. */
 		if (tpnt->dynamic_info[DT_TEXTREL]) {
-			header = (elfhdr *) dl_data[AT_BASE];
-			ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+			header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+			ppnt = (elf_phdr *) (auxv_t[AT_BASE].a_un.a_ptr + header->e_phoff);
 			for (i = 0; i < header->e_phnum; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (load_addr + 
@@ -322,8 +301,8 @@ void _dl_boot(unsigned long args)
 
 		/* Now cover the application program. */
 		if (app_tpnt->dynamic_info[DT_TEXTREL]) {
-			ppnt = (elf_phdr *) dl_data[AT_PHDR];
-			for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+			ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+			for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
 						(ppnt->p_vaddr & 0xfff) + 
@@ -428,7 +407,7 @@ void _dl_boot(unsigned long args)
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+	lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
 	INIT_GOT(lpnt, tpnt);
 
 	/* OK, this was a big step, now we need to scan all of the user images
@@ -443,7 +422,7 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		epnt = (elfhdr *) dl_data[AT_BASE];
+		epnt = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
 		tpnt->n_phent = epnt->e_phnum;
 		tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
 		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
@@ -468,8 +447,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 			if (ppnt->p_type == PT_LOAD) {
 				if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
 					brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
@@ -484,15 +463,15 @@ void _dl_boot(unsigned long args)
 				app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 				_dl_loaded_modules->libtype = elf_executable;
-				_dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
-				_dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+				_dl_loaded_modules->ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+				_dl_loaded_modules->n_phent = auxv_t[AT_PHNUM].a_un.a_val;
 				_dl_symbol_tables = rpnt =
 					(struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 				_dl_memset(rpnt, 0, sizeof(*rpnt));
 				rpnt->dyn = _dl_loaded_modules;
 				app_tpnt->usage_count++;
 				app_tpnt->symbol_scope = _dl_symbol_tables;
-				lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+				lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
 				if (lpnt)
 #endif
@@ -501,7 +480,7 @@ void _dl_boot(unsigned long args)
 			if (ppnt->p_type == PT_INTERP) {	/* OK, fill this in - we did not 
 								   have this before */
 				tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
-							   (dl_data[AT_PHDR] & 0xfffff000));
+							   (auxv_t[AT_PHDR].a_un.a_val & 0xfffff000));
 			}
 		}
 	}
@@ -515,9 +494,10 @@ void _dl_boot(unsigned long args)
 	{
 		_dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
 
-		if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-			(dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
-			 && dl_data[AT_GID] == dl_data[AT_EGID])) {
+		if ((auxv_t[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
+			(auxv_t[AT_UID].a_un.a_val != -1 && 
+			 auxv_t[AT_UID].a_un.a_val == auxv_t[AT_EUID].a_un.a_val
+			 && auxv_t[AT_GID].a_un.a_val== auxv_t[AT_EGID].a_un.a_val)) {
 			_dl_secure = 0;
 			_dl_preload = _dl_getenv("LD_PRELOAD", envp);
 			_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
@@ -889,7 +869,7 @@ void _dl_boot(unsigned long args)
 	}
 
 	/* OK we are done here.  Turn out the lights, and lock up. */
-	_dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
+	_dl_elf_main = (int (*)(int, char **, char **)) auxv_t[AT_ENTRY].a_un.a_fcn;
 
 
 	/*
@@ -898,6 +878,16 @@ void _dl_boot(unsigned long args)
 	START();
 }
 
+/*
+ * This stub function is used by some debuggers.  The idea is that they
+ * can set an internal breakpoint on it, so that we are notified when the
+ * address mapping is changed in some way.
+ */
+void _dl_debug_state()
+{
+	return;
+}
+
 int _dl_fixup(struct elf_resolve *tpnt)
 {
 	int goof = 0;
@@ -952,14 +942,17 @@ void *_dl_malloc(int size)
 {
 	void *retval;
 
+	//SEND_STDERR("malloc: request for ");
+	//SEND_STDERR(_dl_simple_itol(size));
+	//SEND_STDERR(" bytes\n");
+
 	if (_dl_malloc_function)
 		return (*_dl_malloc_function) (size);
 
 	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
-		_dl_mmap_zero = _dl_malloc_addr =
-			(unsigned char *) _dl_mmap((void *) 0, size, 
-						   PROT_READ | PROT_WRITE, 
-						   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		//SEND_STDERR("malloc: mmapping more memory\n");
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 		if (_dl_mmap_check_error(_dl_mmap_zero)) {
 			_dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
 			_dl_exit(20);

+ 98 - 105
ldso/ldso/ld-uClibc.c

@@ -75,12 +75,11 @@
  * someone has alpha patches), so for now everything is loaded writable.
  *
  * We do not have access to malloc and friends at the initial stages of dynamic
- * linking, and it would be handy to have some scratchpad memory available
- * for use as we set things up.  It is a bit of a kluge, but we mmap /dev/zero
- * to get one page of scratchpad.  A simpleminded _dl_malloc is provided so
- * that we have some memory that can be used for this purpose.  Typically
- * we would not want to use the same memory pool as malloc anyway - the user
- * might want to redefine malloc for example.
+ * linking, and it would be handy to have some scratchpad memory available for
+ * use as we set things up.  We mmap one page of scratch space, and have a
+ * simple _dl_malloc that uses this memory.  This is a good thing, since we do
+ * not want to use the same memory pool as malloc anyway - esp if the user
+ * redefines malloc to do something funky.
  *
  * Our first task is to perform a minimal linking so that we can call other
  * portions of the dynamic linker.  Once we have done this, we then build
@@ -92,7 +91,6 @@
  * can transfer control to the user's application.
  */
 
-#include <sys/mman.h>			// For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
 #include "elf.h"
 #include "link.h"
@@ -100,31 +98,12 @@
 #include "hash.h"
 #include "syscall.h"
 #include "string.h"
-
 #include "../config.h"
 
 #define ALLOW_ZERO_PLTGOT
 
-static char *_dl_malloc_addr, *_dl_mmap_zero;
-char *_dl_library_path = 0;		/* Where we look for libraries */
-char *_dl_preload = 0;			/* Things to be loaded before the libs. */
-char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char *_dl_not_lazy = 0;
-static char *_dl_warn = 0;		/* Used by ldd */
-static char *_dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main) (int, char **, char **);
-
-static int (*_dl_elf_init) (void);
-
-void *(*_dl_malloc_function) (int size) = NULL;
-
-struct r_debug *_dl_debug_addr = NULL;
-
-unsigned long *_dl_brkp;
-
-unsigned long *_dl_envp;
-
-#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
+/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
+#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ;  REALIGN();
 /*
  * Make sure that the malloc buffer is aligned on 4 byte boundary.  For 64 bit
  * platforms we may need to increase this to 8, but this is good enough for
@@ -132,8 +111,6 @@ unsigned long *_dl_envp;
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-
-
 #define ELF_HASH(RESULT,NAME) { \
   unsigned long hash = 0; \
     unsigned long tmp;  \
@@ -145,25 +122,39 @@ unsigned long *_dl_envp;
   } \
   RESULT = hash; \
 }
-extern int _dl_linux_resolve(void);
-extern char *_dl_strdup(const char *);
-extern char *_dl_getenv(char *symbol, char **envp);
-extern void _dl_unsetenv(char *symbol, char **envp);
-extern int _dl_fixup(struct elf_resolve *tpnt);
 
-/*
- * This stub function is used by some debuggers.  The idea is that they
- * can set an internal breakpoint on it, so that we are notified when the
- * address mapping is changed in some way.
- */
-void _dl_debug_state()
-{
-	return;
-}
-
-void _dl_boot(unsigned long args)
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;		/* Where we look for libraries */
+char *_dl_preload = 0;			/* Things to be loaded before the libs. */
+char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;		/* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
+static int (*_dl_elf_init) (void);
+void *(*_dl_malloc_function) (int size) = NULL;
+struct r_debug *_dl_debug_addr = NULL;
+unsigned long *_dl_brkp;
+unsigned long *_dl_envp;
+char *_dl_getenv(char *symbol, char **envp);
+void _dl_unsetenv(char *symbol, char **envp);
+int _dl_fixup(struct elf_resolve *tpnt);
+void _dl_debug_state(void);
+
+
+/* When we enter this piece of code, the program stack looks like this:
+        argc            argument counter (integer)
+        argv[0]         program name (pointer)
+        argv[1...N]     program args (pointers)
+        argv[argc-1]    end of args (integer)
+	NULL
+        env[0...N]      environment variables (pointers)
+        NULL
+	auxv_t[0...N]   Auxiliary Vector Table elements (mixed types)
+*/
+void _dl_boot(unsigned int args)
 {
-	unsigned long argc;
+	unsigned int argc;
 	char **argv, **envp;
 	int status;
 
@@ -176,10 +167,10 @@ void _dl_boot(unsigned long args)
 	struct dyn_elf *rpnt;
 	struct elf_resolve *app_tpnt;
 	unsigned long brk_addr;
-	unsigned long dl_data[AT_EGID + 1];
+	Elf32_auxv_t auxv_t[AT_EGID + 1];
 	unsigned char *malloc_buffer, *mmap_zero;
 	int (*_dl_atexit) (void *);
-	unsigned long *lpnt;
+	int *lpnt;
 	Elf32_Dyn *dpnt;
 	unsigned long *hash_addr;
 	struct r_debug *debug_addr;
@@ -199,60 +190,48 @@ void _dl_boot(unsigned long args)
 	while (*aux_dat)
 		aux_dat++;			/* Skip over the envp pointers */
 	aux_dat++;				/* Skip over NULL at end of envp */
-	dl_data[AT_UID] = -1;			/* check later to see if it is changed */
+
+	/* Place -1 here as a checkpoint.  We check later to see if it got changed 
+	 * when we read in the auxv_t */
+	auxv_t[AT_UID].a_type = -1;
+	
+	/* The junk on the stack immediately following the environment is  
+	 * the Auxiliary Vector Table.  Read out the elements of the auxv_t,
+	 * sort and store them in auxv_t for later use. */
 	while (*aux_dat) 
 	{
-		unsigned long *ad1;
+		Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
-		ad1 = aux_dat + 1;
-		if (*aux_dat <= AT_EGID)
-			dl_data[*aux_dat] = *ad1;
+		if (auxv_entry->a_type <= AT_EGID) {
+			_dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+		}
 		aux_dat += 2;
 	}
 
 	/* Next, locate the GOT */
-
-	load_addr = dl_data[AT_BASE];
-
+	load_addr = auxv_t[AT_BASE].a_un.a_val;
 	GET_GOT(got);
 	dpnt = (Elf32_Dyn *) (*got + load_addr);
 
-	/* OK, time for another hack.  Now call mmap to get a page of writable
-	   memory that can be used for a temporary malloc.  We do not know brk
-	   yet, so we cannot use real malloc. */
-
-	{
-#define ZFILENO -1
-
-#ifndef MAP_ANONYMOUS
-#ifdef __sparc__
-#define MAP_ANONYMOUS 0x20
-#else
-#error MAP_ANONYMOUS not defined and suplementary value not known
-#endif
-#endif
-
-		/* See if we need to relocate this address */
-		mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
-			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-		if (_dl_mmap_check_error(mmap_zero)) {
-			SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-			_dl_exit(13);
-		}
+	
+	/* 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, 4096, 
+		PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(mmap_zero)) {
+	    SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
+	    _dl_exit(13);
 	}
 
 	tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(tpnt, 0, sizeof(*tpnt));
 	app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
 	/*
 	 * This is used by gdb to locate the chain of shared libraries that are currently loaded.
 	 */
 	debug_addr = DL_MALLOC(sizeof(struct r_debug));
-	REALIGN();
 	_dl_memset(debug_addr, 0, sizeof(*debug_addr));
 
 	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
@@ -269,8 +248,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++)
 			if (ppnt->p_type == PT_DYNAMIC) {
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				while (dpnt->d_tag) {
@@ -280,7 +259,7 @@ void _dl_boot(unsigned long args)
 					}
 					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
 					if (dpnt->d_tag == DT_DEBUG)
-						dpnt->d_un.d_val = (unsigned long) debug_addr;
+						dpnt->d_un.d_val = (int) debug_addr;
 					if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
 						app_tpnt->dynamic_info[DT_TEXTREL] = 1;
 					dpnt++;
@@ -308,8 +287,8 @@ void _dl_boot(unsigned long args)
 
 		/* First cover the shared library/dynamic linker. */
 		if (tpnt->dynamic_info[DT_TEXTREL]) {
-			header = (elfhdr *) dl_data[AT_BASE];
-			ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+			header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+			ppnt = (elf_phdr *) (auxv_t[AT_BASE].a_un.a_ptr + header->e_phoff);
 			for (i = 0; i < header->e_phnum; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (load_addr + 
@@ -322,8 +301,8 @@ void _dl_boot(unsigned long args)
 
 		/* Now cover the application program. */
 		if (app_tpnt->dynamic_info[DT_TEXTREL]) {
-			ppnt = (elf_phdr *) dl_data[AT_PHDR];
-			for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+			ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+			for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
 						(ppnt->p_vaddr & 0xfff) + 
@@ -428,7 +407,7 @@ void _dl_boot(unsigned long args)
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+	lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
 	INIT_GOT(lpnt, tpnt);
 
 	/* OK, this was a big step, now we need to scan all of the user images
@@ -443,7 +422,7 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		epnt = (elfhdr *) dl_data[AT_BASE];
+		epnt = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
 		tpnt->n_phent = epnt->e_phnum;
 		tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
 		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
@@ -468,8 +447,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 			if (ppnt->p_type == PT_LOAD) {
 				if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
 					brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
@@ -484,15 +463,15 @@ void _dl_boot(unsigned long args)
 				app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 				_dl_loaded_modules->libtype = elf_executable;
-				_dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
-				_dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+				_dl_loaded_modules->ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+				_dl_loaded_modules->n_phent = auxv_t[AT_PHNUM].a_un.a_val;
 				_dl_symbol_tables = rpnt =
 					(struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 				_dl_memset(rpnt, 0, sizeof(*rpnt));
 				rpnt->dyn = _dl_loaded_modules;
 				app_tpnt->usage_count++;
 				app_tpnt->symbol_scope = _dl_symbol_tables;
-				lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+				lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
 				if (lpnt)
 #endif
@@ -501,7 +480,7 @@ void _dl_boot(unsigned long args)
 			if (ppnt->p_type == PT_INTERP) {	/* OK, fill this in - we did not 
 								   have this before */
 				tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
-							   (dl_data[AT_PHDR] & 0xfffff000));
+							   (auxv_t[AT_PHDR].a_un.a_val & 0xfffff000));
 			}
 		}
 	}
@@ -515,9 +494,10 @@ void _dl_boot(unsigned long args)
 	{
 		_dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
 
-		if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-			(dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
-			 && dl_data[AT_GID] == dl_data[AT_EGID])) {
+		if ((auxv_t[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
+			(auxv_t[AT_UID].a_un.a_val != -1 && 
+			 auxv_t[AT_UID].a_un.a_val == auxv_t[AT_EUID].a_un.a_val
+			 && auxv_t[AT_GID].a_un.a_val== auxv_t[AT_EGID].a_un.a_val)) {
 			_dl_secure = 0;
 			_dl_preload = _dl_getenv("LD_PRELOAD", envp);
 			_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
@@ -889,7 +869,7 @@ void _dl_boot(unsigned long args)
 	}
 
 	/* OK we are done here.  Turn out the lights, and lock up. */
-	_dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
+	_dl_elf_main = (int (*)(int, char **, char **)) auxv_t[AT_ENTRY].a_un.a_fcn;
 
 
 	/*
@@ -898,6 +878,16 @@ void _dl_boot(unsigned long args)
 	START();
 }
 
+/*
+ * This stub function is used by some debuggers.  The idea is that they
+ * can set an internal breakpoint on it, so that we are notified when the
+ * address mapping is changed in some way.
+ */
+void _dl_debug_state()
+{
+	return;
+}
+
 int _dl_fixup(struct elf_resolve *tpnt)
 {
 	int goof = 0;
@@ -952,14 +942,17 @@ void *_dl_malloc(int size)
 {
 	void *retval;
 
+	//SEND_STDERR("malloc: request for ");
+	//SEND_STDERR(_dl_simple_itol(size));
+	//SEND_STDERR(" bytes\n");
+
 	if (_dl_malloc_function)
 		return (*_dl_malloc_function) (size);
 
 	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
-		_dl_mmap_zero = _dl_malloc_addr =
-			(unsigned char *) _dl_mmap((void *) 0, size, 
-						   PROT_READ | PROT_WRITE, 
-						   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		//SEND_STDERR("malloc: mmapping more memory\n");
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 		if (_dl_mmap_check_error(_dl_mmap_zero)) {
 			_dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
 			_dl_exit(20);

+ 16 - 0
ldso/ldso/ld_string.h

@@ -109,4 +109,20 @@ extern inline void * _dl_memset(void * str,int c,size_t len)
 	return str;
 }
 
+/* Early on, we can't call printf, so use this to print out
+ * numbers using the SEND_STDERR() macro */
+static inline char *_dl_simple_itol(unsigned long i)
+{
+	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
+	static char local[22];
+	char *p = &local[21];
+	*p-- = '\0';
+	do {
+		*p-- = '0' + i % 10;
+		i /= 10;
+	} while (i > 0);
+	return p + 1;
+}
+
+
 #endif

+ 98 - 105
ldso/ldso/ldso.c

@@ -75,12 +75,11 @@
  * someone has alpha patches), so for now everything is loaded writable.
  *
  * We do not have access to malloc and friends at the initial stages of dynamic
- * linking, and it would be handy to have some scratchpad memory available
- * for use as we set things up.  It is a bit of a kluge, but we mmap /dev/zero
- * to get one page of scratchpad.  A simpleminded _dl_malloc is provided so
- * that we have some memory that can be used for this purpose.  Typically
- * we would not want to use the same memory pool as malloc anyway - the user
- * might want to redefine malloc for example.
+ * linking, and it would be handy to have some scratchpad memory available for
+ * use as we set things up.  We mmap one page of scratch space, and have a
+ * simple _dl_malloc that uses this memory.  This is a good thing, since we do
+ * not want to use the same memory pool as malloc anyway - esp if the user
+ * redefines malloc to do something funky.
  *
  * Our first task is to perform a minimal linking so that we can call other
  * portions of the dynamic linker.  Once we have done this, we then build
@@ -92,7 +91,6 @@
  * can transfer control to the user's application.
  */
 
-#include <sys/mman.h>			// For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
 #include "elf.h"
 #include "link.h"
@@ -100,31 +98,12 @@
 #include "hash.h"
 #include "syscall.h"
 #include "string.h"
-
 #include "../config.h"
 
 #define ALLOW_ZERO_PLTGOT
 
-static char *_dl_malloc_addr, *_dl_mmap_zero;
-char *_dl_library_path = 0;		/* Where we look for libraries */
-char *_dl_preload = 0;			/* Things to be loaded before the libs. */
-char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char *_dl_not_lazy = 0;
-static char *_dl_warn = 0;		/* Used by ldd */
-static char *_dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main) (int, char **, char **);
-
-static int (*_dl_elf_init) (void);
-
-void *(*_dl_malloc_function) (int size) = NULL;
-
-struct r_debug *_dl_debug_addr = NULL;
-
-unsigned long *_dl_brkp;
-
-unsigned long *_dl_envp;
-
-#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
+/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
+#define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ;  REALIGN();
 /*
  * Make sure that the malloc buffer is aligned on 4 byte boundary.  For 64 bit
  * platforms we may need to increase this to 8, but this is good enough for
@@ -132,8 +111,6 @@ unsigned long *_dl_envp;
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-
-
 #define ELF_HASH(RESULT,NAME) { \
   unsigned long hash = 0; \
     unsigned long tmp;  \
@@ -145,25 +122,39 @@ unsigned long *_dl_envp;
   } \
   RESULT = hash; \
 }
-extern int _dl_linux_resolve(void);
-extern char *_dl_strdup(const char *);
-extern char *_dl_getenv(char *symbol, char **envp);
-extern void _dl_unsetenv(char *symbol, char **envp);
-extern int _dl_fixup(struct elf_resolve *tpnt);
 
-/*
- * This stub function is used by some debuggers.  The idea is that they
- * can set an internal breakpoint on it, so that we are notified when the
- * address mapping is changed in some way.
- */
-void _dl_debug_state()
-{
-	return;
-}
-
-void _dl_boot(unsigned long args)
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;		/* Where we look for libraries */
+char *_dl_preload = 0;			/* Things to be loaded before the libs. */
+char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;		/* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
+static int (*_dl_elf_init) (void);
+void *(*_dl_malloc_function) (int size) = NULL;
+struct r_debug *_dl_debug_addr = NULL;
+unsigned long *_dl_brkp;
+unsigned long *_dl_envp;
+char *_dl_getenv(char *symbol, char **envp);
+void _dl_unsetenv(char *symbol, char **envp);
+int _dl_fixup(struct elf_resolve *tpnt);
+void _dl_debug_state(void);
+
+
+/* When we enter this piece of code, the program stack looks like this:
+        argc            argument counter (integer)
+        argv[0]         program name (pointer)
+        argv[1...N]     program args (pointers)
+        argv[argc-1]    end of args (integer)
+	NULL
+        env[0...N]      environment variables (pointers)
+        NULL
+	auxv_t[0...N]   Auxiliary Vector Table elements (mixed types)
+*/
+void _dl_boot(unsigned int args)
 {
-	unsigned long argc;
+	unsigned int argc;
 	char **argv, **envp;
 	int status;
 
@@ -176,10 +167,10 @@ void _dl_boot(unsigned long args)
 	struct dyn_elf *rpnt;
 	struct elf_resolve *app_tpnt;
 	unsigned long brk_addr;
-	unsigned long dl_data[AT_EGID + 1];
+	Elf32_auxv_t auxv_t[AT_EGID + 1];
 	unsigned char *malloc_buffer, *mmap_zero;
 	int (*_dl_atexit) (void *);
-	unsigned long *lpnt;
+	int *lpnt;
 	Elf32_Dyn *dpnt;
 	unsigned long *hash_addr;
 	struct r_debug *debug_addr;
@@ -199,60 +190,48 @@ void _dl_boot(unsigned long args)
 	while (*aux_dat)
 		aux_dat++;			/* Skip over the envp pointers */
 	aux_dat++;				/* Skip over NULL at end of envp */
-	dl_data[AT_UID] = -1;			/* check later to see if it is changed */
+
+	/* Place -1 here as a checkpoint.  We check later to see if it got changed 
+	 * when we read in the auxv_t */
+	auxv_t[AT_UID].a_type = -1;
+	
+	/* The junk on the stack immediately following the environment is  
+	 * the Auxiliary Vector Table.  Read out the elements of the auxv_t,
+	 * sort and store them in auxv_t for later use. */
 	while (*aux_dat) 
 	{
-		unsigned long *ad1;
+		Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
-		ad1 = aux_dat + 1;
-		if (*aux_dat <= AT_EGID)
-			dl_data[*aux_dat] = *ad1;
+		if (auxv_entry->a_type <= AT_EGID) {
+			_dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+		}
 		aux_dat += 2;
 	}
 
 	/* Next, locate the GOT */
-
-	load_addr = dl_data[AT_BASE];
-
+	load_addr = auxv_t[AT_BASE].a_un.a_val;
 	GET_GOT(got);
 	dpnt = (Elf32_Dyn *) (*got + load_addr);
 
-	/* OK, time for another hack.  Now call mmap to get a page of writable
-	   memory that can be used for a temporary malloc.  We do not know brk
-	   yet, so we cannot use real malloc. */
-
-	{
-#define ZFILENO -1
-
-#ifndef MAP_ANONYMOUS
-#ifdef __sparc__
-#define MAP_ANONYMOUS 0x20
-#else
-#error MAP_ANONYMOUS not defined and suplementary value not known
-#endif
-#endif
-
-		/* See if we need to relocate this address */
-		mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
-			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-		if (_dl_mmap_check_error(mmap_zero)) {
-			SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-			_dl_exit(13);
-		}
+	
+	/* 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, 4096, 
+		PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(mmap_zero)) {
+	    SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
+	    _dl_exit(13);
 	}
 
 	tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(tpnt, 0, sizeof(*tpnt));
 	app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-	REALIGN();
 	_dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
 	/*
 	 * This is used by gdb to locate the chain of shared libraries that are currently loaded.
 	 */
 	debug_addr = DL_MALLOC(sizeof(struct r_debug));
-	REALIGN();
 	_dl_memset(debug_addr, 0, sizeof(*debug_addr));
 
 	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
@@ -269,8 +248,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++)
 			if (ppnt->p_type == PT_DYNAMIC) {
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				while (dpnt->d_tag) {
@@ -280,7 +259,7 @@ void _dl_boot(unsigned long args)
 					}
 					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
 					if (dpnt->d_tag == DT_DEBUG)
-						dpnt->d_un.d_val = (unsigned long) debug_addr;
+						dpnt->d_un.d_val = (int) debug_addr;
 					if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
 						app_tpnt->dynamic_info[DT_TEXTREL] = 1;
 					dpnt++;
@@ -308,8 +287,8 @@ void _dl_boot(unsigned long args)
 
 		/* First cover the shared library/dynamic linker. */
 		if (tpnt->dynamic_info[DT_TEXTREL]) {
-			header = (elfhdr *) dl_data[AT_BASE];
-			ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+			header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+			ppnt = (elf_phdr *) (auxv_t[AT_BASE].a_un.a_ptr + header->e_phoff);
 			for (i = 0; i < header->e_phnum; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (load_addr + 
@@ -322,8 +301,8 @@ void _dl_boot(unsigned long args)
 
 		/* Now cover the application program. */
 		if (app_tpnt->dynamic_info[DT_TEXTREL]) {
-			ppnt = (elf_phdr *) dl_data[AT_PHDR];
-			for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+			ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+			for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					_dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
 						(ppnt->p_vaddr & 0xfff) + 
@@ -428,7 +407,7 @@ void _dl_boot(unsigned long args)
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+	lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
 	INIT_GOT(lpnt, tpnt);
 
 	/* OK, this was a big step, now we need to scan all of the user images
@@ -443,7 +422,7 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		epnt = (elfhdr *) dl_data[AT_BASE];
+		epnt = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
 		tpnt->n_phent = epnt->e_phnum;
 		tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
 		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
@@ -468,8 +447,8 @@ void _dl_boot(unsigned long args)
 		elf_phdr *ppnt;
 		int i;
 
-		ppnt = (elf_phdr *) dl_data[AT_PHDR];
-		for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+		ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxv_t[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 			if (ppnt->p_type == PT_LOAD) {
 				if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
 					brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
@@ -484,15 +463,15 @@ void _dl_boot(unsigned long args)
 				app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 				_dl_loaded_modules->libtype = elf_executable;
-				_dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
-				_dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+				_dl_loaded_modules->ppnt = (elf_phdr *) auxv_t[AT_PHDR].a_un.a_ptr;
+				_dl_loaded_modules->n_phent = auxv_t[AT_PHNUM].a_un.a_val;
 				_dl_symbol_tables = rpnt =
 					(struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 				_dl_memset(rpnt, 0, sizeof(*rpnt));
 				rpnt->dyn = _dl_loaded_modules;
 				app_tpnt->usage_count++;
 				app_tpnt->symbol_scope = _dl_symbol_tables;
-				lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+				lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
 				if (lpnt)
 #endif
@@ -501,7 +480,7 @@ void _dl_boot(unsigned long args)
 			if (ppnt->p_type == PT_INTERP) {	/* OK, fill this in - we did not 
 								   have this before */
 				tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
-							   (dl_data[AT_PHDR] & 0xfffff000));
+							   (auxv_t[AT_PHDR].a_un.a_val & 0xfffff000));
 			}
 		}
 	}
@@ -515,9 +494,10 @@ void _dl_boot(unsigned long args)
 	{
 		_dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
 
-		if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-			(dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
-			 && dl_data[AT_GID] == dl_data[AT_EGID])) {
+		if ((auxv_t[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
+			(auxv_t[AT_UID].a_un.a_val != -1 && 
+			 auxv_t[AT_UID].a_un.a_val == auxv_t[AT_EUID].a_un.a_val
+			 && auxv_t[AT_GID].a_un.a_val== auxv_t[AT_EGID].a_un.a_val)) {
 			_dl_secure = 0;
 			_dl_preload = _dl_getenv("LD_PRELOAD", envp);
 			_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
@@ -889,7 +869,7 @@ void _dl_boot(unsigned long args)
 	}
 
 	/* OK we are done here.  Turn out the lights, and lock up. */
-	_dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
+	_dl_elf_main = (int (*)(int, char **, char **)) auxv_t[AT_ENTRY].a_un.a_fcn;
 
 
 	/*
@@ -898,6 +878,16 @@ void _dl_boot(unsigned long args)
 	START();
 }
 
+/*
+ * This stub function is used by some debuggers.  The idea is that they
+ * can set an internal breakpoint on it, so that we are notified when the
+ * address mapping is changed in some way.
+ */
+void _dl_debug_state()
+{
+	return;
+}
+
 int _dl_fixup(struct elf_resolve *tpnt)
 {
 	int goof = 0;
@@ -952,14 +942,17 @@ void *_dl_malloc(int size)
 {
 	void *retval;
 
+	//SEND_STDERR("malloc: request for ");
+	//SEND_STDERR(_dl_simple_itol(size));
+	//SEND_STDERR(" bytes\n");
+
 	if (_dl_malloc_function)
 		return (*_dl_malloc_function) (size);
 
 	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
-		_dl_mmap_zero = _dl_malloc_addr =
-			(unsigned char *) _dl_mmap((void *) 0, size, 
-						   PROT_READ | PROT_WRITE, 
-						   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		//SEND_STDERR("malloc: mmapping more memory\n");
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 		if (_dl_mmap_check_error(_dl_mmap_zero)) {
 			_dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
 			_dl_exit(20);

+ 16 - 0
ldso/ldso/string.h

@@ -109,4 +109,20 @@ extern inline void * _dl_memset(void * str,int c,size_t len)
 	return str;
 }
 
+/* Early on, we can't call printf, so use this to print out
+ * numbers using the SEND_STDERR() macro */
+static inline char *_dl_simple_itol(unsigned long i)
+{
+	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
+	static char local[22];
+	char *p = &local[21];
+	*p-- = '\0';
+	do {
+		*p-- = '0' + i % 10;
+		i /= 10;
+	} while (i > 0);
+	return p + 1;
+}
+
+
 #endif