Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/libunwind/src/UnwindRegistersSave.S
6175 views
1
//===----------------------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "assembly.h"
10
11
#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
12
#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
13
14
#define FROM_0_TO_31 0,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
15
#define FROM_32_TO_63 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
16
17
#if defined(_AIX)
18
.toc
19
#else
20
.text
21
#endif
22
23
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)
24
25
#if defined(__i386__)
26
27
#
28
# extern int __unw_getcontext(unw_context_t* thread_state)
29
#
30
# On entry:
31
# + +
32
# +-----------------------+
33
# + thread_state pointer +
34
# +-----------------------+
35
# + return address +
36
# +-----------------------+ <-- SP
37
# + +
38
#
39
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
40
41
_LIBUNWIND_CET_ENDBR
42
push %eax
43
movl 8(%esp), %eax
44
movl %ebx, 4(%eax)
45
movl %ecx, 8(%eax)
46
movl %edx, 12(%eax)
47
movl %edi, 16(%eax)
48
movl %esi, 20(%eax)
49
movl %ebp, 24(%eax)
50
movl %esp, %edx
51
addl $8, %edx
52
movl %edx, 28(%eax) # store what sp was at call site as esp
53
# skip ss
54
# skip eflags
55
movl 4(%esp), %edx
56
movl %edx, 40(%eax) # store return address as eip
57
# skip cs
58
# skip ds
59
# skip es
60
# skip fs
61
# skip gs
62
movl (%esp), %edx
63
movl %edx, (%eax) # store original eax
64
popl %eax
65
xorl %eax, %eax # return UNW_ESUCCESS
66
ret
67
68
#elif defined(__arm64ec__)
69
70
//
71
// extern int __unw_getcontext(unw_context_t* thread_state)
72
//
73
// On entry:
74
// thread_state pointer is in x0
75
//
76
.section .text,"xr",discard,"#__unw_getcontext"
77
.p2align 2
78
DEFINE_LIBUNWIND_FUNCTION("#__unw_getcontext")
79
stp x8, x27, [x0, #0x000] // rax, rbx
80
stp x0, x1, [x0, #0x010] // rcx, rdx
81
stp x26,x25, [x0, #0x020] // rdi, rsi
82
mov x1, sp
83
stp fp, x1, [x0, #0x030] // rbp, rsp
84
stp x2, x3, [x0, #0x040] // r8, r9
85
stp x4, x5, [x0, #0x050] // r10, r11
86
stp x19,x20, [x0, #0x060] // r12, r13
87
stp x21,x22, [x0, #0x070] // r14, r15
88
str x30, [x0, #0x080] // store return address as pc
89
stp q0, q1, [x0, #0x0b0] // xmm0, xmm1
90
stp q2, q3, [x0, #0x0d0] // xmm2, xmm3
91
stp q4, q5, [x0, #0x0f0] // xmm4, xmm5
92
stp q6, q7, [x0, #0x110] // xmm6, xmm7
93
stp q8, q9, [x0, #0x130] // xmm8, xmm9
94
stp q10,q11, [x0, #0x150] // xmm10,xmm11
95
stp q12,q13, [x0, #0x170] // xmm12,xmm13
96
stp q14,q15, [x0, #0x190] // xmm14,xmm15
97
mov x0, #0 // return UNW_ESUCCESS
98
ret
99
100
.weak_anti_dep __unw_getcontext
101
.set __unw_getcontext, "#__unw_getcontext"
102
103
.section .hybmp$x,"yi"
104
.symidx "#__unw_getcontext"
105
.symidx $ientry_thunk$cdecl$i8$i8
106
.word 1
107
.text
108
109
#elif defined(__x86_64__)
110
111
#
112
# extern int __unw_getcontext(unw_context_t* thread_state)
113
#
114
# On entry:
115
# thread_state pointer is in rdi
116
#
117
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
118
#if defined(_WIN64)
119
#define PTR %rcx
120
#define TMP %rdx
121
#else
122
#define PTR %rdi
123
#define TMP %rsi
124
#endif
125
126
_LIBUNWIND_CET_ENDBR
127
movq %rax, (PTR)
128
movq %rbx, 8(PTR)
129
movq %rcx, 16(PTR)
130
movq %rdx, 24(PTR)
131
movq %rdi, 32(PTR)
132
movq %rsi, 40(PTR)
133
movq %rbp, 48(PTR)
134
movq %rsp, 56(PTR)
135
addq $8, 56(PTR)
136
movq %r8, 64(PTR)
137
movq %r9, 72(PTR)
138
movq %r10, 80(PTR)
139
movq %r11, 88(PTR)
140
movq %r12, 96(PTR)
141
movq %r13,104(PTR)
142
movq %r14,112(PTR)
143
movq %r15,120(PTR)
144
movq (%rsp),TMP
145
movq TMP,128(PTR) # store return address as rip
146
# skip rflags
147
# skip cs
148
# skip fs
149
# skip gs
150
151
#if defined(_WIN64)
152
movdqu %xmm0,176(PTR)
153
movdqu %xmm1,192(PTR)
154
movdqu %xmm2,208(PTR)
155
movdqu %xmm3,224(PTR)
156
movdqu %xmm4,240(PTR)
157
movdqu %xmm5,256(PTR)
158
movdqu %xmm6,272(PTR)
159
movdqu %xmm7,288(PTR)
160
movdqu %xmm8,304(PTR)
161
movdqu %xmm9,320(PTR)
162
movdqu %xmm10,336(PTR)
163
movdqu %xmm11,352(PTR)
164
movdqu %xmm12,368(PTR)
165
movdqu %xmm13,384(PTR)
166
movdqu %xmm14,400(PTR)
167
movdqu %xmm15,416(PTR)
168
#endif
169
xorl %eax, %eax # return UNW_ESUCCESS
170
ret
171
172
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
173
174
#
175
# extern int __unw_getcontext(unw_context_t* thread_state)
176
#
177
# On entry:
178
# thread_state pointer is in a0 ($4)
179
#
180
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
181
.set push
182
.set noat
183
.set noreorder
184
.set nomacro
185
sw $1, (4 * 1)($4)
186
sw $2, (4 * 2)($4)
187
sw $3, (4 * 3)($4)
188
sw $4, (4 * 4)($4)
189
sw $5, (4 * 5)($4)
190
sw $6, (4 * 6)($4)
191
sw $7, (4 * 7)($4)
192
sw $8, (4 * 8)($4)
193
sw $9, (4 * 9)($4)
194
sw $10, (4 * 10)($4)
195
sw $11, (4 * 11)($4)
196
sw $12, (4 * 12)($4)
197
sw $13, (4 * 13)($4)
198
sw $14, (4 * 14)($4)
199
sw $15, (4 * 15)($4)
200
sw $16, (4 * 16)($4)
201
sw $17, (4 * 17)($4)
202
sw $18, (4 * 18)($4)
203
sw $19, (4 * 19)($4)
204
sw $20, (4 * 20)($4)
205
sw $21, (4 * 21)($4)
206
sw $22, (4 * 22)($4)
207
sw $23, (4 * 23)($4)
208
sw $24, (4 * 24)($4)
209
sw $25, (4 * 25)($4)
210
sw $26, (4 * 26)($4)
211
sw $27, (4 * 27)($4)
212
sw $28, (4 * 28)($4)
213
sw $29, (4 * 29)($4)
214
sw $30, (4 * 30)($4)
215
sw $31, (4 * 31)($4)
216
# Store return address to pc
217
sw $31, (4 * 32)($4)
218
#if __mips_isa_rev < 6
219
# hi and lo
220
mfhi $8
221
sw $8, (4 * 33)($4)
222
mflo $8
223
sw $8, (4 * 34)($4)
224
#endif
225
#ifdef __mips_hard_float
226
#if __mips_fpr != 64
227
sdc1 $f0, (4 * 36 + 8 * 0)($4)
228
sdc1 $f2, (4 * 36 + 8 * 2)($4)
229
sdc1 $f4, (4 * 36 + 8 * 4)($4)
230
sdc1 $f6, (4 * 36 + 8 * 6)($4)
231
sdc1 $f8, (4 * 36 + 8 * 8)($4)
232
sdc1 $f10, (4 * 36 + 8 * 10)($4)
233
sdc1 $f12, (4 * 36 + 8 * 12)($4)
234
sdc1 $f14, (4 * 36 + 8 * 14)($4)
235
sdc1 $f16, (4 * 36 + 8 * 16)($4)
236
sdc1 $f18, (4 * 36 + 8 * 18)($4)
237
sdc1 $f20, (4 * 36 + 8 * 20)($4)
238
sdc1 $f22, (4 * 36 + 8 * 22)($4)
239
sdc1 $f24, (4 * 36 + 8 * 24)($4)
240
sdc1 $f26, (4 * 36 + 8 * 26)($4)
241
sdc1 $f28, (4 * 36 + 8 * 28)($4)
242
sdc1 $f30, (4 * 36 + 8 * 30)($4)
243
#else
244
sdc1 $f0, (4 * 36 + 8 * 0)($4)
245
sdc1 $f1, (4 * 36 + 8 * 1)($4)
246
sdc1 $f2, (4 * 36 + 8 * 2)($4)
247
sdc1 $f3, (4 * 36 + 8 * 3)($4)
248
sdc1 $f4, (4 * 36 + 8 * 4)($4)
249
sdc1 $f5, (4 * 36 + 8 * 5)($4)
250
sdc1 $f6, (4 * 36 + 8 * 6)($4)
251
sdc1 $f7, (4 * 36 + 8 * 7)($4)
252
sdc1 $f8, (4 * 36 + 8 * 8)($4)
253
sdc1 $f9, (4 * 36 + 8 * 9)($4)
254
sdc1 $f10, (4 * 36 + 8 * 10)($4)
255
sdc1 $f11, (4 * 36 + 8 * 11)($4)
256
sdc1 $f12, (4 * 36 + 8 * 12)($4)
257
sdc1 $f13, (4 * 36 + 8 * 13)($4)
258
sdc1 $f14, (4 * 36 + 8 * 14)($4)
259
sdc1 $f15, (4 * 36 + 8 * 15)($4)
260
sdc1 $f16, (4 * 36 + 8 * 16)($4)
261
sdc1 $f17, (4 * 36 + 8 * 17)($4)
262
sdc1 $f18, (4 * 36 + 8 * 18)($4)
263
sdc1 $f19, (4 * 36 + 8 * 19)($4)
264
sdc1 $f20, (4 * 36 + 8 * 20)($4)
265
sdc1 $f21, (4 * 36 + 8 * 21)($4)
266
sdc1 $f22, (4 * 36 + 8 * 22)($4)
267
sdc1 $f23, (4 * 36 + 8 * 23)($4)
268
sdc1 $f24, (4 * 36 + 8 * 24)($4)
269
sdc1 $f25, (4 * 36 + 8 * 25)($4)
270
sdc1 $f26, (4 * 36 + 8 * 26)($4)
271
sdc1 $f27, (4 * 36 + 8 * 27)($4)
272
sdc1 $f28, (4 * 36 + 8 * 28)($4)
273
sdc1 $f29, (4 * 36 + 8 * 29)($4)
274
sdc1 $f30, (4 * 36 + 8 * 30)($4)
275
sdc1 $f31, (4 * 36 + 8 * 31)($4)
276
#endif
277
#endif
278
jr $31
279
# return UNW_ESUCCESS
280
or $2, $0, $0
281
.set pop
282
283
#elif defined(__mips64)
284
285
#
286
# extern int __unw_getcontext(unw_context_t* thread_state)
287
#
288
# On entry:
289
# thread_state pointer is in a0 ($4)
290
#
291
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
292
.set push
293
.set noat
294
.set noreorder
295
.set nomacro
296
.irp i,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
297
sd $\i, (8 * \i)($4)
298
.endr
299
# Store return address to pc
300
sd $31, (8 * 32)($4)
301
#if __mips_isa_rev < 6
302
# hi and lo
303
mfhi $8
304
sd $8, (8 * 33)($4)
305
mflo $8
306
sd $8, (8 * 34)($4)
307
#endif
308
#ifdef __mips_hard_float
309
.irp i,FROM_0_TO_31
310
sdc1 $f\i, (280+8*\i)($4)
311
.endr
312
#endif
313
jr $31
314
# return UNW_ESUCCESS
315
or $2, $0, $0
316
.set pop
317
318
# elif defined(__mips__)
319
320
#
321
# extern int __unw_getcontext(unw_context_t* thread_state)
322
#
323
# Just trap for the time being.
324
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
325
teq $0, $0
326
327
#elif defined(__powerpc64__)
328
329
//
330
// extern int __unw_getcontext(unw_context_t* thread_state)
331
//
332
// On entry:
333
// thread_state pointer is in r3
334
//
335
#if defined(_AIX)
336
DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
337
#else
338
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
339
#endif
340
// store register (GPR)
341
#define PPC64_STR(n) \
342
std n, (8 * (n + 2))(3)
343
344
// save GPRs
345
PPC64_STR(0)
346
mflr 0
347
std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
348
PPC64_STR(1)
349
PPC64_STR(4) // Save r4 first since it will be used for fixing r2.
350
#if defined(_AIX)
351
// The TOC register (r2) was changed by the glue code if unw_getcontext
352
// is called from a different module. Save the original TOC register
353
// in the context if this is the case.
354
mflr 4
355
lwz 4, 0(4) // Get the first instruction at the return address.
356
xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
357
cmplwi 0, 0x28
358
bne 0, LnoR2Fix // No need to fix up r2 if it is not.
359
ld 2, 40(1) // Use the saved TOC register in the stack.
360
LnoR2Fix:
361
#endif
362
PPC64_STR(2)
363
PPC64_STR(3)
364
PPC64_STR(5)
365
PPC64_STR(6)
366
PPC64_STR(7)
367
PPC64_STR(8)
368
PPC64_STR(9)
369
PPC64_STR(10)
370
PPC64_STR(11)
371
PPC64_STR(12)
372
PPC64_STR(13)
373
PPC64_STR(14)
374
PPC64_STR(15)
375
PPC64_STR(16)
376
PPC64_STR(17)
377
PPC64_STR(18)
378
PPC64_STR(19)
379
PPC64_STR(20)
380
PPC64_STR(21)
381
PPC64_STR(22)
382
PPC64_STR(23)
383
PPC64_STR(24)
384
PPC64_STR(25)
385
PPC64_STR(26)
386
PPC64_STR(27)
387
PPC64_STR(28)
388
PPC64_STR(29)
389
PPC64_STR(30)
390
PPC64_STR(31)
391
392
mfcr 0
393
std 0, PPC64_OFFS_CR(3)
394
mfxer 0
395
std 0, PPC64_OFFS_XER(3)
396
#if defined(_AIX)
397
// LR value saved from the register is not used, initialize it to 0.
398
li 0, 0
399
#else
400
mflr 0
401
#endif
402
std 0, PPC64_OFFS_LR(3)
403
mfctr 0
404
std 0, PPC64_OFFS_CTR(3)
405
mfvrsave 0
406
std 0, PPC64_OFFS_VRSAVE(3)
407
408
#if defined(__VSX__)
409
// save VS registers
410
// (note that this also saves floating point registers and V registers,
411
// because part of VS is mapped to these registers)
412
413
addi 4, 3, PPC64_OFFS_FP
414
415
// store VS register
416
#ifdef __LITTLE_ENDIAN__
417
// For little-endian targets, we need a swap since stxvd2x will store the
418
// register in the incorrect doubleword order.
419
// FIXME: when supporting targets older than Power9 on LE is no longer required
420
// this can be changed to simply `stxv n, 16 * n(4)`.
421
#define PPC64_STVS(n) \
422
xxswapd n, n ;\
423
stxvd2x n, 0, 4 ;\
424
addi 4, 4, 16
425
#else
426
#define PPC64_STVS(n) \
427
stxvd2x n, 0, 4 ;\
428
addi 4, 4, 16
429
#endif
430
431
PPC64_STVS(0)
432
PPC64_STVS(1)
433
PPC64_STVS(2)
434
PPC64_STVS(3)
435
PPC64_STVS(4)
436
PPC64_STVS(5)
437
PPC64_STVS(6)
438
PPC64_STVS(7)
439
PPC64_STVS(8)
440
PPC64_STVS(9)
441
PPC64_STVS(10)
442
PPC64_STVS(11)
443
PPC64_STVS(12)
444
PPC64_STVS(13)
445
PPC64_STVS(14)
446
PPC64_STVS(15)
447
PPC64_STVS(16)
448
PPC64_STVS(17)
449
PPC64_STVS(18)
450
PPC64_STVS(19)
451
PPC64_STVS(20)
452
PPC64_STVS(21)
453
PPC64_STVS(22)
454
PPC64_STVS(23)
455
PPC64_STVS(24)
456
PPC64_STVS(25)
457
PPC64_STVS(26)
458
PPC64_STVS(27)
459
PPC64_STVS(28)
460
PPC64_STVS(29)
461
PPC64_STVS(30)
462
PPC64_STVS(31)
463
PPC64_STVS(32)
464
PPC64_STVS(33)
465
PPC64_STVS(34)
466
PPC64_STVS(35)
467
PPC64_STVS(36)
468
PPC64_STVS(37)
469
PPC64_STVS(38)
470
PPC64_STVS(39)
471
PPC64_STVS(40)
472
PPC64_STVS(41)
473
PPC64_STVS(42)
474
PPC64_STVS(43)
475
PPC64_STVS(44)
476
PPC64_STVS(45)
477
PPC64_STVS(46)
478
PPC64_STVS(47)
479
PPC64_STVS(48)
480
PPC64_STVS(49)
481
PPC64_STVS(50)
482
PPC64_STVS(51)
483
PPC64_STVS(52)
484
PPC64_STVS(53)
485
PPC64_STVS(54)
486
PPC64_STVS(55)
487
PPC64_STVS(56)
488
PPC64_STVS(57)
489
PPC64_STVS(58)
490
PPC64_STVS(59)
491
PPC64_STVS(60)
492
PPC64_STVS(61)
493
PPC64_STVS(62)
494
PPC64_STVS(63)
495
496
#else
497
498
// store FP register
499
#define PPC64_STF(n) \
500
stfd n, (PPC64_OFFS_FP + n * 16)(3)
501
502
// save float registers
503
PPC64_STF(0)
504
PPC64_STF(1)
505
PPC64_STF(2)
506
PPC64_STF(3)
507
PPC64_STF(4)
508
PPC64_STF(5)
509
PPC64_STF(6)
510
PPC64_STF(7)
511
PPC64_STF(8)
512
PPC64_STF(9)
513
PPC64_STF(10)
514
PPC64_STF(11)
515
PPC64_STF(12)
516
PPC64_STF(13)
517
PPC64_STF(14)
518
PPC64_STF(15)
519
PPC64_STF(16)
520
PPC64_STF(17)
521
PPC64_STF(18)
522
PPC64_STF(19)
523
PPC64_STF(20)
524
PPC64_STF(21)
525
PPC64_STF(22)
526
PPC64_STF(23)
527
PPC64_STF(24)
528
PPC64_STF(25)
529
PPC64_STF(26)
530
PPC64_STF(27)
531
PPC64_STF(28)
532
PPC64_STF(29)
533
PPC64_STF(30)
534
PPC64_STF(31)
535
536
#if defined(__ALTIVEC__)
537
// save vector registers
538
539
// Use 16-bytes below the stack pointer as an
540
// aligned buffer to save each vector register.
541
// Note that the stack pointer is always 16-byte aligned.
542
subi 4, 1, 16
543
544
#define PPC64_STV_UNALIGNED(n) \
545
stvx n, 0, 4 ;\
546
ld 5, 0(4) ;\
547
std 5, (PPC64_OFFS_V + n * 16)(3) ;\
548
ld 5, 8(4) ;\
549
std 5, (PPC64_OFFS_V + n * 16 + 8)(3)
550
551
PPC64_STV_UNALIGNED(0)
552
PPC64_STV_UNALIGNED(1)
553
PPC64_STV_UNALIGNED(2)
554
PPC64_STV_UNALIGNED(3)
555
PPC64_STV_UNALIGNED(4)
556
PPC64_STV_UNALIGNED(5)
557
PPC64_STV_UNALIGNED(6)
558
PPC64_STV_UNALIGNED(7)
559
PPC64_STV_UNALIGNED(8)
560
PPC64_STV_UNALIGNED(9)
561
PPC64_STV_UNALIGNED(10)
562
PPC64_STV_UNALIGNED(11)
563
PPC64_STV_UNALIGNED(12)
564
PPC64_STV_UNALIGNED(13)
565
PPC64_STV_UNALIGNED(14)
566
PPC64_STV_UNALIGNED(15)
567
PPC64_STV_UNALIGNED(16)
568
PPC64_STV_UNALIGNED(17)
569
PPC64_STV_UNALIGNED(18)
570
PPC64_STV_UNALIGNED(19)
571
PPC64_STV_UNALIGNED(20)
572
PPC64_STV_UNALIGNED(21)
573
PPC64_STV_UNALIGNED(22)
574
PPC64_STV_UNALIGNED(23)
575
PPC64_STV_UNALIGNED(24)
576
PPC64_STV_UNALIGNED(25)
577
PPC64_STV_UNALIGNED(26)
578
PPC64_STV_UNALIGNED(27)
579
PPC64_STV_UNALIGNED(28)
580
PPC64_STV_UNALIGNED(29)
581
PPC64_STV_UNALIGNED(30)
582
PPC64_STV_UNALIGNED(31)
583
584
#endif
585
#endif
586
587
li 3, 0 // return UNW_ESUCCESS
588
blr
589
590
591
#elif defined(__powerpc__)
592
593
//
594
// extern int unw_getcontext(unw_context_t* thread_state)
595
//
596
// On entry:
597
// thread_state pointer is in r3
598
//
599
#if defined(_AIX)
600
DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
601
#else
602
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
603
#endif
604
stw 0, 8(3)
605
mflr 0
606
stw 0, 0(3) // store lr as ssr0
607
stw 1, 12(3)
608
stw 4, 24(3) // Save r4 first since it will be used for fixing r2.
609
#if defined(_AIX)
610
// The TOC register (r2) was changed by the glue code if unw_getcontext
611
// is called from a different module. Save the original TOC register
612
// in the context if this is the case.
613
mflr 4
614
lwz 4, 0(4) // Get the instruction at the return address.
615
xoris 0, 4, 0x8041 // Is it reloading the TOC register "lwz 2,20(1)"?
616
cmplwi 0, 0x14
617
bne 0, LnoR2Fix // No need to fix up r2 if it is not.
618
lwz 2, 20(1) // Use the saved TOC register in the stack.
619
LnoR2Fix:
620
#endif
621
stw 2, 16(3)
622
stw 3, 20(3)
623
stw 5, 28(3)
624
stw 6, 32(3)
625
stw 7, 36(3)
626
stw 8, 40(3)
627
stw 9, 44(3)
628
stw 10, 48(3)
629
stw 11, 52(3)
630
stw 12, 56(3)
631
stw 13, 60(3)
632
stw 14, 64(3)
633
stw 15, 68(3)
634
stw 16, 72(3)
635
stw 17, 76(3)
636
stw 18, 80(3)
637
stw 19, 84(3)
638
stw 20, 88(3)
639
stw 21, 92(3)
640
stw 22, 96(3)
641
stw 23,100(3)
642
stw 24,104(3)
643
stw 25,108(3)
644
stw 26,112(3)
645
stw 27,116(3)
646
stw 28,120(3)
647
stw 29,124(3)
648
stw 30,128(3)
649
stw 31,132(3)
650
651
#if defined(__ALTIVEC__)
652
// save VRSave register
653
mfspr 0, 256
654
stw 0, 156(3)
655
#endif
656
// save CR registers
657
mfcr 0
658
stw 0, 136(3)
659
#if defined(_AIX)
660
// LR value from the register is not used, initialize it to 0.
661
li 0, 0
662
stw 0, 144(3)
663
#endif
664
// save CTR register
665
mfctr 0
666
stw 0, 148(3)
667
668
#if !defined(__NO_FPRS__)
669
// save float registers
670
stfd 0, 160(3)
671
stfd 1, 168(3)
672
stfd 2, 176(3)
673
stfd 3, 184(3)
674
stfd 4, 192(3)
675
stfd 5, 200(3)
676
stfd 6, 208(3)
677
stfd 7, 216(3)
678
stfd 8, 224(3)
679
stfd 9, 232(3)
680
stfd 10,240(3)
681
stfd 11,248(3)
682
stfd 12,256(3)
683
stfd 13,264(3)
684
stfd 14,272(3)
685
stfd 15,280(3)
686
stfd 16,288(3)
687
stfd 17,296(3)
688
stfd 18,304(3)
689
stfd 19,312(3)
690
stfd 20,320(3)
691
stfd 21,328(3)
692
stfd 22,336(3)
693
stfd 23,344(3)
694
stfd 24,352(3)
695
stfd 25,360(3)
696
stfd 26,368(3)
697
stfd 27,376(3)
698
stfd 28,384(3)
699
stfd 29,392(3)
700
stfd 30,400(3)
701
stfd 31,408(3)
702
#endif
703
704
#if defined(__ALTIVEC__)
705
// save vector registers
706
707
subi 4, 1, 16
708
rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
709
// r4 is now a 16-byte aligned pointer into the red zone
710
711
#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
712
stvx _vec, 0, 4 SEPARATOR \
713
lwz 5, 0(4) SEPARATOR \
714
stw 5, _offset(3) SEPARATOR \
715
lwz 5, 4(4) SEPARATOR \
716
stw 5, _offset+4(3) SEPARATOR \
717
lwz 5, 8(4) SEPARATOR \
718
stw 5, _offset+8(3) SEPARATOR \
719
lwz 5, 12(4) SEPARATOR \
720
stw 5, _offset+12(3)
721
722
SAVE_VECTOR_UNALIGNED( 0, 424+0x000)
723
SAVE_VECTOR_UNALIGNED( 1, 424+0x010)
724
SAVE_VECTOR_UNALIGNED( 2, 424+0x020)
725
SAVE_VECTOR_UNALIGNED( 3, 424+0x030)
726
SAVE_VECTOR_UNALIGNED( 4, 424+0x040)
727
SAVE_VECTOR_UNALIGNED( 5, 424+0x050)
728
SAVE_VECTOR_UNALIGNED( 6, 424+0x060)
729
SAVE_VECTOR_UNALIGNED( 7, 424+0x070)
730
SAVE_VECTOR_UNALIGNED( 8, 424+0x080)
731
SAVE_VECTOR_UNALIGNED( 9, 424+0x090)
732
SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)
733
SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)
734
SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)
735
SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)
736
SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)
737
SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)
738
SAVE_VECTOR_UNALIGNED(16, 424+0x100)
739
SAVE_VECTOR_UNALIGNED(17, 424+0x110)
740
SAVE_VECTOR_UNALIGNED(18, 424+0x120)
741
SAVE_VECTOR_UNALIGNED(19, 424+0x130)
742
SAVE_VECTOR_UNALIGNED(20, 424+0x140)
743
SAVE_VECTOR_UNALIGNED(21, 424+0x150)
744
SAVE_VECTOR_UNALIGNED(22, 424+0x160)
745
SAVE_VECTOR_UNALIGNED(23, 424+0x170)
746
SAVE_VECTOR_UNALIGNED(24, 424+0x180)
747
SAVE_VECTOR_UNALIGNED(25, 424+0x190)
748
SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)
749
SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)
750
SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)
751
SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)
752
SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)
753
SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)
754
#endif
755
756
li 3, 0 // return UNW_ESUCCESS
757
blr
758
759
760
#elif defined(__aarch64__)
761
762
//
763
// extern int __unw_getcontext(unw_context_t* thread_state)
764
//
765
// On entry:
766
// thread_state pointer is in x0
767
//
768
.p2align 2
769
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
770
stp x0, x1, [x0, #0x000]
771
stp x2, x3, [x0, #0x010]
772
stp x4, x5, [x0, #0x020]
773
stp x6, x7, [x0, #0x030]
774
stp x8, x9, [x0, #0x040]
775
stp x10,x11, [x0, #0x050]
776
stp x12,x13, [x0, #0x060]
777
stp x14,x15, [x0, #0x070]
778
stp x16,x17, [x0, #0x080]
779
stp x18,x19, [x0, #0x090]
780
stp x20,x21, [x0, #0x0A0]
781
stp x22,x23, [x0, #0x0B0]
782
stp x24,x25, [x0, #0x0C0]
783
stp x26,x27, [x0, #0x0D0]
784
stp x28,x29, [x0, #0x0E0]
785
str x30, [x0, #0x0F0]
786
mov x1,sp
787
str x1, [x0, #0x0F8]
788
str x30, [x0, #0x100] // store return address as pc
789
// skip cpsr
790
#if defined(__ARM_FP) && __ARM_FP != 0
791
stp d0, d1, [x0, #0x110]
792
stp d2, d3, [x0, #0x120]
793
stp d4, d5, [x0, #0x130]
794
stp d6, d7, [x0, #0x140]
795
stp d8, d9, [x0, #0x150]
796
stp d10,d11, [x0, #0x160]
797
stp d12,d13, [x0, #0x170]
798
stp d14,d15, [x0, #0x180]
799
stp d16,d17, [x0, #0x190]
800
stp d18,d19, [x0, #0x1A0]
801
stp d20,d21, [x0, #0x1B0]
802
stp d22,d23, [x0, #0x1C0]
803
stp d24,d25, [x0, #0x1D0]
804
stp d26,d27, [x0, #0x1E0]
805
stp d28,d29, [x0, #0x1F0]
806
str d30, [x0, #0x200]
807
str d31, [x0, #0x208]
808
#endif
809
mov x0, #0 // return UNW_ESUCCESS
810
ret
811
812
#elif defined(__arm__) && !defined(__APPLE__)
813
814
#if !defined(__ARM_ARCH_ISA_ARM)
815
#if (__ARM_ARCH_ISA_THUMB == 2)
816
.syntax unified
817
#endif
818
.thumb
819
#endif
820
821
@
822
@ extern int __unw_getcontext(unw_context_t* thread_state)
823
@
824
@ On entry:
825
@ thread_state pointer is in r0
826
@
827
@ Per EHABI #4.7 this only saves the core integer registers.
828
@ EHABI #7.4.5 notes that in general all VRS registers should be restored
829
@ however this is very hard to do for VFP registers because it is unknown
830
@ to the library how many registers are implemented by the architecture.
831
@ Instead, VFP registers are demand saved by logic external to __unw_getcontext.
832
@
833
.p2align 2
834
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
835
#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1
836
stm r0!, {r0-r7}
837
mov r1, r8
838
mov r2, r9
839
mov r3, r10
840
stm r0!, {r1-r3}
841
mov r1, r11
842
mov r2, sp
843
mov r3, lr
844
str r1, [r0, #0] @ r11
845
@ r12 does not need storing, it it the intra-procedure-call scratch register
846
str r2, [r0, #8] @ sp
847
str r3, [r0, #12] @ lr
848
str r3, [r0, #16] @ store return address as pc
849
@ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
850
@ It is safe to use here though because we are about to return, and cpsr is
851
@ not expected to be preserved.
852
movs r0, #0 @ return UNW_ESUCCESS
853
#else
854
@ 32bit thumb-2 restrictions for stm:
855
@ . the sp (r13) cannot be in the list
856
@ . the pc (r15) cannot be in the list in an STM instruction
857
stm r0, {r0-r12}
858
str sp, [r0, #52]
859
str lr, [r0, #56]
860
str lr, [r0, #60] @ store return address as pc
861
mov r0, #0 @ return UNW_ESUCCESS
862
#endif
863
JMP(lr)
864
865
@
866
@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
867
@
868
@ On entry:
869
@ values pointer is in r0
870
@
871
.p2align 2
872
#if defined(__ELF__)
873
.fpu vfpv3-d16
874
#endif
875
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv)
876
vstmia r0, {d0-d15}
877
JMP(lr)
878
879
@
880
@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
881
@
882
@ On entry:
883
@ values pointer is in r0
884
@
885
.p2align 2
886
#if defined(__ELF__)
887
.fpu vfpv3-d16
888
#endif
889
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv)
890
vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
891
JMP(lr)
892
893
@
894
@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
895
@
896
@ On entry:
897
@ values pointer is in r0
898
@
899
.p2align 2
900
#if defined(__ELF__)
901
.fpu vfpv3
902
#endif
903
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv)
904
@ VFP and iwMMX instructions are only available when compiling with the flags
905
@ that enable them. We do not want to do that in the library (because we do not
906
@ want the compiler to generate instructions that access those) but this is
907
@ only accessed if the personality routine needs these registers. Use of
908
@ these registers implies they are, actually, available on the target, so
909
@ it's ok to execute.
910
@ So, generate the instructions using the corresponding coprocessor mnemonic.
911
vstmia r0, {d16-d31}
912
JMP(lr)
913
914
#if defined(_LIBUNWIND_ARM_WMMX)
915
916
@
917
@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
918
@
919
@ On entry:
920
@ values pointer is in r0
921
@
922
.p2align 2
923
#if defined(__ELF__)
924
.arch armv5te
925
#endif
926
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv)
927
stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8
928
stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8
929
stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8
930
stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8
931
stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8
932
stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8
933
stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8
934
stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8
935
stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8
936
stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8
937
stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8
938
stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8
939
stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8
940
stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8
941
stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8
942
stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8
943
JMP(lr)
944
945
@
946
@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
947
@
948
@ On entry:
949
@ values pointer is in r0
950
@
951
.p2align 2
952
#if defined(__ELF__)
953
.arch armv5te
954
#endif
955
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
956
stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4
957
stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4
958
stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4
959
stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4
960
JMP(lr)
961
962
#endif
963
964
#elif defined(__or1k__)
965
966
#
967
# extern int __unw_getcontext(unw_context_t* thread_state)
968
#
969
# On entry:
970
# thread_state pointer is in r3
971
#
972
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
973
l.sw 0(r3), r0
974
l.sw 4(r3), r1
975
l.sw 8(r3), r2
976
l.sw 12(r3), r3
977
l.sw 16(r3), r4
978
l.sw 20(r3), r5
979
l.sw 24(r3), r6
980
l.sw 28(r3), r7
981
l.sw 32(r3), r8
982
l.sw 36(r3), r9
983
l.sw 40(r3), r10
984
l.sw 44(r3), r11
985
l.sw 48(r3), r12
986
l.sw 52(r3), r13
987
l.sw 56(r3), r14
988
l.sw 60(r3), r15
989
l.sw 64(r3), r16
990
l.sw 68(r3), r17
991
l.sw 72(r3), r18
992
l.sw 76(r3), r19
993
l.sw 80(r3), r20
994
l.sw 84(r3), r21
995
l.sw 88(r3), r22
996
l.sw 92(r3), r23
997
l.sw 96(r3), r24
998
l.sw 100(r3), r25
999
l.sw 104(r3), r26
1000
l.sw 108(r3), r27
1001
l.sw 112(r3), r28
1002
l.sw 116(r3), r29
1003
l.sw 120(r3), r30
1004
l.sw 124(r3), r31
1005
# store ra to pc
1006
l.sw 128(r3), r9
1007
# zero epcr
1008
l.sw 132(r3), r0
1009
1010
#elif defined(__hexagon__)
1011
#
1012
# extern int unw_getcontext(unw_context_t* thread_state)
1013
#
1014
# On entry:
1015
# thread_state pointer is in r0
1016
#
1017
#define OFFSET(offset) (offset/4)
1018
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1019
memw(r0+#32) = r8
1020
memw(r0+#36) = r9
1021
memw(r0+#40) = r10
1022
memw(r0+#44) = r11
1023
1024
memw(r0+#48) = r12
1025
memw(r0+#52) = r13
1026
memw(r0+#56) = r14
1027
memw(r0+#60) = r15
1028
1029
memw(r0+#64) = r16
1030
memw(r0+#68) = r17
1031
memw(r0+#72) = r18
1032
memw(r0+#76) = r19
1033
1034
memw(r0+#80) = r20
1035
memw(r0+#84) = r21
1036
memw(r0+#88) = r22
1037
memw(r0+#92) = r23
1038
1039
memw(r0+#96) = r24
1040
memw(r0+#100) = r25
1041
memw(r0+#104) = r26
1042
memw(r0+#108) = r27
1043
1044
memw(r0+#112) = r28
1045
memw(r0+#116) = r29
1046
memw(r0+#120) = r30
1047
memw(r0+#124) = r31
1048
r1 = c4 // Predicate register
1049
memw(r0+#128) = r1
1050
r1 = memw(r30) // *FP == Saved FP
1051
r1 = r31
1052
memw(r0+#132) = r1
1053
1054
jumpr r31
1055
1056
#elif defined(__sparc__) && defined(__arch64__)
1057
1058
#
1059
# extern int __unw_getcontext(unw_context_t* thread_state)
1060
#
1061
# On entry:
1062
# thread_state pointer is in %o0
1063
#
1064
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1065
.register %g2, #scratch
1066
.register %g3, #scratch
1067
.register %g6, #scratch
1068
.register %g7, #scratch
1069
stx %g1, [%o0 + 0x08]
1070
stx %g2, [%o0 + 0x10]
1071
stx %g3, [%o0 + 0x18]
1072
stx %g4, [%o0 + 0x20]
1073
stx %g5, [%o0 + 0x28]
1074
stx %g6, [%o0 + 0x30]
1075
stx %g7, [%o0 + 0x38]
1076
stx %o0, [%o0 + 0x40]
1077
stx %o1, [%o0 + 0x48]
1078
stx %o2, [%o0 + 0x50]
1079
stx %o3, [%o0 + 0x58]
1080
stx %o4, [%o0 + 0x60]
1081
stx %o5, [%o0 + 0x68]
1082
stx %o6, [%o0 + 0x70]
1083
stx %o7, [%o0 + 0x78]
1084
stx %l0, [%o0 + 0x80]
1085
stx %l1, [%o0 + 0x88]
1086
stx %l2, [%o0 + 0x90]
1087
stx %l3, [%o0 + 0x98]
1088
stx %l4, [%o0 + 0xa0]
1089
stx %l5, [%o0 + 0xa8]
1090
stx %l6, [%o0 + 0xb0]
1091
stx %l7, [%o0 + 0xb8]
1092
stx %i0, [%o0 + 0xc0]
1093
stx %i1, [%o0 + 0xc8]
1094
stx %i2, [%o0 + 0xd0]
1095
stx %i3, [%o0 + 0xd8]
1096
stx %i4, [%o0 + 0xe0]
1097
stx %i5, [%o0 + 0xe8]
1098
stx %i6, [%o0 + 0xf0]
1099
stx %i7, [%o0 + 0xf8]
1100
1101
# save StackGhost cookie
1102
mov %i7, %g4
1103
save %sp, -176, %sp
1104
# register window flush necessary even without StackGhost
1105
flushw
1106
restore
1107
ldx [%sp + 2047 + 0x78], %g5
1108
xor %g4, %g5, %g4
1109
stx %g4, [%o0 + 0x100]
1110
retl
1111
# return UNW_ESUCCESS
1112
clr %o0
1113
1114
#elif defined(__sparc__)
1115
1116
#
1117
# extern int __unw_getcontext(unw_context_t* thread_state)
1118
#
1119
# On entry:
1120
# thread_state pointer is in o0
1121
#
1122
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1123
ta 3
1124
add %o7, 8, %o7
1125
std %g0, [%o0 + 0]
1126
std %g2, [%o0 + 8]
1127
std %g4, [%o0 + 16]
1128
std %g6, [%o0 + 24]
1129
std %o0, [%o0 + 32]
1130
std %o2, [%o0 + 40]
1131
std %o4, [%o0 + 48]
1132
std %o6, [%o0 + 56]
1133
std %l0, [%o0 + 64]
1134
std %l2, [%o0 + 72]
1135
std %l4, [%o0 + 80]
1136
std %l6, [%o0 + 88]
1137
std %i0, [%o0 + 96]
1138
std %i2, [%o0 + 104]
1139
std %i4, [%o0 + 112]
1140
std %i6, [%o0 + 120]
1141
jmp %o7
1142
clr %o0 // return UNW_ESUCCESS
1143
1144
#elif defined(__riscv)
1145
1146
#
1147
# extern int __unw_getcontext(unw_context_t* thread_state)
1148
#
1149
# On entry:
1150
# thread_state pointer is in a0
1151
#
1152
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1153
ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
1154
#if defined(__riscv_32e)
1155
.irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1156
#else
1157
.irp i,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
1158
#endif
1159
ISTORE x\i, (RISCV_ISIZE * \i)(a0)
1160
.endr
1161
1162
# if defined(__riscv_flen)
1163
.irp i,FROM_0_TO_31
1164
FSTORE f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0)
1165
.endr
1166
# endif
1167
1168
li a0, 0 // return UNW_ESUCCESS
1169
ret // jump to ra
1170
1171
#elif defined(__s390x__)
1172
1173
//
1174
// extern int __unw_getcontext(unw_context_t* thread_state)
1175
//
1176
// On entry:
1177
// thread_state pointer is in r2
1178
//
1179
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1180
1181
// Save GPRs
1182
stmg %r0, %r15, 16(%r2)
1183
1184
// Save PSWM
1185
epsw %r0, %r1
1186
stm %r0, %r1, 0(%r2)
1187
1188
// Store return address as PSWA
1189
stg %r14, 8(%r2)
1190
1191
// Save FPRs
1192
.irp i,FROM_0_TO_15
1193
std %f\i, (144+8*\i)(%r2)
1194
.endr
1195
1196
// Return UNW_ESUCCESS
1197
lghi %r2, 0
1198
br %r14
1199
1200
#elif defined(__loongarch__) && __loongarch_grlen == 64
1201
1202
#
1203
# extern int __unw_getcontext(unw_context_t* thread_state)
1204
#
1205
# On entry:
1206
# thread_state pointer is in $a0($r4)
1207
#
1208
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1209
.irp i,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
1210
st.d $r\i, $a0, (8*\i)
1211
.endr
1212
st.d $r1, $a0, (8 * 32) // store $ra to pc
1213
1214
# if __loongarch_frlen == 64
1215
.irp i,FROM_0_TO_31
1216
fst.d $f\i, $a0, (8 * 33 + 8 * \i)
1217
.endr
1218
# endif
1219
1220
move $a0, $zero // UNW_ESUCCESS
1221
jr $ra
1222
1223
#endif
1224
1225
#ifdef __arm64ec__
1226
.globl "#unw_getcontext"
1227
.set "#unw_getcontext", "#__unw_getcontext"
1228
.weak_anti_dep unw_getcontext
1229
.set unw_getcontext, "#unw_getcontext"
1230
EXPORT_SYMBOL(unw_getcontext)
1231
#else
1232
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
1233
#endif
1234
1235
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */
1236
1237
NO_EXEC_STACK_DIRECTIVE
1238
1239