Fix _mips_rtld_bind() to handle ELF filters.

MIPS does not use the common _rtld_bind() to handle runtime binding.
Instead, it uses a private _mips_rtld_bind().  Update _mips_rtld_bind()
to include the changes made to _rtld_bind() in r216695 and r218476 to
support upgrading the read-locked rtld_bind_lock to a write lock when
an object with a filter is encountered.

While here, add a 'where' variable to track the location of the fixup
in the GOT to make the code flow more closely match _rtld_bind().

Reviewed by:	kib
Obtained from:	CheriBSD
Sponsored by:	DARPA / AFRL
Differential Revision:	https://reviews.freebsd.org/D8625
This commit is contained in:
jhb 2016-11-23 20:21:53 +00:00
parent 5ffcdc8bcc
commit c7684cbde0
2 changed files with 15 additions and 4 deletions

View File

@ -240,10 +240,17 @@ _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,
NULL);
&lockstate);
if (def == NULL)
rtld_die();
@ -251,9 +258,9 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
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 *)got[obj->local_gotno + reloff - obj->gotsym],
(void *)target);
got[obj->local_gotno + reloff - obj->gotsym] = target;
(void *)*where, (void *)target);
*where = target;
lock_release(rtld_bind_lock, &lockstate);
return (Elf_Addr)target;
}

View File

@ -695,6 +695,10 @@ rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
return ((void *)target);
}
/*
* NB: MIPS uses a private version of this function (_mips_rtld_bind).
* Changes to this function should be applied there as well.
*/
Elf_Addr
_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
{