Ejemplo n.º 1
0
long
powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
{
	struct reg regs;
	struct freebsd_syscall *fsc;
	struct syscall *sc;
	lwpid_t tid;
	long retval;
	int errorp, i;

	if (trussinfo->curthread->fsc == NULL)
		return (-1);

	tid = trussinfo->curthread->tid;

	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
		fprintf(trussinfo->outfile, "\n");
		return (-1);
	}

	retval = regs.fixreg[3];
	errorp = !!(regs.cr & 0x10000000);

	/*
	 * This code, while simpler than the initial versions I used, could
	 * stand some significant cleaning.
	 */

	fsc = trussinfo->curthread->fsc;
	sc = fsc->sc;
	if (!sc) {
		for (i = 0; i < fsc->nargs; i++)
			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
	} else {
		/*
		 * Here, we only look for arguments that have OUT masked in --
		 * otherwise, they were handled in the syscall_entry function.
		 */
		for (i = 0; i < sc->nargs; i++) {
			char *temp;
			if (sc->args[i].type & OUT) {
				/*
				 * If an error occurred, then don't bother
				 * getting the data; it may not be valid.
				 */
				if (errorp) {
					asprintf(&temp, "0x%lx",
					    fsc->args[sc->args[i].offset]);
				} else {
					temp = print_arg(&sc->args[i],
					    fsc->args, retval, trussinfo);
				}
				fsc->s_args[i] = temp;
			}
		}
	}

	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
	    strcmp(fsc->name, "exit") == 0))
		trussinfo->curthread->in_syscall = 1;

	/*
	 * It would probably be a good idea to merge the error handling,
	 * but that complicates things considerably.
	 */

	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
	    retval, fsc->sc);
	free_fsc(fsc);

	return (retval);
}
Ejemplo n.º 2
0
long
powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
{
    struct reg regs;
    long retval;
    int i;
    int errorp;
    struct syscall *sc;

    if (fsc.name == NULL)
        return (-1);

    cpid = trussinfo->curthread->tid;

    if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
        fprintf(trussinfo->outfile, "\n");
        return (-1);
    }
    retval = regs.fixreg[3];
    errorp = !!(regs.cr & 0x10000000);

    /*
     * This code, while simpler than the initial versions I used, could
     * stand some significant cleaning.
     */

    sc = fsc.sc;
    if (!sc) {
        for (i = 0; i < fsc.nargs; i++)
            asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
    } else {
        /*
         * On 32-bit big-endian, the low word of a 64-bit return is
         * in the greater address. Switch to this. XXX note that
         * print_syscall_ret can't handle 64-bit return values (llseek)
         */
        if (sc->ret_type == 2)
            retval = regs.fixreg[4];

        /*
         * Here, we only look for arguments that have OUT masked in --
         * otherwise, they were handled in the syscall_entry function.
         */
        for (i = 0; i < sc->nargs; i++) {
            char *temp;
            if (sc->args[i].type & OUT) {
                /*
                 * If an error occurred, than don't bothe getting the data;
                 * it may not be valid.
                 */
                if (errorp)
                    asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
                else
                    temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
                fsc.s_args[i] = temp;
            }
        }
    }

    if (fsc.name != NULL &&
            (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
        trussinfo->curthread->in_syscall = 1;
    }


    /*
     * It would probably be a good idea to merge the error handling,
     * but that complicates things considerably.
     */

    print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
                      retval, fsc.sc);
    clear_fsc();

    return (retval);
}
Ejemplo n.º 3
0
long
amd64_linux32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
{
  struct reg regs;
  long retval;
  int i;
  int errorp;
  struct syscall *sc;

  if (fsc.name == NULL)
	return (-1);

  cpid = trussinfo->curthread->tid;
  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
  {
    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
    return (-1);
  }

  retval = regs.r_rax;
  errorp = !!(regs.r_rflags & PSL_C);

  /*
   * This code, while simpler than the initial versions I used, could
   * stand some significant cleaning.
   */

  sc = fsc.sc;
  if (!sc) {
    for (i = 0; i < fsc.nargs; i++)
      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
  } else {
    /*
     * Here, we only look for arguments that have OUT masked in --
     * otherwise, they were handled in the syscall_entry function.
     */
    for (i = 0; i < sc->nargs; i++) {
      char *temp;
      if (sc->args[i].type & OUT) {
	/*
	 * If an error occurred, than don't bothe getting the data;
	 * it may not be valid.
	 */
	if (errorp)
	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
	else
	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
	fsc.s_args[i] = temp;
      }
    }
  }

  /*
   * It would probably be a good idea to merge the error handling,
   * but that complicates things considerably.
   */
  if (errorp) {
    for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++)
      if (retval == bsd_to_linux_errno[i])
      break;
  }

  if (fsc.name != NULL &&
      (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
	trussinfo->curthread->in_syscall = 1;
  }

  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
                    errorp ? i : retval, fsc.sc);
  clear_fsc();

  return (retval);
}
Ejemplo n.º 4
0
Archivo: strace.c Proyecto: CPFL/gxen
void
print_openbsd_syscall_ret(int num, abi_long ret)
{
    print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
}
Ejemplo n.º 5
0
Archivo: strace.c Proyecto: CPFL/gxen
void
print_netbsd_syscall_ret(int num, abi_long ret)
{
    print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
}
Ejemplo n.º 6
0
Archivo: strace.c Proyecto: CPFL/gxen
void
print_freebsd_syscall_ret(int num, abi_long ret)
{
    print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
}