Beispiel #1
0
__private_extern__ kern_return_t
chudxnu_thread_get_state(
						 thread_t	 	thread, 
						 thread_flavor_t	 	flavor,
						 thread_state_t	 	tstate,
						 mach_msg_type_number_t	*count,
						 boolean_t	 	user_only)
{
	if (user_only) {
		/* We can't get user state for kernel threads */
		if (thread->task == kernel_task)
			return KERN_FAILURE;
		/* this properly handles deciding whether or not the thread is 64 bit or not */
		return machine_thread_get_state(thread, flavor, tstate, count);
	} else {
		// i386 machine_thread_get_kern_state() is different from the PPC version which returns
		// the previous save area - user or kernel - rather than kernel or NULL if no kernel
		// interrupt state available
		
		// the real purpose of this branch is the following:
		// the user doesn't care if the thread states are user or kernel, he
		// just wants the thread state, so we need to determine the proper one
		// to return, kernel or user, for the given thread.
		if(thread == current_thread() && current_cpu_datap()->cpu_int_state) {
			// the above are conditions where we possibly can read the kernel
			// state. we still need to determine if this interrupt happened in
			// kernel or user context
			if(USER_STATE(thread) == current_cpu_datap()->cpu_int_state &&
			   current_cpu_datap()->cpu_interrupt_level == 1) {
				// interrupt happened in user land
				return machine_thread_get_state(thread, flavor, tstate, count);
			} else {
				// kernel interrupt.
				return machine_thread_get_kern_state(thread, flavor, tstate, count);
			}
		} else {
            // get the user-mode thread state
			return machine_thread_get_state(thread, flavor, tstate, count);
		}
	}
}
Beispiel #2
0
static void
kern_collectth_state(thread_t thread, tir_t *t)
{
	vm_offset_t	header;
	int  hoffset, i ;
	mythread_state_flavor_t *flavors;
	struct thread_command	*tc;
	/*
	 *	Fill in thread command structure.
	 */
	header = t->header;
	hoffset = t->hoffset;
	flavors = t->flavors;
	
	tc = (struct thread_command *) (header + hoffset);
	tc->cmd = LC_THREAD;
	tc->cmdsize = (uint32_t)sizeof(struct thread_command) + t->tstate_size;
	hoffset += (uint32_t)sizeof(struct thread_command);
	/*
	 * Follow with a struct thread_state_flavor and
	 * the appropriate thread state struct for each
	 * thread state flavor.
	 */
	for (i = 0; i < kdp_mynum_flavors; i++) {
		*(mythread_state_flavor_t *)(header+hoffset) =
		    flavors[i];
		hoffset += (uint32_t)sizeof(mythread_state_flavor_t);
		/* Locate and obtain the non-volatile register context
		 * for this kernel thread. This should ideally be
		 * encapsulated in machine_thread_get_kern_state()
		 * but that routine appears to have been co-opted
		 * by CHUD to obtain pre-interrupt state.
		 */
		if (flavors[i].flavor == x86_THREAD_STATE64) {
			x86_thread_state64_t *tstate = (x86_thread_state64_t *) (header + hoffset);
			vm_offset_t kstack;
			x86_saved_state64_t *cpstate = current_cpu_datap()->cpu_fatal_trap_state;
			bzero(tstate, x86_THREAD_STATE64_COUNT * sizeof(int));
			if ((current_thread() == thread) && (cpstate != NULL)) {
				tstate->rax = cpstate->rax;
				tstate->rbx = cpstate->rbx;
				tstate->rcx = cpstate->rcx;
				tstate->rdx = cpstate->rdx;
				tstate->rdi = cpstate->rdi;
				tstate->rsi = cpstate->rsi;
				tstate->rbp = cpstate->rbp;
				tstate->r8 = cpstate->r8;
				tstate->r9 = cpstate->r9;
				tstate->r10 = cpstate->r10;
				tstate->r11 = cpstate->r11;
				tstate->r12 = cpstate->r12;
				tstate->r13 = cpstate->r13;
				tstate->r14 = cpstate->r14;
				tstate->r15 = cpstate->r15;
				tstate->rip = cpstate->isf.rip;
				tstate->rsp = cpstate->isf.rsp;
				tstate->rflags = cpstate->isf.rflags;
				tstate->cs = cpstate->isf.cs;
				tstate->fs = cpstate->fs;
				tstate->gs = cpstate->gs;
			} else if ((kstack = thread->kernel_stack) != 0){
				struct x86_kernel_state *iks = STACK_IKS(kstack);
				tstate->rbx = iks->k_rbx;
				tstate->rsp = iks->k_rsp;
				tstate->rbp = iks->k_rbp;
				tstate->r12 = iks->k_r12;
				tstate->r13 = iks->k_r13;
				tstate->r14 = iks->k_r14;
				tstate->r15 = iks->k_r15;
				tstate->rip = iks->k_rip;
			}
		}
		else if (machine_thread_get_kern_state(thread,
			flavors[i].flavor, (thread_state_t) (header+hoffset),
			&flavors[i].count) != KERN_SUCCESS)
			printf ("Failure in machine_thread_get_kern_state()\n");
		hoffset += (uint32_t)(flavors[i].count*sizeof(int));
	}

	t->hoffset = hoffset;
}