static inline unsigned long __remote_syscall(pid_t pid, int syscall_no, char *syscall_name, int use_ebx, unsigned long ebx, int use_ecx, unsigned long ecx, int use_edx, unsigned long edx, int use_esi, unsigned long esi, int use_edi, unsigned long edi) { struct user_regs_struct orig_regs, regs; unsigned long ret; int status; if (!syscall_loc) { fprintf(stderr, "No syscall locations found! Cannot do remote syscall.\n"); abort(); } if (save_registers(pid, &orig_regs) < 0) abort(); memcpy(®s, &orig_regs, sizeof(regs)); regs.eax = syscall_no; if (use_ebx) regs.ebx = ebx; if (use_ecx) regs.ecx = ecx; if (use_edx) regs.edx = edx; if (use_esi) regs.esi = esi; if (use_edi) regs.edi = edi; /* Set up registers for ptrace syscall */ regs.eip = syscall_loc; if (restore_registers(pid, ®s) < 0) abort(); /* Execute call */ if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) { perror("ptrace singlestep"); abort(); } ret = waitpid(pid, &status, 0); if (ret == -1) { perror("Failed to wait for child"); abort(); } /* Get our new registers */ if (save_registers(pid, ®s) < 0) abort(); /* Return everything back to normal */ if (restore_registers(pid, &orig_regs) < 0) abort(); if (regs.eax < 0) { errno = -regs.eax; return -1; } return regs.eax; }
void vp9_short_idct10_16x16_add_neon(int16_t *input, uint8_t *dest, int dest_stride) { int16_t pass1_output[16*16] = {0}; int16_t row_idct_output[16*16] = {0}; // save d8-d15 register values. save_registers(); /* Parallel idct on the upper 8 rows */ // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the // stage 6 result in pass1_output. vp9_short_idct10_16x16_add_neon_pass1(input, pass1_output, 8); // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines // with result in pass1(pass1_output) to calculate final result in stage 7 // which will be saved into row_idct_output. vp9_short_idct10_16x16_add_neon_pass2(input+1, row_idct_output, pass1_output, 0, dest, dest_stride); /* Skip Parallel idct on the lower 8 rows as they are all 0s */ /* Parallel idct on the left 8 columns */ // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the // stage 6 result in pass1_output. vp9_short_idct16x16_add_neon_pass1(row_idct_output, pass1_output, 8); // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines // with result in pass1(pass1_output) to calculate final result in stage 7. // Then add the result to the destination data. vp9_short_idct16x16_add_neon_pass2(row_idct_output+1, row_idct_output, pass1_output, 1, dest, dest_stride); /* Parallel idct on the right 8 columns */ // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the // stage 6 result in pass1_output. vp9_short_idct16x16_add_neon_pass1(row_idct_output+8*16, pass1_output, 8); // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines // with result in pass1(pass1_output) to calculate final result in stage 7. // Then add the result to the destination data. vp9_short_idct16x16_add_neon_pass2(row_idct_output+8*16+1, row_idct_output+8, pass1_output, 1, dest+8, dest_stride); // restore d8-d15 register values. restore_registers(); return; }
static void pre_ckpt() { int r; DPRINTF("\n*** Before checkpointing. ***\n"); if (dummy == 1) { r = save_registers(); if (r < 0) { DPRINTF("ERROR: Querying CPU state from the kernel returned: %d\n", r); DPRINTF("WARNING: Please try checkpointing again\n"); } r = save_pit2(); if (r < 0) { DPRINTF("ERROR: Querying PIT state from the kernel returned: %d\n", r); DPRINTF("WARNING: Please try checkpointing again\n"); } r = save_irqchip(); if (r < 0) { DPRINTF("ERROR: Querying IRQCHIP state from the kernel returned: %d\n", r); DPRINTF("WARNING: Please try checkpointing again\n"); } // dummy = 2; } else if (dummy >= 2) { r = restore_registers(); if (r < 0) { DPRINTF("ERROR: Restoring the registers returned: %d\n", r); DPRINTF("WARNING: Cannot continue\n"); exit(-1); } } }
void userspace(union uml_pt_regs *regs) { int err, status, op, pid = userspace_pid[0]; int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ while(1){ restore_registers(pid, regs); /* Now we set local_using_sysemu to be used for one loop */ local_using_sysemu = get_using_sysemu(); op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL)); err = ptrace(op, pid, 0, 0); if(err) panic("userspace - could not resume userspace process, " "pid=%d, ptrace operation = %d, errno = %d\n", op, errno); CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if(err < 0) panic("userspace - waitpid failed, errno = %d\n", errno); regs->skas.is_user = 1; save_registers(pid, regs); UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if(WIFSTOPPED(status)){ switch(WSTOPSIG(status)){ case SIGSEGV: handle_segv(pid, regs); break; case SIGTRAP + 0x80: handle_trap(pid, regs, local_using_sysemu); break; case SIGTRAP: relay_signal(SIGTRAP, regs); break; case SIGIO: case SIGVTALRM: case SIGILL: case SIGBUS: case SIGFPE: case SIGWINCH: user_signal(WSTOPSIG(status), regs, pid); break; default: printk("userspace - child stopped with signal " "%d\n", WSTOPSIG(status)); } interrupt_end(); /* Avoid -ERESTARTSYS handling in host */ PT_SYSCALL_NR(regs->skas.regs) = -1; } } }
void userspace(union uml_pt_regs *regs) { int err, status, op, pid = userspace_pid[0]; restore_registers(regs); err = ptrace(PTRACE_SYSCALL, pid, 0, 0); if(err) panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", errno); while(1){ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if(err < 0) panic("userspace - waitpid failed, errno = %d\n", errno); regs->skas.is_user = 1; save_registers(regs); if(WIFSTOPPED(status)){ switch(WSTOPSIG(status)){ case SIGSEGV: handle_segv(pid); break; case SIGTRAP: handle_trap(pid, regs); break; case SIGIO: case SIGVTALRM: case SIGILL: case SIGBUS: case SIGFPE: case SIGWINCH: user_signal(WSTOPSIG(status), regs); break; default: printk("userspace - child stopped with signal " "%d\n", WSTOPSIG(status)); } interrupt_end(); } restore_registers(regs); op = singlestepping_skas() ? PTRACE_SINGLESTEP : PTRACE_SYSCALL; err = ptrace(op, pid, 0, 0); if(err) panic("userspace - PTRACE_SYSCALL failed, " "errno = %d\n", errno); } }
fault (void) { /* Transfer all registers and fault code to the stack in canonical order: registers in order of GDB register number, followed by fault code. */ PUSH_REGISTERS; /* Transfer them to saved_regs and fault_code. */ save_registers (); restore_gdb (); /* Control does not reach here */ }
void get_process(pid_t pid, int flags, struct list *process_image, long *bin_offset) { int success = 0; char* pagebackup; struct user_regs_struct r; struct cp_chunk *libcgp; start_ptrace(pid); if (save_registers(pid, &r) < 0) { fprintf(stderr, "Unable to save process's registers!\n"); goto out_ptrace; } /* The order below is very important. Do not change without good reason and * careful thought. */ fetch_chunks_tls(pid, flags, process_image); /* this gives us a scribble zone: */ fetch_chunks_vma(pid, flags, process_image, bin_offset); if (!scribble_zone) { fprintf(stderr, "[-] No suitable scribble zone could be found. Aborting.\n"); goto out_ptrace; } pagebackup = backup_page(pid, (void*)scribble_zone); fetch_chunks_fd(pid, flags, process_image); fetch_chunks_sighand(pid, flags, process_image); fetch_chunks_i387_data(pid, flags, process_image); fetch_chunks_regs(pid, flags, process_image, process_was_stopped); /* add __getpid chunk to the image list, if requested by the user */ if ((flags & REFRESH_PID) && fetch_chunk_libcgp(&libcgp) == 0) list_append(process_image, libcgp); success = 1; restore_page(pid, (void*)scribble_zone, pagebackup); restore_registers(pid, &r); out_ptrace: end_ptrace(pid, flags); if (!success) abort(); }
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) { unsigned long *ptr = addr, tmp; long ret; int pid = task->mm->context.id.u.pid; /* * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to * be safe), we need to call arch_prctl on the host because * setting %fs may result in something else happening (like a * GDT or thread.fs being set instead). So, we let the host * fiddle the registers and thread struct and restore the * registers afterwards. * * So, the saved registers are stored to the process (this * needed because a stub may have been the last thing to run), * arch_prctl is run on the host, then the registers are read * back. */ switch (code) { case ARCH_SET_FS: case ARCH_SET_GS: ret = restore_registers(pid, ¤t->thread.regs.regs); if (ret) return ret; break; case ARCH_GET_FS: case ARCH_GET_GS: /* * With these two, we read to a local pointer and * put_user it to the userspace pointer that we were * given. If addr isn't valid (because it hasn't been * faulted in or is just bogus), we want put_user to * fault it in (or return -EFAULT) instead of having * the host return -EFAULT. */ ptr = &tmp; } ret = os_arch_prctl(pid, code, ptr); if (ret) return ret; switch (code) { case ARCH_SET_FS: current->thread.arch.fs = (unsigned long) ptr; ret = save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_SET_GS: ret = save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_GET_FS: ret = put_user(tmp, addr); break; case ARCH_GET_GS: ret = put_user(tmp, addr); break; } return ret; }
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) { unsigned long *ptr = addr, tmp; long ret; int pid = task->mm->context.id.u.pid; /* */ switch (code) { case ARCH_SET_FS: case ARCH_SET_GS: ret = restore_registers(pid, ¤t->thread.regs.regs); if (ret) return ret; break; case ARCH_GET_FS: case ARCH_GET_GS: /* */ ptr = &tmp; } ret = os_arch_prctl(pid, code, ptr); if (ret) return ret; switch (code) { case ARCH_SET_FS: current->thread.arch.fs = (unsigned long) ptr; ret = save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_SET_GS: ret = save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_GET_FS: ret = put_user(tmp, addr); break; case ARCH_GET_GS: ret = put_user(tmp, addr); break; } return ret; }
//method to set CPU to idle int cpu_idle(int *fp) { save_registers(); clear_cache(); return 0; }
void userspace(union uml_pt_regs *regs) { int err, status, op, pt_syscall_parm, pid = userspace_pid[0]; int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ restore_registers(regs); local_using_sysemu = get_using_sysemu(); pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL; err = ptrace(pt_syscall_parm, pid, 0, 0); if(err) panic("userspace - PTRACE_%s failed, errno = %d\n", local_using_sysemu ? "SYSEMU" : "SYSCALL", errno); while(1){ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if(err < 0) panic("userspace - waitpid failed, errno = %d\n", errno); regs->skas.is_user = 1; save_registers(regs); if(WIFSTOPPED(status)){ switch(WSTOPSIG(status)){ case SIGSEGV: handle_segv(pid); break; case SIGTRAP: handle_trap(pid, regs, local_using_sysemu); break; case SIGIO: case SIGVTALRM: case SIGILL: case SIGBUS: case SIGFPE: case SIGWINCH: user_signal(WSTOPSIG(status), regs); break; default: printk("userspace - child stopped with signal " "%d\n", WSTOPSIG(status)); } interrupt_end(); } restore_registers(regs); /*Now we ended the syscall, so re-read local_using_sysemu.*/ local_using_sysemu = get_using_sysemu(); pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL; op = singlestepping(NULL) ? PTRACE_SINGLESTEP : pt_syscall_parm; err = ptrace(op, pid, 0, 0); if(err) panic("userspace - PTRACE_%s failed, " "errno = %d\n", local_using_sysemu ? "SYSEMU" : "SYSCALL", errno); } }