1 /* 2 * Emulation of Linux signals 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "qemu/osdep.h" 20 #include "qemu.h" 21 #include "user-internals.h" 22 #include "signal-common.h" 23 #include "linux-user/trace.h" 24 #include "target/arm/cpu-features.h" 25 #include "vdso-asmoffset.h" 26 27 struct target_sigcontext { 28 abi_ulong trap_no; 29 abi_ulong error_code; 30 abi_ulong oldmask; 31 abi_ulong arm_r0; 32 abi_ulong arm_r1; 33 abi_ulong arm_r2; 34 abi_ulong arm_r3; 35 abi_ulong arm_r4; 36 abi_ulong arm_r5; 37 abi_ulong arm_r6; 38 abi_ulong arm_r7; 39 abi_ulong arm_r8; 40 abi_ulong arm_r9; 41 abi_ulong arm_r10; 42 abi_ulong arm_fp; 43 abi_ulong arm_ip; 44 abi_ulong arm_sp; 45 abi_ulong arm_lr; 46 abi_ulong arm_pc; 47 abi_ulong arm_cpsr; 48 abi_ulong fault_address; 49 }; 50 51 struct target_ucontext { 52 abi_ulong tuc_flags; 53 abi_ulong tuc_link; 54 target_stack_t tuc_stack; 55 struct target_sigcontext tuc_mcontext; 56 target_sigset_t tuc_sigmask; /* mask last for extensibility */ 57 char __unused[128 - sizeof(target_sigset_t)]; 58 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8))); 59 }; 60 61 struct target_user_vfp { 62 uint64_t fpregs[32]; 63 abi_ulong fpscr; 64 }; 65 66 struct target_user_vfp_exc { 67 abi_ulong fpexc; 68 abi_ulong fpinst; 69 abi_ulong fpinst2; 70 }; 71 72 struct target_vfp_sigframe { 73 abi_ulong magic; 74 abi_ulong size; 75 struct target_user_vfp ufp; 76 struct target_user_vfp_exc ufp_exc; 77 } __attribute__((__aligned__(8))); 78 79 struct target_iwmmxt_sigframe { 80 abi_ulong magic; 81 abi_ulong size; 82 uint64_t regs[16]; 83 /* Note that not all the coprocessor control registers are stored here */ 84 uint32_t wcssf; 85 uint32_t wcasf; 86 uint32_t wcgr0; 87 uint32_t wcgr1; 88 uint32_t wcgr2; 89 uint32_t wcgr3; 90 } __attribute__((__aligned__(8))); 91 92 #define TARGET_VFP_MAGIC 0x56465001 93 #define TARGET_IWMMXT_MAGIC 0x12ef842a 94 95 struct sigframe 96 { 97 struct target_ucontext uc; 98 abi_ulong retcode[4]; 99 }; 100 101 struct rt_sigframe 102 { 103 struct target_siginfo info; 104 struct sigframe sig; 105 }; 106 107 QEMU_BUILD_BUG_ON(offsetof(struct sigframe, retcode[3]) 108 != SIGFRAME_RC3_OFFSET); 109 QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, sig.retcode[3]) 110 != RT_SIGFRAME_RC3_OFFSET); 111 112 static abi_ptr sigreturn_fdpic_tramp; 113 114 /* 115 * Up to 3 words of 'retcode' in the sigframe are code, 116 * with retcode[3] being used by fdpic for the function descriptor. 117 * This code is not actually executed, but is retained for ABI compat. 118 * 119 * We will create a table of 8 retcode variants in the sigtramp page. 120 * Let each table entry use 3 words. 121 */ 122 #define RETCODE_WORDS 3 123 #define RETCODE_BYTES (RETCODE_WORDS * 4) 124 125 static inline int valid_user_regs(CPUARMState *regs) 126 { 127 return 1; 128 } 129 130 static void 131 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ 132 CPUARMState *env, abi_ulong mask) 133 { 134 __put_user(env->regs[0], &sc->arm_r0); 135 __put_user(env->regs[1], &sc->arm_r1); 136 __put_user(env->regs[2], &sc->arm_r2); 137 __put_user(env->regs[3], &sc->arm_r3); 138 __put_user(env->regs[4], &sc->arm_r4); 139 __put_user(env->regs[5], &sc->arm_r5); 140 __put_user(env->regs[6], &sc->arm_r6); 141 __put_user(env->regs[7], &sc->arm_r7); 142 __put_user(env->regs[8], &sc->arm_r8); 143 __put_user(env->regs[9], &sc->arm_r9); 144 __put_user(env->regs[10], &sc->arm_r10); 145 __put_user(env->regs[11], &sc->arm_fp); 146 __put_user(env->regs[12], &sc->arm_ip); 147 __put_user(env->regs[13], &sc->arm_sp); 148 __put_user(env->regs[14], &sc->arm_lr); 149 __put_user(env->regs[15], &sc->arm_pc); 150 __put_user(cpsr_read(env), &sc->arm_cpsr); 151 152 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no); 153 __put_user(/* current->thread.error_code */ 0, &sc->error_code); 154 __put_user(/* current->thread.address */ 0, &sc->fault_address); 155 __put_user(mask, &sc->oldmask); 156 } 157 158 static inline abi_ulong 159 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize) 160 { 161 unsigned long sp; 162 163 sp = target_sigsp(get_sp_from_cpustate(regs), ka); 164 /* 165 * ATPCS B01 mandates 8-byte alignment 166 */ 167 return (sp - framesize) & ~7; 168 } 169 170 static void write_arm_sigreturn(uint32_t *rc, int syscall); 171 static void write_arm_fdpic_sigreturn(uint32_t *rc, int ofs); 172 173 static int 174 setup_return(CPUARMState *env, struct target_sigaction *ka, int usig, 175 struct sigframe *frame, abi_ulong sp_addr) 176 { 177 abi_ulong handler = 0; 178 abi_ulong handler_fdpic_GOT = 0; 179 abi_ulong retcode; 180 bool is_fdpic = info_is_fdpic(get_task_state(thread_cpu)->info); 181 bool is_rt = ka->sa_flags & TARGET_SA_SIGINFO; 182 bool thumb; 183 184 if (is_fdpic) { 185 /* In FDPIC mode, ka->_sa_handler points to a function 186 * descriptor (FD). The first word contains the address of the 187 * handler. The second word contains the value of the PIC 188 * register (r9). */ 189 abi_ulong funcdesc_ptr = ka->_sa_handler; 190 if (get_user_ual(handler, funcdesc_ptr) 191 || get_user_ual(handler_fdpic_GOT, funcdesc_ptr + 4)) { 192 return 1; 193 } 194 } else { 195 handler = ka->_sa_handler; 196 } 197 thumb = handler & 1; 198 199 uint32_t cpsr = cpsr_read(env); 200 201 cpsr &= ~CPSR_IT; 202 if (thumb) { 203 cpsr |= CPSR_T; 204 } else { 205 cpsr &= ~CPSR_T; 206 } 207 if (env->cp15.sctlr_el[1] & SCTLR_E0E) { 208 cpsr |= CPSR_E; 209 } else { 210 cpsr &= ~CPSR_E; 211 } 212 213 /* Our vdso default_sigreturn label is a table of entry points. */ 214 retcode = default_sigreturn + (is_fdpic * 2 + is_rt) * 8; 215 216 /* 217 * Put the sigreturn code on the stack no matter which return 218 * mechanism we use in order to remain ABI compliant. 219 * Because this is about ABI, always use the A32 instructions, 220 * despite the fact that our actual vdso trampoline is T16. 221 */ 222 if (is_fdpic) { 223 write_arm_fdpic_sigreturn(frame->retcode, 224 is_rt ? RT_SIGFRAME_RC3_OFFSET 225 : SIGFRAME_RC3_OFFSET); 226 } else { 227 write_arm_sigreturn(frame->retcode, 228 is_rt ? TARGET_NR_rt_sigreturn 229 : TARGET_NR_sigreturn); 230 } 231 232 if (ka->sa_flags & TARGET_SA_RESTORER) { 233 if (is_fdpic) { 234 /* Place the function descriptor in slot 3. */ 235 __put_user((abi_ulong)ka->sa_restorer, &frame->retcode[3]); 236 } else { 237 retcode = ka->sa_restorer; 238 } 239 } 240 241 env->regs[0] = usig; 242 if (is_fdpic) { 243 env->regs[9] = handler_fdpic_GOT; 244 } 245 env->regs[13] = sp_addr; 246 env->regs[14] = retcode; 247 env->regs[15] = handler & (thumb ? ~1 : ~3); 248 cpsr_write(env, cpsr, CPSR_IT | CPSR_T | CPSR_E, CPSRWriteByInstr); 249 250 return 0; 251 } 252 253 static abi_ulong *setup_sigframe_vfp(abi_ulong *regspace, CPUARMState *env) 254 { 255 int i; 256 struct target_vfp_sigframe *vfpframe; 257 vfpframe = (struct target_vfp_sigframe *)regspace; 258 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic); 259 __put_user(sizeof(*vfpframe), &vfpframe->size); 260 for (i = 0; i < 32; i++) { 261 __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]); 262 } 263 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr); 264 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc); 265 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst); 266 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2); 267 return (abi_ulong*)(vfpframe+1); 268 } 269 270 static abi_ulong *setup_sigframe_iwmmxt(abi_ulong *regspace, CPUARMState *env) 271 { 272 int i; 273 struct target_iwmmxt_sigframe *iwmmxtframe; 274 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace; 275 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic); 276 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size); 277 for (i = 0; i < 16; i++) { 278 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]); 279 } 280 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf); 281 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf); 282 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0); 283 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1); 284 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2); 285 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3); 286 return (abi_ulong*)(iwmmxtframe+1); 287 } 288 289 static void setup_sigframe(struct target_ucontext *uc, 290 target_sigset_t *set, CPUARMState *env) 291 { 292 struct target_sigaltstack stack; 293 int i; 294 abi_ulong *regspace; 295 296 /* Clear all the bits of the ucontext we don't use. */ 297 memset(uc, 0, offsetof(struct target_ucontext, tuc_mcontext)); 298 299 memset(&stack, 0, sizeof(stack)); 300 target_save_altstack(&stack, env); 301 memcpy(&uc->tuc_stack, &stack, sizeof(stack)); 302 303 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]); 304 /* Save coprocessor signal frame. */ 305 regspace = uc->tuc_regspace; 306 if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) { 307 regspace = setup_sigframe_vfp(regspace, env); 308 } 309 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 310 regspace = setup_sigframe_iwmmxt(regspace, env); 311 } 312 313 /* Write terminating magic word */ 314 __put_user(0, regspace); 315 316 for(i = 0; i < TARGET_NSIG_WORDS; i++) { 317 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]); 318 } 319 } 320 321 void setup_frame(int usig, struct target_sigaction *ka, 322 target_sigset_t *set, CPUARMState *regs) 323 { 324 struct sigframe *frame; 325 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame)); 326 327 trace_user_setup_frame(regs, frame_addr); 328 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { 329 goto sigsegv; 330 } 331 332 setup_sigframe(&frame->uc, set, regs); 333 334 if (setup_return(regs, ka, usig, frame, frame_addr)) { 335 goto sigsegv; 336 } 337 338 unlock_user_struct(frame, frame_addr, 1); 339 return; 340 sigsegv: 341 unlock_user_struct(frame, frame_addr, 1); 342 force_sigsegv(usig); 343 } 344 345 void setup_rt_frame(int usig, struct target_sigaction *ka, 346 target_siginfo_t *info, 347 target_sigset_t *set, CPUARMState *env) 348 { 349 struct rt_sigframe *frame; 350 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame)); 351 abi_ulong info_addr, uc_addr; 352 353 trace_user_setup_rt_frame(env, frame_addr); 354 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { 355 goto sigsegv; 356 } 357 358 info_addr = frame_addr + offsetof(struct rt_sigframe, info); 359 uc_addr = frame_addr + offsetof(struct rt_sigframe, sig.uc); 360 tswap_siginfo(&frame->info, info); 361 362 setup_sigframe(&frame->sig.uc, set, env); 363 364 if (setup_return(env, ka, usig, &frame->sig, frame_addr)) { 365 goto sigsegv; 366 } 367 368 env->regs[1] = info_addr; 369 env->regs[2] = uc_addr; 370 371 unlock_user_struct(frame, frame_addr, 1); 372 return; 373 sigsegv: 374 unlock_user_struct(frame, frame_addr, 1); 375 force_sigsegv(usig); 376 } 377 378 static int 379 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc) 380 { 381 int err = 0; 382 uint32_t cpsr; 383 384 __get_user(env->regs[0], &sc->arm_r0); 385 __get_user(env->regs[1], &sc->arm_r1); 386 __get_user(env->regs[2], &sc->arm_r2); 387 __get_user(env->regs[3], &sc->arm_r3); 388 __get_user(env->regs[4], &sc->arm_r4); 389 __get_user(env->regs[5], &sc->arm_r5); 390 __get_user(env->regs[6], &sc->arm_r6); 391 __get_user(env->regs[7], &sc->arm_r7); 392 __get_user(env->regs[8], &sc->arm_r8); 393 __get_user(env->regs[9], &sc->arm_r9); 394 __get_user(env->regs[10], &sc->arm_r10); 395 __get_user(env->regs[11], &sc->arm_fp); 396 __get_user(env->regs[12], &sc->arm_ip); 397 __get_user(env->regs[13], &sc->arm_sp); 398 __get_user(env->regs[14], &sc->arm_lr); 399 __get_user(env->regs[15], &sc->arm_pc); 400 __get_user(cpsr, &sc->arm_cpsr); 401 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr); 402 403 err |= !valid_user_regs(env); 404 405 return err; 406 } 407 408 static abi_ulong *restore_sigframe_vfp(CPUARMState *env, abi_ulong *regspace) 409 { 410 int i; 411 abi_ulong magic, sz; 412 uint32_t fpscr, fpexc; 413 struct target_vfp_sigframe *vfpframe; 414 vfpframe = (struct target_vfp_sigframe *)regspace; 415 416 __get_user(magic, &vfpframe->magic); 417 __get_user(sz, &vfpframe->size); 418 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) { 419 return 0; 420 } 421 for (i = 0; i < 32; i++) { 422 __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]); 423 } 424 __get_user(fpscr, &vfpframe->ufp.fpscr); 425 vfp_set_fpscr(env, fpscr); 426 __get_user(fpexc, &vfpframe->ufp_exc.fpexc); 427 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid 428 * and the exception flag is cleared 429 */ 430 fpexc |= (1 << 30); 431 fpexc &= ~((1 << 31) | (1 << 28)); 432 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc; 433 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst); 434 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2); 435 return (abi_ulong*)(vfpframe + 1); 436 } 437 438 static abi_ulong *restore_sigframe_iwmmxt(CPUARMState *env, 439 abi_ulong *regspace) 440 { 441 int i; 442 abi_ulong magic, sz; 443 struct target_iwmmxt_sigframe *iwmmxtframe; 444 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace; 445 446 __get_user(magic, &iwmmxtframe->magic); 447 __get_user(sz, &iwmmxtframe->size); 448 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) { 449 return 0; 450 } 451 for (i = 0; i < 16; i++) { 452 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]); 453 } 454 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf); 455 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf); 456 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0); 457 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1); 458 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2); 459 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3); 460 return (abi_ulong*)(iwmmxtframe + 1); 461 } 462 463 static int do_sigframe_return(CPUARMState *env, 464 target_ulong context_addr, 465 struct target_ucontext *uc) 466 { 467 sigset_t host_set; 468 abi_ulong *regspace; 469 470 target_to_host_sigset(&host_set, &uc->tuc_sigmask); 471 set_sigmask(&host_set); 472 473 if (restore_sigcontext(env, &uc->tuc_mcontext)) { 474 return 1; 475 } 476 477 /* Restore coprocessor signal frame */ 478 regspace = uc->tuc_regspace; 479 if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) { 480 regspace = restore_sigframe_vfp(env, regspace); 481 if (!regspace) { 482 return 1; 483 } 484 } 485 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 486 regspace = restore_sigframe_iwmmxt(env, regspace); 487 if (!regspace) { 488 return 1; 489 } 490 } 491 492 target_restore_altstack(&uc->tuc_stack, env); 493 494 #if 0 495 /* Send SIGTRAP if we're single-stepping */ 496 if (ptrace_cancel_bpt(current)) 497 send_sig(SIGTRAP, current, 1); 498 #endif 499 500 return 0; 501 } 502 503 long do_sigreturn(CPUARMState *env) 504 { 505 abi_ulong frame_addr; 506 struct sigframe *frame = NULL; 507 508 /* 509 * Since we stacked the signal on a 64-bit boundary, 510 * then 'sp' should be word aligned here. If it's 511 * not, then the user is trying to mess with us. 512 */ 513 frame_addr = env->regs[13]; 514 trace_user_do_sigreturn(env, frame_addr); 515 if (frame_addr & 7) { 516 goto badframe; 517 } 518 519 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { 520 goto badframe; 521 } 522 523 if (do_sigframe_return(env, 524 frame_addr + offsetof(struct sigframe, uc), 525 &frame->uc)) { 526 goto badframe; 527 } 528 529 unlock_user_struct(frame, frame_addr, 0); 530 return -QEMU_ESIGRETURN; 531 532 badframe: 533 unlock_user_struct(frame, frame_addr, 0); 534 force_sig(TARGET_SIGSEGV); 535 return -QEMU_ESIGRETURN; 536 } 537 538 long do_rt_sigreturn(CPUARMState *env) 539 { 540 abi_ulong frame_addr; 541 struct rt_sigframe *frame = NULL; 542 543 /* 544 * Since we stacked the signal on a 64-bit boundary, 545 * then 'sp' should be word aligned here. If it's 546 * not, then the user is trying to mess with us. 547 */ 548 frame_addr = env->regs[13]; 549 trace_user_do_rt_sigreturn(env, frame_addr); 550 if (frame_addr & 7) { 551 goto badframe; 552 } 553 554 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { 555 goto badframe; 556 } 557 558 if (do_sigframe_return(env, 559 frame_addr + offsetof(struct rt_sigframe, sig.uc), 560 &frame->sig.uc)) { 561 goto badframe; 562 } 563 564 unlock_user_struct(frame, frame_addr, 0); 565 return -QEMU_ESIGRETURN; 566 567 badframe: 568 unlock_user_struct(frame, frame_addr, 0); 569 force_sig(TARGET_SIGSEGV); 570 return -QEMU_ESIGRETURN; 571 } 572 573 /* 574 * EABI syscalls pass the number via r7. 575 * Note that the kernel still adds the OABI syscall number to the trap, 576 * presumably for backward ABI compatibility with unwinders. 577 */ 578 #define ARM_MOV_R7_IMM(X) (0xe3a07000 | (X)) 579 #define ARM_SWI_SYS(X) (0xef000000 | (X) | ARM_SYSCALL_BASE) 580 581 #define THUMB_MOVS_R7_IMM(X) (0x2700 | (X)) 582 #define THUMB_SWI_SYS 0xdf00 583 584 static void write_arm_sigreturn(uint32_t *rc, int syscall) 585 { 586 __put_user(ARM_MOV_R7_IMM(syscall), rc); 587 __put_user(ARM_SWI_SYS(syscall), rc + 1); 588 /* Wrote 8 of 12 bytes */ 589 } 590 591 static void write_thm_sigreturn(uint32_t *rc, int syscall) 592 { 593 __put_user(THUMB_SWI_SYS << 16 | THUMB_MOVS_R7_IMM(syscall), rc); 594 /* Wrote 4 of 12 bytes */ 595 } 596 597 /* 598 * Stub needed to make sure the FD register (r9) contains the right value. 599 * Use the same instruction sequence as the kernel. 600 */ 601 static void write_arm_fdpic_sigreturn(uint32_t *rc, int ofs) 602 { 603 assert(ofs <= 0xfff); 604 __put_user(0xe59d3000 | ofs, rc + 0); /* ldr r3, [sp, #ofs] */ 605 __put_user(0xe8930908, rc + 1); /* ldm r3, { r3, r9 } */ 606 __put_user(0xe12fff13, rc + 2); /* bx r3 */ 607 /* Wrote 12 of 12 bytes */ 608 } 609 610 static void write_thm_fdpic_sigreturn(void *vrc, int ofs) 611 { 612 uint16_t *rc = vrc; 613 614 assert((ofs & ~0x3fc) == 0); 615 __put_user(0x9b00 | (ofs >> 2), rc + 0); /* ldr r3, [sp, #ofs] */ 616 __put_user(0xcb0c, rc + 1); /* ldm r3, { r2, r3 } */ 617 __put_user(0x4699, rc + 2); /* mov r9, r3 */ 618 __put_user(0x4710, rc + 3); /* bx r2 */ 619 /* Wrote 8 of 12 bytes */ 620 } 621 622 void setup_sigtramp(abi_ulong sigtramp_page) 623 { 624 uint32_t total_size = 8 * RETCODE_BYTES; 625 uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, total_size, 0); 626 627 assert(tramp != NULL); 628 629 default_sigreturn = sigtramp_page; 630 write_arm_sigreturn(&tramp[0 * RETCODE_WORDS], TARGET_NR_sigreturn); 631 write_thm_sigreturn(&tramp[1 * RETCODE_WORDS], TARGET_NR_sigreturn); 632 write_arm_sigreturn(&tramp[2 * RETCODE_WORDS], TARGET_NR_rt_sigreturn); 633 write_thm_sigreturn(&tramp[3 * RETCODE_WORDS], TARGET_NR_rt_sigreturn); 634 635 sigreturn_fdpic_tramp = sigtramp_page + 4 * RETCODE_BYTES; 636 write_arm_fdpic_sigreturn(tramp + 4 * RETCODE_WORDS, 637 offsetof(struct sigframe, retcode[3])); 638 write_thm_fdpic_sigreturn(tramp + 5 * RETCODE_WORDS, 639 offsetof(struct sigframe, retcode[3])); 640 write_arm_fdpic_sigreturn(tramp + 6 * RETCODE_WORDS, 641 offsetof(struct rt_sigframe, sig.retcode[3])); 642 write_thm_fdpic_sigreturn(tramp + 7 * RETCODE_WORDS, 643 offsetof(struct rt_sigframe, sig.retcode[3])); 644 645 unlock_user(tramp, sigtramp_page, total_size); 646 } 647