Elf_Addr _mips_rtld_bind(Obj_Entry *obj, Elf_Size reloff) { Elf_Addr *got = obj->pltgot; const Elf_Sym *def; const Obj_Entry *defobj; Elf_Addr *where; Elf_Addr target; RtldLockState lockstate; rlock_acquire(rtld_bind_lock, &lockstate); if (sigsetjmp(lockstate.env, 0) != 0) lock_upgrade(rtld_bind_lock, &lockstate); where = &got[obj->local_gotno + reloff - obj->gotsym]; def = find_symdef(reloff, obj, &defobj, SYMLOOK_IN_PLT, NULL, &lockstate); if (def == NULL) rtld_die(); target = (Elf_Addr)(defobj->relocbase + def->st_value); dbg("bind now/fixup at %s sym # %jd in %s --> was=%p new=%p", obj->path, (intmax_t)reloff, defobj->strtab + def->st_name, (void *)*where, (void *)target); if (!ld_bind_not) *where = target; lock_release(rtld_bind_lock, &lockstate); return (Elf_Addr)target; }
void shared_spinlock::unlock_and_lock_upgrade() { unlock(); lock_upgrade(); }