From 6a7d71b6f3e65a7aaea0b142a004d9168848530f Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Mon, 4 Oct 2010 16:02:11 +0000 Subject: 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. MFC after: 10 days --- libexec/rtld-elf/powerpc/reloc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'libexec/rtld-elf') diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c index c90852f..84feff3 100644 --- a/libexec/rtld-elf/powerpc/reloc.c +++ b/libexec/rtld-elf/powerpc/reloc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "debug.h" @@ -481,6 +482,7 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj, 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 */ @@ -489,7 +491,8 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj, /* 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); } @@ -577,7 +580,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 -- cgit v1.1