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