Port-powerpc archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
semi-random crashes on some macppc hardware
Hello,
I've seen semi-random crashes ( often, but nowhere near always things
like sshd or makemandb would segfault during boot ) on some of my
macppc boxes for a while, for some reason mostly on a Powerbook Pismo
and not nearly as much on a beige G3. I finally had a closer look by
examining a bunch of .core files. Turns out on my Powerbook Pismo
( 500MHz ppc750, 1MB cache ) pretty much all the crashes happened in
PLT entries, and for no obvious reason.
To me that looks like insufficient instruction cache syncing when
writing the PLT entries in ld.elf_so, in order to test this I sprinkled
__syncicache() calls in a few suspicious-looking places in ppc_reloc.c.
I haven't seen any PLT-related crashes since.
The diff is attached, I'm sure it does more __syncicache()ing than
needed but so far I didn't have time to investigate further.
I dimly remember similar problems years ago.
have fun
Michael
Index: ppc_reloc.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c,v
retrieving revision 1.53
diff -u -w -r1.53 ppc_reloc.c
--- ppc_reloc.c 25 Aug 2014 20:40:52 -0000 1.53
+++ ppc_reloc.c 12 May 2016 02:35:02 -0000
@@ -341,7 +341,7 @@
* in _rtld_setup_pltgot() after all the entries have been
* initialized.
*/
- /* __syncicache(where - 3, 12); */
+ __syncicache(where - 3, 12);
}
}
#endif /* !_LP64 */
@@ -353,6 +353,7 @@
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff, Elf_Addr *tp)
{
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
+ Elf_Word *w = where;
Elf_Addr value;
const Elf_Sym *def;
const Obj_Entry *defobj;
@@ -397,6 +398,7 @@
assert(where >= (Elf_Word *)obj->pltgot);
assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
*where = value;
+ __syncicache(where, 4);
} else if (labs(distance) < 32*1024*1024) { /* inside 32MB? */
/* b value # branch directly */
*where = 0x48000000 | (distance & 0x03fffffc);
@@ -437,7 +439,7 @@
/* b pltcall */
distance = (Elf_Addr)pltcall - (Elf_Addr)where;
*where++ = 0x48000000 | (distance & 0x03fffffc);
- __syncicache(where - 3, 12);
+ __syncicache(w, 12);
}
#endif /* _LP64 */
Home |
Main Index |
Thread Index |
Old Index