1/* Copyright (C) 2012-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18/* ??? Needs more rearrangement for the LDM to handle thumb mode. */ 19#define NO_THUMB 20#include <sysdep.h> 21#include <rtld-global-offsets.h> 22 23#include "ucontext_i.h" 24 25 .syntax unified 26 .text 27 28/* int setcontext (const ucontext_t *ucp) */ 29 30ENTRY(__setcontext) 31 mov r4, r0 32 add r0, r0, #UCONTEXT_REGSPACE 33 34 /* Restore the VFP registers. Copied from arm/__longjmp.S. */ 35#ifdef SHARED 36 ldr r2, 1f 37 ldr r1, .Lrtld_global_ro 380: add r2, pc, r2 39 ldr r2, [r2, r1] 40 ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] 41#else 42 ldr r2, .Lhwcap 43 ldr r2, [r2, #0] 44#endif 45 46#ifdef __SOFTFP__ 47 tst r2, #HWCAP_ARM_VFP 48 beq .Lno_vfp_sc 49#endif 50 51 /* Following instruction is vldmia r0!, {d8-d15}. */ 52 ldc p11, cr8, [r0], #64 53 /* Restore the floating-point status register. */ 54 ldr r1, [r0], #4 55 /* Following instruction is fmxr fpscr, r1. */ 56 mcr p10, 7, r1, cr1, cr0, 0 57.Lno_vfp_sc: 58 tst r2, #HWCAP_ARM_IWMMXT 59 beq .Lno_iwmmxt_sc 60 61 /* Restore the call-preserved iWMMXt registers. */ 62 /* Following instructions are wldrd wr10, [r0], #8 (etc.) */ 63 ldcl p1, cr10, [r0], #8 64 ldcl p1, cr11, [r0], #8 65 ldcl p1, cr12, [r0], #8 66 ldcl p1, cr13, [r0], #8 67 ldcl p1, cr14, [r0], #8 68 ldcl p1, cr15, [r0], #8 69.Lno_iwmmxt_sc: 70 71 /* Now bring back the signal status. */ 72 mov r0, #SIG_SETMASK 73 add r1, r4, #UCONTEXT_SIGMASK 74 mov r2, #0 75 bl PLTJMP(__sigprocmask) 76 77 /* Loading r0-r3 makes makecontext easier. */ 78 add r14, r4, #MCONTEXT_ARM_R0 79 ldmia r14, {r0-r12} 80 ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)] 81 add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0) 82 ldmia r14, {r14, pc} 83 84END(setcontext) 85weak_alias(__setcontext, setcontext) 86 87 /* Called when a makecontext() context returns. Start the 88 context in R4 or fall through to exit(). */ 89 /* Unwind descriptors are looked up based on PC - 2, so we have to 90 make sure to mark the instruction preceding the __startcontext 91 label as .cantunwind. */ 92 .fnstart 93 .cantunwind 94 nop 95ENTRY(__startcontext) 96 movs r0, r4 97 bne PLTJMP(__setcontext) 98 99 @ New context was 0 - exit 100 b PLTJMP(HIDDEN_JUMPTARGET(exit)) 101 .fnend 102END(__startcontext) 103 104#ifdef SHARED 1051: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS 106.Lrtld_global_ro: 107 .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) 108#else 109.Lhwcap: 110 .long C_SYMBOL_NAME(_dl_hwcap) 111#endif 112