예제 #1
0
파일: trap.c 프로젝트: 1060351485/6.828-JOS
static void
trap_dispatch(struct Trapframe *tf)
{
	// Handle processor exceptions.
	// LAB 3: Your code here.
	
	int32_t ret;

	switch (tf->tf_trapno){
		case T_PGFLT:{ //14
			page_fault_handler(tf);
			return;
		}
		case T_BRKPT:{ //3 
			breakpoint_handler(tf);
			return;
		}
		case T_DEBUG:{
			breakpoint_handler(tf);
			return;
		}
		case T_SYSCALL:{
			ret = system_call_handler(tf);
			tf->tf_regs.reg_eax = ret;
			return;
		}
		case IRQ_OFFSET+IRQ_TIMER:{
			lapic_eoi();
			time_tick();
			sched_yield();
			return;
		}
		case IRQ_OFFSET+IRQ_KBD:{
			kbd_intr();
			return;
		}
		case IRQ_OFFSET+IRQ_SERIAL:{
			serial_intr();
			return;
		}
		case IRQ_OFFSET+IRQ_E1000:{
			e1000_trap_handler();
			return;
		}
	}	

	// Handle spurious interrupts
	// The hardware sometimes raises these because of noise on the
	// IRQ line or other reasons. We don't care.
	if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) {
		cprintf("Spurious interrupt on irq 7\n");
		print_trapframe(tf);
		return;
	}

	// Handle clock interrupts. Don't forget to acknowledge the
	// interrupt using lapic_eoi() before calling the scheduler!
	// LAB 4: Your code here.

	// Add time tick increment to clock interrupts.
	// Be careful! In multiprocessors, clock interrupts are
	// triggered on every CPU.
	// LAB 6: Your code here.


	// Handle keyboard and serial interrupts.
	// LAB 5: Your code here.

	// Unexpected trap: The user process or the kernel has a bug.
	print_trapframe(tf);
	if (tf->tf_cs == GD_KT)
	  panic("unhandled trap in kernel");
	else {
		env_destroy(curenv);
		return;
	}
}
예제 #2
0
void debugger_proc(pid_t child_proc, struct execute_context *ctx)
{
    /* about child process */
    int child_stat;
    kern_return_t kret;
    mach_port_t task;
    int wait_cnt = 0;
    char **args = ctx->passing_args;

    /* related analysys of target process binary. */
    int i;
    int nsym;
    int text_section;
    uint64_t text_section_offset;
    uint64_t text_section_size;
    uint64_t text_section_vmaddr;
    struct symbol_info *psymbol_table;
    int init = 0;
    struct breakpoint_entry top;

    int stack_depth = 0;

    /* error check */
    if (child_proc == 0 || child_proc == -1)	return;

    /* initialize */
    memset(&top, 0x00, sizeof(top));

    /* open the port (do as an administrator) */
    kret = task_for_pid(mach_task_self(), child_proc, &task);
    if (kret != KERN_SUCCESS) {
        fprintf(stderr, "task_for_pid() failed\n");
        fprintf(stderr, "%s\n", mach_error_string(kret));
        exit(0);
    }

    fprintf(stderr, "[Tracer] child_proc: %d\n", child_proc);
    /* main loop */
    while(waitpid(child_proc, &child_stat, WUNTRACED)) {    /* {{{ */
        char buffer[128];
        char w_buf[128];
        w_buf[0] = 0x90;	/* nop */

        if (WIFEXITED(child_stat)) {
            /* Child Process Terminated */
            fprintf(stderr, "[Tracer]  Process :%d Terminated\n", child_proc);
            return;
        }
        memset(buffer, 0x00, 128);
        if(wait_cnt == 0) {
            /* The First time trapped   {{{ */
            /* -- The debugee program has not been expanded.-- */
            /* -- 	lookup named symbol	-- */
            struct file_info bininfo;
            ud_t ud_obj;
            uint64_t previous_eip;
            uint64_t func_start_addr;
            uint64_t func_end_addr;

            nsym = get_func_table(args[0], &psymbol_table, &text_section, &text_section_offset, &text_section_size, &text_section_vmaddr);
            debug_printf("nsym: %d\n", nsym);
            debug_printf("text section = %d\n", text_section);
            debug_printf("text section offset: 0x%llx\n", text_section_offset);
            debug_printf("text section size: 0x%llx\n", text_section_size);
            debug_printf("text section vmaddr: 0x%llx\n", text_section_vmaddr);

            qsort(psymbol_table, nsym, sizeof(struct symbol_info), symbolinfo_comp);

            /* XXX for debugging  */
            /*display_symbol_table(psymbol_table, nsym);  */

            /* code analysys */
            map_binary(args[0], &bininfo);
            ud_init(&ud_obj);
            ud_set_input_buffer(&ud_obj, bininfo.top + text_section_offset, text_section_size);
            ud_set_mode(&ud_obj, 64);

            previous_eip = text_section_vmaddr;
            /* set breakpoint at the entry and exit points of functions */
            for(i = 0; i < nsym; i++) {
                /* Set breakpoints {{{ */
                if (is_exclude_func(psymbol_table + i) == 1) {
                    continue;
                }
                /* 1, specifying the region of the function */
                func_start_addr = psymbol_table[i].nlist64.n_value;
                if (i != nsym - 1) {
                    /* next section's entry point - 1 */
                    func_end_addr = psymbol_table[i + 1].nlist64.n_value;
                } else {
                    func_end_addr = text_section_vmaddr + text_section_size + 1;
                }
                printf("%s: 0x%llx --> 0x%llx\n", psymbol_table[i].name, func_start_addr, func_end_addr);
                /*
                if (strstr(psymbol_table[i].name, "main") != NULL) {
                    __asm__("int3");
                }
                */
                psymbol_table[i].ret_address_num = 0;

                previous_eip = ud_obj.pc + text_section_vmaddr;

                while(ud_disassemble(&ud_obj) && previous_eip < func_start_addr) {
                    previous_eip = ud_obj.pc + text_section_vmaddr;
                }
                while(ud_disassemble(&ud_obj) && previous_eip < func_end_addr) {
                    if (func_start_addr <= previous_eip && ud_obj.mnemonic == UD_Iret) {
                        set_breakpoint(task, previous_eip, &top);
                        psymbol_table[i].ret_inst_address[ psymbol_table[i].ret_address_num ] = previous_eip;
                        psymbol_table[i].ret_address_num++;
                    }
                    previous_eip = ud_obj.pc + text_section_vmaddr;
                }
                /*
                if (0 < psymbol_table[i].ret_address_num) {
                    set_breakpoint(task, psymbol_table[i].nlist64.n_value, &top);
                }
                */
                set_breakpoint(task, psymbol_table[i].nlist64.n_value, &top);
                /* }}} */
            }
            debug_printf("break point insert\n");
            unmap_binary(&bininfo);
            /* }}} */
        } else {
            /* {{{ */
            /* break point */
            /* 1, Get current address from RIP value.
            * 2, Find current function name by EIP, and Logging.
            * 3, Substitute original instruction code for current break point code(0x90).
            * 4, Decrement EIP value.
            * 5, Execute only one op-code.
            * 6, Substitute 0x90 for oroginal code (located in entrance of function).
            * */
            uint64_t rip;
            read_process_register_64(task, RIP, &rip);
            if (is_breakpoint(rip - 1, &top) == 1) {
                stack_depth = breakpoint_handler(task, rip - 1, psymbol_table, nsym, stack_depth);
                write_process_register_64(task, RIP, RELATIVE_VAL, -1);
                disable_breakpoint(task, rip - 1, &top);
                ptrace(PT_STEP, child_proc, (caddr_t)1, 0);
                set_breakpoint(task, rip - 1, &top);
            }
            /* }}} */
        }
        wait_cnt++;
        ptrace(PT_CONTINUE, child_proc, (caddr_t)1, 0);
    }   /* }}} */
}