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