Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Oct 2010 13:56:26 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r213833 - stable/8/libexec/rtld-elf/powerpc
Message-ID:  <201010141356.o9EDuQwS026103@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Thu Oct 14 13:56:26 2010
New Revision: 213833
URL: http://svn.freebsd.org/changeset/base/213833

Log:
  MFC r213406:
  
  Fix two subtle problems in PPC32 RTLD. The first is a concurrency issue
  where long PLT calls in multi-threaded environments could end up with
  incorrect jmptab values. The second is that, after the addition of extended
  PLT support, I forgot to update the PLT icache synchronization code to cover
  the extended PLT instead of just the basic PLT.

Modified:
  stable/8/libexec/rtld-elf/powerpc/reloc.c
Directory Properties:
  stable/8/libexec/rtld-elf/   (props changed)

Modified: stable/8/libexec/rtld-elf/powerpc/reloc.c
==============================================================================
--- stable/8/libexec/rtld-elf/powerpc/reloc.c	Thu Oct 14 12:32:49 2010	(r213832)
+++ stable/8/libexec/rtld-elf/powerpc/reloc.c	Thu Oct 14 13:56:26 2010	(r213833)
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <machine/cpu.h>
+#include <machine/cpufunc.h>
 #include <machine/md_var.h>
 
 #include "debug.h"
@@ -485,6 +486,7 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 
 		jmptab = obj->pltgot + JMPTAB_BASE(N);
 		jmptab[reloff] = target;
+		powerpc_mb(); /* Order jmptab update before next changes */
 
 		if (reloff < PLT_EXTENDED_BEGIN) {
 			/* for extended PLT entries, we keep the old code */
@@ -493,7 +495,8 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 
 			/* li   r11,reloff */
 			/* b    pltcall  # use indirect pltcall routine */
-			wherep[0] = 0x39600000 | reloff;
+
+			/* first instruction same as before */
 			wherep[1] = 0x48000000 | (distance & 0x03fffffc);
 			__syncicache(wherep, 8);
 		}
@@ -581,7 +584,7 @@ init_pltgot(Obj_Entry *obj)
 	 * Sync the icache for the byte range represented by the
 	 * trampoline routines and call slots.
 	 */
-	__syncicache(pltcall, 72 + N * 8);
+	__syncicache(obj->pltgot, JMPTAB_BASE(N)*4);
 }
 
 void



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