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)
 {
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to