svn commit: trunk/uClibc/ldso: include ldso ldso/bfin libdl

bernds at uclibc.org bernds at uclibc.org
Mon Dec 3 22:54:19 UTC 2007


Author: bernds
Date: 2007-12-03 14:54:16 -0800 (Mon, 03 Dec 2007)
New Revision: 20614

Log:
Blackfin FD-PIC patch 3/6.
Change _dl_find_hash to _dl_lookup_hash, as on the NPTL branch.
_dl_find_hash is now a wrapper function around it; unlike on the NPTL branch,
it retains the old interface so that not all callers need to be changed.

_dl_lookup_hash can optionally give its caller a pointer to the module where
the symbol was found.

Introduce ELF_RTYPE_CLASS_DLSYM for lookups from libdl.

Spelling fixes in the Blackfin port, since Alex Oliva's original version of
these patches used _dl_find_hash_mod as the name of the function rather than
_dl_lookup_hash.


Modified:
   trunk/uClibc/ldso/include/dl-defs.h
   trunk/uClibc/ldso/include/dl-elf.h
   trunk/uClibc/ldso/include/dl-hash.h
   trunk/uClibc/ldso/ldso/bfin/elfinterp.c
   trunk/uClibc/ldso/ldso/dl-hash.c
   trunk/uClibc/ldso/libdl/libdl.c


Changeset:
Modified: trunk/uClibc/ldso/include/dl-defs.h
===================================================================
--- trunk/uClibc/ldso/include/dl-defs.h	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/include/dl-defs.h	2007-12-03 22:54:16 UTC (rev 20614)
@@ -181,4 +181,11 @@
 #define __C_SYMBOL_PREFIX__ "_"
 #endif
 
+/* Define this if you want to modify the VALUE returned by
+   _dl_find_hash for this reloc TYPE.  TPNT is the module in which the
+   matching SYM was found.  */
+#ifndef DL_FIND_HASH_VALUE
+# define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
+#endif
+
 #endif	/* _LD_DEFS_H */

Modified: trunk/uClibc/ldso/include/dl-elf.h
===================================================================
--- trunk/uClibc/ldso/include/dl-elf.h	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/include/dl-elf.h	2007-12-03 22:54:16 UTC (rev 20614)
@@ -183,7 +183,12 @@
 #endif
 #define ELF_RTYPE_CLASS_PLT	(0x1)
 
+/* dlsym() calls _dl_find_hash with this value, that enables
+   DL_FIND_HASH_VALUE to return something different than the symbol
+   itself, e.g., a function descriptor.  */
+#define ELF_RTYPE_CLASS_DLSYM 0x80000000
 
+
 /* Convert between the Linux flags for page protections and the
    ones specified in the ELF standard. */
 #define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \

Modified: trunk/uClibc/ldso/include/dl-hash.h
===================================================================
--- trunk/uClibc/ldso/include/dl-hash.h	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/include/dl-hash.h	2007-12-03 22:54:16 UTC (rev 20614)
@@ -105,9 +105,23 @@
 	DL_LOADADDR_TYPE loadaddr, unsigned long * dynamic_info,
 	unsigned long dynamic_addr, unsigned long dynamic_size);
 
-extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1,
-			    struct elf_resolve *mytpnt, int type_class);
+extern char * _dl_lookup_hash(const char * name, struct dyn_elf * rpnt,
+			      struct elf_resolve *mytpnt, int type_class
+#ifdef __FDPIC__
+			      , struct elf_resolve **tpntp
+#endif
+			      );
 
+static __always_inline char *_dl_find_hash(const char *name, struct dyn_elf *rpnt,
+					   struct elf_resolve *mytpnt, int type_class)
+{
+#ifdef __FDPIC__
+	return _dl_lookup_hash(name, rpnt, mytpnt, type_class, NULL);
+#else
+	return _dl_lookup_hash(name, rpnt, mytpnt, type_class);
+#endif
+}
+
 extern int _dl_linux_dynamic_link(void);
 
 extern char * _dl_library_path;

Modified: trunk/uClibc/ldso/ldso/bfin/elfinterp.c
===================================================================
--- trunk/uClibc/ldso/ldso/bfin/elfinterp.c	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/ldso/bfin/elfinterp.c	2007-12-03 22:54:16 UTC (rev 20614)
@@ -72,11 +72,9 @@
 	got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset);
 
 	/* Get the address to be used to fill in the GOT entry.  */
-	new_addr = _dl_find_hash_mod(symname, tpnt->symbol_scope, NULL, 0,
-				     &new_tpnt);
+	new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &new_tpnt);
 	if (!new_addr) {
-		new_addr = _dl_find_hash_mod(symname, NULL, NULL, 0,
-					     &new_tpnt);
+		new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &new_tpnt);
 		if (!new_addr) {
 			_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 				    _dl_progname, symname);
@@ -188,7 +186,7 @@
 	} else {
 
 		symbol_addr = (unsigned long)
-		  _dl_find_hash_mod(symname, scope, NULL, 0, &symbol_tpnt);
+		  _dl_lookup_hash(symname, scope, NULL, 0, &symbol_tpnt);
 
 		/*
 		 * We want to allow undefined references to weak symbols - this might

Modified: trunk/uClibc/ldso/ldso/dl-hash.c
===================================================================
--- trunk/uClibc/ldso/ldso/dl-hash.c	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/ldso/dl-hash.c	2007-12-03 22:54:16 UTC (rev 20614)
@@ -257,7 +257,12 @@
  * This function resolves externals, and this is either called when we process
  * relocations or when we call an entry in the PLT table for the first time.
  */
-char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, int type_class)
+char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt,
+		      struct elf_resolve *mytpnt, int type_class
+#ifdef __FDPIC__
+		      , struct elf_resolve **tpntp
+#endif
+		      )
 {
 	struct elf_resolve *tpnt = NULL;
 	ElfW(Sym) *symtab;
@@ -265,7 +270,8 @@
 	unsigned long elf_hash_number = 0xffffffff;
 	const ElfW(Sym) *sym = NULL;
 
-	char *weak_result = NULL;
+	const ElfW(Sym) *weak_sym = 0;
+	struct elf_resolve *weak_tpnt = 0;
 
 #ifdef __LDSO_GNU_HASH_SUPPORT__
 	unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name);
@@ -326,15 +332,32 @@
 #if 0
 /* Perhaps we should support old style weak symbol handling
  * per what glibc does when you export LD_DYNAMIC_WEAK */
-				if (!weak_result)
-					weak_result = (char *) DL_RELOC_ADDR(tpnt->loadaddr, sym->st_value);
+				if (!weak_sym) {
+					weak_tpnt = tpnt;
+					weak_sym = sym;
+				}
 				break;
 #endif
 			case STB_GLOBAL:
-				return (char*) DL_RELOC_ADDR(tpnt->loadaddr, sym->st_value);
+#ifdef __FDPIC__
+				if (tpntp)
+					*tpntp = tpnt;
+#endif
+				return DL_FIND_HASH_VALUE (tpnt, type_class, sym);
 			default:	/* Local symbols not handled here */
 				break;
 		}
 	}
-	return weak_result;
+	if (weak_sym) {
+#ifdef __FDPIC__
+		if (tpntp)
+			*tpntp = weak_tpnt;
+#endif
+		return DL_FIND_HASH_VALUE (weak_tpnt, type_class, weak_sym);
+	}
+#ifdef __FDPIC__
+	if (tpntp)
+		*tpntp = NULL;
+#endif
+	return NULL;
 }

Modified: trunk/uClibc/ldso/libdl/libdl.c
===================================================================
--- trunk/uClibc/ldso/libdl/libdl.c	2007-12-03 22:46:53 UTC (rev 20613)
+++ trunk/uClibc/ldso/libdl/libdl.c	2007-12-03 22:54:16 UTC (rev 20614)
@@ -500,7 +500,7 @@
 	tpnt = NULL;
 	if (handle == _dl_symbol_tables)
 	   tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
-	ret = _dl_find_hash(name2, handle, tpnt, 0);
+	ret = _dl_find_hash(name2, handle, tpnt, ELF_RTYPE_CLASS_DLSYM);
 
 	/*
 	 * Nothing found.




More information about the uClibc-cvs mailing list