コード例 #1
0
ファイル: se_ptrace.c プロジェクト: 0-T-0/linux-sgx
long int ptrace (enum __ptrace_request __request, ...)
{
    pid_t pid;
    void *addr, *data;
    va_list ap;

    va_start(ap, __request);
    pid = va_arg(ap, pid_t);
    addr = va_arg(ap, void *);
    data = va_arg(ap, void *);
    va_end(ap);

    if(__request == PTRACE_GETREGS)
    {
        return get_regs(pid, addr, data);
    }
    else if(__request == PTRACE_SETREGS)
    {
        return set_regs(pid, addr, data);
    }
#if 0
    //some old system may require this command to get register
    else if(__request == PTRACE_PEEKUSER)
    {

    }
#endif
    else if(__request == PTRACE_GETFPREGS)
    {
        return get_fpregs(pid, addr, data, FALSE);
    }
    else if(__request == PTRACE_SETFPREGS)
    {
        return set_fpregs(pid, addr, data, FALSE);

    }
    else if(__request == PTRACE_GETFPXREGS)
    {
        return get_fpregs(pid, addr, data, TRUE);
    }
    else if(__request == PTRACE_SETFPXREGS)
    {
        return set_fpregs(pid, addr, data, TRUE);
    }

    //xstave for avx
    else if(__request == PTRACE_GETREGSET)
    {
        return get_regset(pid, addr, data);
    }
    else if(__request == PTRACE_SETREGSET)
    {
        return set_regset(pid, addr, data);
    }
    //For other request just forward it to real ptrace call;
    return g_sys_ptrace(__request, pid, addr, data);
}
コード例 #2
0
ファイル: syscall.c プロジェクト: bigzz/strace_android
static long
get_regset(pid_t pid)
{
# ifdef ARCH_IOVEC_FOR_GETREGSET
	/* variable iovec */
	ARCH_IOVEC_FOR_GETREGSET.iov_len = sizeof(ARCH_REGS_FOR_GETREGSET);
	return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS,
		      &ARCH_IOVEC_FOR_GETREGSET);
# else
	/* constant iovec */
	static struct iovec io = {
		.iov_base = &ARCH_REGS_FOR_GETREGSET,
		.iov_len = sizeof(ARCH_REGS_FOR_GETREGSET)
	};
	return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &io);

# endif
}
#endif /* ARCH_REGS_FOR_GETREGSET */

void
get_regs(pid_t pid)
{
#ifdef ARCH_REGS_FOR_GETREGSET
# ifdef X86_64
	/* Try PTRACE_GETREGSET first, fallback to PTRACE_GETREGS. */
	static int getregset_support;

	if (getregset_support >= 0) {
		get_regs_error = get_regset(pid);
		if (getregset_support > 0)
			return;
		if (get_regs_error >= 0) {
			getregset_support = 1;
			return;
		}
		if (errno == EPERM || errno == ESRCH)
			return;
		getregset_support = -1;
	}
	getregs_old(pid);
# else /* !X86_64 */
	/* Assume that PTRACE_GETREGSET works. */
	get_regs_error = get_regset(pid);
# endif
#elif defined ARCH_REGS_FOR_GETREGS
# if defined SPARC || defined SPARC64
	/* SPARC systems have the meaning of data and addr reversed */
	get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&ARCH_REGS_FOR_GETREGS, 0);
# elif defined POWERPC
	static bool old_kernel = 0;
	if (old_kernel)
		goto old;
	get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
	if (get_regs_error && errno == EIO) {
		old_kernel = 1;
 old:
		get_regs_error = getregs_old(pid);
	}
# else
	/* Assume that PTRACE_GETREGS works. */
	get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
# endif

#else /* !ARCH_REGS_FOR_GETREGSET && !ARCH_REGS_FOR_GETREGS */
#  warning get_regs is not implemented for this architecture yet
	get_regs_error = 0;
#endif
}

/* Returns:
 * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently.
 * 1: ok, continue in trace_syscall_entering().
 * other: error, trace_syscall_entering() should print error indicator
 *    ("????" etc) and bail out.
 */
int
get_scno(struct tcb *tcp)
{
	if (get_regs_error)
		return -1;

	long scno = 0;

#include "get_scno.c"

	tcp->scno = scno;
	if (SCNO_IS_VALID(tcp->scno)) {
		tcp->s_ent = &sysent[scno];
		tcp->qual_flg = qual_flags[scno];
	} else {
		static const struct_sysent unknown = {
			.nargs = MAX_ARGS,
			.sys_flags = 0,
			.sys_func = printargs,
			.sys_name = "system call",
		};
		tcp->s_ent = &unknown;
		tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS;
		if (debug_flag)
			fprintf(stderr, "pid %d invalid syscall %ld\n",
				tcp->pid, scno);
	}
	return 1;
}

/* Return -1 on error or 1 on success (never 0!) */
static int
get_syscall_args(struct tcb *tcp)
{
#include "get_syscall_args.c"
	return 1;
}

static void
get_error(struct tcb *tcp)
{
	const bool check_errno = !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS);
	tcp->u_error = 0;

#include "get_error.c"
}

/* Returns:
 * 1: ok, continue in trace_syscall_exiting().
 * -1: error, trace_syscall_exiting() should print error indicator
 *    ("????" etc) and bail out.
 */
static int
get_syscall_result(struct tcb *tcp)
{
#if defined ARCH_REGS_FOR_GETREGSET || defined ARCH_REGS_FOR_GETREGS
	/* already done by get_regs */
#else
# include "get_syscall_result.c"
#endif
	get_error(tcp);
	return 1;
}