OSDN Git Service

Update C6X support
[uclinux-h8/uClibc.git] / ldso / ldso / c6x / elfinterp.c
index 3772f90..f0e05b9 100644 (file)
@@ -69,14 +69,12 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
        got_addr = (char **) 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(symname, tpnt->symbol_scope, tpnt,
-                                ELF_RTYPE_CLASS_PLT, NULL);
+       new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
        if (unlikely(!new_addr)) {
                _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
                _dl_exit(1);
        }
 
-
 #if defined (__SUPPORT_LD_DEBUG__)
        if (_dl_debug_bindings) {
                _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
@@ -96,9 +94,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
 }
 
 static int
-_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
+_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope,
          unsigned long rel_addr, unsigned long rel_size,
-         int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
+         int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope,
                            ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
 {
        unsigned int i;
@@ -148,7 +146,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 }
 
 static int
-_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+_dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope,
              ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
 {
        int reloc_type;
@@ -157,7 +155,9 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
        unsigned long *reloc_addr;
        unsigned long symbol_addr, sym_val;
        long reloc_addend;
-       unsigned long old_val, new_val;
+       unsigned long old_val, new_val = 0;
+       struct symbol_ref sym_ref;
+       struct elf_resolve *symbol_tpnt;
 
        reloc_addr = (unsigned long *)(intptr_t)
                DL_RELOC_ADDR (tpnt->loadaddr, rpnt->r_offset);
@@ -167,14 +167,17 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
        symtab_index = ELF_R_SYM(rpnt->r_info);
        symbol_addr  = 0;
        symname      = strtab + symtab[symtab_index].st_name;
+       sym_ref.sym = &symtab[symtab_index];
+       sym_ref.tpnt = NULL;
 
        if (ELF_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) {
                symbol_addr = (unsigned long)
                        DL_RELOC_ADDR (tpnt->loadaddr, symtab[symtab_index].st_value);
+               symbol_tpnt = tpnt;
        } else {
-               symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
-                                                           scope, tpnt, elf_machine_type_class(reloc_type),
-                                                           NULL);
+               symbol_addr = (unsigned long) _dl_find_hash(symname,
+                                                           scope, NULL, elf_machine_type_class(reloc_type),
+                                                           &sym_ref);
                /*
                 * We want to allow undefined references to weak symbols - this might
                 * have been intentional.  We should not be linking local symbols
@@ -186,6 +189,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
                                     _dl_progname, strtab + symtab[symtab_index].st_name);
                        _dl_exit (1);
                }
+               symbol_tpnt = sym_ref.tpnt;
        }
        old_val = *reloc_addr;
        sym_val = symbol_addr + reloc_addend;
@@ -199,7 +203,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
                *reloc_addr = sym_val;
                break;
        case R_C6000_DSBT_INDEX:
-               new_val = (old_val & ~0x007fff00) | ((tpnt->loadaddr.map->dsbt_index & 0x7fff) << 8);
+               new_val = (old_val & ~0x007fff00) | ((symbol_tpnt->dsbt_index & 0x7fff) << 8);
                *reloc_addr = new_val;
                break;
        case R_C6000_ABS_L16:
@@ -242,7 +246,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
 
 static int
 _dl_do_lazy_reloc (struct elf_resolve *tpnt,
-                  struct dyn_elf *scope attribute_unused,
+                  struct r_scope_elem *scope attribute_unused,
                   ELF_RELOC *rpnt, ElfW(Sym) *symtab attribute_unused,
                   char *strtab attribute_unused)
 {
@@ -283,9 +287,9 @@ _dl_parse_lazy_relocation_information
 
 int
 _dl_parse_relocation_information
-(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size)
+(struct dyn_elf *rpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size)
 {
-       return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+       return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc);
 }
 
 /* We don't have copy relocs.  */