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