summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/elf.h7
-rw-r--r--ldso/include/dl-string.h40
-rw-r--r--ldso/include/ldso.h2
-rw-r--r--ldso/ldso/dl-elf.c47
-rw-r--r--ldso/ldso/dl-hash.c23
-rw-r--r--ldso/ldso/dl-startup.c7
-rw-r--r--ldso/ldso/ldso.c304
-rw-r--r--ldso/libdl/libdl.c58
-rw-r--r--utils/ldd.c20
-rw-r--r--utils/readelf.c33
10 files changed, 271 insertions, 270 deletions
diff --git a/include/elf.h b/include/elf.h
index 4ebe15c23..3e174bccf 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -120,6 +120,13 @@ typedef struct
/* Conglomeration of the identification bytes, for easy testing as a word. */
#define ELFMAG "\177ELF"
#define SELFMAG 4
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define ELFMAG_U32 ((uint32_t)(ELFMAG0 + 0x100 * (ELFMAG1 + (0x100 * (ELFMAG2 + 0x100 * ELFMAG3)))))
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define ELFMAG_U32 ((uint32_t)((((ELFMAG0 * 0x100) + ELFMAG1) * 0x100 + ELFMAG2) * 0x100 + ELFMAG3))
+#else
+# error Unknown host byte order!
+#endif
#define EI_CLASS 4 /* File class byte index */
#define ELFCLASSNONE 0 /* Invalid class */
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index 746bd91c6..1a47e31ed 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -19,26 +19,26 @@
# define do_div_10(result, remain) ((result) /= 10)
#endif
-static size_t _dl_strlen(const char * str);
+static size_t _dl_strlen(const char *str);
static char *_dl_strcat(char *dst, const char *src);
-static char * _dl_strcpy(char * dst,const char *src);
-static int _dl_strcmp(const char * s1,const char * s2);
-static int _dl_strncmp(const char * s1,const char * s2,size_t len);
-static char * _dl_strchr(const char * str,int c);
+static char *_dl_strcpy(char *dst, const char *src);
+static int _dl_strcmp(const char *s1, const char *s2);
+static int _dl_strncmp(const char *s1, const char *s2, size_t len);
+static char *_dl_strchr(const char *str, int c);
static char *_dl_strrchr(const char *str, int c);
static char *_dl_strstr(const char *s1, const char *s2);
-static void * _dl_memcpy(void * dst, const void * src, size_t len);
-static int _dl_memcmp(const void * s1,const void * s2,size_t len);
-static void *_dl_memset(void * str,int c,size_t len);
+static void *_dl_memcpy(void *dst, const void *src, size_t len);
+static int _dl_memcmp(const void *s1, const void *s2, size_t len);
+static void *_dl_memset(void *str, int c, size_t len);
static char *_dl_get_last_path_component(char *path);
-static char *_dl_simple_ltoa(char * local, unsigned long i);
-static char *_dl_simple_ltoahex(char * local, unsigned long i);
+static char *_dl_simple_ltoa(char *local, unsigned long i);
+static char *_dl_simple_ltoahex(char *local, unsigned long i);
#ifndef NULL
#define NULL ((void *) 0)
#endif
-static __always_inline size_t _dl_strlen(const char * str)
+static __always_inline size_t _dl_strlen(const char *str)
{
register const char *ptr = (char *) str-1;
while (*++ptr)
@@ -59,7 +59,7 @@ static __always_inline char * _dl_strcat(char *dst, const char *src)
return dst;
}
-static __always_inline char * _dl_strcpy(char * dst,const char *src)
+static __always_inline char * _dl_strcpy(char *dst, const char *src)
{
register char *ptr = dst;
@@ -70,7 +70,7 @@ static __always_inline char * _dl_strcpy(char * dst,const char *src)
return ptr;
}
-static __always_inline int _dl_strcmp(const char * s1,const char * s2)
+static __always_inline int _dl_strcmp(const char *s1, const char *s2)
{
register unsigned char c1, c2;
s1--;s2--;
@@ -84,7 +84,7 @@ static __always_inline int _dl_strcmp(const char * s1,const char * s2)
return c1 - c2;
}
-static __always_inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
+static __always_inline int _dl_strncmp(const char *s1, const char *s2, size_t len)
{
register unsigned char c1 = '\0';
register unsigned char c2 = '\0';
@@ -100,7 +100,7 @@ static __always_inline int _dl_strncmp(const char * s1,const char * s2,size_t le
return c1 - c2;
}
-static __always_inline char * _dl_strchr(const char * str,int c)
+static __always_inline char * _dl_strchr(const char *str, int c)
{
register char ch;
str--;
@@ -147,7 +147,7 @@ static __always_inline char * _dl_strstr(const char *s1, const char *s2)
} while (1);
}
-static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+static __always_inline void * _dl_memcpy(void *dst, const void *src, size_t len)
{
register char *a = dst-1;
register const char *b = src-1;
@@ -159,7 +159,7 @@ static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t le
return dst;
}
-static __always_inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
+static __always_inline int _dl_memcmp(const void *s1, const void *s2, size_t len)
{
unsigned char *c1 = (unsigned char *)s1-1;
unsigned char *c2 = (unsigned char *)s2-1;
@@ -200,7 +200,7 @@ lessthan4:
return to;
}
#else
-static __always_inline void * _dl_memset(void * str,int c,size_t len)
+static __always_inline void * _dl_memset(void *str, int c, size_t len)
{
register char *a = str;
@@ -232,7 +232,7 @@ static __always_inline char * _dl_get_last_path_component(char *path)
/* Early on, we can't call printf, so use this to print out
* numbers using the SEND_STDERR() macro. Avoid using mod
* or using long division */
-static __always_inline char * _dl_simple_ltoa(char * local, unsigned long i)
+static __always_inline char * _dl_simple_ltoa(char *local, unsigned long i)
{
/* 20 digits plus a null terminator should be good for
* 64-bit or smaller ints (2^64 - 1)*/
@@ -247,7 +247,7 @@ static __always_inline char * _dl_simple_ltoa(char * local, unsigned long i)
return p;
}
-static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
+static __always_inline char * _dl_simple_ltoahex(char *local, unsigned long i)
{
/* 16 digits plus a leading "0x" plus a null terminator,
* should be good for 64-bit or smaller ints */
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h
index 4fa68522b..36bbd9e73 100644
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -67,7 +67,7 @@ extern char *_dl_library_path; /* Where we look for libraries */
extern char *_dl_preload; /* Things to be loaded before the libs */
extern char *_dl_ldsopath; /* Where the shared lib loader was found */
extern const char *_dl_progname; /* The name of the executable being run */
-extern int _dl_secure; /* Are we dealing with setuid stuff? */
+//now static: 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__
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index b27da3af2..7be47e184 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -272,13 +272,14 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
_dl_if_debug_dprint("\tsearching cache='%s'\n", LDSO_CACHE);
for (i = 0; i < header->nlibs; i++) {
- if ((libent[i].flags == LIB_ELF ||
- libent[i].flags == LIB_ELF_LIBC0 ||
- libent[i].flags == LIB_ELF_LIBC5) &&
- _dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
- (tpnt1 = _dl_load_elf_shared_library(secure,
- rpnt, strs + libent[i].liboffset)))
+ if ((libent[i].flags == LIB_ELF
+ || libent[i].flags == LIB_ELF_LIBC0
+ || libent[i].flags == LIB_ELF_LIBC5)
+ && _dl_strcmp(libname, strs + libent[i].sooffset) == 0
+ && (tpnt1 = _dl_load_elf_shared_library(secure, rpnt, strs + libent[i].liboffset))
+ ) {
return tpnt1;
+ }
}
}
#endif
@@ -286,26 +287,22 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
/* Look for libraries wherever the shared library loader
* was installed */
_dl_if_debug_dprint("\tsearching ldso dir='%s'\n", _dl_ldsopath);
- if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL)
- {
+ tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt);
+ if (tpnt1 != NULL)
return tpnt1;
- }
-
/* Lastly, search the standard list of paths for the library.
This list must exactly match the list in uClibc/ldso/util/ldd.c */
_dl_if_debug_dprint("\tsearching full lib path list\n");
- if ((tpnt1 = search_for_named_library(libname, secure,
+ tpnt1 = search_for_named_library(libname, secure,
UCLIBC_RUNTIME_PREFIX "lib:"
UCLIBC_RUNTIME_PREFIX "usr/lib"
#ifndef __LDSO_CACHE_SUPPORT__
":" UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib"
#endif
- , rpnt)
- ) != NULL)
- {
+ , rpnt);
+ if (tpnt1 != NULL)
return tpnt1;
- }
goof:
/* Well, we shot our wad on that one. All we can do now is punt */
@@ -361,11 +358,12 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
}
/* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
we don't load the library if it isn't setuid. */
- if (secure)
+ if (secure) {
if (!(st.st_mode & S_ISUID)) {
_dl_close(infile);
return NULL;
}
+ }
/* Check if file is already loaded */
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
@@ -387,11 +385,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
_dl_read(infile, header, _dl_pagesize);
epnt = (ElfW(Ehdr) *) (intptr_t) header;
- if (epnt->e_ident[0] != 0x7f ||
- epnt->e_ident[1] != 'E' ||
- epnt->e_ident[2] != 'L' ||
- epnt->e_ident[3] != 'F')
- {
+ if (*((uint32_t*) &epnt->e_ident) != ELFMAG_U32) {
_dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
libname);
_dl_internal_error_number = LD_ERROR_NOTELF;
@@ -714,14 +708,17 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
- if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+ if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
_dl_mprotect((void *) ((piclib ? libaddr : 0) +
(ppnt->p_vaddr & PAGE_ALIGN)),
(ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
PROT_READ | PROT_WRITE | PROT_EXEC);
+ }
}
#else
- _dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname);
+ _dl_dprintf(_dl_debug_file, "Can't modify %s's text section."
+ " Use GCC option -fPIC for shared objects, please.\n",
+ libname);
_dl_exit(1);
#endif
}
@@ -770,7 +767,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
* Add this object into the symbol chain
*/
if (*rpnt) {
- (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+ (*rpnt)->next = _dl_malloc(sizeof(struct dyn_elf));
_dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
(*rpnt)->next->prev = (*rpnt);
*rpnt = (*rpnt)->next;
@@ -781,7 +778,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
* and initialize the _dl_symbol_table.
*/
else {
- *rpnt = _dl_symbol_tables = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+ *rpnt = _dl_symbol_tables = _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(*rpnt, 0, sizeof(struct dyn_elf));
}
#endif
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index 531fbb9b5..3103d9f0b 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -95,17 +95,18 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
struct elf_resolve *tpnt;
int i;
- if (!_dl_loaded_modules) {
- tpnt = _dl_loaded_modules = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
- _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
- } else {
- tpnt = _dl_loaded_modules;
- while (tpnt->next)
- tpnt = tpnt->next;
- tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
- _dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));
- tpnt->next->prev = tpnt;
- tpnt = tpnt->next;
+ tpnt = _dl_malloc(sizeof(struct elf_resolve));
+ _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
+
+ if (!_dl_loaded_modules)
+ _dl_loaded_modules = tpnt;
+ else {
+ struct elf_resolve *t = _dl_loaded_modules;
+ while (t->next)
+ t = t->next;
+ t->next = tpnt;
+ t->next->prev = t;
+ tpnt = t->next;
}
tpnt->next = NULL;
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
index 640056587..0617cbd81 100644
--- a/ldso/ldso/dl-startup.c
+++ b/ldso/ldso/dl-startup.c
@@ -176,11 +176,8 @@ DL_START(unsigned long args)
/* Do not use an inline _dl_strncmp here or some arches
* will blow chunks, i.e. those that need to relocate all
* string constants... */
- || header->e_ident[EI_MAG0] != ELFMAG0
- || header->e_ident[EI_MAG1] != ELFMAG1
- || header->e_ident[EI_MAG2] != ELFMAG2
- || header->e_ident[EI_MAG3] != ELFMAG3)
- {
+ || *((uint32_t*) &header->e_ident) != ELFMAG_U32
+ ) {
SEND_EARLY_STDERR("Invalid ELF header\n");
_dl_exit(0);
}
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index f74fb4aab..bec79bb84 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -46,24 +46,25 @@
#include LDSO_ELFINTERP
/* Global variables used within the shared library loader */
-char *_dl_library_path = 0; /* Where we look for libraries */
-char *_dl_preload = 0; /* Things to be loaded before the libs */
-char *_dl_ldsopath = 0; /* Location of the shared lib loader */
-int _dl_secure = 1; /* Are we dealing with setuid stuff? */
+char *_dl_library_path = NULL; /* Where we look for libraries */
+char *_dl_preload = NULL; /* Things to be loaded before the libs */
+char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
int _dl_errno = 0; /* We can't use the real errno in ldso */
size_t _dl_pagesize = 0; /* Store the page size for use later */
struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
void *(*_dl_malloc_function) (size_t size) = NULL;
void (*_dl_free_function) (void *p) = NULL;
+static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
+
#ifdef __SUPPORT_LD_DEBUG__
-char *_dl_debug = 0;
-char *_dl_debug_symbols = 0;
-char *_dl_debug_move = 0;
-char *_dl_debug_reloc = 0;
-char *_dl_debug_detail = 0;
-char *_dl_debug_nofixups = 0;
-char *_dl_debug_bindings = 0;
+char *_dl_debug = NULL;
+char *_dl_debug_symbols = NULL;
+char *_dl_debug_move = NULL;
+char *_dl_debug_reloc = NULL;
+char *_dl_debug_detail = NULL;
+char *_dl_debug_nofixups = NULL;
+char *_dl_debug_bindings = NULL;
int _dl_debug_file = 2;
#endif
@@ -73,8 +74,6 @@ const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being
#include "dl-startup.c"
#include "dl-symbols.c"
#include "dl-array.c"
-/* Forward function declarations */
-static int _dl_suid_ok(void);
/*
* This stub function is used by some debuggers. The idea is that they
@@ -92,8 +91,8 @@ void _dl_debug_state(void)
}
rtld_hidden_def(_dl_debug_state);
-static unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */
-static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
+static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
+static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
static struct elf_resolve **init_fini_list;
static unsigned int nlist; /* # items in init_fini_list */
@@ -114,6 +113,138 @@ uintptr_t __guard attribute_relro;
# endif
#endif
+char *_dl_getenv(const char *symbol, char **envp)
+{
+ char *pnt;
+ const char *pnt1;
+
+ while ((pnt = *envp++)) {
+ pnt1 = symbol;
+ while (*pnt && *pnt == *pnt1)
+ pnt1++, pnt++;
+ if (!*pnt || *pnt != '=' || *pnt1)
+ continue;
+ return pnt + 1;
+ }
+ return 0;
+}
+
+void _dl_unsetenv(const char *symbol, char **envp)
+{
+ char *pnt;
+ const char *pnt1;
+ char **newenvp = envp;
+
+ for (pnt = *envp; pnt; pnt = *++envp) {
+ pnt1 = symbol;
+ while (*pnt && *pnt == *pnt1)
+ pnt1++, pnt++;
+ if (!*pnt || *pnt != '=' || *pnt1)
+ *newenvp++ = *envp;
+ }
+ *newenvp++ = *envp;
+ return;
+}
+
+static int _dl_suid_ok(void)
+{
+ __kernel_uid_t uid, euid;
+ __kernel_gid_t gid, egid;
+
+ uid = _dl_getuid();
+ euid = _dl_geteuid();
+ gid = _dl_getgid();
+ egid = _dl_getegid();
+
+ if (uid == euid && gid == egid) {
+ return 1;
+ }
+ return 0;
+}
+
+void *_dl_malloc(size_t size)
+{
+ void *retval;
+
+#if 0
+ _dl_debug_early("request for %d bytes\n", size);
+#endif
+
+ if (_dl_malloc_function)
+ return (*_dl_malloc_function) (size);
+
+ if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
+ size_t rounded_size;
+
+ /* Since the above assumes we get a full page even if
+ we request less than that, make sure we request a
+ full page, since uClinux may give us less than than
+ a full page. We might round even
+ larger-than-a-page sizes, but we end up never
+ reusing _dl_mmap_zero/_dl_malloc_addr in that case,
+ so we don't do it.
+
+ The actual page size doesn't really matter; as long
+ as we're self-consistent here, we're safe. */
+ if (size < _dl_pagesize)
+ rounded_size = (size + _dl_pagesize - 1) & _dl_pagesize;
+ else
+ rounded_size = size;
+
+ _dl_debug_early("mmapping more memory\n");
+ _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (_dl_mmap_check_error(_dl_mmap_zero)) {
+ _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
+ _dl_exit(20);
+ }
+ }
+ retval = _dl_malloc_addr;
+ _dl_malloc_addr += size;
+
+ /*
+ * Align memory to DL_MALLOC_ALIGN byte boundary. Some
+ * platforms require this, others simply get better
+ * performance.
+ */
+ _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
+ return retval;
+}
+
+static void *_dl_zalloc(size_t size)
+{
+ void *p = _dl_malloc(size);
+ if (p)
+ _dl_memset(p, 0, size);
+ return p;
+}
+
+#if USE_TLS
+void * _dl_memalign (size_t __boundary, size_t __size)
+{
+ void *result;
+ int i = 0;
+ size_t delta;
+ size_t rounded = 0;
+
+ if (_dl_memalign_function)
+ return (*_dl_memalign_function) (__boundary, __size);
+
+ while (rounded < __boundary) {
+ rounded = (1 << i++);
+ }
+
+ delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
+
+ if ((result = _dl_malloc(rounded - delta)) == NULL)
+ return result;
+
+ result = _dl_malloc(__size);
+
+ return result;
+}
+#endif
+
static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
{
unsigned int i;
@@ -166,7 +297,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
* setup so we can use _dl_dprintf() to print debug noise
* instead of the SEND_STDERR macros used in dl-startup.c */
- _dl_memset(app_tpnt, 0x00, sizeof(*app_tpnt));
+ _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
/* Store the page size for later use */
_dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
@@ -227,7 +358,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
do {
_dl_unsetenv (nextp, envp);
/* We could use rawmemchr but this need not be fast. */
- nextp = (char *) _dl_strchr(nextp, '\0') + 1;
+ nextp = _dl_strchr(nextp, '\0') + 1;
} while (*nextp != '\0');
_dl_preload = NULL;
_dl_library_path = NULL;
@@ -281,8 +412,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
* This is used by gdb to locate the chain of shared libraries that are
* currently loaded.
*/
- debug_addr = _dl_malloc(sizeof(struct r_debug));
- _dl_memset(debug_addr, 0, sizeof(struct r_debug));
+ debug_addr = _dl_zalloc(sizeof(struct r_debug));
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
@@ -336,7 +466,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_loaded_modules->libtype = elf_executable;
_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
- _dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+ _dl_symbol_tables = rpnt = _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
rpnt->dyn = _dl_loaded_modules;
app_tpnt->mapaddr = app_mapaddr;
@@ -444,14 +574,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
len1 = _dl_strlen(dl_debug_output);
len2 = _dl_strlen(tmp1);
- filename = _dl_malloc(len1+len2+2);
+ filename = _dl_malloc(len1 + len2 + 2);
if (filename) {
_dl_strcpy (filename, dl_debug_output);
filename[len1] = '.';
_dl_strcpy (&filename[len1+1], tmp1);
- _dl_debug_file= _dl_open(filename, O_WRONLY|O_CREAT, 0644);
+ _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
if (_dl_debug_file < 0) {
_dl_debug_file = 2;
_dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
@@ -767,13 +897,11 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
tpnt->usage_count++;
tpnt->symbol_scope = _dl_symbol_tables;
if (rpnt) {
- rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
- _dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
+ rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
rpnt->next->prev = rpnt;
rpnt = rpnt->next;
} else {
- rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
- _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
+ rpnt = _dl_zalloc(sizeof(struct dyn_elf));
}
rpnt->dyn = tpnt;
tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
@@ -952,129 +1080,5 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_debug_state();
}
-char *_dl_getenv(const char *symbol, char **envp)
-{
- char *pnt;
- const char *pnt1;
-
- while ((pnt = *envp++)) {
- pnt1 = symbol;
- while (*pnt && *pnt == *pnt1)
- pnt1++, pnt++;
- if (!*pnt || *pnt != '=' || *pnt1)
- continue;
- return pnt + 1;
- }
- return 0;
-}
-
-void _dl_unsetenv(const char *symbol, char **envp)
-{
- char *pnt;
- const char *pnt1;
- char **newenvp = envp;
-
- for (pnt = *envp; pnt; pnt = *++envp) {
- pnt1 = symbol;
- while (*pnt && *pnt == *pnt1)
- pnt1++, pnt++;
- if (!*pnt || *pnt != '=' || *pnt1)
- *newenvp++ = *envp;
- }
- *newenvp++ = *envp;
- return;
-}
-
-static int _dl_suid_ok(void)
-{
- __kernel_uid_t uid, euid;
- __kernel_gid_t gid, egid;
-
- uid = _dl_getuid();
- euid = _dl_geteuid();
- gid = _dl_getgid();
- egid = _dl_getegid();
-
- if (uid == euid && gid == egid) {
- return 1;
- }
- return 0;
-}
-
-void *_dl_malloc(size_t size)
-{
- void *retval;
-
-#if 0
- _dl_debug_early("request for %d bytes\n", size);
-#endif
-
- if (_dl_malloc_function)
- return (*_dl_malloc_function) (size);
-
- if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
- size_t rounded_size;
-
- /* Since the above assumes we get a full page even if
- we request less than that, make sure we request a
- full page, since uClinux may give us less than than
- a full page. We might round even
- larger-than-a-page sizes, but we end up never
- reusing _dl_mmap_zero/_dl_malloc_addr in that case,
- so we don't do it.
-
- The actual page size doesn't really matter; as long
- as we're self-consistent here, we're safe. */
- if (size < _dl_pagesize)
- rounded_size = (size + _dl_pagesize - 1) & _dl_pagesize;
- else
- rounded_size = size;
-
- _dl_debug_early("mmapping more memory\n");
- _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (_dl_mmap_check_error(_dl_mmap_zero)) {
- _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
- _dl_exit(20);
- }
- }
- retval = _dl_malloc_addr;
- _dl_malloc_addr += size;
-
- /*
- * Align memory to DL_MALLOC_ALIGN byte boundary. Some
- * platforms require this, others simply get better
- * performance.
- */
- _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
- return retval;
-}
-
-#if USE_TLS
-void * _dl_memalign (size_t __boundary, size_t __size)
-{
- void *result;
- int i = 0;
- size_t delta;
- size_t rounded = 0;
-
- if (_dl_memalign_function)
- return (*_dl_memalign_function) (__boundary, __size);
-
- while (rounded < __boundary) {
- rounded = (1 << i++);
- }
-
- delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
-
- if ((result = _dl_malloc(rounded - delta)) == NULL)
- return result;
-
- result = _dl_malloc(__size);
-
- return result;
-}
-#endif
-
#include "dl-hash.c"
#include "dl-elf.c"
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 6f4d626f7..0e683e3ea 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -77,8 +77,7 @@ extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, in
extern char *_dl_debug;
#endif
-
-#else /* SHARED */
+#else /* !SHARED */
#define _dl_malloc malloc
#define _dl_free free
@@ -89,20 +88,20 @@ extern char *_dl_debug;
#ifdef __SUPPORT_LD_DEBUG__
/* Needed for 'strstr' prototype' */
#include <string.h>
-char *_dl_debug = 0;
-char *_dl_debug_symbols = 0;
-char *_dl_debug_move = 0;
-char *_dl_debug_reloc = 0;
-char *_dl_debug_detail = 0;
-char *_dl_debug_nofixups = 0;
-char *_dl_debug_bindings = 0;
+char *_dl_debug = NULL;
+char *_dl_debug_symbols = NULL;
+char *_dl_debug_move = NULL;
+char *_dl_debug_reloc = NULL;
+char *_dl_debug_detail = NULL;
+char *_dl_debug_nofixups = NULL;
+char *_dl_debug_bindings = NULL;
int _dl_debug_file = 2;
#endif
const char *_dl_progname = ""; /* Program name */
void *(*_dl_malloc_function)(size_t);
void (*_dl_free_function) (void *p);
-char *_dl_library_path = 0; /* Where we look for libraries */
-char *_dl_ldsopath = 0; /* Location of the shared lib loader */
+char *_dl_library_path = NULL; /* Where we look for libraries */
+char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
int _dl_errno = 0; /* We can't use the real errno in ldso */
size_t _dl_pagesize = PAGE_SIZE; /* Store the page size for use later */
/* This global variable is also to communicate with debuggers such as gdb. */
@@ -138,7 +137,7 @@ size_t _dl_tls_static_size = 2048;
static int do_dlclose(void *, int need_fini);
-static const char *dl_error_names[] = {
+static const char *const dl_error_names[] = {
"",
"File not found",
"Unable to open /dev/zero",
@@ -350,7 +349,8 @@ void *dlopen(const char *libname, int flag)
tfrom = tpnt;
}
}
- for (rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
+ for (rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt = rpnt->next)
+ continue;
relro_ptr = rpnt;
now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
@@ -393,18 +393,17 @@ void *dlopen(const char *libname, int flag)
}
}
return dyn_chain;
- } else {
- tpnt->init_flag |= DL_OPENED;
}
+ tpnt->init_flag |= DL_OPENED;
+
_dl_if_debug_print("Looking for needed libraries\n");
nlist = 0;
runp = alloca(sizeof(*runp));
runp->tpnt = tpnt;
runp->next = NULL;
dep_list = runp2 = runp;
- for (; runp; runp = runp->next)
- {
+ for (; runp; runp = runp->next) {
ElfW(Dyn) *dpnt;
char *lpntstr;
@@ -627,10 +626,10 @@ void *dlsym(void *vhandle, const char *name)
char *name2 = tmp_buf;
size_t nlen = strlen (name) + 1;
if (nlen + 1 > sizeof (tmp_buf))
- name2 = malloc (nlen + 1);
+ name2 = malloc (nlen + 1);
if (name2 == 0) {
- _dl_error_number = LD_ERROR_MMAP_FAILED;
- return 0;
+ _dl_error_number = LD_ERROR_MMAP_FAILED;
+ return 0;
}
name2[0] = '_';
memcpy (name2 + 1, name, nlen);
@@ -674,12 +673,11 @@ void *dlsym(void *vhandle, const char *name)
}
tpnt = NULL;
if (handle == _dl_symbol_tables)
- tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
+ tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
ret = _dl_find_hash(name2, handle, NULL, 0, &tls_tpnt);
#if defined USE_TLS && defined SHARED
if(tls_tpnt) {
-
/* The found symbol is a thread-local storage variable.
Return the address for to the current thread. */
ret = _dl_tls_symaddr ((struct link_map *)tls_tpnt, (Elf32_Addr)ret);
@@ -755,8 +753,9 @@ static int do_dlclose(void *vhandle, int need_fini)
if (--tpnt->usage_count == 0) {
if ((tpnt->dynamic_info[DT_FINI]
|| tpnt->dynamic_info[DT_FINI_ARRAY])
- && need_fini &&
- !(tpnt->init_flag & FINI_FUNCS_CALLED)) {
+ && need_fini
+ && !(tpnt->init_flag & FINI_FUNCS_CALLED)
+ ) {
tpnt->init_flag |= FINI_FUNCS_CALLED;
_dl_run_fini_array(tpnt);
@@ -901,8 +900,8 @@ static int do_dlclose(void *vhandle, int need_fini)
_dl_loaded_modules = tpnt->next;
if (_dl_loaded_modules)
_dl_loaded_modules->prev = 0;
- } else
- for (run_tpnt = _dl_loaded_modules; run_tpnt; run_tpnt = run_tpnt->next)
+ } else {
+ for (run_tpnt = _dl_loaded_modules; run_tpnt; run_tpnt = run_tpnt->next) {
if (run_tpnt->next == tpnt) {
_dl_if_debug_print("removing loaded_modules: %s\n", tpnt->libname);
run_tpnt->next = run_tpnt->next->next;
@@ -910,6 +909,8 @@ static int do_dlclose(void *vhandle, int need_fini)
run_tpnt->next->prev = run_tpnt;
break;
}
+ }
+ }
/* Next, remove tpnt from the global symbol table list */
if (_dl_symbol_tables) {
@@ -917,7 +918,7 @@ static int do_dlclose(void *vhandle, int need_fini)
_dl_symbol_tables = _dl_symbol_tables->next;
if (_dl_symbol_tables)
_dl_symbol_tables->prev = 0;
- } else
+ } else {
for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
if (rpnt1->next->dyn == tpnt) {
_dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname);
@@ -929,6 +930,7 @@ static int do_dlclose(void *vhandle, int need_fini)
break;
}
}
+ }
}
free(tpnt->libname);
free(tpnt);
@@ -986,7 +988,7 @@ char *dlerror(void)
* Dump information to stderr about the current loaded modules
*/
#ifdef __USE_GNU
-static char *type[] = { "Lib", "Exe", "Int", "Mod" };
+static const char type[][4] = { "Lib", "Exe", "Int", "Mod" };
int dlinfo(void)
{
diff --git a/utils/ldd.c b/utils/ldd.c
index 17bab2079..289d163b2 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -238,31 +238,27 @@ static char *elf_find_rpath(ElfW(Ehdr) *ehdr, ElfW(Dyn) *dynamic)
int check_elf_header(ElfW(Ehdr) *const ehdr)
{
- if (!ehdr || strncmp((char *)ehdr, ELFMAG, SELFMAG) != 0 ||
- ehdr->e_ident[EI_CLASS] != ELFCLASSM ||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT)
- {
+ if (!ehdr || *(uint32_t*)ehdr != ELFMAG_U32
+ || ehdr->e_ident[EI_CLASS] != ELFCLASSM
+ || ehdr->e_ident[EI_VERSION] != EV_CURRENT
+ ) {
return 1;
}
/* Check if the target endianness matches the host's endianness */
byteswap = 0;
#if __BYTE_ORDER == __LITTLE_ENDIAN
- if (ehdr->e_ident[5] == ELFDATA2MSB) {
- /* Ick -- we will have to byte-swap everything */
+ if (ehdr->e_ident[5] == ELFDATA2MSB)
byteswap = 1;
- }
#elif __BYTE_ORDER == __BIG_ENDIAN
- if (ehdr->e_ident[5] == ELFDATA2LSB) {
- /* Ick -- we will have to byte-swap everything */
+ if (ehdr->e_ident[5] == ELFDATA2LSB)
byteswap = 1;
- }
#else
#error Unknown host byte order!
#endif
- /* Be vary lazy, and only byteswap the stuff we use */
- if (byteswap == 1) {
+ /* Be very lazy, and only byteswap the stuff we use */
+ if (byteswap) {
ehdr->e_type = bswap_16(ehdr->e_type);
ehdr->e_phoff = byteswap_to_host(ehdr->e_phoff);
ehdr->e_shoff = byteswap_to_host(ehdr->e_shoff);
diff --git a/utils/readelf.c b/utils/readelf.c
index 2af4b5ca9..60f14a6bf 100644
--- a/utils/readelf.c
+++ b/utils/readelf.c
@@ -93,36 +93,33 @@ static void * elf_find_dynamic( int64_t const key, ElfW(Dyn) *dynp,
static int check_elf_header(ElfW(Ehdr) *const ehdr)
{
- if (! ehdr || strncmp((void *)ehdr, ELFMAG, SELFMAG) != 0 ||
- (ehdr->e_ident[EI_CLASS] != ELFCLASS32 &&
- ehdr->e_ident[EI_CLASS] != ELFCLASS64) ||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT)
- {
+ if (!ehdr || *(uint32_t*)ehdr != ELFMAG_U32
+ || (ehdr->e_ident[EI_CLASS] != ELFCLASS32
+ && ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+ || ehdr->e_ident[EI_VERSION] != EV_CURRENT
+ ) {
return 1;
}
/* Check if the target endianness matches the host's endianness */
byteswap = 0;
#if __BYTE_ORDER == __LITTLE_ENDIAN
- if (ehdr->e_ident[5] == ELFDATA2MSB) {
- /* Ick -- we will have to byte-swap everything */
+ if (ehdr->e_ident[5] == ELFDATA2MSB)
byteswap = 1;
- }
#elif __BYTE_ORDER == __BIG_ENDIAN
- if (ehdr->e_ident[5] == ELFDATA2LSB) {
+ if (ehdr->e_ident[5] == ELFDATA2LSB)
byteswap = 1;
- }
#else
#error Unknown host byte order!
#endif
- /* Be vary lazy, and only byteswap the stuff we use */
- if (byteswap==1) {
- ehdr->e_type=bswap_16(ehdr->e_type);
- ehdr->e_machine=bswap_16(ehdr->e_machine);
- ehdr->e_phoff=byteswap_to_host(ehdr->e_phoff);
- ehdr->e_shoff=byteswap_to_host(ehdr->e_shoff);
- ehdr->e_phnum=bswap_16(ehdr->e_phnum);
- ehdr->e_shnum=bswap_16(ehdr->e_shnum);
+ /* Be very lazy, and only byteswap the stuff we use */
+ if (byteswap) {
+ ehdr->e_type = bswap_16(ehdr->e_type);
+ ehdr->e_machine = bswap_16(ehdr->e_machine);
+ ehdr->e_phoff = byteswap_to_host(ehdr->e_phoff);
+ ehdr->e_shoff = byteswap_to_host(ehdr->e_shoff);
+ ehdr->e_phnum = bswap_16(ehdr->e_phnum);
+ ehdr->e_shnum = bswap_16(ehdr->e_shnum);
}
return 0;
}