Skip to content

Commit 8339488

Browse files
Implement setjmp / longjmp in jerry-libc.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan [email protected]
1 parent 90b197d commit 8339488

File tree

7 files changed

+464
-2
lines changed

7 files changed

+464
-2
lines changed

jerry-libc/arch/arm-v7.h

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,88 @@
8080
\
8181
pop {r4-r12, pc};
8282

83+
/*
84+
* ldr argc ([sp + 0x0]) -> r0
85+
* add argv (sp + 0x4) -> r1
86+
*
87+
* bl main
88+
*
89+
* bl exit
90+
*
91+
* infinite loop
92+
*/
8393
#define _START \
8494
ldr r0, [sp, #0]; \
8595
add r1, sp, #4; \
8696
bl main; \
8797
\
88-
bl exit; \
98+
bl exit; \
8999
1: \
90100
b 1b
91101

102+
103+
/*
104+
* setjmp
105+
*
106+
* According to procedure call standard for the ARM architecture, the following
107+
* registers are callee-saved, and so need to be stored in context:
108+
* - r4 - r11
109+
* - sp
110+
* - s16-s31
111+
*
112+
* Also, we should store:
113+
* - lr
114+
*
115+
* stmia {r4-r11, sp, lr} -> jmp_buf_0 (r0)!
116+
*
117+
* FIXME:
118+
* vstm should not be performed in softfp mode
119+
* vstm {s16-s31} -> jmp_buf_32 (r0)!
120+
*
121+
* mov r0, #0
122+
*
123+
* bx lr
124+
*/
125+
#define _SETJMP \
126+
stmia r0!, {r4 - r11, sp, lr}; \
127+
\
128+
vstm r0!, {s16 - s31}; \
129+
\
130+
mov r0, #0; \
131+
\
132+
bx lr;
133+
134+
/*
135+
* longjmp
136+
*
137+
* See also:
138+
* _SETJMP
139+
*
140+
* ldmia jmp_buf_0 (r0)! -> {r4-r11, sp, lr}
141+
*
142+
* FIXME:
143+
* vstm should not be performed in softfp mode
144+
* vldm jmp_buf_32 (r0)! -> {s16-s31}
145+
*
146+
* mov r1 -> r0
147+
* cmp r0, #0
148+
* bne 1f
149+
* mov #1 -> r0
150+
* 1:
151+
*
152+
* bx lr
153+
*/
154+
#define _LONGJMP \
155+
ldmia r0!, {r4 - r11, sp, lr}; \
156+
\
157+
vldm r0!, {s16 - s31}; \
158+
\
159+
mov r0, r1; \
160+
cmp r0, #0; \
161+
bne 1f; \
162+
mov r0, #1; \
163+
1: \
164+
\
165+
bx lr;
166+
92167
#endif /* !ASM_ARM_H */

jerry-libc/arch/x86-32.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@
9292
pop %edi; \
9393
ret;
9494

95+
/*
96+
* push argv (%esp + 4)
97+
* push argc ([%esp + 0x4])
98+
*
99+
* call main
100+
*
101+
* push main_ret (%eax)
102+
* call exit
103+
*
104+
* infinite loop
105+
*/
95106
#define _START \
96107
mov %esp, %eax; \
97108
add $4, %eax; \
@@ -103,7 +114,100 @@
103114
\
104115
push %eax; \
105116
call exit; \
117+
\
106118
1: \
107119
jmp 1b
108120

121+
/*
122+
* setjmp
123+
*
124+
* According to x86_32 System V ABI, the following registers are
125+
* callee-saved, and so need to be stored in context:
126+
* - %ebx
127+
* - %esp
128+
* - %ebp
129+
* - %esi
130+
* - %edi
131+
* - x87 control word
132+
*
133+
* Also, we should store:
134+
* - return address (to jump to upon longjmp)
135+
*
136+
* mov return_address ([%esp]) -> %eax
137+
*
138+
* mov env ([%esp + 0x4]) -> %edx
139+
*
140+
* mov %ebx -> jmp_buf_0 ([%edx + 0x0])
141+
* mov %esp -> jmp_buf_4 ([%edx + 0x4])
142+
* mov %ebp -> jmp_buf_8 ([%edx + 0x8])
143+
* mov %esi -> jmp_buf_12 ([%edx + 0xc])
144+
* mov %edi -> jmp_buf_16 ([%edx + 0x10])
145+
* mov %eax -> jmp_buf_20 ([%edx + 0x14])
146+
* fnstcw -> jmp_buf_24 ([%edx + 0x18])
147+
*
148+
* ret
149+
*/
150+
#define _SETJMP \
151+
mov (%esp), %eax; \
152+
mov 0x4 (%esp), %edx; \
153+
\
154+
mov %ebx, 0x00 (%edx); \
155+
mov %esp, 0x04 (%edx); \
156+
mov %ebp, 0x08 (%edx); \
157+
mov %esi, 0x0c (%edx); \
158+
mov %edi, 0x10 (%edx); \
159+
mov %eax, 0x14 (%edx); \
160+
fnstcw 0x18 (%edx); \
161+
\
162+
xor %eax, %eax; \
163+
\
164+
ret
165+
166+
/*
167+
* longjmp
168+
*
169+
* See also:
170+
* _SETJMP
171+
*
172+
* mov env ([%esp + 0x4]) -> %edx
173+
* mov val ([%esp + 0x8]) -> %eax
174+
*
175+
* mov jmp_buf_0 ([%edx + 0x0]) -> %ebx
176+
* mov jmp_buf_4 ([%edx + 0x8]) -> %esp
177+
* mov jmp_buf_8 ([%edx + 0x10]) -> %ebp
178+
* mov jmp_buf_12 ([%edx + 0x18]) -> %esi
179+
* mov jmp_buf_16 ([%edx + 0x20]) -> %edi
180+
* mov jmp_buf_20 ([%edx + 0x28]) -> %ecx
181+
* fldcw jmp_buf_24 ([%edx + 0x30])
182+
*
183+
* mov return_address (%ecx) -> ([%esp])
184+
*
185+
* cmp (%eax), 0x0
186+
* jnz 1f
187+
* xor %eax, %eax
188+
* 1:
189+
*
190+
* ret
191+
*/
192+
#define _LONGJMP \
193+
mov 0x4 (%esp), %edx; \
194+
mov 0x8 (%esp), %eax; \
195+
\
196+
mov 0x0 (%edx), %ebx; \
197+
mov 0x4 (%edx), %esp; \
198+
mov 0x8 (%edx), %ebp; \
199+
mov 0xc (%edx), %esi; \
200+
mov 0x10 (%edx), %edi; \
201+
mov 0x14 (%edx), %ecx; \
202+
fldcw 0x18 (%edx); \
203+
\
204+
mov %ecx, (%esp); \
205+
\
206+
test %eax, %eax; \
207+
jnz 1f; \
208+
xor %eax, %eax; \
209+
1: \
210+
\
211+
ret
212+
109213
#endif /* !ASM_X86_H */

jerry-libc/arch/x86-64.h

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,125 @@
6464
syscall; \
6565
ret;
6666

67+
/*
68+
* mov argc ([%rsp]) -> %rdi
69+
* mov argv (%rsp + 0x8) -> %rsi
70+
*
71+
* call main
72+
*
73+
* mov main_ret (%rax) -> %rdi
74+
* call exit
75+
*
76+
* infinite loop
77+
*/
6778
#define _START \
6879
mov (%rsp), %rdi; \
6980
mov %rsp, %rsi; \
7081
add $8, %rsi; \
7182
callq main; \
7283
\
7384
mov %rax, %rdi; \
74-
callq exit; \
85+
callq exit; \
7586
1: \
7687
jmp 1b
7788

89+
/*
90+
* setjmp
91+
*
92+
* According to x86_64 System V ABI, the following registers are
93+
* callee-saved, and so need to be stored in context:
94+
* - %rbp
95+
* - %rbx
96+
* - %r12
97+
* - %r13
98+
* - %r14
99+
* - %r15
100+
* - x87 control word
101+
*
102+
* Also, we should store:
103+
* - %rsp (stack pointer)
104+
* - return address (to jump to upon longjmp)
105+
*
106+
* mov return_address ([%rsp]) -> %rax
107+
*
108+
* mov %rsp -> jmp_buf_0 ([%rdi + 0x0])
109+
* mov %rax -> jmp_buf_8 ([%rdi + 0x8])
110+
* mov %rbp -> jmp_buf_16 ([%rdi + 0x10])
111+
* mov %rbx -> jmp_buf_24 ([%rdi + 0x18])
112+
* mov %r12 -> jmp_buf_32 ([%rdi + 0x20])
113+
* mov %r13 -> jmp_buf_40 ([%rdi + 0x28])
114+
* mov %r14 -> jmp_buf_48 ([%rdi + 0x30])
115+
* mov %r15 -> jmp_buf_56 ([%rdi + 0x38])
116+
* fnstcw -> jmp_buf_64 ([%rdi + 0x40])
117+
*
118+
* ret
119+
*/
120+
#define _SETJMP \
121+
mov (%rsp), %rax; \
122+
\
123+
mov %rsp, 0x00(%rdi); \
124+
mov %rax, 0x08(%rdi); \
125+
mov %rbp, 0x10(%rdi); \
126+
mov %rbx, 0x18(%rdi); \
127+
mov %r12, 0x20(%rdi); \
128+
mov %r13, 0x28(%rdi); \
129+
mov %r14, 0x30(%rdi); \
130+
mov %r15, 0x38(%rdi); \
131+
fnstcw 0x40(%rdi); \
132+
\
133+
xor %rax, %rax; \
134+
\
135+
ret;
136+
137+
/*
138+
* longjmp
139+
*
140+
* See also:
141+
* _SETJMP
142+
*
143+
* mov jmp_buf_0 ([%rdi + 0x0]) -> %rsp
144+
* mov jmp_buf_8 ([%rdi + 0x8]) -> %rax
145+
* mov jmp_buf_16 ([%rdi + 0x10]) -> %rbp
146+
* mov jmp_buf_24 ([%rdi + 0x18]) -> %rbx
147+
* mov jmp_buf_32 ([%rdi + 0x20]) -> %r12
148+
* mov jmp_buf_40 ([%rdi + 0x28]) -> %r13
149+
* mov jmp_buf_48 ([%rdi + 0x30]) -> %r14
150+
* mov jmp_buf_56 ([%rdi + 0x38]) -> %r15
151+
* fldcw jmp_buf_64 ([%rdi + 0x40])
152+
*
153+
* mov return_address (%rax) -> ([%rsp])
154+
*
155+
* mov val (%rsi) -> %rax
156+
*
157+
* test (%rax), (%rax)
158+
* jnz 1f
159+
* mov $1, %rax
160+
* 1:
161+
*
162+
* ret
163+
*/
164+
#define _LONGJMP \
165+
mov 0x00(%rdi), %rsp; \
166+
mov 0x08(%rdi), %rax; \
167+
mov 0x10(%rdi), %rbp; \
168+
mov 0x18(%rdi), %rbx; \
169+
mov 0x20(%rdi), %r12; \
170+
mov 0x28(%rdi), %r13; \
171+
mov 0x30(%rdi), %r14; \
172+
mov 0x38(%rdi), %r15; \
173+
fldcw 0x40(%rdi); \
174+
\
175+
mov %rax, (%rsp); \
176+
\
177+
mov %rsi, %rax; \
178+
\
179+
test %rax, %rax; \
180+
jnz 1f; \
181+
mov $1, %rax; \
182+
1: \
183+
\
184+
ret
185+
186+
187+
78188
#endif /* !ASM_X64_H */

jerry-libc/include/setjmp.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* Copyright 2015 Samsung Electronics Co., Ltd.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#ifndef JERRY_LIBC_SETJMP_H
17+
#define JERRY_LIBC_SETJMP_H
18+
19+
#ifdef __cplusplus
20+
# define EXTERN_C "C"
21+
#else /* !__cplusplus */
22+
# define EXTERN_C
23+
#endif /* !__cplusplus */
24+
25+
/**
26+
* Storage for context, used for nonlocal goto
27+
*
28+
* x86_64 (8 * 8 + 2 bytes):
29+
* 0x00 - %rsp
30+
* 0x08 - return address
31+
* 0x10 - %rbp
32+
* 0x18 - %rbx
33+
* 0x20 - %r12
34+
* 0x28 - %r13
35+
* 0x30 - %r14
36+
* 0x38 - %r15
37+
* 0x40 - x87 control word
38+
*
39+
* x86_32 (6 * 4 + 2 bytes):
40+
* - %ebx
41+
* - %esp
42+
* - %ebp
43+
* - %esi
44+
* - %edi
45+
* - return address (to jump to upon longjmp)
46+
* - x87 control word
47+
*
48+
* ARMv7 (8 * 4 + 16 * 4 bytes):
49+
* - r4 - r11
50+
* - s16 - s31 (if hardfp enabled)
51+
*
52+
* See also:
53+
* setjmp, longjmp
54+
*/
55+
typedef uint64_t jmp_buf[12];
56+
57+
extern EXTERN_C int setjmp (jmp_buf env);
58+
extern EXTERN_C void longjmp (jmp_buf env, int val);
59+
60+
#endif /* !JERRY_LIBC_SETJMP_H */

0 commit comments

Comments
 (0)