int steal_cleanup_child(struct steal_pty_state *steal) { if (ptrace_memcpy_to_child(&steal->child, steal->child_scratch, "/dev/null", sizeof("/dev/null"))) { return steal->child.error; } int nullfd = do_syscall(&steal->child, openat, -1, steal->child_scratch, O_RDWR, 0, 0, 0); if (nullfd < 0) { return steal->child.error; } int i; for (i = 0; i < steal->master_fds.n; ++i) { do_dup2(&steal->child, nullfd, steal->master_fds.fds[i]); } do_syscall(&steal->child, close, nullfd, 0, 0, 0, 0, 0); do_syscall(&steal->child, close, steal->child_fd, 0, 0, 0, 0, 0); steal->child_fd = 0; ptrace_restore_regs(&steal->child); ptrace_detach_child(&steal->child); ptrace_wait(&steal->child); return 0; }
static int do_fork(struct ptrace_child *child) { if (ptrace_syscall_numbers(child)->nr_fork != -1) { return do_syscall(child, fork, 0, 0, 0, 0, 0, 0); } else { return do_syscall(child, clone, SIGCHLD, 0, 0, 0, 0, 0); } }
static int do_dup2(struct ptrace_child *child, int oldfd, int newfd) { if (oldfd == newfd) { return 0; } if (ptrace_syscall_numbers(child)->nr_dup2 != -1) { return do_syscall(child, dup2, oldfd, newfd, 0, 0, 0, 0); } else { return do_syscall(child, dup3, oldfd, newfd, 0, 0, 0, 0); } }
int do_setsid(struct ptrace_child *child) { int err = 0; struct ptrace_child dummy; err = do_fork(child); if (err < 0) return err; debug("Forked a child: %ld", child->forked_pid); err = ptrace_finish_attach(&dummy, child->forked_pid); if (err < 0) goto out_kill; dummy.state = ptrace_after_syscall; copy_user(&dummy, child); if (ptrace_restore_regs(&dummy)) { err = dummy.error; goto out_kill; } err = do_syscall(&dummy, setpgid, 0, 0, 0, 0, 0, 0); if (err < 0) { error("Failed to setpgid: %s", strerror(-err)); goto out_kill; } move_process_group(child, child->pid, dummy.pid); err = do_syscall(child, setsid, 0, 0, 0, 0, 0, 0); if (err < 0) { error("Failed to setsid: %s", strerror(-err)); move_process_group(child, dummy.pid, child->pid); goto out_kill; } debug("Did setsid()"); out_kill: kill(dummy.pid, SIGKILL); ptrace_wait(&dummy); ptrace_detach_child(&dummy); do_syscall(child, wait4, dummy.pid, 0, WNOHANG, 0, 0, 0); return err; }
int _stat (const char *fname, struct stat *st) { int block[2]; block[0] = (int) fname; block[1] = (int) st; return do_syscall (SYS_stat, block); }
/** \brief Wait on a condition variable until another thread either signals * or broadcasts. * * \author Wesley Peck <*****@*****.**> * * This function will cause the callling thread to wait on the condition * variable. The thread can be woken up by either signalling or broadcasting * to the condition variable. The mutex object parameter is unlocked if the * thread will be blocked because of this function and will be relocked * before the function returns to the caller. * * \param cond This parameter is the condition variable object which will * be used. This parameter should be a pointer to a valid * memory location. * \param mutex This parameter is the mutex object which will be used. The * parameter should be a pointer to a valid memory location. * \return The return value is one of the following: * - HTHREAD_SUCCESS\n * The function successfully processed the request. * - HTHREAD_FAILURE\n * The function failed to process the request. */ Hint hthread_cond_wait( hthread_cond_t *cond, hthread_mutex_t *mutex ) { return (Hint)do_syscall( HTHREAD_SYSCALL_COND_WAIT, (void*)cond, (void*)mutex, NULL, NULL, NULL ); }
/** \brief Signal a condition variable object to wake up all threads which * is waiting for the condition to occur. * * \author Wesley Peck <*****@*****.**> * * This function will wake up all of the threads which are waiting on the * condition variable. If the condition variable has no waiting threads * then nothing will occur. * * \param cond This parameter is the condition variable object which will * be used. This parameter should be a pointer to a valid * memory location. * \return The return value is one of the following: * - HTHREAD_SUCCESS\n * The function successfully processed the request. * - HTHREAD_FAILURE\n * The function failed to process the request. */ Hint hthread_cond_broadcast( hthread_cond_t *cond ) { return (Hint)do_syscall( HTHREAD_SYSCALL_COND_BROADCAST, (void*)cond, NULL, NULL, NULL, NULL ); }
/** \internal * \brief Set the given threads scheduling parameter. * * \author Wesley Peck <*****@*****.**> * * This function sets the given threads priority value and returns * it to the caller. The priority of a thread ranges from 0 to 127 with * smaller values indicating higher priorities. * * Setting a threads priority can only be done by the thread itself or * the parent of the thread. If a thread other than these two attempts * to change another thread's priority then an error value will be returned. * * \param th The thread id of the thread to set the priority for. * \param pl The scheduling policy to use. This parameter is unused. * \param pr The priority value to give to the thread. This value should * be in the range 0 to 127 with lower values indicating higher * priority. * \return This function returns one of the following:\n * - HT_SUCCESS\n * The thread's priority was updated to the new value. * - HT_FAILURE\n * The thread's priority was not updated because the * set priority operation failed. */ Hint hthread_setschedparam( hthread_t th, Hint pl, const struct sched_param *pr ) { return (Hint)do_syscall( HTHREAD_SYSCALL_SETPRI, (void*)th, (void*)(pr->sched_priority), NULL, NULL, NULL ); }
/** \brief Signal a condition variable object to wake up one thread which * is waiting for the condition to occur. * * \author Wesley Peck <*****@*****.**> * * This function will wake up a single thread which is waiting on the * condition variable. If the condition variable has no waiting threads * then nothing will occur. * * This function will wake up exactly one thread, however, the exact thread * which is woken up is undefined. * * \param cond This parameter is the condition variable object which will * be used. This parameter should be a pointer to a valid * memory location. * \return The return value is one of the following: * - HTHREAD_SUCCESS\n * The function successfully processed the request. * - HTHREAD_FAILURE\n * The function failed to process the request. */ Hint hthread_cond_signal( hthread_cond_t *cond ) { return (Hint)do_syscall( HTHREAD_SYSCALL_COND_SIGNAL, (void*)cond, NULL, NULL, NULL, NULL ); }
/** \brief Attempt to acquire a mutex but return an error condition if the * mutex could not be acquired. * * \author Wesley Peck <*****@*****.**> * * This function will attempt to acquire a mutex. If the mutex is already * held by another thread then the function will return with a failure * instead of blocking until the mutex can be acquired. * * \param mutex This parameter is the mutex object which is going to * be acquired. This parameter should be a pointer to a * valid memory location. * \return The return value is one of the following: * - HTHREAD_SUCCESS\n * The mutex was successfully acquired. * - HTHREAD_BUSY\n * The mutex has already been locked by another thread. * - HTHREAD_FAILURE\n * The lock was not acquired. This indicates that either * the mutex object is invalid or that some unknown * error has occurred. */ Hint hthread_mutex_trylock( hthread_mutex_t *mutex ) { return (Hint)do_syscall( HTHREAD_SYSCALL_MUTEX_TRYLOCK, (void*)mutex, NULL, NULL, NULL, NULL ); }
int ignore_hup(struct ptrace_child *child, unsigned long scratch_page) { int err; if (ptrace_syscall_numbers(child)->nr_signal != -1) { err = do_syscall(child, signal, SIGHUP, (unsigned long)SIG_IGN, 0, 0, 0, 0); } else { struct sigaction act = { .sa_handler = SIG_IGN, }; err = ptrace_memcpy_to_child(child, scratch_page, &act, sizeof act); if (err < 0) return err; err = do_syscall(child, rt_sigaction, SIGHUP, scratch_page, 0, 8, 0, 0); } return err; }
int _kill (int n, int m) { int block[2]; block[0] = n; block[1] = m; return do_syscall (SYS_kill, block); }
int _open (const char *path, int flags) { int block[2]; block[0] = (int) path; block[1] = flags; return do_syscall (SYS_open, block); }
int _fstat (int file, struct stat *st) { int block[2]; block[0] = file; block[1] = (int) st; return do_syscall (SYS_fstat, block); }
int _lseek (int file, int ptr, int whence) { int block[3]; block[0] = file; block[1] = ptr; block[2] = whence; return do_syscall (SYS_lseek, block); }
int _write (int file, char *ptr, int len) { int block[3]; block[0] = file; block[1] = (int) ptr; block[2] = len; return do_syscall (SYS_write, block); }
// Find the fd(s) in the terminal emulator process that corresponds to // the master side of the target's pty. Store the result in // steal->master_fds. int find_master_fd(struct steal_pty_state *steal) { DIR *dir; struct dirent *d; struct stat st; int err; char buf[PATH_MAX]; snprintf(buf, sizeof buf, "/proc/%d/fd/", steal->child.pid); if ((dir = opendir(buf)) == NULL) return errno; while ((d = readdir(dir)) != NULL) { if (d->d_name[0] == '.') continue; snprintf(buf, sizeof buf, "/proc/%d/fd/%s", steal->child.pid, d->d_name); if (stat(buf, &st) < 0) continue; debug("Checking fd: %s: st_dev=%x", d->d_name, (int)st.st_rdev); if (st.st_rdev != PTMX_DEVICE) continue; debug("found a ptmx fd: %s", d->d_name); err = do_syscall(&steal->child, ioctl, atoi(d->d_name), TIOCGPTN, steal->child_scratch, 0, 0, 0); if (err < 0) { debug(" error doing TIOCGPTN: %s", strerror(-err)); continue; } int ptn; err = ptrace_memcpy_from_child(&steal->child, &ptn, steal->child_scratch, sizeof(ptn)); if (err < 0) { debug(" error getting ptn: %s", strerror(steal->child.error)); continue; } if (ptn == (int)minor(steal->target_stat.ctty)) { debug("found a master fd: %d", atoi(d->d_name)); if (fd_array_push(&steal->master_fds, atoi(d->d_name)) != 0) { error("unable to allocate memory for fd array!"); return ENOMEM; } } } if (steal->master_fds.n == 0) { return ESRCH; } return 0; }
/** \internal * \brief Retreive the given threads priority. * * \author Wesley Peck <*****@*****.**> * * This function retrieves the given threads priority value and returns * it to the caller. The priority of a thread ranges from 0 to 127 with * smaller values indicating higher priorities. * * \param th The thread id to retrieve the priority of. * \return This function returns a positive value in the range 0 to 127 * upon success and a negative value to indicate failure. */ Hint hthread_getschedparam( hthread_t th, Hint *policy, struct sched_param *pr ) { // Make sure policy is not a NULL pointer before // dereferencing it. You may accidentally write // to the Microblaze's IVT if (policy != NULL) *policy = SCHED_OTHER; return (Hint)do_syscall( HTHREAD_SYSCALL_GETPRI, (void*)th, (void*)(&pr->sched_priority), NULL, NULL, NULL ); }
static inline int syscall(int num, ...) { va_list ap; va_start(ap, num); uint32_t a[MAX_ARGS]; int i, ret; for (i = 0; i < MAX_ARGS; i ++) { a[i] = va_arg(ap, uint32_t); } va_end(ap); ret = do_syscall(a[0], a[1], a[2], a[3], a[4], num); return ret; }
int ignore_hup(struct ptrace_child *child, child_addr_t scratch_page) { int err; struct sigaction act = { .sa_handler = SIG_IGN, }; err = ptrace_memcpy_to_child(child, scratch_page, &act, sizeof act); if (err < 0) return err; err = do_syscall(child, rt_sigaction, SIGHUP, (unsigned long)scratch_page, 0, 8, 0, 0); return err; }
static void syscall_handler(struct dune_tf *tf) { // printf("Syscall No. %d\n", tf->rax); if (tf->rax >= SYSCALL_START) return do_syscall(tf, tf->rax - SYSCALL_START); if (syscall_check_params(tf) == -1) return; KSTATS_POP(NULL); KSTATS_PUSH(posix_syscall, NULL); syscall_do(tf); KSTATS_POP(NULL); KSTATS_PUSH(user, NULL); }
int main( int argc, char *argv[] ) { char buf[65536] __attribute__((aligned(32))); uint32_t aica_addr = AICA_RAM_BASE; int len; int totallen = 0; aica_disable(); /* Load ARM program from stdin and copy to ARM memory */ while( (len = read(0, buf, sizeof(buf))) > 0 ) { if(memcpy_to_aica( aica_addr, buf, len ) != 0 ) { printf( "Failed to load program!\n" ); return 1; } aica_addr += len; totallen += len; } printf( "Program loaded (%d bytes)\n", totallen); /* Main loop waiting for IO commands */ aica_enable(); do { g2_fifo_wait(); irq_disable(); int syscall = long_read(AICA_SYSCALL); irq_enable(); if( syscall != -1 ) { if( syscall == -2 ) { fprintf( stderr, "ARM aborted with general exception\n" ); return -2; } else if( syscall == SYS_EXIT ) { printf( "Exiting at ARM request\n" ); aica_disable(); return long_read(AICA_SYSCALL_ARG1); } else { uint32_t result = do_syscall( syscall, long_read(AICA_SYSCALL_ARG1), long_read(AICA_SYSCALL_ARG2), long_read(AICA_SYSCALL_ARG3) ); g2_fifo_wait(); irq_disable(); long_write( AICA_SYSCALL_RETURN, result ); long_write( AICA_SYSCALL, -1 ); irq_enable(); } } } while( 1 ); }
void main (int argc, char* argv[]) { int i; int rc = 0; /* Open the file */ strcat(the_file, dir_name); strcat(the_file, "/"); strcat(the_file, file_name); if ((fp = open (the_file, O_RDWR)) == -1) { fprintf (stderr, "error opening %s\n", the_file); exit (-1); } int my_pid = getpid(); fprintf(stdout, "System call getpid() returns %d\n", my_pid); /* open the input file */ if ((fdin = open (argv[1], O_RDONLY)) < 0) errx (-1, "can't open input for reading"); /* find size of input file */ if (fstat (fdin,&statbuf) < 0) errx (-1,"fstat error"); /* mmap the input file */ if ((src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == (caddr_t) -1) errx (-1, "mmap error for input"); do_syscall("vmlogger_new"); fprintf(stdout, "Module vmlogger returns %s", resp_buf); if(strncmp(argv[1] , "BigFileRandom", sizeof("BigFileRandom")) == 0){ do_mmap_stuff_rand(); } else if(strncmp(argv[1] , "BigFileSequential", sizeof("BigFileSequential")) == 0){ do_mmap_stuff_seq(); } else if(strncmp(argv[1] , "BigFileStride", sizeof("BigFileStride")) == 0){ do_mmap_stuff_stride(); } //else do nothing // close (fp); } /* end main() */
unsigned long ptrace_socketcall(struct ptrace_child *child, unsigned long scratch, unsigned long socketcall, unsigned long p0, unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4) { // We assume that socketcall is only used on 32-bit // architectures. If there are any 64-bit architectures that do // socketcall, and we port to them, this will need to change. uint32_t args[] = {p0, p1, p2, p3, p4}; int err; err = ptrace_memcpy_to_child(child, scratch, &args, sizeof args); if (err < 0) return (unsigned long)err; return do_syscall(child, socketcall, socketcall, scratch, 0, 0, 0, 0); }
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) { struct procstat *procstat; struct kinfo_proc *kp; unsigned int cnt; int i; int err; procstat = procstat_open_sysctl(); kp = procstat_getprocs(procstat, KERN_PROC_PGRP, from, &cnt); for (i = 0; i < cnt; i++) { debug("Change pgid for pid %d to %d", kp[i].ki_pid, to); err = do_syscall(child, setpgid, kp[i].ki_pid, to, 0, 0, 0, 0); if (err < 0) error(" failed: %s", strerror(-err)); } procstat_freeprocs(procstat, kp); procstat_close(procstat); }
void main (int argc, char* argv[]) { int i; int rc = 0; /* Open the file */ strcat(the_file, dir_name); //fprintf(stdout, "dir_name %s\n", dir_name); strcat(the_file, "/"); strcat(the_file, file_name); //fprintf(stdout, "file_name %s\n", file_name); if ((fp = open (the_file, O_RDWR)) == -1) { fprintf (stderr, "error opening %s\n", the_file); exit (-1); } int my_pid = getpid(); char* argS = malloc(sizeof(char) * MAX_CALL); i = 1; while(1){ if(i < argc){ strcat(argS, argv[i]); } if(i < argc - 1){ strcat(argS, " "); } else{break;} i++; } strcat(argS, "\0"); //fprintf(stdout, "Strcmp, %i", strcmp("event_create myev", argS) ); fprintf(stdout, "Process %d calls usersync with: %s\n",my_pid, argS); do_syscall(argS); fprintf(stdout, "Module usersync returns %s to PID %d\n", resp_buf, my_pid); close (fp); free(argS); } /* end main() */
void irq_handle(TrapFrame *tf) { /* TODO: Re-organize the ``TrapFrame'' structure in `include/irq.h' * to match the trap frame built during ``do_irq.S''. Remove the * following line after you are done. */ int irq = tf->irq; if (irq < 0) { panic("unexpected exception %d",irq); } else if (irq == 0x80) { do_syscall(tf); } else if (irq < 1000) { panic("Unexpected exception #%d at eip = %x", irq, tf->eip); } else if (irq >= 1000) { int irq_id = irq - 1000; assert(irq_id < NR_HARD_INTR); struct IRQ_t *f = handles[irq_id]; while (f != NULL) { /* call handlers one by one */ f->routine(); f = f->next; } } }
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) { DIR *dir; struct dirent *d; pid_t pid; char *p; int err; if ((dir = opendir("/proc/")) == NULL) return; while ((d = readdir(dir)) != NULL) { if (d->d_name[0] == '.') continue; pid = strtol(d->d_name, &p, 10); if (*p) continue; if (getpgid(pid) == from) { debug("Change pgid for pid %d", pid); err = do_syscall(child, setpgid, pid, to, 0, 0, 0, 0); if (err < 0) error(" failed: %s", strerror(-err)); } } closedir(dir); }
static void do_unmap(struct ptrace_child *child, child_addr_t addr, unsigned long len) { if (addr == (child_addr_t) - 1) return; do_syscall(child, munmap, (unsigned long)addr, len, 0, 0, 0, 0); }
int steal_pty(pid_t pid, int *pty) { int err = 0; struct steal_pty_state steal = {}; long page_size = sysconf(_SC_PAGE_SIZE); if ((err = preflight_check(pid))) goto out; if ((err = get_terminal_state(&steal, pid))) goto out; if ((err = setup_steal_socket(&steal))) goto out; debug("Listening on socket: %s", steal.addr_un.sun_path); debug("Attaching terminal emulator pid=%d", steal.emulator_pid); if ((err = grab_pid(steal.emulator_pid, &steal.child, &steal.child_scratch))) goto out; debug("Attached to terminal emulator (pid %d)", (int)steal.emulator_pid); if ((err = find_master_fd(&steal))) { error("Unable to find the fd for the pty!"); goto out; } if ((err = setup_steal_socket_child(&steal))) goto out; if ((err = steal_child_pty(&steal))) goto out; if ((err = steal_block_hup(&steal))) goto out; if ((err = steal_cleanup_child(&steal))) goto out; goto out_no_child; out: if (steal.ptyfd) { close(steal.ptyfd); steal.ptyfd = 0; } if (steal.child_fd > 0) do_syscall(&steal.child, close, steal.child_fd, 0, 0, 0, 0, 0); if (steal.child_scratch > 0) do_unmap(&steal.child, steal.child_scratch, page_size); if (steal.child.state != ptrace_detached) { ptrace_restore_regs(&steal.child); ptrace_detach_child(&steal.child); } out_no_child: if (steal.sockfd > 0) { close(steal.sockfd); unlink(steal.addr_un.sun_path); } if (steal.tmpdir[0]) { rmdir(steal.tmpdir); } if (steal.ptyfd) *pty = steal.ptyfd; free(steal.master_fds.fds); return err; }