-
-
Notifications
You must be signed in to change notification settings - Fork 560
/
context_arm.S
205 lines (178 loc) · 7.57 KB
/
context_arm.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
Copyright Oliver Kowalke 2009.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* //////////////////////////////////////////////////////////////////////////////////////
* macros
*/
#ifdef TB_CONFIG_OS_IOS
# define TB_CONTEXT_SJLJ_BYTES 4
#else
# define TB_CONTEXT_SJLJ_BYTES 0
#endif
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
/* make context (refer to boost.context)
*
*
* --------------------------------------------------------------------------------------
* stackdata: | | context ||
* --------------------------------------------------------------------------------------
* (16-align)
*
* for macho (ios):
*
* save and restore the sjlj(setjmp/longjmp) exception handler on tls
*
* -------------------------------------------------------
* context: | sjlj | retval | r4 | r5 | r6 | r7 |
* -------------------------------------------------------
* 0 4 | 8 12 16 20
* |
* ------------------------------------------------
* \|/
* __end func retval(from)
* --------------------------------------------------------------------------------------
* | r8 | r9 | r10 | r11 | lr | pc | context | priv | padding |
* --------------------------------------------------------------------------------------
* 24 28 32 36 40 44 48 52 |
* | |
* | 16-align
* |
* sp when jump to function
*
* for elf (linux, ..):
*
* -----------------------------------------------
* context: | retval | r4 | r5 | r6 | r7 |
* -----------------------------------------------
* 0 | 4 8 12 16
* |
* ---------------------------------------------------------
* \|/
* __end func retval(from)
* --------------------------------------------------------------------------------------
* | r8 | r9 | r10 | r11 | lr | pc | context | priv | padding |
* --------------------------------------------------------------------------------------
* 20 24 28 32 36 40 44 48 |
* | |
* | 16-align
* |
* sp when jump to function
*
*
* @param stackdata the stack data (r0)
* @param stacksize the stack size (r1)
* @param func the entry function (r2)
*
* @return the context pointer (r0)
*/
function tb_context_make, export=1
// save the stack top to r0
add r0, r0, r1
// 16-align of the stack top address
bic r0, r0, #15
/* reserve space for context-data on context-stack
*
* 64 = align8(52 + TB_CONTEXT_SJLJ_BYTES)
*/
sub r0, r0, #64
// context.pc = func
str r2, [r0, #40 + TB_CONTEXT_SJLJ_BYTES]
/* init retval = a writeable space (context)
*
* it will write retval(context, priv) when jump to a new context function entry first
*/
add r1, r0, #44 + TB_CONTEXT_SJLJ_BYTES
str r1, [r0, #0 + TB_CONTEXT_SJLJ_BYTES]
// context.lr = address of label __end
adr r1, __end
str r1, [r0, #36 + TB_CONTEXT_SJLJ_BYTES]
// return pointer to context-data
bx lr
__end:
// exit(0)
mov r0, #0
#ifdef __ELF__
bl _exit@PLT
#else
bl __exit
#endif
endfunc
/* jump context (refer to boost.context)
*
* @param retval the from-context (r0)
* @param context the to-context (r1)
* @param priv the passed user private data (r2)
*
* @return the from-context (retval)
*/
function tb_context_jump, export=1
// save lr as pc
push {lr}
// save retval, r4 - r11, lr
push {r0, r4 - r11, lr}
#ifdef TB_CONFIG_OS_IOS
// load tls to save or restore sjlj handler
mrc p15, 0, r5, c13, c0, #3
bic r5, r5, #3
// load and save sjlj handler: tls[__PTK_LIBC_DYLD_Unwind_SjLj_Key]
ldr r4, [r5, #8]
push {r4}
#endif
// save the old context(sp) to r0
mov r0, sp
// switch to the new context(sp) and stack
mov sp, r1
#ifdef TB_CONFIG_OS_IOS
// restore sjlj handler
pop {r4}
str r4, [r5, #8]
#endif
// restore retval, r4 - r11, lr
pop {r3, r4 - r11, lr}
// return from-context: retval(context: r0, priv: r2) from jump
str r0, [r3, #0]
str r2, [r3, #4]
// pass old-context(context: r0, priv: r1 = r2) arguments to the context function
mov r1, r2
/* jump to the return or entry address(pc)
*
* func retval(from)
* ---------------------------------------
* context: | pc | context | priv | padding |
* ---------------------------------------
* 0 4 8
* |
* sp
*/
pop {pc}
endfunc