/*--------------------------------------------------------------------*/ /*--- A minimal setjmp/longjmp implementation. m_libcsetjmp.c ---*/ /*--------------------------------------------------------------------*/ /* This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2010-2010 Mozilla Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. The GNU General Public License is contained in the file COPYING. */ /* Contributed by Julian Seward */ #include "pub_core_basics.h" #include "pub_core_libcsetjmp.h" /* self */ /* See include/pub_tool_libcsetjmp.h for background and rationale. */ /* The only alternative implementations are for ppc{32,64}-linux. See #259977. */ /* ------------ ppc32-linux ------------ */ #if defined(VGP_ppc32_linux) __asm__( ".text" "\n" "" "\n" ".global VG_MINIMAL_SETJMP" "\n" // r3 = jmp_buf "VG_MINIMAL_SETJMP:" "\n" " stw 0, 0(3)" "\n" " stw 1, 4(3)" "\n" " stw 2, 8(3)" "\n" " stw 3, 12(3)" "\n" " stw 4, 16(3)" "\n" " stw 5, 20(3)" "\n" " stw 6, 24(3)" "\n" " stw 7, 28(3)" "\n" " stw 8, 32(3)" "\n" " stw 9, 36(3)" "\n" " stw 10, 40(3)" "\n" " stw 11, 44(3)" "\n" " stw 12, 48(3)" "\n" " stw 13, 52(3)" "\n" " stw 14, 56(3)" "\n" " stw 15, 60(3)" "\n" " stw 16, 64(3)" "\n" " stw 17, 68(3)" "\n" " stw 18, 72(3)" "\n" " stw 19, 76(3)" "\n" " stw 20, 80(3)" "\n" " stw 21, 84(3)" "\n" " stw 22, 88(3)" "\n" " stw 23, 92(3)" "\n" " stw 24, 96(3)" "\n" " stw 25, 100(3)" "\n" " stw 26, 104(3)" "\n" " stw 27, 108(3)" "\n" " stw 28, 112(3)" "\n" " stw 29, 116(3)" "\n" " stw 30, 120(3)" "\n" " stw 31, 124(3)" "\n" // must use a caller-save register here as scratch, hence r4 " mflr 4" "\n" " stw 4, 128(3)" "\n" " mfcr 4" "\n" " stw 4, 132(3)" "\n" " li 3, 0" "\n" " blr" "\n" "" "\n" ".global VG_MINIMAL_LONGJMP" "\n" "VG_MINIMAL_LONGJMP:" "\n" // r3 = jmp_buf // do r4 = 1 // and park it in the restore slot for r3 (the ret reg) " li 4, 1" "\n" " stw 4, 12(3)" "\n" // restore everything except r3 // then r3 last of all // then blr " lwz 0, 128(3)" "\n" " mtlr 0" "\n" " lwz 0, 132(3)" "\n" " mtcr 0" "\n" " lwz 0, 0(3)" "\n" " lwz 1, 4(3)" "\n" " lwz 2, 8(3)" "\n" // r3 is done at the end " lwz 4, 16(3)" "\n" " lwz 5, 20(3)" "\n" " lwz 6, 24(3)" "\n" " lwz 7, 28(3)" "\n" " lwz 8, 32(3)" "\n" " lwz 9, 36(3)" "\n" " lwz 10, 40(3)" "\n" " lwz 11, 44(3)" "\n" " lwz 12, 48(3)" "\n" " lwz 13, 52(3)" "\n" " lwz 14, 56(3)" "\n" " lwz 15, 60(3)" "\n" " lwz 16, 64(3)" "\n" " lwz 17, 68(3)" "\n" " lwz 18, 72(3)" "\n" " lwz 19, 76(3)" "\n" " lwz 20, 80(3)" "\n" " lwz 21, 84(3)" "\n" " lwz 22, 88(3)" "\n" " lwz 23, 92(3)" "\n" " lwz 24, 96(3)" "\n" " lwz 25, 100(3)" "\n" " lwz 26, 104(3)" "\n" " lwz 27, 108(3)" "\n" " lwz 28, 112(3)" "\n" " lwz 29, 116(3)" "\n" " lwz 30, 120(3)" "\n" " lwz 31, 124(3)" "\n" " lwz 3, 12(3)" "\n" " blr" "\n" "" "\n" ".previous" "\n" ); #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 ---*/ /*--------------------------------------------------------------------*/