| 1 |
module setjump; |
|---|
| 2 |
// setjmp.c |
|---|
| 3 |
// |
|---|
| 4 |
// Non-local goto |
|---|
| 5 |
// |
|---|
| 6 |
// Copyright (C) 2002 Michael Ringgaard. All rights reserved. |
|---|
| 7 |
// |
|---|
| 8 |
// Redistribution and use in source and binary forms, with or without |
|---|
| 9 |
// modification, are permitted provided that the following conditions |
|---|
| 10 |
// are met: |
|---|
| 11 |
// |
|---|
| 12 |
// 1. Redistributions of source code must retain the above copyright |
|---|
| 13 |
// notice, this list of conditions and the following disclaimer. |
|---|
| 14 |
// 2. Redistributions in binary form must reproduce the above copyright |
|---|
| 15 |
// notice, this list of conditions and the following disclaimer in the |
|---|
| 16 |
// documentation and/or other materials provided with the distribution. |
|---|
| 17 |
// 3. Neither the name of the project nor the names of its contributors |
|---|
| 18 |
// may be used to endorse or promote products derived from this software |
|---|
| 19 |
// without specific prior written permission. |
|---|
| 20 |
// |
|---|
| 21 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|---|
| 22 |
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|---|
| 23 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|---|
| 24 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
|---|
| 25 |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|---|
| 26 |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|---|
| 27 |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|---|
| 28 |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|---|
| 29 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|---|
| 30 |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|---|
| 31 |
// SUCH DAMAGE. |
|---|
| 32 |
// |
|---|
| 33 |
|
|---|
| 34 |
struct jmp_buf |
|---|
| 35 |
{ |
|---|
| 36 |
ulong ebp; |
|---|
| 37 |
ulong ebx; |
|---|
| 38 |
ulong edi; |
|---|
| 39 |
ulong esi; |
|---|
| 40 |
ulong esp; |
|---|
| 41 |
ulong eip; |
|---|
| 42 |
} |
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
const OFS_EBP= 0; |
|---|
| 46 |
const OFS_EBX= 4; |
|---|
| 47 |
const OFS_EDI= 8; |
|---|
| 48 |
const OFS_ESI= 12; |
|---|
| 49 |
const OFS_ESP= 16; |
|---|
| 50 |
const OFS_EIP= 20; |
|---|
| 51 |
extern (C) |
|---|
| 52 |
{ |
|---|
| 53 |
int setjmp(ref jmp_buf env) |
|---|
| 54 |
{ |
|---|
| 55 |
asm |
|---|
| 56 |
{ |
|---|
| 57 |
naked; |
|---|
| 58 |
mov EDX, 4[ESP] ; // Get jmp_buf pointer |
|---|
| 59 |
mov EAX, [ESP] ; // Save EIP |
|---|
| 60 |
mov OFS_EIP[EDX], EAX; |
|---|
| 61 |
mov OFS_EBP[EDX], EBP; // Save EBP, EBX, EDI, ESI, and ESP |
|---|
| 62 |
mov OFS_EBX[EDX], EBX; |
|---|
| 63 |
mov OFS_EDI[EDX], EDI; |
|---|
| 64 |
mov OFS_ESI[EDX], ESI; |
|---|
| 65 |
mov OFS_ESP[EDX], ESP; |
|---|
| 66 |
add ESP,8; |
|---|
| 67 |
push EAX; |
|---|
| 68 |
xor EAX, EAX; // Return 0 |
|---|
| 69 |
ret; |
|---|
| 70 |
}; |
|---|
| 71 |
} |
|---|
| 72 |
|
|---|
| 73 |
void longjmp(ref jmp_buf env, int value) |
|---|
| 74 |
{ |
|---|
| 75 |
asm |
|---|
| 76 |
{ |
|---|
| 77 |
naked ; |
|---|
| 78 |
mov EDX, 4[ESP] ; // Get jmp_buf pointer |
|---|
| 79 |
mov EAX, 8[ESP] ; // Get return value (eax) |
|---|
| 80 |
|
|---|
| 81 |
mov ESP, OFS_ESP[EDX]; // Switch to new stack position |
|---|
| 82 |
mov EBX, OFS_EIP[EDX]; // Get new EIP value and set as return address |
|---|
| 83 |
mov [ESP], EBX; |
|---|
| 84 |
|
|---|
| 85 |
mov EBP, OFS_EBP[EDX]; // Restore EBP, EBX, EDI, and ESI |
|---|
| 86 |
mov EBX, OFS_EBX[EDX]; |
|---|
| 87 |
mov EDI, OFS_EDI[EDX]; |
|---|
| 88 |
mov ESI, OFS_ESI[EDX]; |
|---|
| 89 |
|
|---|
| 90 |
ret; |
|---|
| 91 |
}; |
|---|
| 92 |
} |
|---|
| 93 |
} |
|---|