svn commit: branches/uClibc-nptl/ldso: include ldso ldso/sh libdl
carmelo at uclibc.org
carmelo at uclibc.org
Wed Mar 5 17:54:18 UTC 2008
Author: carmelo
Date: 2008-03-05 09:54:17 -0800 (Wed, 05 Mar 2008)
New Revision: 21172
Log:
Merge ldso tree with trunk.
Step 1: basically code formatting and minor changes
Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>
Modified:
branches/uClibc-nptl/ldso/include/dl-hash.h
branches/uClibc-nptl/ldso/include/dl-syscall.h
branches/uClibc-nptl/ldso/include/ldso.h
branches/uClibc-nptl/ldso/include/unsecvars.h
branches/uClibc-nptl/ldso/ldso/dl-hash.c
branches/uClibc-nptl/ldso/ldso/dl-startup.c
branches/uClibc-nptl/ldso/ldso/dl-tls.c
branches/uClibc-nptl/ldso/ldso/ldso.c
branches/uClibc-nptl/ldso/ldso/sh/dl-syscalls.h
branches/uClibc-nptl/ldso/ldso/sh/elfinterp.c
branches/uClibc-nptl/ldso/libdl/Makefile.in
branches/uClibc-nptl/ldso/libdl/libdl.c
Changeset:
Modified: branches/uClibc-nptl/ldso/include/dl-hash.h
===================================================================
--- branches/uClibc-nptl/ldso/include/dl-hash.h 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/include/dl-hash.h 2008-03-05 17:54:17 UTC (rev 21172)
@@ -66,7 +66,7 @@
unsigned short int init_flag;
unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
Elf_Symndx nbucket;
-
+
#ifdef __LDSO_GNU_HASH_SUPPORT__
/* Data needed to support GNU hash style */
Elf32_Word l_gnu_bitmask_idxbits;
@@ -81,7 +81,7 @@
#else
Elf_Symndx *elf_buckets;
#endif
-
+
struct init_fini_list *init_fini;
struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
/*
@@ -95,10 +95,9 @@
const Elf32_Word *l_gnu_buckets;
const Elf_Symndx *chains;
};
-#else
+#else
Elf_Symndx *chains;
-#endif
-
+#endif
unsigned long dynamic_info[DYNAMIC_SIZE];
unsigned long n_phent;
@@ -148,7 +147,6 @@
#endif
}
-
extern int _dl_linux_dynamic_link(void);
extern char * _dl_library_path;
@@ -156,12 +154,11 @@
static inline int _dl_symbol(char * name)
{
- if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
+ if (name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
return 0;
return 1;
}
-
#define LD_ERROR_NOFILE 1
#define LD_ERROR_NOZERO 2
#define LD_ERROR_NOTELF 3
@@ -177,5 +174,3 @@
#endif /* _LD_HASH_H_ */
-
-
Modified: branches/uClibc-nptl/ldso/include/dl-syscall.h
===================================================================
--- branches/uClibc-nptl/ldso/include/dl-syscall.h 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/include/dl-syscall.h 2008-03-05 17:54:17 UTC (rev 21172)
@@ -11,11 +11,16 @@
/* Pull in the arch specific syscall implementation */
#include <dl-syscalls.h>
/* For MAP_ANONYMOUS -- differs between platforms */
-#include <asm/mman.h>
+#define _SYS_MMAN_H 1
+#include <bits/mman.h>
/* Pull in whatever this particular arch's kernel thinks the kernel version of
* struct stat should look like. It turns out that each arch has a different
* opinion on the subject, and different kernel revs use different names... */
+#if defined(__sparc_v9__) && (__WORDSIZE == 64)
+#define kernel_stat64 stat
+#else
#define kernel_stat stat
+#endif
#include <bits/kernel_stat.h>
#include <bits/kernel_types.h>
@@ -54,69 +59,69 @@
dynamic linking at all, so we cannot return any error codes.
We just punt if there is an error. */
#define __NR__dl_exit __NR_exit
-static inline _syscall1(void, _dl_exit, int, status);
+static __always_inline _syscall1(void, _dl_exit, int, status);
#define __NR__dl_close __NR_close
-static inline _syscall1(int, _dl_close, int, fd);
+static __always_inline _syscall1(int, _dl_close, int, fd);
#define __NR__dl_open __NR_open
-static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
+static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags,
__kernel_mode_t, mode);
#define __NR__dl_write __NR_write
-static inline _syscall3(unsigned long, _dl_write, int, fd,
+static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
const void *, buf, unsigned long, count);
#define __NR__dl_read __NR_read
-static inline _syscall3(unsigned long, _dl_read, int, fd,
+static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
const void *, buf, unsigned long, count);
#define __NR__dl_mprotect __NR_mprotect
-static inline _syscall3(int, _dl_mprotect, const void *, addr,
+static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
unsigned long, len, int, prot);
#define __NR__dl_stat __NR_stat
-static inline _syscall2(int, _dl_stat, const char *, file_name,
+static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
struct stat *, buf);
#define __NR__dl_fstat __NR_fstat
-static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
+static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
#define __NR__dl_munmap __NR_munmap
-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
#ifdef __NR_getxuid
# define __NR_getuid __NR_getxuid
#endif
#define __NR__dl_getuid __NR_getuid
-static inline _syscall0(uid_t, _dl_getuid);
+static __always_inline _syscall0(uid_t, _dl_getuid);
#ifndef __NR_geteuid
# define __NR_geteuid __NR_getuid
#endif
#define __NR__dl_geteuid __NR_geteuid
-static inline _syscall0(uid_t, _dl_geteuid);
+static __always_inline _syscall0(uid_t, _dl_geteuid);
#ifdef __NR_getxgid
# define __NR_getgid __NR_getxgid
#endif
#define __NR__dl_getgid __NR_getgid
-static inline _syscall0(gid_t, _dl_getgid);
+static __always_inline _syscall0(gid_t, _dl_getgid);
#ifndef __NR_getegid
# define __NR_getegid __NR_getgid
#endif
#define __NR__dl_getegid __NR_getegid
-static inline _syscall0(gid_t, _dl_getegid);
+static __always_inline _syscall0(gid_t, _dl_getegid);
#ifdef __NR_getxpid
# define __NR_getpid __NR_getxpid
#endif
#define __NR__dl_getpid __NR_getpid
-static inline _syscall0(gid_t, _dl_getpid);
+static __always_inline _syscall0(gid_t, _dl_getpid);
#define __NR__dl_readlink __NR_readlink
-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
+static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
size_t, bufsiz);
#ifdef __UCLIBC_HAS_SSP__
@@ -145,14 +150,14 @@
#if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
# define __NR__dl_mmap __NR_mmap
-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
int, prot, int, flags, int, fd, off_t, offset);
/* then try mmap2() */
#elif defined(__NR_mmap2)
# define __NR___syscall_mmap2 __NR_mmap2
-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
+static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
int, prot, int, flags, int, fd, off_t, offset);
/* Some architectures always use 12 as page shift for mmap2() eventhough the
@@ -163,7 +168,7 @@
# define MMAP2_PAGE_SHIFT 12
#endif
-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
int flags, int fd, unsigned long offset)
{
if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
@@ -176,8 +181,8 @@
#elif defined(__NR_mmap)
# define __NR__dl_mmap_real __NR_mmap
-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
int flags, int fd, unsigned long offset)
{
unsigned long buffer[6];
Modified: branches/uClibc-nptl/ldso/include/ldso.h
===================================================================
--- branches/uClibc-nptl/ldso/include/ldso.h 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/include/ldso.h 2008-03-05 17:54:17 UTC (rev 21172)
@@ -11,7 +11,7 @@
#include <features.h>
/* Prepare for the case that `__builtin_expect' is not available. */
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
#endif
#ifndef likely
@@ -70,19 +70,28 @@
_dl_dprintf(_dl_debug_file, "%s:%i: " fmt, __FUNCTION__, __LINE__, ## args);
# define _dl_if_debug_dprint(fmt, args...) \
do { if (_dl_debug) __dl_debug_dprint(fmt, ## args); } while (0)
-# define _dl_assert(expr) \
+#else
+# define __dl_debug_dprint(fmt, args...)
+# define _dl_if_debug_dprint(fmt, args...)
+# define _dl_debug_file 2
+#endif /* __SUPPORT_LD_DEBUG__ */
+
+#ifdef IS_IN_rtld
+# ifdef __SUPPORT_LD_DEBUG__
+# define _dl_assert(expr) \
do { \
if (!(expr)) { \
__dl_debug_dprint("assert(%s)\n", #expr); \
_dl_exit(45); \
} \
} while (0)
+# else
+# define _dl_assert(expr) ((void)0)
+# endif
#else
-# define __dl_debug_dprint(fmt, args...)
-# define _dl_if_debug_dprint(fmt, args...)
-# define _dl_assert(expr)
-# define _dl_debug_file 2
-#endif /* __SUPPORT_LD_DEBUG__ */
+# include <assert.h>
+# define _dl_assert(expr) assert(expr)
+#endif
#ifdef __SUPPORT_LD_DEBUG_EARLY__
# define _dl_debug_early(fmt, args...) __dl_debug_dprint(fmt, ## args)
Modified: branches/uClibc-nptl/ldso/include/unsecvars.h
===================================================================
--- branches/uClibc-nptl/ldso/include/unsecvars.h 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/include/unsecvars.h 2008-03-05 17:54:17 UTC (rev 21172)
@@ -5,7 +5,7 @@
* GNU Lesser General Public License version 2.1 or later.
*/
-/*
+/*
* Environment variable to be removed for SUID programs. The names are all
* stuffed in a single string which means they have to be terminated with a
* '\0' explicitly.
@@ -19,7 +19,7 @@
"LD_TRACE_LOADED_OBJECTS\0" \
"TMPDIR\0"
-/*
+/*
* LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h
* though used by ldd
*
Modified: branches/uClibc-nptl/ldso/ldso/dl-hash.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/dl-hash.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/dl-hash.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -4,7 +4,7 @@
* after resolving ELF shared library symbols
*
* Copyright (C) 2004 by Joakim Tjernlund <joakim.tjernlund at lumentis.se>
- * Copyright (C) 2000-2004 by Erik Andersen <andersen at codepoet.org>
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen at codepoet.org>
* Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
* David Engel, Hongjiu Lu and Mitch D'Souza
*
@@ -114,33 +114,32 @@
_dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));
tpnt->next->prev = tpnt;
tpnt = tpnt->next;
- };
+ }
tpnt->next = NULL;
tpnt->init_flag = 0;
tpnt->libname = _dl_strdup(libname);
tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
tpnt->libtype = loaded_file;
-
+
#ifdef __LDSO_GNU_HASH_SUPPORT__
if (dynamic_info[DT_GNU_HASH_IDX] != 0) {
-
- Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX];
-
- tpnt->nbucket = *hash32++;
- Elf32_Word symbias = *hash32++;
- Elf32_Word bitmask_nwords = *hash32++;
- /* Must be a power of two. */
- _dl_assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
- tpnt->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
- tpnt->l_gnu_shift = *hash32++;
+ Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX];
- tpnt->l_gnu_bitmask = (ElfW(Addr) *) hash32;
- hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
+ tpnt->nbucket = *hash32++;
+ Elf32_Word symbias = *hash32++;
+ Elf32_Word bitmask_nwords = *hash32++;
+ /* Must be a power of two. */
+ _dl_assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
+ tpnt->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
+ tpnt->l_gnu_shift = *hash32++;
- tpnt->l_gnu_buckets = hash32;
- hash32 += tpnt->nbucket;
- tpnt->l_gnu_chain_zero = hash32 - symbias;
+ tpnt->l_gnu_bitmask = (ElfW(Addr) *) hash32;
+ hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
+
+ tpnt->l_gnu_buckets = hash32;
+ hash32 += tpnt->nbucket;
+ tpnt->l_gnu_chain_zero = hash32 - symbias;
} else
/* Fall using old SysV hash table if GNU hash is not present */
#endif
@@ -162,7 +161,8 @@
/* Routine to check whether the symbol matches. */
static __attribute_noinline__ const ElfW(Sym) *
-check_match (const ElfW(Sym) *sym, char *strtab, const char* undef_name, int type_class) {
+check_match (const ElfW(Sym) *sym, char *strtab, const char* undef_name, int type_class)
+{
#if USE_TLS
if((sym->st_value == 0 && (ELF_ST_TYPE(sym->st_info) != STT_TLS))
@@ -182,48 +182,49 @@
if (type_class & (sym->st_shndx == SHN_UNDEF))
/* undefined symbol itself */
return NULL;
-
+
if (sym->st_value == 0)
/* No value */
return NULL;
-
- if (ELF_ST_TYPE(sym->st_info) > STT_FUNC)
- /* Ignore all but STT_NOTYPE, STT_OBJECT and STT_FUNC
- * entries since these are no code/data definitions.
- */
- return NULL;
+
+ if (ELF_ST_TYPE(sym->st_info) > STT_FUNC
+ && ELF_ST_TYPE(sym->st_info) != STT_COMMON)
+ /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC
+ * and STT_COMMON entries since these are no
+ * code/data definitions
+ */
+ return NULL;
#endif
- if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0)
- return NULL;
+ if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0)
+ return NULL;
- /* This is the matching symbol */
- return sym;
+ /* This is the matching symbol */
+ return sym;
}
#ifdef __LDSO_GNU_HASH_SUPPORT__
-static __always_inline const ElfW(Sym) *
-_dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash,
- const char* undef_name, int type_class) {
-
+static __always_inline const ElfW(Sym) *
+_dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash,
+ const char* undef_name, int type_class)
+{
Elf_Symndx symidx;
const ElfW(Sym) *sym;
char *strtab;
-
+
const ElfW(Addr) *bitmask = tpnt->l_gnu_bitmask;
- ElfW(Addr) bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS) & tpnt->l_gnu_bitmask_idxbits];
+ ElfW(Addr) bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS) & tpnt->l_gnu_bitmask_idxbits];
unsigned int hashbit1 = hash & (__ELF_NATIVE_CLASS - 1);
unsigned int hashbit2 = ((hash >> tpnt->l_gnu_shift) & (__ELF_NATIVE_CLASS - 1));
_dl_assert (bitmask != NULL);
- if (__builtin_expect ((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1, 0)) {
-
+ if (unlikely((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1)) {
Elf32_Word bucket = tpnt->l_gnu_buckets[hash % tpnt->nbucket];
-
+
if (bucket != 0) {
const Elf32_Word *hasharr = &tpnt->l_gnu_chain_zero[bucket];
do {
@@ -242,20 +243,20 @@
}
#endif
-static __always_inline const ElfW(Sym) *
-_dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, const char* undef_name, int type_class) {
-
+static __always_inline const ElfW(Sym) *
+_dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, const char* undef_name, int type_class)
+{
unsigned long hn;
char *strtab;
const ElfW(Sym) *sym;
Elf_Symndx symidx;
-
+
/* Avoid calling .urem here. */
do_rem(hn, hash, tpnt->nbucket);
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
-
+
_dl_assert(tpnt->elf_buckets != NULL);
-
+
for (symidx = tpnt->elf_buckets[hn]; symidx != STN_UNDEF; symidx = tpnt->chains[symidx]) {
sym = check_match (&symtab[symidx], strtab, undef_name, type_class);
if (sym != NULL)
@@ -264,7 +265,7 @@
}
/* No symbol found into the current module*/
return NULL;
-}
+}
/*
* This function resolves externals, and this is either called when we process
@@ -287,7 +288,7 @@
#ifdef __LDSO_GNU_HASH_SUPPORT__
unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name);
#endif
-
+
for (; rpnt; rpnt = rpnt->next) {
tpnt = rpnt->dyn;
@@ -308,36 +309,37 @@
/* Don't search the executable when resolving a copy reloc. */
if ((type_class & ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)
continue;
-
+
/* If the hash table is empty there is nothing to do here. */
if (tpnt->nbucket == 0)
continue;
-
- symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
-
+
+ symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
+
#ifdef __LDSO_GNU_HASH_SUPPORT__
/* Prefer GNU hash style, if any */
- if(tpnt->l_gnu_bitmask) {
- if((sym = _dl_lookup_gnu_hash(tpnt, symtab, gnu_hash_number, name, type_class)) != NULL)
+ if (tpnt->l_gnu_bitmask) {
+ sym = _dl_lookup_gnu_hash(tpnt, symtab, gnu_hash_number, name, type_class);
+ if (sym != NULL)
/* If sym has been found, do not search further */
- break;
+ break;
} else {
-#endif
+#endif
/* Use the old SysV-style hash table */
-
+
/* Calculate the old sysv hash number only once */
- if(elf_hash_number == 0xffffffff)
+ if (elf_hash_number == 0xffffffff)
elf_hash_number = _dl_elf_hash((const unsigned char *)name);
-
- if((sym = _dl_lookup_sysv_hash(tpnt, symtab, elf_hash_number, name, type_class)) != NULL )
+
+ sym = _dl_lookup_sysv_hash(tpnt, symtab, elf_hash_number, name, type_class);
+ if (sym != NULL)
break;
-
-#ifdef __LDSO_GNU_HASH_SUPPORT__
+#ifdef __LDSO_GNU_HASH_SUPPORT__
}
-#endif
+#endif
} /* end of for (; rpnt; rpnt = rpnt->next) { */
-
- if(sym) {
+
+ if (sym) {
/* At this point we have found the requested symbol, do binding */
#if USE_TLS
if(ELF_ST_TYPE(sym->st_info) == STT_TLS) {
@@ -356,7 +358,6 @@
if (!weak_result)
weak_result = (char *)tpnt->loadaddr + sym->st_value;
break;
-
#endif
case STB_GLOBAL:
return (char*)tpnt->loadaddr + sym->st_value;
Modified: branches/uClibc-nptl/ldso/ldso/dl-startup.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/dl-startup.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/dl-startup.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -4,7 +4,7 @@
* after resolving ELF shared library symbols
*
* Copyright (C) 2005 by Joakim Tjernlund
- * Copyright (C) 2000-2004 by Erik Andersen <andersen at codepoet.org>
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen at codepoet.org>
* Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
* David Engel, Hongjiu Lu and Mitch D'Souza
*
@@ -270,7 +270,7 @@
if (!indx && relative_count) {
rel_size -= relative_count * sizeof(ELF_RELOC);
elf_machine_relative(load_addr, rel_addr, relative_count);
- rel_addr += relative_count * sizeof(ELF_RELOC);;
+ rel_addr += relative_count * sizeof(ELF_RELOC);
}
rpnt = (ELF_RELOC *) (rel_addr + load_addr);
Modified: branches/uClibc-nptl/ldso/ldso/dl-tls.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/dl-tls.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/dl-tls.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -33,7 +33,7 @@
void *(*_dl_calloc_function) (size_t __nmemb, size_t __size) = NULL;
void *(*_dl_realloc_function) (void *__ptr, size_t __size) = NULL;
void *(*_dl_memalign_function) (size_t __boundary, size_t __size) = NULL;
-void (*_dl_free_function) (void *__ptr) = NULL;
+extern void (*_dl_free_function) (void *__ptr);
void *_dl_memalign (size_t __boundary, size_t __size);
struct link_map *_dl_update_slotinfo (unsigned long int req_modid);
Modified: branches/uClibc-nptl/ldso/ldso/ldso.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/ldso.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/ldso.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -4,7 +4,7 @@
* after resolving ELF shared library symbols
*
* Copyright (C) 2005 by Joakim Tjernlund
- * Copyright (C) 2000-2004 by Erik Andersen <andersen at codepoet.org>
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen at codepoet.org>
* Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
* David Engel, Hongjiu Lu and Mitch D'Souza
*
@@ -54,6 +54,7 @@
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;
#ifdef __SUPPORT_LD_DEBUG__
char *_dl_debug = 0;
@@ -79,9 +80,15 @@
* address mapping is changed in some way.
*/
void _dl_debug_state(void);
-void _dl_debug_state()
+rtld_hidden_proto(_dl_debug_state, noinline);
+void _dl_debug_state(void)
{
+ /* Make sure GCC doesn't recognize this function as pure, to avoid
+ * having the calls optimized away.
+ */
+ __asm__("");
}
+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 */
@@ -181,7 +188,7 @@
ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
char **argv)
{
- ElfW(Addr) app_loadaddr = NULL;
+ ElfW(Addr) app_mapaddr = 0;
ElfW(Phdr) *ppnt;
ElfW(Dyn) *dpnt;
char *lpntstr;
@@ -197,6 +204,7 @@
unsigned long *_dl_envp; /* The environment address */
ElfW(Addr) relro_addr = 0;
size_t relro_size = 0;
+ struct stat st;
#if USE_TLS
void *tcbp = NULL;
#endif
@@ -330,8 +338,8 @@
relro_addr = ppnt->p_vaddr;
relro_size = ppnt->p_memsz;
}
- if (!app_loadaddr && (ppnt->p_type == PT_LOAD)) {
- app_loadaddr = ppnt->p_vaddr;
+ if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
+ app_mapaddr = ppnt->p_vaddr;
}
if (ppnt->p_type == PT_DYNAMIC) {
dpnt = (ElfW(Dyn) *) (ppnt->p_vaddr + app_tpnt->loadaddr);
@@ -345,6 +353,7 @@
_dl_debug_early("calling mprotect on the application program\n");
/* Now cover the application program. */
if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+ ElfW(Phdr) *ppnt_outer = ppnt;
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
@@ -353,7 +362,13 @@
(unsigned long) ppnt->p_filesz,
PROT_READ | PROT_WRITE | PROT_EXEC);
}
+ ppnt = ppnt_outer;
}
+#else
+ if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+ _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
+ _dl_exit(1);
+ }
#endif
#ifndef ALLOW_ZERO_PLTGOT
@@ -370,7 +385,7 @@
_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
rpnt->dyn = _dl_loaded_modules;
- app_tpnt->mapaddr = app_loadaddr;
+ app_tpnt->mapaddr = app_mapaddr;
app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
app_tpnt->usage_count++;
app_tpnt->symbol_scope = _dl_symbol_tables;
@@ -514,9 +529,7 @@
debug_addr->r_brk = (unsigned long) &_dl_debug_state;
_dl_debug_addr = debug_addr;
- /* Notify the debugger we are in a consistant state */
- _dl_debug_addr->r_state = RT_CONSISTENT;
- _dl_debug_state();
+ /* Do not notify the debugger until the interpreter is in the list */
/* OK, we now have the application in the list, and we have some
* basic stuff in place. Now search through the list for other shared
@@ -783,6 +796,10 @@
(unsigned long)tpnt->dynamic_addr,
0);
+ if (_dl_stat(tpnt->libname, &st) >= 0) {
+ tpnt->st_dev = st.st_dev;
+ tpnt->st_ino = st.st_ino;
+ }
tpnt->n_phent = epnt->e_phnum;
tpnt->ppnt = myppnt;
for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
Modified: branches/uClibc-nptl/ldso/ldso/sh/dl-syscalls.h
===================================================================
--- branches/uClibc-nptl/ldso/ldso/sh/dl-syscalls.h 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/sh/dl-syscalls.h 2008-03-05 17:54:17 UTC (rev 21172)
@@ -4,3 +4,11 @@
extern int _dl_errno;
#undef __set_errno
#define __set_errno(X) {(_dl_errno) = (X);}
+
+#if __GNUC_PREREQ (4, 1)
+#warning !!! gcc 4.1 and later have problems with __always_inline so redefined as inline
+# ifdef __always_inline
+# undef __always_inline
+# define __always_inline inline
+# endif
+#endif
Modified: branches/uClibc-nptl/ldso/ldso/sh/elfinterp.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/sh/elfinterp.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/ldso/sh/elfinterp.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -252,7 +252,7 @@
}
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", old_val, *reloc_addr, reloc_addr);
+ _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
#endif
return 0;
@@ -289,7 +289,7 @@
}
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", old_val, *reloc_addr, reloc_addr);
+ _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
#endif
return 0;
Modified: branches/uClibc-nptl/ldso/libdl/Makefile.in
===================================================================
--- branches/uClibc-nptl/ldso/libdl/Makefile.in 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/libdl/Makefile.in 2008-03-05 17:54:17 UTC (rev 21172)
@@ -1,7 +1,6 @@
# Makefile.in for uClibc
#
-# Copyright (C) 2000 by Lineo, inc.
-# Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
+# Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
Modified: branches/uClibc-nptl/ldso/libdl/libdl.c
===================================================================
--- branches/uClibc-nptl/ldso/libdl/libdl.c 2008-03-05 16:44:02 UTC (rev 21171)
+++ branches/uClibc-nptl/ldso/libdl/libdl.c 2008-03-05 17:54:17 UTC (rev 21172)
@@ -59,24 +59,30 @@
extern struct r_debug *_dl_debug_addr;
extern unsigned long _dl_error_number;
extern void *(*_dl_malloc_function)(size_t);
+extern void (*_dl_free_function) (void *p);
extern void _dl_run_init_array(struct elf_resolve *);
extern void _dl_run_fini_array(struct elf_resolve *);
-# ifdef __LDSO_CACHE_SUPPORT__
+#ifdef __LDSO_CACHE_SUPPORT__
int _dl_map_cache(void);
int _dl_unmap_cache(void);
-# endif
-# ifdef __mips__
+#endif
+#ifdef __mips__
extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
-# endif
-# ifdef __SUPPORT_LD_DEBUG__
+#endif
+#ifdef __SUPPORT_LD_DEBUG__
extern char *_dl_debug;
-# endif
+#endif
+
+
#else /* SHARED */
+#define _dl_malloc malloc
+#define _dl_free free
+
/* When libdl is linked as a static library, we need to replace all
* the symbols that otherwise would have been loaded in from ldso... */
-# ifdef __SUPPORT_LD_DEBUG__
+#ifdef __SUPPORT_LD_DEBUG__
/* Needed for 'strstr' prototype' */
#include <string.h>
char *_dl_debug = 0;
@@ -87,16 +93,17 @@
char *_dl_debug_nofixups = 0;
char *_dl_debug_bindings = 0;
int _dl_debug_file = 2;
-# endif
+#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 */
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. */
struct r_debug *_dl_debug_addr = NULL;
-#define _dl_malloc malloc
-#define _dl_free free
+
#include "../ldso/dl-debug.c"
@@ -278,6 +285,7 @@
struct init_fini_list *tmp, *runp, *runp2, *dep_list;
unsigned int nlist, i;
struct elf_resolve **init_fini_list;
+ static int _dl_init = 0;
#if USE_TLS
bool any_tls = false;
#endif
@@ -290,6 +298,11 @@
from = (ElfW(Addr)) __builtin_return_address(0);
+ if (!_dl_init) {
+ _dl_init++;
+ _dl_malloc_function = malloc;
+ _dl_free_function = free;
+ }
/* Cover the trivial case first */
if (!libname)
return _dl_symbol_tables;
@@ -310,7 +323,7 @@
_dl_debug_bindings = strstr(_dl_debug, "bind");
}
}
-# endif
+# endif
#endif
_dl_map_cache();
@@ -333,7 +346,7 @@
tfrom = tpnt;
}
}
- for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
+ for (rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
relro_ptr = rpnt;
now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
@@ -343,8 +356,8 @@
#ifndef SHARED
/* When statically linked, the _dl_library_path is not yet initialized */
_dl_library_path = getenv("LD_LIBRARY_PATH");
-#endif
-
+#endif
+
/* Try to load the specified library */
_dl_if_debug_print("Trying to dlopen '%s', RTLD_GLOBAL:%d RTLD_NOW:%d\n",
(char*)libname, (flag & RTLD_GLOBAL ? 1:0), (now_flag & RTLD_NOW ? 1:0));
@@ -369,7 +382,7 @@
if (handle->dyn == tpnt) {
dyn_chain->init_fini.init_fini = handle->init_fini.init_fini;
dyn_chain->init_fini.nlist = handle->init_fini.nlist;
- for(i=0; i < dyn_chain->init_fini.nlist; i++)
+ for (i = 0; i < dyn_chain->init_fini.nlist; i++)
dyn_chain->init_fini.init_fini[i]->rtld_flags |= (flag & RTLD_GLOBAL);
dyn_chain->next = handle->next;
break;
@@ -419,7 +432,7 @@
for (tmp=dep_list; tmp; tmp = tmp->next) {
if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */
_dl_if_debug_print("Circular dependency, skipping '%s',\n",
- tmp->tpnt->libname);
+ tmp->tpnt->libname);
tpnt1->usage_count--;
break;
}
@@ -439,7 +452,7 @@
i = 0;
for (runp2 = dep_list; runp2; runp2 = runp2->next) {
init_fini_list[i++] = runp2->tpnt;
- for(runp = runp2->tpnt->init_fini; runp; runp = runp->next){
+ for (runp = runp2->tpnt->init_fini; runp; runp = runp->next) {
if (!(runp->tpnt->rtld_flags & RTLD_GLOBAL)) {
tmp = malloc(sizeof(struct init_fini_list));
tmp->tpnt = runp->tpnt;
@@ -471,9 +484,9 @@
}
}
#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug) {
+ if (_dl_debug) {
fprintf(stderr, "\nINIT/FINI order and dependencies:\n");
- for (i=0;i < nlist;i++) {
+ for (i = 0; i < nlist; i++) {
fprintf(stderr, "lib: %s has deps:\n", init_fini_list[i]->libname);
runp = init_fini_list[i]->init_fini;
for (; runp; runp = runp->next)
@@ -1033,6 +1046,7 @@
strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
sf = sn = 0;
+
#ifdef __LDSO_GNU_HASH_SUPPORT__
if (pelf->l_gnu_bitmask) {
for (hn = 0; hn < pelf->nbucket; hn++) {
@@ -1050,9 +1064,7 @@
sn = si;
sf = 1;
}
-
- _dl_if_debug_print("Symbol \"%s\" at %p\n",
- strtab + symtab[si].st_name, symbol_addr);
+ _dl_if_debug_print("Symbol \"%s\" at %p\n", strtab + symtab[si].st_name, symbol_addr);
++si;
} while ((*hasharr++ & 1u) == 0);
}
@@ -1070,7 +1082,7 @@
}
_dl_if_debug_print("Symbol \"%s\" at %p\n",
- strtab + symtab[si].st_name, symbol_addr);
+ strtab + symtab[si].st_name, symbol_addr);
}
}
More information about the uClibc-cvs
mailing list