summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/boot1.c203
-rw-r--r--ldso/ldso/ld-uClibc.c203
-rw-r--r--ldso/ldso/ld_string.h16
-rw-r--r--ldso/ldso/ldso.c203
-rw-r--r--ldso/ldso/string.h16
5 files changed, 326 insertions, 315 deletions
diff --git a/ldso/ldso/boot1.c b/ldso/ldso/boot1.c
index ca8bdbab4..729c72e53 100644
--- a/ldso/ldso/boot1.c
+++ b/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);
diff --git a/ldso/ldso/ld-uClibc.c b/ldso/ldso/ld-uClibc.c
index ca8bdbab4..729c72e53 100644
--- a/ldso/ldso/ld-uClibc.c
+++ b/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);
diff --git a/ldso/ldso/ld_string.h b/ldso/ldso/ld_string.h
index be0de45b1..98f2dab81 100644
--- a/ldso/ldso/ld_string.h
+++ b/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
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index ca8bdbab4..729c72e53 100644
--- a/ldso/ldso/ldso.c
+++ b/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);
diff --git a/ldso/ldso/string.h b/ldso/ldso/string.h
index be0de45b1..98f2dab81 100644
--- a/ldso/ldso/string.h
+++ b/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