OSDN Git Service

ldso: bfin: add alias from __start to _start
[uclinux-h8/uClibc.git] / ldso / ldso / dl-hash.c
index 2c4571f..36ebec6 100644 (file)
@@ -146,7 +146,6 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
                tpnt->chains = hash_addr;
        }
        tpnt->loadaddr = loadaddr;
-       tpnt->mapaddr = DL_RELOC_ADDR(loadaddr, 0);
        for (i = 0; i < DYNAMIC_SIZE; i++)
                tpnt->dynamic_info[i] = dynamic_info[i];
        return tpnt;
@@ -189,6 +188,10 @@ check_match (const ElfW(Sym) *sym, char *strtab, const char* undef_name, int typ
                 */
                return NULL;
 #endif
+#ifdef ARCH_SKIP_RELOC
+       if (ARCH_SKIP_RELOC(type_class, sym))
+               return NULL;
+#endif
        if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0)
                return NULL;
 
@@ -268,8 +271,8 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long
  * 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_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt,
-       int type_class, struct elf_resolve **tpntp)
+char *_dl_find_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt,
+       int type_class, struct symbol_ref *sym_ref)
 {
        struct elf_resolve *tpnt = NULL;
        ElfW(Sym) *symtab;
@@ -285,6 +288,11 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r
        unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name);
 #endif
 
+       if ((sym_ref) && (sym_ref->sym) && (ELF32_ST_VISIBILITY(sym_ref->sym->st_other) == STV_PROTECTED)) {
+                       sym = sym_ref->sym;
+               if (mytpnt)
+                       tpnt = mytpnt;
+       } else
        for (loop_scope = scope; loop_scope && !sym; loop_scope = loop_scope->next) {
                for (i = 0; i < loop_scope->r_nlist; i++) {
                        tpnt = loop_scope->r_list[i];
@@ -339,12 +347,14 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r
        }
 
        if (sym) {
+               if (sym_ref) {
+                       sym_ref->sym = sym;
+                       sym_ref->tpnt = tpnt;
+               }
                /* At this point we have found the requested symbol, do binding */
 #if defined(USE_TLS) && USE_TLS
                if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
-                       _dl_assert(tpntp != NULL);
-                       *tpntp = tpnt;
-
+                       _dl_assert(sym_ref != NULL);
                        return (char *)sym->st_value;
                }
 #endif
@@ -360,8 +370,8 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r
 #endif
                        case STB_GLOBAL:
 #ifdef __FDPIC__
-                               if (tpntp)
-                                       *tpntp = tpnt;
+                       if (sym_ref)
+                               sym_ref->tpnt = tpnt;
 #endif
                                return (char *)DL_FIND_HASH_VALUE(tpnt, type_class, sym);
                        default:        /* Local symbols not handled here */
@@ -369,8 +379,8 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r
                }
        }
 #ifdef __FDPIC__
-       if (tpntp)
-               *tpntp = tpnt;
+       if (sym_ref)
+               sym_ref->tpnt = tpnt;
 #endif
        return weak_result;
 }