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
This commit is contained in:
parent
85d8a2efbb
commit
6a7d71b6f3
@ -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"
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user