Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Nov 2016 20:21:53 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r309068 - in head/libexec/rtld-elf: . mips
Message-ID:  <201611232021.uANKLrkC026015@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Nov 23 20:21:53 2016
New Revision: 309068
URL: https://svnweb.freebsd.org/changeset/base/309068

Log:
  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

Modified:
  head/libexec/rtld-elf/mips/reloc.c
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/mips/reloc.c
==============================================================================
--- head/libexec/rtld-elf/mips/reloc.c	Wed Nov 23 19:50:12 2016	(r309067)
+++ head/libexec/rtld-elf/mips/reloc.c	Wed Nov 23 20:21:53 2016	(r309068)
@@ -240,10 +240,17 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size
         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
         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;
 }
 

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Wed Nov 23 19:50:12 2016	(r309067)
+++ head/libexec/rtld-elf/rtld.c	Wed Nov 23 20:21:53 2016	(r309068)
@@ -695,6 +695,10 @@ rtld_resolve_ifunc(const Obj_Entry *obj,
 	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)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611232021.uANKLrkC026015>