From: Julian Seward Date: Mon, 11 Apr 2011 21:26:27 +0000 (+0000) Subject: Add an alternative implementation of VG_MINIMAL_{SET,LONG}JMP X-Git-Tag: svn/VALGRIND_3_7_0~546 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5a3e4f014ed746a0eea1ad4180d4c2e1bfeabb9;p=thirdparty%2Fvalgrind.git Add an alternative implementation of VG_MINIMAL_{SET,LONG}JMP for ppc32-linux, that works for gcc >= 4.4. Related to #259977. (modified version of patch from Maynard Johnson ) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11689 --- diff --git a/coregrind/m_libcsetjmp.c b/coregrind/m_libcsetjmp.c index ae0b620393..3ca3303e49 100644 --- a/coregrind/m_libcsetjmp.c +++ b/coregrind/m_libcsetjmp.c @@ -39,11 +39,13 @@ /* The only alternative implementations are for ppc{32,64}-linux. See #259977. */ +/* ------------ ppc32-linux ------------ */ + #if defined(VGP_ppc32_linux) __asm__( ".text" "\n" -"" "\n" +"" "\n" ".global VG_MINIMAL_SETJMP" "\n" // r3 = jmp_buf "VG_MINIMAL_SETJMP:" "\n" " stw 0, 0(3)" "\n" @@ -85,7 +87,7 @@ __asm__( " stw 4, 132(3)" "\n" " li 3, 0" "\n" " blr" "\n" -"" "\n" +"" "\n" ".global VG_MINIMAL_LONGJMP" "\n" @@ -135,8 +137,7 @@ __asm__( " lwz 31, 124(3)" "\n" " lwz 3, 12(3)" "\n" " blr" "\n" -"" "\n" - +"" "\n" ".previous" "\n" ); @@ -144,6 +145,132 @@ __asm__( #endif /* VGP_ppc32_linux */ +/* ------------ ppc64-linux ------------ */ + +#if defined(VGP_ppc64_linux) + +__asm__( +".section \".toc\",\"aw\"" "\n" + +".section \".text\"" "\n" +".align 2" "\n" +".p2align 4,,15" "\n" +".globl VG_MINIMAL_SETJMP" "\n" + +".section \".opd\",\"aw\"" "\n" +".align 3" "\n" +"VG_MINIMAL_SETJMP:" "\n" +".quad .L.VG_MINIMAL_SETJMP,.TOC.@tocbase,0" "\n" +".previous" "\n" + +".type VG_MINIMAL_SETJMP, @function" "\n" +".L.VG_MINIMAL_SETJMP:" "\n" +" std 0, 0(3)" "\n" +" std 1, 8(3)" "\n" +" std 2, 16(3)" "\n" +" std 3, 24(3)" "\n" +" std 4, 32(3)" "\n" +" std 5, 40(3)" "\n" +" std 6, 48(3)" "\n" +" std 7, 56(3)" "\n" +" std 8, 64(3)" "\n" +" std 9, 72(3)" "\n" +" std 10, 80(3)" "\n" +" std 11, 88(3)" "\n" +" std 12, 96(3)" "\n" +" std 13, 104(3)" "\n" +" std 14, 112(3)" "\n" +" std 15, 120(3)" "\n" +" std 16, 128(3)" "\n" +" std 17, 136(3)" "\n" +" std 18, 144(3)" "\n" +" std 19, 152(3)" "\n" +" std 20, 160(3)" "\n" +" std 21, 168(3)" "\n" +" std 22, 176(3)" "\n" +" std 23, 184(3)" "\n" +" std 24, 192(3)" "\n" +" std 25, 200(3)" "\n" +" std 26, 208(3)" "\n" +" std 27, 216(3)" "\n" +" std 28, 224(3)" "\n" +" std 29, 232(3)" "\n" +" std 30, 240(3)" "\n" +" std 31, 248(3)" "\n" + // must use a caller-save register here as scratch, hence r4 +" mflr 4" "\n" +" std 4, 256(3)" "\n" +" mfcr 4" "\n" +" std 4, 264(3)" "\n" +" li 3, 0" "\n" +" blr" "\n" +"" "\n" + + +".globl VG_MINIMAL_LONGJMP" "\n" + +".section \".opd\",\"aw\"" "\n" +".align 3" "\n" +"VG_MINIMAL_LONGJMP:" "\n" +".quad .L.VG_MINIMAL_LONGJMP,.TOC.@tocbase,0" "\n" +".previous" "\n" + +".type VG_MINIMAL_LONGJMP, @function" "\n" +".L.VG_MINIMAL_LONGJMP:" "\n" + // do r4 = 1 + // and park it in the restore slot for r3 (the ret reg) +" li 4, 1" "\n" +" std 4, 24(3)" "\n" + // restore everything except r3 + // then r3 last of all + // then blr +" ld 0, 256(3)" "\n" +" mtlr 0" "\n" +" ld 0, 264(3)" "\n" +" mtcr 0" "\n" +" ld 0, 0(3)" "\n" +" ld 1, 8(3)" "\n" +" ld 2, 16(3)" "\n" + // r3 is done at the end +" ld 4, 32(3)" "\n" +" ld 5, 40(3)" "\n" +" ld 6, 48(3)" "\n" +" ld 7, 56(3)" "\n" +" ld 8, 64(3)" "\n" +" ld 9, 72(3)" "\n" +" ld 10, 80(3)" "\n" +" ld 11, 88(3)" "\n" +" ld 12, 96(3)" "\n" +" ld 13, 104(3)" "\n" +" ld 14, 112(3)" "\n" +" ld 15, 120(3)" "\n" +" ld 16, 128(3)" "\n" +" ld 17, 136(3)" "\n" +" ld 18, 144(3)" "\n" +" ld 19, 152(3)" "\n" +" ld 20, 160(3)" "\n" +" ld 21, 168(3)" "\n" +" ld 22, 176(3)" "\n" +" ld 23, 184(3)" "\n" +" ld 24, 192(3)" "\n" +" ld 25, 200(3)" "\n" +" ld 26, 208(3)" "\n" +" ld 27, 216(3)" "\n" +" ld 28, 224(3)" "\n" +" ld 29, 232(3)" "\n" +" ld 30, 240(3)" "\n" +" ld 31, 248(3)" "\n" +" ld 3, 24(3)" "\n" +" blr" "\n" +"" "\n" + +".previous" "\n" +".previous" "\n" +); + + +#endif /* VGP_ppc64_linux */ + /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/include/pub_tool_libcsetjmp.h b/include/pub_tool_libcsetjmp.h index 4a17f7a356..3c0f15cd20 100644 --- a/include/pub_tool_libcsetjmp.h +++ b/include/pub_tool_libcsetjmp.h @@ -71,6 +71,12 @@ Int VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env)); void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env)); +#elif defined(VGP_ppc64_linux) + +#define VG_MINIMAL_JMP_BUF(_name) ULong _name [32+1+1] +Int VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env)); +void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env)); + #else /* The default implementation. */