Ejemplo n.º 1
0
void syslogd_print (int priority, char const * format, ...) 

{ 
	extern char const * host_name; 
	extern char const * program_name; 
	char buffer [TEXTLINE_MAX] = "no error message"; 
	size_t length = 0; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_error"); 

#endif

	if (program_name != (char const *) (0)) 
	{ 
		length += snprintf (buffer + length, sizeof (buffer) - length, "%s: ", program_name); 
	} 
	if ((format != (char const *) (0)) && (* format != (char) (0))) 
	{ 
		va_list arglist; 
		va_start (arglist, format); 
		length += vsnprintf (buffer + length, sizeof (buffer) - length, format, arglist); 
		va_end (arglist); 
	} 
	syslogd_queue (priority, host_name, buffer); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_error"); 

#endif

	return; 
} 
Ejemplo n.º 2
0
VOID fn_ret(CONTEXT *ctxt, UINT32 fid) {
    trace_enter();
    
    counter += 1;

    if (!call_stack.is_top_forgotten()) {
        while (is_jump_stack.top()) {
            FID fid = call_stack.top();
            if (is_instrumented[fid]) {
                param_t *new_ret = (param_t *) malloc(sizeof(param_t));
                new_ret->fid = fid;
                new_ret->counter = counter;
                new_ret->val = val_from_reg(ctxt, 0); 
                new_ret->is_addr = param_addr[fid][0];
                param_out->push_front(new_ret);
            }
            call_stack.pop();
            is_jump_stack.pop();
        }
        FID fid = call_stack.top();
        if (is_instrumented[fid]) {
            param_t *new_ret = (param_t *) malloc(sizeof(param_t));
            new_ret->fid = fid;
            new_ret->counter = counter;
            new_ret->val = val_from_reg(ctxt, 0); 
            new_ret->is_addr = param_addr[fid][0];
            param_out->push_front(new_ret);
        }
        call_stack.pop();
        is_jump_stack.pop();
    }

    trace_leave();
    return;
}
Ejemplo n.º 3
0
Archivo: type.cpp Proyecto: Frky/scat
VOID check_parameter_out(ADDRINT addr) {
    trace_enter();

    if (call_stack.is_top_forgotten()) {
        trace_leave();
        return;
    }

    FID fid = call_stack.top();
    UINT64 sp = sp_stack.top();
    if (sp + 1000 <= addr && addr < sp) {
        trace_leave();
        return;
    }

    unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
    for (unsigned int pid = 1; pid < param_val_size; pid++) {
        if (param_val[fid][pid]->back() == addr) {
            nb_out[fid][pid]++;
            trace_leave();
            return;
        }
    }

    trace_leave();
}
Ejemplo n.º 4
0
void fn_registered(
                    FID fid, 
                    unsigned int nb_param, 
                    vector<bool> type_param
                ) {

    trace_enter();

    /* Set the number of parameters */
    nb_p[fid] = nb_param;
    /* Set the array of booleans indicating which parameter is an ADDR */
    param_addr[fid] = (bool *) calloc(nb_p[fid], sizeof(bool));

    /* Is this function instrumented?*/
    is_instrumented[fid] = false;

    /* Iteration on parameters */
    for (unsigned int i = 0; i <= nb_p[fid]; i++) {
        if (type_param[i]) {
            param_addr[fid][i] = true;
            is_instrumented[fid] = true;
        }
        else
            param_addr[fid][i] = false;
    }

    trace_leave();
    return;
}
Ejemplo n.º 5
0
void syslogd_open_sockets (struct socket *sockets) 

{
	struct socket *socket = sockets;

#if SYSLOGD_TRACE

	trace_enter ("syslogd_open_sockets");

#endif

	do 
	{
		socket = socket->next;
		if (socket->desc != -1) 
		{
			continue;
		}
		if (socket->sockaddr == (struct sockaddr *)(0)) 
		{
			syslogd_error (EINVAL, "Missing socket address");
			continue;
		}

#ifdef SYSLOGD_UNIXAF

		if (socket->sockaddr->sa_family == AF_UNIX) 
		{
			struct sockaddr_un * sockaddr_un = (struct sockaddr_un *)(socket->sockaddr);
			syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "Opening host connection on %s", sockaddr_un->sun_path);
			socket->desc = syslogd_unix_socket (sockaddr_un);
			continue;
		}

#endif
#ifdef SYSLOGD_INETAF

		if (socket->sockaddr->sa_family == AF_INET) 
		{
			char buffer [HOSTADDR_MAX];
			struct sockaddr_in * sockaddr_in = (struct sockaddr_in *)(socket->sockaddr);
			getsocketname (buffer, sizeof (buffer), sockaddr_in);
			syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "Opening inet connection on %s", buffer);
			socket->desc = syslogd_inet_socket (sockaddr_in);
			continue;
		}

#endif

	}
	while (socket != sockets);

#if SYSLOGD_TRACE

	trace_leave ("syslogd_open_sockets");

#endif

	return;
}
Ejemplo n.º 6
0
Archivo: type.cpp Proyecto: Frky/scat
/*  Instrumentation of each instruction
 *  that uses a memory operand
 */
VOID Instruction(INS ins, VOID *v) {
    trace_enter();

    if (!INS_IsStackRead(ins)) {
        for (UINT32 memopIdx = 0; memopIdx < INS_MemoryOperandCount(ins); memopIdx++) {
            if (INS_MemoryOperandIsWritten(ins, memopIdx)) {
                INS_InsertCall(ins,
                                IPOINT_BEFORE,
                                (AFUNPTR) update_stack_heap_region,
                                IARG_CONST_CONTEXT,
                                IARG_MEMORYOP_EA, memopIdx,
                                IARG_END);

                UINT32 opIdx = INS_MemoryOperandIndexToOperandIndex(ins, memopIdx);
                REG base_reg = INS_OperandMemoryBaseReg(ins, opIdx);
                if (base_reg != REG_INVALID()) {
                    INS_InsertCall(ins,
                                    IPOINT_BEFORE,
                                    (AFUNPTR) check_parameter_out,
                                    IARG_REG_VALUE, base_reg,
                                    IARG_END);
                }
            }
        }
    }

    if (INS_IsCall(ins)) {
        if (INS_IsDirectCall(ins)) {
            ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins);
            FID fid = fn_lookup_by_address(addr);

            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_call,
                        IARG_CONST_CONTEXT,
                        IARG_UINT32, fid,
                        IARG_END);
        }
        else {
            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_indirect_call,
                        IARG_CONST_CONTEXT,
                        IARG_BRANCH_TARGET_ADDR,
                        IARG_END);
        }
    }

    if (INS_IsRet(ins)) {
        INS_InsertCall(ins,
                    IPOINT_BEFORE,
                    (AFUNPTR) fn_ret,
                    IARG_CONST_CONTEXT,
                    IARG_END);
    }

    trace_leave();
}
Ejemplo n.º 7
0
Archivo: type.cpp Proyecto: Frky/scat
VOID update_stack_heap_region(CONTEXT* ctxt, ADDRINT addr) {
    trace_enter();

    if (!is_addr(addr)) {
        stack_heap_region.extend(addr);
    }

    trace_leave();
}
Ejemplo n.º 8
0
VOID Commence() {

    trace_enter();

    /* Init instruction counter */
    counter = 0;
    init = true;
    string _addr, _name;
    if (ifile.is_open()) {
        while (ifile) {
            char m;
            unsigned int nb_param = 0;
            vector<bool> type_param;
            string img_name = read_part(&m);

            if (img_name.empty()) {
                continue;
            }

            ADDRINT img_addr = atol(read_part(&m).c_str());
            string name = read_part(&m);

            /* Read parameters */
            while (ifile && m != '\n') {
                string part = read_part(&m);
                switch (part[0]) {
                case 'A':
                    type_param.push_back(true);
                    break;
                case 'I':
                case 'V':
                    type_param.push_back(false);
                    break;
                case 'F':
                    type_param.push_back(false);
                    break;
                default:
                    type_param.push_back(false);
                }
                nb_param += 1;
            }

            FID fid = fn_register(img_name, img_addr, name);
            if (fid != FID_UNKNOWN) {
                fn_registered(fid, nb_param - 1, type_param);
            }
        }
    }

    gettimeofday(&start, NULL);

    trace_leave();

    return;
}
Ejemplo n.º 9
0
VOID Fini(INT32 code, VOID *v) {

    trace_enter();

    list<param_t *>::reverse_iterator it_in, it_out;
    it_in = param_in->rbegin();
    it_out = param_out->rbegin();

    int depth = 0;
    UINT64 last_date = -1;
    bool is_in = false;

    gettimeofday(&stop, NULL);

    ofile << "Elapsed time ] Commence ; Fini [ : " << (stop.tv_usec / 1000.0 + 1000 * stop.tv_sec - start.tv_sec * 1000 - start.tv_usec / 1000.0) / 1000.0 << "s" << endl;

    while (it_in != param_in->rend() || it_out != param_out->rend()) {
        // for (int i = 0; i < depth; i++) 
        //  ofile << " ";
        param_t *p;
        if (it_in == param_in->rend()) {
            p = *it_out;
            it_out++;
            is_in = false;
            ofile << "out:";
        } else if (it_out == param_out->rend() || (*it_out)->counter >= (*it_in)->counter) {
            p = *it_in;
            it_in++;
            is_in = true;
            ofile << "in:";
        } else {
            p = *it_out;
            it_out++;
            is_in = false;
            ofile << "out:";
        }
        if (p->is_addr)
            ofile << "addr:";
        else 
            ofile << "int:";
        if (last_date != p->counter) {
            if (is_in)
                depth++;
            else
                depth--;
        }
        last_date = p->counter;
        ofile << p->val << ":" << fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << ":" << p->pos << ":" << p->counter << endl;
    }
    ofile.close();

    trace_leave();

    return;
}
Ejemplo n.º 10
0
Archivo: type.cpp Proyecto: Frky/scat
VOID image_loaded(IMG img, void* data) {
    trace_enter();

    for (int i = 0; i < IMG_NumRegions(img); i++) {
        Region* region = data_regions + data_regions_size;
        data_regions_size++;

        region->low = IMG_RegionLowAddress(img, i);
        region->high = IMG_RegionHighAddress(img, i);
    }

    trace_leave();
}
Ejemplo n.º 11
0
void syslogd_stop (struct syslogd * syslogs, flag_t flags)

{
    extern char const * program_name;
    struct syslogd * syslog;

#if SYSLOGD_TRACE

    trace_enter ("syslogd_stop");

#endif

    syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "%s %s.%s stopped", program_name, VERSION, RELEASE);
    while (syslogs->next != syslogs)
    {
        syslog = syslogs->next;
        syslog->next->prev = syslogs;
        syslogs->next = syslog->next;
        if (syslog->f_repeat > 0)
        {
            syslogd_write (syslog, flags);
        }
        if (syslog->f_sockaddr_in != (struct sockaddr_in *) (0))
        {
            free (syslog->f_sockaddr_in);
            syslog->f_sockaddr_in = (struct sockaddr_in *) (0);
        }
        switch (syslog->f_type)
        {
        case SYSLOGD_TYPE_HOST:
        case SYSLOGD_TYPE_FILE:
        case SYSLOGD_TYPE_PIPE:
        case SYSLOGD_TYPE_TERM:
        case SYSLOGD_TYPE_CONSOLE:
            close (syslog->f_desc);
            break;
        }
        syslog->prev = (struct syslogd *) (0);
        syslog->next = (struct syslogd *) (0);
        free (syslog->f_name);
        free (syslog);
    }

#if SYSLOGD_TRACE

    trace_leave ("syslogd_stop");

#endif

    return;
}
Ejemplo n.º 12
0
Archivo: type.cpp Proyecto: Frky/scat
VOID fn_indirect_call(CONTEXT* ctxt, ADDRINT target) {
    trace_enter();

    // Indirect call, we have to look up the function each time
    // The functions `fn_lookup` & `fn_register` needs PIN's Lock.
    // Locking is not implicit in inserted call, as opposed
    // to callback added with *_AddInstrumentFunction().
    PIN_LockClient();
    FID fid = fn_lookup_by_address(target);
    PIN_UnlockClient();

    fn_call(ctxt, fid);

    trace_leave();
}
Ejemplo n.º 13
0
Archivo: type.cpp Proyecto: Frky/scat
VOID fn_ret(CONTEXT *ctxt) {
    trace_enter();

    if (!call_stack.is_top_forgotten()) {
        FID fid = call_stack.top();

        if (has_return[fid] == 1) {
            add_val(fid, ctxt, 0, 0);
        }
    }

    call_stack.pop();
    sp_stack.pop();

    trace_leave();
}
Ejemplo n.º 14
0
void syslogd_configure (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	file_t fd; 
	char string [TEXTLINE_MAX]; 
	size_t lineno = 0; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_configure"); 

#endif

	if ((fd = open (filename, O_RDONLY)) == - 1) 
	{ 
		syslogd_error (errno, "cant open %s", filename); 
		return; 
	} 
	while (statement (fd, string, sizeof (string), & lineno)) 
	{ 
		if (* string != (char) (0)) 
		{ 
			struct syslogd * syslog = NEW (struct syslogd); 
			syslogd_parse (syslog, flags, string); 
			if (syslog->f_type == SYSLOGD_TYPE_NONE) 
			{ 
				free (syslog->f_name); 
				free (syslog); 
				continue; 
			} 
			syslog->prev = syslogs->prev; 
			syslogs->prev->next = syslog; 
			syslogs->prev = syslog; 
			syslog->next = syslogs; 
		} 
	} 
	close (fd); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_configure"); 

#endif

	return; 
} 
Ejemplo n.º 15
0
Archivo: type.cpp Proyecto: Frky/scat
VOID fn_call(CONTEXT *ctxt, FID fid) {
    trace_enter();

    call_stack.push(fid);

    UINT64 sp;
    PIN_GetContextRegval(ctxt, REG_RSP, (UINT8*) &sp);
    sp_stack.push(sp);

    nb_call[fid]++;
    unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
    for (unsigned int pid = 1; pid < param_val_size; pid++) {
        if (!param_is_not_addr[fid][pid])
            add_val(fid, ctxt, pid, sp);
    }

    trace_leave();
}
Ejemplo n.º 16
0
VOID fn_call(CONTEXT *ctxt, FID fid, bool is_jump) {
    
    trace_enter();

    call_stack.push(fid);
    is_jump_stack.push(is_jump);
    counter += 1;

    bool param_pushed = false;

    if (!is_instrumented[fid]) {
        trace_leave();
        return;
    }

    for (unsigned int i = 1; i <= nb_p[fid]; i++) {
        if (!param_addr[fid][i])
            continue;
        param_t *new_param = (param_t *) malloc(sizeof(param_t));
        new_param->fid = fid;
        new_param->counter = counter;
        new_param->val = val_from_reg(ctxt, i); 
        new_param->is_addr = param_addr[fid][i];
        new_param->pos = i;
        param_in->push_front(new_param);
        param_pushed = true;
    }

    /* If the function is instrumented (ie for instance has an ADDR as
       a return value) AND was not logged yet, create a special
       entry to log the date of call */
    if (!param_pushed) {
        param_t *new_addr = (param_t *) malloc(sizeof(param_t));
        new_addr->fid = fid;
        new_addr->counter = counter;
        new_addr->val = 0; // val_from_reg(ctxt, i); 
        new_addr->pos = 0;
        new_addr->is_addr = false; // true;
        param_in->push_front(new_addr);
    }

    trace_leave();
    return;
}
void
netbsd32_syscall(struct trapframe *frame)
{
	char *params;
	const struct sysent *callp;
	struct proc *p;
	struct lwp *l;
	int error;
	int i;
	register32_t code, args[2 + SYS_MAXSYSARGS];
	register_t rval[2];
	register_t args64[SYS_MAXSYSARGS];

	l = curlwp;
	p = l->l_proc;

	code = frame->tf_rax & (SYS_NSYSENT - 1);
	callp = p->p_emul->e_sysent + code;

	LWP_CACHE_CREDS(l, p);

	SYSCALL_COUNT(syscall_counts, code);
	SYSCALL_TIME_SYS_ENTRY(l, syscall_times, code);

	params = (char *)frame->tf_rsp + sizeof(int);

	if (callp->sy_argsize) {
		error = copyin(params, args, callp->sy_argsize);
		if (__predict_false(error != 0))
			goto bad;
		/* Recover 'code' - not in a register */
		code = frame->tf_rax & (SYS_NSYSENT - 1);
	}

	if (__predict_false(p->p_trace_enabled)
	    && !__predict_false(callp->sy_flags & SYCALL_INDIRECT)) {
		int narg = callp->sy_argsize >> 2;
		for (i = 0; i < narg; i++)
			args64[i] = args[i];
		error = trace_enter(code, args64, narg);
		if (__predict_false(error != 0))
			goto out;
	}
Ejemplo n.º 18
0
ADDRINT val_from_reg(CONTEXT *ctxt, unsigned int pid) {

    trace_enter();

    REG reg;
    switch (pid) {
    case 0:
        reg = REG_RAX;
        break;
    case 1:
        reg = REG_RDI;
        break;
    case 2:
        reg = REG_RSI;
        break;
    case 3:
        reg = REG_RDX;
        break;
    case 4:
        reg = REG_RCX;
        break;
    case 5:
        reg = REG_R8;
        break;
    case 6:
        reg = REG_R9;
        break;
    default:

        trace_leave();

        return 0;
    }

    trace_leave();

    return PIN_GetContextReg(ctxt, reg);
}
Ejemplo n.º 19
0
Archivo: type.cpp Proyecto: Frky/scat
VOID add_val(unsigned int fid, CONTEXT *ctxt, unsigned int pid, UINT64 sp) {
    trace_enter();

    if (param_val[fid][pid]->size() >= MAX_VALS_TO_COLLECT) {
        trace_leave();
        return;
    }

    UINT64 val;
    if (pid < 1 + nb_param_int[fid]) {
        PIN_GetContextRegval(ctxt, param_reg(pid), (UINT8*) &val);
    }
    else {
        unsigned int sp_offset = pid - (1 + nb_param_int[fid]);
        UINT64* addr = (UINT64*) (sp + sp_offset * 8);
        val = *addr;
    }

    if (val != 0)
        param_val[fid][pid]->push_front(val);

    trace_leave();
}
Ejemplo n.º 20
0
void syslogd_admin (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	FILE * fp; 
	struct syslogd * syslog; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_admin"); 

#endif

	if ((filename == (char *) (0)) || (* filename == (char) (0))) 
	{ 
		return; 
	} 
	if ((fp = fopen (filename, "w")) == (FILE *) (0)) 
	{ 
		syslogd_error (errno, "can't open %s", filename); 
		return; 
	} 
	syslogd_enumerate (syslogs, flags, fp); 
	for (syslog = syslogs->next; syslog != syslogs; syslog = syslog->next) 
	{ 
		syslogd_state (syslog, flags, fp); 
	} 
	syslogd_state (syslog, flags, fp); 
	fclose (fp); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_admin"); 

#endif

	return; 
} 
Ejemplo n.º 21
0
/*
 * syscall(frame):
 *	System call request from POSIX system call gate interface to kernel.
 * Like trap(), argument is call by reference.
 */
void
linux_syscall(struct trapframe *frame)
{
	register const struct sysent *callp;
	struct lwp *l;
	int error;
	register_t code, args[6], rval[2];

	l = curlwp;
	LWP_CACHE_CREDS(l, l->l_proc);

	code = frame->tf_eax & (LINUX_SYS_NSYSENT - 1);
	callp = linux_sysent;

	callp += code;
	/*
	 * Linux passes the args in ebx, ecx, edx, esi, edi, ebp, in
	 * increasing order.
	 */
	args[0] = frame->tf_ebx;
	args[1] = frame->tf_ecx;
	args[2] = frame->tf_edx;
	args[3] = frame->tf_esi;
	args[4] = frame->tf_edi;
	args[5] = frame->tf_ebp;

	rval[0] = 0;
	rval[1] = 0;

	if (__predict_false(l->l_proc->p_trace_enabled)) {
		error = trace_enter(code, args, callp->sy_narg);
		if (__predict_true(error == 0)) {
			error = sy_call(callp, l, args, rval);
			code = frame->tf_eax & (LINUX_SYS_NSYSENT - 1);
			trace_exit(code, rval, error);
		}
	} else
		error = sy_call(callp, l, args, rval);

	if (__predict_true(error == 0)) {
		frame->tf_eax = rval[0];
		/*
		 * XXX The linux libc code I (dsl) looked at doesn't use the
		 * carry bit.
		 * Values above 0xfffff000 are assumed to be errno values and
		 * not result codes!
		 */
		frame->tf_eflags &= ~PSL_C;	/* carry bit */
	} else {
		switch (error) {
		case ERESTART:
			/*
			 * The offset to adjust the PC by depends on whether
			 * we entered the kernel through the trap or call gate.
			 * We save the instruction size in tf_err on entry.
			 */
			frame->tf_eip -= frame->tf_err;
			break;
		case EJUSTRETURN:
			/* nothing to do */
			break;
		default:
			error = native_to_linux_errno[error];
			frame->tf_eax = error;
			frame->tf_eflags |= PSL_C;	/* carry bit */
			break;
		}
	}

	userret(l);
}
Ejemplo n.º 22
0
/*
 * syscall(frame):
 *	System call request from POSIX system call gate interface to kernel.
 * Like trap(), argument is call by reference.
 */
static void
linux_syscall(struct trapframe *frame)
{
    const struct sysent *callp;
    struct proc *p;
    struct lwp *l;
    int error;
    register_t code, rval[2];
#define args (&frame->tf_rdi)

    l = curlwp;
    p = l->l_proc;

    code = frame->tf_rax;

    LWP_CACHE_CREDS(l, p);

    callp = p->p_emul->e_sysent;

    code &= (LINUX_SYS_NSYSENT - 1);
    callp += code;

    /*
     * Linux system calls have a maximum of 6 arguments, they are
     * already adjacent in the syscall trapframe.
     */

    if (__predict_false(p->p_trace_enabled)
            && (error = trace_enter(code, args, callp->sy_narg)) != 0)
        goto out;

    rval[0] = 0;
    rval[1] = 0;
    error = sy_call(callp, l, args, rval);
out:
    switch (error) {
    case 0:
        frame->tf_rax = rval[0];
        break;
    case ERESTART:
        /*
         * The offset to adjust the PC by depends on whether we entered
         * the kernel through the trap or call gate.  We pushed the
         * size of the instruction into tf_err on entry.
         */
        frame->tf_rip -= frame->tf_err;
        break;
    case EJUSTRETURN:
        /* nothing to do */
        break;
    default:
        error = native_to_linux_errno[error];
        frame->tf_rax = error;
        break;
    }

    if (__predict_false(p->p_trace_enabled))
        trace_exit(code, rval, error);

    userret(l);
}
static void
syscall_fancy(register_t code, struct lwp *l, struct frame *frame)
{
	char *params;
	const struct sysent *callp;
	int error, nsys;
	size_t argsize;
	register_t args[16], rval[2];
	struct proc *p = l->l_proc;

	nsys = p->p_emul->e_nsysent;
	callp = p->p_emul->e_sysent;

	params = (char *)frame->f_regs[SP] + sizeof(int);

	switch (code) {
	case SYS_syscall:
		/*
		 * Code is first argument, followed by actual args.
		 */
		code = fuword(params);
		params += sizeof(int);
#if defined(COMPAT_13) || defined(COMPAT_16)
		/*
		 * XXX sigreturn requires special stack manipulation
		 * that is only done if entered via the sigreturn
		 * trap.  Cannot allow it here so make sure we fail.
		 */
		switch (code) {
#ifdef COMPAT_13
		case SYS_compat_13_sigreturn13:
#endif
#ifdef COMPAT_16
		case SYS_compat_16___sigreturn14:
#endif
			code = nsys;
			break;
		}
#endif
		break;
	case SYS___syscall:
		/*
		 * Like syscall, but code is a quad, so as to maintain
		 * quad alignment for the rest of the arguments.
		 */
		code = fuword(params + _QUAD_LOWWORD * sizeof(int));
		params += sizeof(quad_t);
		break;
	default:
		break;
	}

	if (code < 0 || code >= nsys)
		callp += p->p_emul->e_nosys;		/* illegal */
	else
		callp += code;

	argsize = callp->sy_argsize;
	if (argsize) {
		error = copyin(params, (void *)args, argsize);
		if (error)
			goto bad;
	}

	if ((error = trace_enter(code, args, callp->sy_narg)) != 0)
		goto out;

	rval[0] = 0;
	rval[1] = frame->f_regs[D1];
	error = sy_call(callp, l, args, rval);
out:
	switch (error) {
	case 0:
		/*
		 * Reinitialize lwp/proc pointers as they may be different
		 * if this is a child returning from fork syscall.
		 */
		l = curlwp;
		p = l->l_proc;
		frame->f_regs[D0] = rval[0];
		frame->f_regs[D1] = rval[1];
		frame->f_sr &= ~PSL_C;	/* carry bit */
#ifdef COMPAT_50
		/* see syscall_plain for a comment explaining this */

		/*
		 * Some pre-m68k ELF libc assembler stubs assume
		 * %a0 is preserved across system calls...
		 */
		if (p->p_emul == &emul_netbsd)
			frame->f_regs[A0] = rval[0];
#endif
		break;
	case ERESTART:
		/*
		 * We always enter through a `trap' instruction, which is 2
		 * bytes, so adjust the pc by that amount.
		 */
		frame->f_pc = frame->f_pc - 2;
		break;
	case EJUSTRETURN:
		/* nothing to do */
		break;
	default:
	bad:
		/*
		 * XXX: SVR4 uses this code-path, so we may have
		 * to translate errno.
		 */
		if (p->p_emul->e_errno)
			error = p->p_emul->e_errno[error];
		frame->f_regs[D0] = error;
		frame->f_sr |= PSL_C;	/* carry bit */
		break;
	}

	trace_exit(code, rval, error);
}
Ejemplo n.º 24
0
void
syscall(struct trapframe *frame, lwp_t *l, uint32_t insn)
{
	struct proc * const p = l->l_proc;
	const struct sysent *callp;
	int error;
	u_int nargs;
	register_t *args;
	register_t copyargs[2+SYS_MAXSYSARGS];
	register_t rval[2];
	ksiginfo_t ksi;
	const uint32_t os_mask = insn & SWI_OS_MASK;
	uint32_t code = insn & 0x000fffff;

	/* test new official and old unofficial NetBSD ranges */
	if (__predict_false(os_mask != SWI_OS_NETBSD)
	    && __predict_false(os_mask != 0)) {
		if (os_mask == SWI_OS_ARM
		    && (code == SWI_IMB || code == SWI_IMBrange)) {
			userret(l);
			return;
		}

		/* Undefined so illegal instruction */
		KSI_INIT_TRAP(&ksi);
		ksi.ksi_signo = SIGILL;
		ksi.ksi_code = 0;	/* XXX get an ILL_ILLSYSCALL assigned */
#ifdef THUMB_CODE
		if (frame->tf_spsr & PSR_T_bit) 
			ksi.ksi_addr = (void *)(frame->tf_pc - THUMB_INSN_SIZE);
		else
#endif
			ksi.ksi_addr = (void *)(frame->tf_pc - INSN_SIZE);
		ksi.ksi_trap = insn;
		trapsignal(l, &ksi);
		userret(l);
		return;
	}

	code &= (SYS_NSYSENT - 1);
	callp = p->p_emul->e_sysent + code;
	nargs = callp->sy_narg;
	if (nargs > 4) {
		args = copyargs;
		memcpy(args, &frame->tf_r0, 4 * sizeof(register_t));
		error = copyin((void *)frame->tf_usr_sp, args + 4,
		    (nargs - 4) * sizeof(register_t));
		if (error)
			goto bad;
	} else {
		args = &frame->tf_r0;
	}

	if (!__predict_false(p->p_trace_enabled)
	    || __predict_false(callp->sy_flags & SYCALL_INDIRECT)
	    || (error = trace_enter(code, args, nargs)) == 0) {
		rval[0] = 0;
		rval[1] = 0;
		KASSERT(l->l_holdcnt == 0);
		error = (*callp->sy_call)(l, args, rval);
	}

	if (__predict_false(p->p_trace_enabled)
	    || !__predict_false(callp->sy_flags & SYCALL_INDIRECT))
		trace_exit(code, rval, error);

	switch (error) {
	case 0:
		frame->tf_r0 = rval[0];
		frame->tf_r1 = rval[1];

#ifdef __PROG32
		frame->tf_spsr &= ~PSR_C_bit;	/* carry bit */
#else
		frame->tf_r15 &= ~R15_FLAG_C;	/* carry bit */
#endif
		break;

	case ERESTART:
		/*
		 * Reconstruct the pc to point at the swi.
		 */
#ifdef THUMB_CODE
		if (frame->tf_spsr & PSR_T_bit)
			frame->tf_pc -= THUMB_INSN_SIZE;
		else
#endif
			frame->tf_pc -= INSN_SIZE;
		break;

	case EJUSTRETURN:
		/* nothing to do */
		break;

	default:
	bad:
		frame->tf_r0 = error;
#ifdef __PROG32
		frame->tf_spsr |= PSR_C_bit;	/* carry bit */
#else
		frame->tf_r15 |= R15_FLAG_C;	/* carry bit */
#endif
		break;
	}

	userret(l);
}
Ejemplo n.º 25
0
int
trace_read (const char *filename)
{
  FILE *trace = fopen(filename, "r");
  assert_inner(trace, "fopen");

  void *trace_buf = NULL;
  unsigned long trace_bufsize = 0;

  size_t n = fread(&trace_bufsize, sizeof(unsigned long), 1, trace);
  assert_set_errno(ENOTSUP, n == 1, "fread");

  trace_buf = malloc(trace_bufsize);
  assert_inner(trace_buf, "malloc");

  n = fread(trace_buf, 1, trace_bufsize, trace);
  assert_set_errno(ENOTSUP, n == trace_bufsize, "fread");
  assert_set_errno(ENOTSUP, feof(trace), "feof");

  unsigned int trace_ended = 0;

  unsigned long trace_index = 0;
  while (trace_index < trace_bufsize)
    {
      char sign = *((char*)(trace_buf + trace_index));
      trace_index += sizeof(char);
      switch (sign)
        {
        case 'e':
          trace_enter(trace_buf + trace_index);
          trace_index += 2 * sizeof(uintptr_t) + sizeof(unsigned long long);
          break;
        case 'x':
          trace_exit(trace_buf + trace_index);
          trace_index += sizeof(unsigned long long);
          break;
        case '+':
          trace_malloc(trace_buf + trace_index);
          trace_index += sizeof(size_t) + 2 * sizeof(uintptr_t) + sizeof(unsigned long long);
          break;
        case '*':
          trace_realloc(trace_buf + trace_index);
          trace_index += sizeof(size_t) + 3 * sizeof(uintptr_t) + sizeof(unsigned long long);
          break;
        case '-':
          trace_free(trace_buf + trace_index);
          trace_index += 2 * sizeof(uintptr_t) + sizeof(unsigned long long);
          break;
        case 'E':
          trace_end(trace_buf + trace_index);
          trace_index += sizeof(unsigned long long);
          trace_ended = 1;
          assert_set_errno(ENOTSUP, trace_bufsize == trace_index, "END not at end");
          break;
        default:
          assert_set_errno(ENOTSUP, 0, "sign switch");
          break;
        }
    }

  if (!trace_ended)
    assert_set_errno(ENOTSUP, 0, "no END at end");

  free(trace_buf);
  fclose(trace);

  return 0;
}
Ejemplo n.º 26
0
void syslogd_start (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	extern char const * program_name; 
	char buffer [TEXTLINE_MAX]; 
	size_t lineno = 0; 
	file_t fd; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_start"); 

#endif

	if ((fd = open (filename, O_RDONLY)) == - 1) 
	{ 
		syslogd_error (errno, "Can't open %s", filename); 
		return; 
	} 
	while (statement (fd, buffer, sizeof (buffer), & lineno)) 
	{ 
		struct syslogd * syslog = NEW (struct syslogd); 
		memset (syslog, 0, sizeof (struct syslogd)); 
		syslog->f_type = SYSLOGD_TYPE_NONE; 
		syslog->f_name = ""; 
		syslog->f_line = lineno; 
		syslog->f_desc = - 1; 
		syslog->f_time = time ((time_t *) (0)); 
		syslogd_parse (syslog, flags, buffer); 
		syslogd_ready (syslog, flags); 
		if (syslog->f_type == SYSLOGD_TYPE_NONE) 
		{ 
			free (syslog->f_name); 
			free (syslog); 
			continue; 
		} 
		syslog->prev = syslogs->prev; 
		syslogs->prev->next = syslog; 
		syslogs->prev = syslog; 
		syslog->next = syslogs; 
		for (syslog = syslogs->next; syslog != syslogs->prev; syslog = syslog->next) 
		{ 
			if (!strcmp (syslog->f_name, syslogs->prev->f_name)) 
			{ 
				syslogd_print (SYSLOG_SYSLOG | SYSLOG_WARNING, "New %s selections on line %d replace old ones on line %d", syslogs->prev->f_name, syslogs->prev->f_line, syslog->f_line); 
				syslog->next->prev = syslog->prev; 
				syslog->prev->next = syslog->next; 
				syslog->prev = (struct syslogd *) (0); 
				syslog->next = (struct syslogd *) (0); 
				free (syslog->f_name); 
				free (syslog); 
				break; 
			} 
		} 
	} 
	close (fd); 
	syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "%s %s.%s started", program_name, VERSION, RELEASE); 
	syslogd_print (SYSLOG_SYSLOG | SYSLOG_INFO, "Configured with %s", filename); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_start"); 

#endif

	return; 
} 
static void
sunos_syscall_fancy(register_t code, struct lwp *l, struct frame *frame)
{
	struct proc *p = l->l_proc;
	char *params;
	const struct sysent *callp;
	int error, nsys;
	size_t argsize;
	register_t args[16], rval[2];

	nsys = p->p_emul->e_nsysent;
	callp = p->p_emul->e_sysent;

	/*
	 * SunOS passes the syscall-number on the stack, whereas
	 * BSD passes it in D0. So, we have to get the real "code"
	 * from the stack, and clean up the stack, as SunOS glue
	 * code assumes the kernel pops the syscall argument the
	 * glue pushed on the stack. Sigh...
	 */
	code = fuword((void *)frame->f_regs[SP]);

	/*
	 * XXX
	 * Don't do this for sunos_sigreturn, as there's no stored pc
	 * on the stack to skip, the argument follows the syscall
	 * number without a gap.
	 */
	if (code != SUNOS_SYS_sigreturn) {
		frame->f_regs[SP] += sizeof (int);
		/*
		 * remember that we adjusted the SP,
		 * might have to undo this if the system call
		 * returns ERESTART.
		 */
		l->l_md.md_flags |= MDL_STACKADJ;
	} else
		l->l_md.md_flags &= ~MDL_STACKADJ;

	params = (char *)frame->f_regs[SP] + sizeof(int);

	switch (code) {
	case SUNOS_SYS_syscall:
		/*
		 * Code is first argument, followed by actual args.
		 */
		code = fuword(params);
		params += sizeof(int);
		break;
	default:
		break;
	}

	if (code < 0 || code >= nsys)
		callp += p->p_emul->e_nosys;		/* illegal */
	else
		callp += code;

	argsize = callp->sy_argsize;
	if (argsize) {
		error = copyin(params, (void *)args, argsize);
		if (error)
			goto bad;
	}

	if ((error = trace_enter(code, args, callp->sy_narg)) != 0)
		goto out;

	rval[0] = 0;
	rval[1] = frame->f_regs[D1];
	error = sy_call(callp, l, args, rval);
out:
	switch (error) {
	case 0:
		/*
		 * Reinitialize proc pointer `p' as it may be different
		 * if this is a child returning from fork syscall.
		 */
		p = curproc;
		frame->f_regs[D0] = rval[0];
		frame->f_regs[D1] = rval[1];
		frame->f_sr &= ~PSL_C;	/* carry bit */
		break;
	case ERESTART:
		/*
		 * We always enter through a `trap' instruction, which is 2
		 * bytes, so adjust the pc by that amount.
		 */
		frame->f_pc = frame->f_pc - 2;
		break;
	case EJUSTRETURN:
		/* nothing to do */
		break;
	default:
	bad:
		frame->f_regs[D0] = error;
		frame->f_sr |= PSL_C;	/* carry bit */
		break;
	}

	/* need new p-value for this */
	if (l->l_md.md_flags & MDL_STACKADJ) {
		l->l_md.md_flags &= ~MDL_STACKADJ;
		if (error == ERESTART)
			frame->f_regs[SP] -= sizeof (int);
	}

	trace_exit(code, rval, error);
}
void
linux32_syscall(struct trapframe *frame)
{
	const struct sysent *callp;
	struct proc *p;
	struct lwp *l;
	int error;
	size_t narg;
	register32_t code, args[6];
	register_t rval[2];
	int i;
	register_t args64[6];

	l = curlwp;
	p = l->l_proc;

	code = frame->tf_rax;

	LWP_CACHE_CREDS(l, p);

	callp = p->p_emul->e_sysent;

	code &= (LINUX32_SYS_NSYSENT - 1);
	callp += code;

	/*
	 * Linux passes the args in ebx, ecx, edx, esi, edi, ebp, in
	 * increasing order.
	 */
	args[0] = frame->tf_rbx & 0xffffffff;
	args[1] = frame->tf_rcx & 0xffffffff;
	args[2] = frame->tf_rdx & 0xffffffff;
	args[3] = frame->tf_rsi & 0xffffffff;
	args[4] = frame->tf_rdi & 0xffffffff;
	args[5] = frame->tf_rbp & 0xffffffff;

	if (__predict_false(p->p_trace_enabled)) {
		narg = callp->sy_narg;
		if (__predict_false(narg > __arraycount(args)))
			panic("impossible syscall narg, code %d, narg %zd",
			    code, narg);
		for (i = 0; i < narg; i++)
			args64[i] = args[i] & 0xffffffff;
		if ((error = trace_enter(code, args64, narg)) != 0)
			goto out;
	}

	rval[0] = 0;
	rval[1] = 0;

	error = sy_call(callp, l, args, rval);
out:
	switch (error) {
	case 0:
		frame->tf_rax = rval[0];
		frame->tf_rflags &= ~PSL_C;	/* carry bit */
		break;
	case ERESTART:
		/*
		 * The offset to adjust the PC by depends on whether we entered
		 * the kernel through the trap or call gate.  We pushed the
		 * size of the instruction into tf_err on entry.
		 */
		frame->tf_rip -= frame->tf_err;
		break;
	case EJUSTRETURN:
		/* nothing to do */
		break;
	default:
		error = native_to_linux32_errno[error];
		frame->tf_rax = error;
		frame->tf_rflags |= PSL_C;	/* carry bit */
		break;
	}

	if (__predict_false(p->p_trace_enabled))
		trace_exit(code, rval, error);
	userret(l);
}
Ejemplo n.º 29
0
VOID Fini(INT32 code, VOID *v) {

    trace_enter();

    list<param_t *>::reverse_iterator it_in, it_out;
    it_in = param_in->rbegin();
    it_out = param_out->rbegin();

    int depth = 0;
    UINT64 last_date = -1;
    bool is_in = false;

    gettimeofday(&stop, NULL);

    ofile << "Elapsed time ] Commence ; Fini [ : " << (stop.tv_usec / 1000.0 + 1000 * stop.tv_sec - start.tv_sec * 1000 - start.tv_usec / 1000.0) / 1000.0 << "s" << endl;

    while (it_in != param_in->rend() || it_out != param_out->rend()) {
        param_t *p;
        if (it_in == param_in->rend()) {
            p = *it_out;
            it_out++;
            is_in = false;
        } else if (it_out == param_out->rend() || (*it_out)->counter >= (*it_in)->counter) {
            p = *it_in;
            it_in++;
            is_in = true;
        } else {
            p = *it_out;
            it_out++;
            is_in = false;
        }
#if 0
        if (p->is_addr)
            ofile << "a:";
        else 
            ofile << "n:";
#endif
        if (last_date != p->counter) {
            if (is_in)
                depth++;
            else
                depth--;
        }
        last_date = p->counter;
        char head = 0x00;
        /* Construct the first byte */
        /* First two bits are for i/o  and addr/not addr */
        head |= 0x80 & ((is_in?1:0) << 7);
        head |= 0x40 & ((p->is_addr?1:0) << 6);
        /* Then we encode the position of the parameter */
        head |= 0x3F & p->pos;
        if (!pushed_in_log[p->fid]) {
            ofile << '\xff' << p->fid << ":" <<  fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << endl;
            pushed_in_log[p->fid] = true;
        }
        ofile << head;
        ofile << p->fid << ":" << p->counter << ":" << p->val << endl;
#if 0
        ofile << p->val << ":" << fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << ":" << p->pos << ":" << p->counter << endl;
#endif
    }
    ofile.close();

    trace_leave();

    return;
}
Ejemplo n.º 30
0
Archivo: type.cpp Proyecto: Frky/scat
VOID Fini(INT32 code, VOID *v) {
    trace_enter();

    #define append_type(type) \
            if (need_comma) \
                ofile << "," ; \
            ofile << (type); \
            need_comma = true

    for(unsigned int fid = 1; fid <= fn_nb(); fid++) {
        if (nb_call[fid] < NB_CALLS_TO_CONCLUDE)
            continue;

        ofile << fn_img(fid) << ":" << fn_imgaddr(fid)
                << ":" << fn_name(fid)
                << ":";

        bool need_comma = false;

        unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
        for (unsigned int pid = 0; pid < param_val_size; pid++) {
            if (((float) nb_out[fid][pid]) > 0.75 * ((float) nb_call[fid])) {
                debug("Found 'out parameter' candidate : [%s@%lX] %s %u (%u <=> %u)\n",
                        fn_img(fid).c_str(),
                        fn_imgaddr(fid),
                        fn_name(fid).c_str(),
                        pid,
                        nb_out[fid][pid],
                        nb_call[fid]);
            }

            if (pid == 0 && has_return[fid] == 0) {
                append_type("VOID");
            }
            else if (pid == 0 && has_return[fid] == 2) {
                append_type("FLOAT");
            }
            else if (pid < 1 + nb_param_int[fid] && param_is_not_addr[fid][pid]) {
                append_type("INT");
            }
            else if (param_val[fid][pid]->size() == 0) {
                append_type("UNDEF");
            }
            else {
                int param_addr = 0;
                for (list<UINT64>::iterator it = param_val[fid][pid]->begin(); it != param_val[fid][pid]->end(); it++) {
                    if (is_addr(*it)) {
                        param_addr++;
                    }
                }

                float coef = ((float) param_addr) / ((float) param_val[fid][pid]->size());
                append_type(coef > THRESHOLD ? "ADDR" : "INT");

                ofile << "(" << coef << ")";
            }
        }

        for (unsigned int pid = 0;
                pid < nb_param_float[fid] + nb_param_float_stack[fid];
                pid++) {
            append_type("FLOAT");
        }

        ofile << endl;
    }

    ofile.close();

    trace_leave();
}