semi-random crashes on some macppc hardware
Michael <[email protected]> Thu, 12 May 2016 00:19:16 -0400
| Newsgroups | gmane.os.netbsd.ports.powerpc |
|---|---|
| Organization | The NetBSD Foundation |
| Message-ID | <20160512001916.60fb2815@blackbush> |
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
ppc_reloc.diff
(text/x-patch, 1.3 KB)
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 */