static int x86_cpu_gdb_load_seg(X86CPU *cpu, int sreg, uint8_t *mem_buf) { CPUX86State *env = &cpu->env; uint16_t selector = ldl_p(mem_buf); if (selector != env->segs[sreg].selector) { #if defined(CONFIG_USER_ONLY) cpu_x86_load_seg(env, sreg, selector); #else unsigned int limit, flags; target_ulong base; if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { int dpl = (env->eflags & VM_MASK) ? 3 : 0; base = selector << 4; limit = 0xffff; flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | DESC_A_MASK | (dpl << DESC_DPL_SHIFT); } else { if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, &flags)) { return 4; } } cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); #endif } return 4; }
/* ------------------------------------------------------------ thread type syscall handling */ long do_thread_syscall(void *cpu_env, int num, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7, uint32_t arg8) { extern uint32_t cthread_set_self(uint32_t); extern uint32_t processor_facilities_used(); long ret = 0; arg1 = tswap32(arg1); arg2 = tswap32(arg2); arg3 = tswap32(arg3); arg4 = tswap32(arg4); arg5 = tswap32(arg5); arg6 = tswap32(arg6); arg7 = tswap32(arg7); arg8 = tswap32(arg8); DPRINTF("thread syscall %d : " , num); switch(num) { #ifdef TARGET_I386 case 0x3: #endif case 0x7FF1: /* cthread_set_self */ DPRINTF("cthread_set_self(0x%x)\n", (unsigned int)arg1); ret = cthread_set_self(arg1); #ifdef TARGET_I386 /* we need to update the LDT with the address of the thread */ write_dt((void *)(((CPUX86State *) cpu_env)->ldt.base + (4 * sizeof(uint64_t))), arg1, 1, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); /* New i386 convention, %gs should be set to our this LDT entry */ cpu_x86_load_seg(cpu_env, R_GS, 0x27); /* Old i386 convention, the kernel returns the selector for the cthread (pre-10.4.8?)*/ ret = 0x27; #endif break; case 0x7FF2: /* Called the super-fast pthread_self handler by the apple guys */ DPRINTF("pthread_self()\n"); ret = (uint32_t)pthread_self(); break; case 0x7FF3: DPRINTF("processor_facilities_used()\n"); #ifdef __i386__ qerror("processor_facilities_used: not implemented!\n"); #else ret = (uint32_t)processor_facilities_used(); #endif break; default: gemu_log("qemu: Unsupported thread syscall: %d(0x%x)\n", num, num); gdb_handlesig (cpu_env, SIGTRAP); exit(0); break; } return ret; }
static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) { abi_long ret = 0; abi_ulong val; int idx; switch(op) { #ifdef TARGET_ABI32 case TARGET_FREEBSD_I386_SET_GSBASE: case TARGET_FREEBSD_I386_SET_FSBASE: if (op == TARGET_FREEBSD_I386_SET_GSBASE) #else case TARGET_FREEBSD_AMD64_SET_GSBASE: case TARGET_FREEBSD_AMD64_SET_FSBASE: if (op == TARGET_FREEBSD_AMD64_SET_GSBASE) #endif idx = R_GS; else idx = R_FS; if (get_user(val, parms, abi_ulong)) return -TARGET_EFAULT; cpu_x86_load_seg(env, idx, 0); env->segs[idx].base = val; break; #ifdef TARGET_ABI32 case TARGET_FREEBSD_I386_GET_GSBASE: case TARGET_FREEBSD_I386_GET_FSBASE: if (op == TARGET_FREEBSD_I386_GET_GSBASE) #else case TARGET_FREEBSD_AMD64_GET_GSBASE: case TARGET_FREEBSD_AMD64_GET_FSBASE: if (op == TARGET_FREEBSD_AMD64_GET_GSBASE) #endif idx = R_GS; else idx = R_FS; val = env->segs[idx].base; if (put_user(val, parms, abi_ulong)) return -TARGET_EFAULT; break; /* XXX handle the others... */ default: ret = -TARGET_EINVAL; break; } return ret; }