summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-01-10 21:02:48 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-01-10 21:02:48 +0000
commit27d501fdbf0c6932e6170e8dece4d178d912bf94 (patch)
tree054224e4ebe3ee638fb5b8d28e9873fbcd13c537
parent1c778b7cfac9228aa6dbd3c7d3b1417887fc3031 (diff)
simple optimizations and style fixes in dynamic loading
text data bss dec hex filename - 16709 240 92 17041 4291 lib/ld-uClibc.so + 16634 236 92 16962 4242 lib/ld-uClibc.so - 4602 344 4 4950 1356 lib/libdl-0.9.30-svn.so + 4571 328 4 4903 1327 lib/libdl-0.9.30-svn.so - 4602 344 4 4950 1356 lib/libdl.so + 4571 328 4 4903 1327 lib/libdl.so
-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.c264
-rw-r--r--ldso/libdl/libdl.c61
-rw-r--r--utils/ldd.c20
-rw-r--r--utils/readelf.c33
10 files changed, 252 insertions, 252 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 ec0663cea..df4a1d479 100644
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -63,7 +63,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 ecaaa552c..5f59162a7 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 */
@@ -358,11 +355,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) {
@@ -384,11 +382,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;
@@ -688,14 +682,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
}
@@ -713,7 +710,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;
@@ -724,7 +721,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 a251aaff3..4809c4348 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 efd02da46..6b69c7498 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 f631fd983..4dcd99bfe 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -42,24 +42,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
@@ -69,8 +70,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
@@ -88,8 +87,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 */
@@ -110,6 +109,118 @@ 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 + ADDR_ALIGN) & _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;
+}
+
+void _dl_free (void *p)
+{
+ if (_dl_free_function)
+ (*_dl_free_function) (p);
+}
+
static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
{
unsigned int i;
@@ -158,7 +269,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;
@@ -219,7 +330,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;
@@ -269,8 +380,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++) {
@@ -324,7 +434,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;
@@ -389,14 +499,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);
@@ -711,13 +821,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 */
@@ -840,109 +948,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 + ADDR_ALIGN) & _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;
-}
-
-void _dl_free (void *p)
-{
- if (_dl_free_function)
- (*_dl_free_function) (p);
-}
-
#include "dl-hash.c"
#include "dl-elf.c"
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index f914cf3be..8646a74d8 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -67,8 +67,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
@@ -77,20 +76,20 @@ extern char *_dl_debug;
* the symbols that otherwise would have been loaded in from ldso... */
#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;
-int _dl_debug_file = 2;
+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 = NULL;
#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. */
@@ -117,7 +116,7 @@ struct r_debug *_dl_debug_addr = NULL;
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",
@@ -222,7 +221,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;
@@ -265,18 +265,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;
@@ -397,7 +396,6 @@ void *dlopen(const char *libname, int flag)
}
/* TODO: Should we set the protections of all pages back to R/O now ? */
-
/* Notify the debugger we have added some objects. */
if (_dl_debug_addr) {
dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
@@ -453,10 +451,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);
@@ -500,7 +498,7 @@ 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, tpnt, ELF_RTYPE_CLASS_DLSYM);
/*
@@ -566,8 +564,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);
@@ -600,8 +599,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;
@@ -609,6 +608,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) {
@@ -616,7 +617,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);
@@ -628,6 +629,7 @@ static int do_dlclose(void *vhandle, int need_fini)
break;
}
}
+ }
}
free(tpnt->libname);
free(tpnt);
@@ -636,7 +638,6 @@ static int do_dlclose(void *vhandle, int need_fini)
free(handle->init_fini.init_fini);
free(handle);
-
if (_dl_debug_addr) {
dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
if (dl_brk != NULL) {
@@ -671,7 +672,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;
}