示例#1
0
文件: strace.c 项目: CPFL/gxen
static void
print_execve(const struct syscallname *name,
             abi_long arg1, abi_long arg2, abi_long arg3,
             abi_long arg4, abi_long arg5, abi_long arg6)
{
    abi_ulong arg_ptr_addr;
    char *s;

    if (!(s = lock_user_string(arg1)))
        return;
    gemu_log("%s(\"%s\",{", name->name, s);
    unlock_user(s, arg1, 0);

    for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
        abi_ulong *arg_ptr, arg_addr, s_addr;

        arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
        if (!arg_ptr)
            return;
        arg_addr = tswapl(*arg_ptr);
        unlock_user(arg_ptr, arg_ptr_addr, 0);
        if (!arg_addr)
            break;
        if ((s = lock_user_string(arg_addr))) {
            gemu_log("\"%s\",", s);
            unlock_user(s, s_addr, 0);
        }
    }

    gemu_log("NULL})");
}
示例#2
0
文件: m68k-semi.c 项目: 3a9LL/panda
void do_m68k_semihosting(CPUM68KState *env, int nr)
{
    uint32_t args;
    void *p;
    void *q;
    uint32_t len;
    uint32_t result;

    args = env->dregs[1];
    switch (nr) {
    case HOSTED_EXIT:
        gdb_exit(env, env->dregs[0]);
        exit(env->dregs[0]);
    case HOSTED_OPEN:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", ARG(0), (int)ARG(1),
                           ARG(2), ARG(3));
            return;
        } else {
            if (!(p = lock_user_string(ARG(0)))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = open(p, translate_openflags(ARG(2)), ARG(3));
                unlock_user(p, ARG(0), 0);
            }
        }
        break;
    case HOSTED_CLOSE:
        {
            /* Ignore attempts to close stdin/out/err.  */
            int fd = ARG(0);
            if (fd > 2) {
                if (use_gdb_syscalls()) {
                    gdb_do_syscall(m68k_semi_cb, "close,%x", ARG(0));
                    return;
                } else {
                    result = close(fd);
                }
            } else {
                result = 0;
            }
            break;
        }
    case HOSTED_READ:
        len = ARG(2);
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "read,%x,%x,%x",
                           ARG(0), ARG(1), len);
            return;
        } else {
            if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = read(ARG(0), p, len);
                unlock_user(p, ARG(1), len);
            }
        }
        break;
    case HOSTED_WRITE:
        len = ARG(2);
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "write,%x,%x,%x",
                           ARG(0), ARG(1), len);
            return;
        } else {
            if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = write(ARG(0), p, len);
                unlock_user(p, ARG(0), 0);
            }
        }
        break;
    case HOSTED_LSEEK:
        {
            uint64_t off;
            off = (uint32_t)ARG(2) | ((uint64_t)ARG(1) << 32);
            if (use_gdb_syscalls()) {
                m68k_semi_is_fseek = 1;
                gdb_do_syscall(m68k_semi_cb, "fseek,%x,%lx,%x",
                               ARG(0), off, ARG(3));
            } else {
                off = lseek(ARG(0), off, ARG(3));
                /* FIXME - handle put_user() failure */
                put_user_u32(off >> 32, args);
                put_user_u32(off, args + 4);
                put_user_u32(errno, args + 8);
            }
            return;
        }
    case HOSTED_RENAME:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "rename,%s,%s",
                           ARG(0), (int)ARG(1), ARG(2), (int)ARG(3));
            return;
        } else {
            p = lock_user_string(ARG(0));
            q = lock_user_string(ARG(2));
            if (!p || !q) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = rename(p, q);
            }
            unlock_user(p, ARG(0), 0);
            unlock_user(q, ARG(2), 0);
        }
        break;
    case HOSTED_UNLINK:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "unlink,%s",
                           ARG(0), (int)ARG(1));
            return;
        } else {
            if (!(p = lock_user_string(ARG(0)))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = unlink(p);
                unlock_user(p, ARG(0), 0);
            }
        }
        break;
    case HOSTED_STAT:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "stat,%s,%x",
                           ARG(0), (int)ARG(1), ARG(2));
            return;
        } else {
            struct stat s;
            if (!(p = lock_user_string(ARG(0)))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = stat(p, &s);
                unlock_user(p, ARG(0), 0);
            }
            if (result == 0) {
                translate_stat(env, ARG(2), &s);
            }
        }
        break;
    case HOSTED_FSTAT:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "fstat,%x,%x",
                           ARG(0), ARG(1));
            return;
        } else {
            struct stat s;
            result = fstat(ARG(0), &s);
            if (result == 0) {
                translate_stat(env, ARG(1), &s);
            }
        }
        break;
    case HOSTED_GETTIMEOFDAY:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "gettimeofday,%x,%x",
                           ARG(0), ARG(1));
            return;
        } else {
            qemu_timeval tv;
            struct gdb_timeval *p;
            result = qemu_gettimeofday(&tv);
            if (result != 0) {
                if (!(p = lock_user(VERIFY_WRITE,
                                    ARG(0), sizeof(struct gdb_timeval), 0))) {
                    /* FIXME - check error code? */
                    result = -1;
                } else {
                    p->tv_sec = cpu_to_be32(tv.tv_sec);
                    p->tv_usec = cpu_to_be64(tv.tv_usec);
                    unlock_user(p, ARG(0), sizeof(struct gdb_timeval));
                }
            }
        }
        break;
    case HOSTED_ISATTY:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "isatty,%x", ARG(0));
            return;
        } else {
            result = isatty(ARG(0));
        }
        break;
    case HOSTED_SYSTEM:
        if (use_gdb_syscalls()) {
            gdb_do_syscall(m68k_semi_cb, "system,%s",
                           ARG(0), (int)ARG(1));
            return;
        } else {
            if (!(p = lock_user_string(ARG(0)))) {
                /* FIXME - check error code? */
                result = -1;
            } else {
                result = system(p);
                unlock_user(p, ARG(0), 0);
            }
        }
        break;
    case HOSTED_INIT_SIM:
#if defined(CONFIG_USER_ONLY)
        {
        TaskState *ts = env->opaque;
        /* Allocate the heap using sbrk.  */
        if (!ts->heap_limit) {
            abi_ulong ret;
            uint32_t size;
            uint32_t base;

            base = do_brk(0);
            size = SEMIHOSTING_HEAP_SIZE;
            /* Try a big heap, and reduce the size if that fails.  */
            for (;;) {
                ret = do_brk(base + size);
                if (ret >= (base + size)) {
                    break;
                }
                size >>= 1;
            }
            ts->heap_limit = base + size;
        }
        /* This call may happen before we have writable memory, so return
           values directly in registers.  */
        env->dregs[1] = ts->heap_limit;
        env->aregs[7] = ts->stack_base;
        }
#else
        /* FIXME: This is wrong for boards where RAM does not start at
           address zero.  */
        env->dregs[1] = ram_size;
        env->aregs[7] = ram_size;
#endif
        return;
    default:
        cpu_abort(env, "Unsupported semihosting syscall %d\n", nr);
        result = 0;
    }
示例#3
0
abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                            abi_long arg2, abi_long arg3, abi_long arg4,
                            abi_long arg5, abi_long arg6)
{
    abi_long ret;
    void *p;

#ifdef DEBUG
    gemu_log("openbsd syscall %d\n", num);
#endif
    if(do_strace)
        print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);

    switch(num) {
    case TARGET_OPENBSD_NR_exit:
#ifdef TARGET_GPROF
        _mcleanup();
#endif
        gdb_exit(cpu_env, arg1);
        /* XXX: should free thread stack and CPU env */
        _exit(arg1);
        ret = 0; /* avoid warning */
        break;
    case TARGET_OPENBSD_NR_read:
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
            goto efault;
        ret = get_errno(read(arg1, p, arg3));
        unlock_user(p, arg2, ret);
        break;
    case TARGET_OPENBSD_NR_write:
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
            goto efault;
        ret = get_errno(write(arg1, p, arg3));
        unlock_user(p, arg2, 0);
        break;
    case TARGET_OPENBSD_NR_open:
        if (!(p = lock_user_string(arg1)))
            goto efault;
        ret = get_errno(open(path(p),
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
                             arg3));
        unlock_user(p, arg1, 0);
        break;
    case TARGET_OPENBSD_NR_mmap:
        ret = get_errno(target_mmap(arg1, arg2, arg3,
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
                                    arg5,
                                    arg6));
        break;
    case TARGET_OPENBSD_NR_mprotect:
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
        break;
    case TARGET_OPENBSD_NR_syscall:
    case TARGET_OPENBSD_NR___syscall:
        ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
        break;
    default:
        ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
        break;
    }
 fail:
#ifdef DEBUG
    gemu_log(" = %ld\n", ret);
#endif
    if (do_strace)
        print_openbsd_syscall_ret(num, ret);
    return ret;
 efault:
    ret = -TARGET_EFAULT;
    goto fail;
}
示例#4
0
/* do_syscall() should always have a single exit point at the end so
   that actions, such as logging of syscall results, can be performed.
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                            abi_long arg2, abi_long arg3, abi_long arg4,
                            abi_long arg5, abi_long arg6, abi_long arg7,
                            abi_long arg8)
{
    abi_long ret;
    void *p;

#ifdef DEBUG
    gemu_log("freebsd syscall %d\n", num);
#endif
    if(do_strace)
        print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);

    switch(num) {
    case TARGET_FREEBSD_NR_exit:
#ifdef TARGET_GPROF
        _mcleanup();
#endif
        gdb_exit(cpu_env, arg1);
        /* XXX: should free thread stack and CPU env */
        _exit(arg1);
        ret = 0; /* avoid warning */
        break;
    case TARGET_FREEBSD_NR_read:
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
            goto efault;
        ret = get_errno(read(arg1, p, arg3));
        unlock_user(p, arg2, ret);
        break;
    case TARGET_FREEBSD_NR_write:
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
            goto efault;
        ret = get_errno(write(arg1, p, arg3));
        unlock_user(p, arg2, 0);
        break;
    case TARGET_FREEBSD_NR_writev:
        {
            int count = arg3;
            struct iovec *vec;

            vec = alloca(count * sizeof(struct iovec));
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
                goto efault;
            ret = get_errno(writev(arg1, vec, count));
            unlock_iovec(vec, arg2, count, 0);
        }
        break;
    case TARGET_FREEBSD_NR_open:
        if (!(p = lock_user_string(arg1)))
            goto efault;
        ret = get_errno(open(path(p),
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
                             arg3));
        unlock_user(p, arg1, 0);
        break;
    case TARGET_FREEBSD_NR_mmap:
        ret = get_errno(target_mmap(arg1, arg2, arg3,
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
                                    arg5,
                                    arg6));
        break;
    case TARGET_FREEBSD_NR_mprotect:
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
        break;
    case TARGET_FREEBSD_NR_break:
        ret = do_obreak(arg1);
        break;
#ifdef __FreeBSD__
    case TARGET_FREEBSD_NR___sysctl:
        ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6);
        break;
#endif
    case TARGET_FREEBSD_NR_sysarch:
        ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
        break;
    case TARGET_FREEBSD_NR_syscall:
    case TARGET_FREEBSD_NR___syscall:
        ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0);
        break;
    default:
        ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
        break;
    }
 fail:
#ifdef DEBUG
    gemu_log(" = %ld\n", ret);
#endif
    if (do_strace)
        print_freebsd_syscall_ret(num, ret);
    return ret;
 efault:
    ret = -TARGET_EFAULT;
    goto fail;
}
示例#5
0
uint32_t do_syscall_arm(ProgramBase *prog, uint32_t num, uint32_t arg1,uint32_t
    arg2, uint32_t arg3,uint32_t arg4,uint32_t arg5, uint32_t arg6, FILE *syscallTrace)

{ 

#ifdef DEBUG2
  printf ("syscall %d \n", num);
#endif

  uint32_t ret;  
  void  *p;
#if defined (CONFIG_ESESC_system) || defined (CONFIG_ESESC_user)
  struct timespec startTime;
  clock_gettime(CLOCK_REALTIME,&startTime);
#endif

  char tmp_str[128];
  char pc[32];
  char systrace_syscall_num[32];
  char emul_syscall_num[32];
  int i, j, ret1; 
  regex_t re1;
  regmatch_t match[3];

  if (syscallTrace != NULL) {

    // Example trace file section
    //
    //----------
    //pc: 0x8174
    //syscall: 122
    //Linux
    //masca1
    //3.0.0-1205-omap4
    //#10-Ubuntu SMP PREEMPT Thu Sep 29 03:57:24 UTC 2011
    //armv7l
    //----------
    //pc: 0x8230
    //syscall: 4
    //----------

    //printf("Advance to the section \n");
    fgets(tmp_str, sizeof tmp_str, syscallTrace);
    tmp_str[strlen (tmp_str) - 1] = '\0';
    memset(tmp_str, '\0', 128);

    // read pc
    fgets(pc, sizeof pc, syscallTrace);
    pc[strlen (pc) - 1] = '\0';

    // read syscall number
    fgets(tmp_str, sizeof tmp_str, syscallTrace);
    tmp_str[strlen (tmp_str) - 1] = '\0';
    //printf("pc %s, syscall %s \n", pc, tmp_str);

    ret1 = regcomp(&re1, "syscall: ([0-9]+)", REG_EXTENDED);
    ret1 = regexec(&re1, tmp_str, 2, match, 0);
    if(!ret1) {
      j = 0;
      for(i = match[1].rm_so; i < match[1].rm_eo; i++) {
        systrace_syscall_num[j] = tmp_str[i];
        j++;
      }
      systrace_syscall_num[j] = '\0';
    }else{
      I(0);
    }

    sprintf(emul_syscall_num, "%d", num);

    // Sanity check for syscall number
    if (strcmp(systrace_syscall_num, emul_syscall_num) != 0) {
      printf("Emulator syscall trace and expected syscall trace are out of sync \n");
      printf("  syscall num - Expected: %s, Emulator: %s\n", systrace_syscall_num, emul_syscall_num);
      I(0);
      // exit(0);
    }
  }

  switch(num) {
    case TARGET_NR_exit:
      exit(arg1);
      return 0;
      break;
    case TARGET_NR_exit_group:
      exit(arg1);
      return 0;
      break;
    case TARGET_NR_write: 
      ret = write(arg1, prog->g2h(arg2), arg3);
      return ret;
      break;
    case TARGET_NR_read: 
      if (arg3 == 0) {
        ret = 0;
      }else{
        ret = read(arg1, prog->g2h(arg2), arg3);
      }
      return ret;
      break;
      /* case TARGET_NR_ioctl:
         do_ioctl(prog, arg1, arg2, arg3);
         return 0;
         break;*/
    case TARGET_NR_lseek:
      ret = lseek(arg1, arg2, arg3);
      return ret;
      break;
    case TARGET_NR_gettimeofday:
      {          
        // FIXME: Not correct
        struct timeval tv; 
        gettimeofday(&tv, NULL);
      }  
      return 0;
      break;
    case TARGET_NR_open:
      // FIXME: how to check if this is a open(a,b,c) or open(a,b)
      ret = open((const char *)prog->g2h(arg1), arg2);
      return ret;
      break;        
    case TARGET_NR_close:
      ret = close(arg1);
      return ret;
      break;
    case TARGET_NR_mkdir:
      p = lock_user_string(prog, arg1);
      ret = mkdir((const char *)p, arg2);
      return ret; 
      break;
    case TARGET_NR_rmdir:
      p = lock_user_string(prog, arg1);
      ret = rmdir((const char *)p);
      return ret;                
      break;
    case TARGET_NR_rename:
      {
        void *p2;
        p  = lock_user_string(prog, arg1);
        p2 = lock_user_string(prog, arg2);
        if (!p || !p2)
          ret = -TARGET_EFAULT;
        else
          rename((const char *)p, (const char *)p2);
      }
      return 0;
      break;

    case TARGET_NR_uname:
      // copy 390 bytes from syscalltrace to buf
      //Linux
      //masca1
      //3.0.0-1205-omap4
      //#10-Ubuntu SMP PREEMPT Thu Sep 29 03:57:24 UTC 2011
      {
        struct utsname *uts_buf = (struct utsname *)prog->g2h(arg1);

        if (syscallTrace != NULL) {

          for (i = 0; i < 5; i++) {
            memset(tmp_str, '\0', 65);
            fgets(tmp_str, sizeof tmp_str, syscallTrace);
            tmp_str[strlen (tmp_str) - 1] = '\0';
            if(i == 0)
              strcpy(uts_buf->sysname, tmp_str);
            else if(i == 1)
              strcpy(uts_buf->nodename, tmp_str);
            else if(i == 2)
              strcpy(uts_buf->release, tmp_str);
            else if(i == 3)
              strcpy(uts_buf->version, tmp_str);
            else if(i == 4)
              strcpy(uts_buf->machine, tmp_str);
          }
        } else {
          if (uname(uts_buf) < 0)
            return (-1);
        }
      }
      return 0;
      break;

    case TARGET_NR_brk:
      {

        if (!arg1) {
          return target_brk;
        } else if(arg1 < target_original_brk) { 
          return target_brk; 
        } else {

          if(arg1 < brk_page) {
            if(arg1 > target_brk) {
              // initialize as it may contain garbage due to a previous heap usage
              // (grown then shrunken)
              memset(prog->g2h(target_brk), 0, arg1 - target_brk);
            }
            // deallocate is handled automatically here.
            target_brk = arg1;
            return target_brk;
          } 

          // Need to allocate memory.
          // We can't call local host brk() system call which tends to change the 
          // simulator program's brk_addr.
          // What we need to adjust here is the simulated virtual memory data segment.
          // so simulate brk here by calling realloc to reallocate simulator data segment.

          uint32_t size_incr = PAGE_ALIGN_UP(arg1 - brk_page); 

          uint32_t old_size;
          uint32_t *data_ptr = NULL;
          data_ptr = prog->get_data_buffer(&old_size);

          uint8_t *new_data_ptr = (uint8_t *)realloc(data_ptr, (old_size + size_incr));

          if (new_data_ptr != NULL) {

            prog->set_data_buffer((old_size + size_incr), new_data_ptr);
            target_brk = arg1;
            brk_page = PAGE_ALIGN_UP(target_brk);

            return target_brk;
          } else {
            return (-1);
          }
        }
      }
      return target_brk;;
      break;

    case TARGET_NR_fstat64:
      {
        if (syscallTrace == NULL) {
          ret = fstat(arg1, (struct stat *)prog->g2h(arg2));
          return ret;
        } else {
          // copy 144 bytes (size of stat structure) from systrace file
          // number of lines in the file: total 144 bytes/8 bytes per line = 18 lines
          for (i=0; i < 18; i++) {
            memset(tmp_str, '\0', 128);
            fgets(tmp_str, 128, syscallTrace);
            long long int val = strtoull(tmp_str, NULL, 16);
            memcpy( (prog->g2h(arg2 + (i * 8) )), &val, 8);
          }
        }
      }
      return 0;
      break;

    case TARGET_NR_mmap2:
      {
        if (arg1 != 0x00000000) {
          // FIXME: This is the non-zero address case.
          // The address gives a hint to the kernel about where to map the file.
          // We might still do a malloc but need to remember a mapping of the native
          // address (i.e arg1) to pointer returned by malloc.
          printf("TARGET_NR_mmap2 map address not zero!!! This case is not handled \n");
          exit(-1);
        }
        uint8_t *p = (uint8_t *)malloc(arg2);
        if (p == MAP_FAILED)
          return -1;
        else {
          prog->set_mem_mapped_file_endpts((long)p, arg2);
          return (long)p;
        }
      }
      return 0;
      printf("return address 0x%08x \n", p);
      break;

    case TARGET_NR_getpid:
      getpid();
      return 0;
      break;
    case TARGET_NR_kill:
      kill(arg1, target_to_host_signal(arg2));
      return 0;                 
      break;
    case TARGET_NR_pause:
      pause();
      return 0;
      break;
#ifdef TARGET_NR_shutdown
    case TARGET_NR_shutdown:
      shutdown(arg1, arg2);
      return 0;
      break;
#endif
#ifdef TARGET_NR_semget
    case TARGET_NR_semget:
      semget(arg1, arg2, arg3);
      return 0;       
      break; 
#endif
    case TARGET_NR_setdomainname:
      p = lock_user_string(prog, arg1);
      setdomainname((const char *)p, arg2);
      return 0;      
      break;
    case TARGET_NR_getsid:
      getsid(arg1);
      return 0;
      break;
#if defined(TARGET_NR_fdatasync)
      /* Not on alpha (osf_datasync ?) */
    case TARGET_NR_fdatasync:
      fdatasync(arg1);
      return 0;
      break;
#endif
#ifdef TARGET_NR_getuid32
    case TARGET_NR_getuid32:
      getuid();
      return 0;
      break;
#endif 
    case TARGET_NR_ioctl:
      printf("ioctl syscall not implemented\n");
      return 0;
      break;
    default:
      printf("syscall %d is not implemented\n", num);
      exit(-1);
  }    

}