18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright (C) 2019 ARM Limited */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <asm/unistd.h> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci.section .rodata, "a" 78c2ecf20Sopenharmony_cicall_fmt: 88c2ecf20Sopenharmony_ci .asciz "Calling sigreturn with fake sigframe sized:%zd at SP @%08lX\n" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci.text 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci.globl fake_sigreturn 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* fake_sigreturn x0:&sigframe, x1:sigframe_size, x2:misalign_bytes */ 158c2ecf20Sopenharmony_cifake_sigreturn: 168c2ecf20Sopenharmony_ci stp x29, x30, [sp, #-16]! 178c2ecf20Sopenharmony_ci mov x29, sp 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci mov x20, x0 208c2ecf20Sopenharmony_ci mov x21, x1 218c2ecf20Sopenharmony_ci mov x22, x2 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci /* create space on the stack for fake sigframe 16 bytes-aligned */ 248c2ecf20Sopenharmony_ci add x0, x21, x22 258c2ecf20Sopenharmony_ci add x0, x0, #15 268c2ecf20Sopenharmony_ci bic x0, x0, #15 /* round_up(sigframe_size + misalign_bytes, 16) */ 278c2ecf20Sopenharmony_ci sub sp, sp, x0 288c2ecf20Sopenharmony_ci add x23, sp, x22 /* new sigframe base with misaligment if any */ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci ldr x0, =call_fmt 318c2ecf20Sopenharmony_ci mov x1, x21 328c2ecf20Sopenharmony_ci mov x2, x23 338c2ecf20Sopenharmony_ci bl printf 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci /* memcpy the provided content, while still keeping SP aligned */ 368c2ecf20Sopenharmony_ci mov x0, x23 378c2ecf20Sopenharmony_ci mov x1, x20 388c2ecf20Sopenharmony_ci mov x2, x21 398c2ecf20Sopenharmony_ci bl memcpy 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci /* 428c2ecf20Sopenharmony_ci * Here saving a last minute SP to current->token acts as a marker: 438c2ecf20Sopenharmony_ci * if we got here, we are successfully faking a sigreturn; in other 448c2ecf20Sopenharmony_ci * words we are sure no bad fatal signal has been raised till now 458c2ecf20Sopenharmony_ci * for unrelated reasons, so we should consider the possibly observed 468c2ecf20Sopenharmony_ci * fatal signal like SEGV coming from Kernel restore_sigframe() and 478c2ecf20Sopenharmony_ci * triggered as expected from our test-case. 488c2ecf20Sopenharmony_ci * For simplicity this assumes that current field 'token' is laid out 498c2ecf20Sopenharmony_ci * as first in struct tdescr 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci ldr x0, current 528c2ecf20Sopenharmony_ci str x23, [x0] 538c2ecf20Sopenharmony_ci /* finally move SP to misaligned address...if any requested */ 548c2ecf20Sopenharmony_ci mov sp, x23 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci mov x8, #__NR_rt_sigreturn 578c2ecf20Sopenharmony_ci svc #0 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* 608c2ecf20Sopenharmony_ci * Above sigreturn should not return...looping here leads to a timeout 618c2ecf20Sopenharmony_ci * and ensure proper and clean test failure, instead of jumping around 628c2ecf20Sopenharmony_ci * on a potentially corrupted stack. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci b . 65