diff options
Diffstat (limited to 'libexec/rtld-elf/sparc64')
-rw-r--r-- | libexec/rtld-elf/sparc64/reloc.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/libexec/rtld-elf/sparc64/reloc.c b/libexec/rtld-elf/sparc64/reloc.c index 1b8f1fd..c8d657c 100644 --- a/libexec/rtld-elf/sparc64/reloc.c +++ b/libexec/rtld-elf/sparc64/reloc.c @@ -193,7 +193,7 @@ static const long reloc_target_bitmask[] = { __asm __volatile("flush %0 + %1" : : "r" (va), "I" (offs)); static int reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, - SymCache *cache); + SymCache *cache, RtldLockState *lockstate); static void install_plt(Elf_Word *pltgot, Elf_Addr proc); extern char _rtld_bind_start_0[]; @@ -206,13 +206,13 @@ do_copy_relocations(Obj_Entry *dstobj) const Elf_Rela *rela; const Elf_Sym *dstsym; const Elf_Sym *srcsym; - const Ver_Entry *ve; void *dstaddr; const void *srcaddr; - Obj_Entry *srcobj; - unsigned long hash; + const Obj_Entry *srcobj, *defobj; + SymLook req; const char *name; size_t size; + int res; assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */ @@ -222,16 +222,20 @@ do_copy_relocations(Obj_Entry *dstobj) dstaddr = (void *)(dstobj->relocbase + rela->r_offset); dstsym = dstobj->symtab + ELF_R_SYM(rela->r_info); name = dstobj->strtab + dstsym->st_name; - hash = elf_hash(name); size = dstsym->st_size; - ve = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info)); + symlook_init(&req, name); + req.ventry = fetch_ventry(dstobj, + ELF_R_SYM(rela->r_info)); for (srcobj = dstobj->next; srcobj != NULL; - srcobj = srcobj->next) - if ((srcsym = symlook_obj(name, hash, srcobj, - ve, 0)) != NULL) + srcobj = srcobj->next) { + res = symlook_obj(&req, srcobj); + if (res == 0) { + srcsym = req.sym_out; + defobj = req.defobj_out; break; - + } + } if (srcobj == NULL) { _rtld_error("Undefined symbol \"%s\"" "referenced from COPY relocation" @@ -239,7 +243,7 @@ do_copy_relocations(Obj_Entry *dstobj) return (-1); } - srcaddr = (const void *)(srcobj->relocbase + + srcaddr = (const void *)(defobj->relocbase + srcsym->st_value); memcpy(dstaddr, srcaddr, size); } @@ -249,7 +253,7 @@ do_copy_relocations(Obj_Entry *dstobj) } int -reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) +reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate) { const Elf_Rela *relalim; const Elf_Rela *rela; @@ -268,7 +272,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize); for (rela = obj->rela; rela < relalim; rela++) { - if (reloc_nonplt_object(obj, rela, cache) < 0) + if (reloc_nonplt_object(obj, rela, cache, lockstate) < 0) goto done; } r = 0; @@ -279,7 +283,8 @@ done: } static int -reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache) +reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache, + RtldLockState *lockstate) { const Obj_Entry *defobj; const Elf_Sym *def; @@ -333,7 +338,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache) /* Find the symbol */ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - false, cache); + false, cache, lockstate); if (def == NULL) return (-1); @@ -416,7 +421,7 @@ reloc_plt(Obj_Entry *obj) assert(ELF64_R_TYPE_ID(rela->r_info) == R_SPARC_JMP_SLOT); where = (Elf_Addr *)(obj->relocbase + rela->r_offset); def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - true, NULL); + true, NULL, lockstate); value = (Elf_Addr)(defobj->relocbase + def->st_value); *where = value; } @@ -446,7 +451,7 @@ reloc_plt(Obj_Entry *obj) #define LOVAL(v) ((v) & 0x000003ff) int -reloc_jmpslots(Obj_Entry *obj) +reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate) { const Obj_Entry *defobj; const Elf_Rela *relalim; @@ -460,7 +465,7 @@ reloc_jmpslots(Obj_Entry *obj) assert(ELF64_R_TYPE_ID(rela->r_info) == R_SPARC_JMP_SLOT); where = (Elf_Addr *)(obj->relocbase + rela->r_offset); def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - true, NULL); + true, NULL, lockstate); if (def == NULL) return -1; target = (Elf_Addr)(defobj->relocbase + def->st_value); |