Revision 03acab66
b/linux-user/syscall.c | ||
---|---|---|
2229 | 2229 |
/* NOTE: there is really one LDT for all the threads */ |
2230 | 2230 |
uint8_t *ldt_table; |
2231 | 2231 |
|
2232 |
static int read_ldt(abi_ulong ptr, unsigned long bytecount)
|
|
2232 |
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
|
|
2233 | 2233 |
{ |
2234 | 2234 |
int size; |
2235 | 2235 |
void *p; |
... | ... | |
2241 | 2241 |
size = bytecount; |
2242 | 2242 |
p = lock_user(VERIFY_WRITE, ptr, size, 0); |
2243 | 2243 |
if (!p) |
2244 |
return -EFAULT; |
|
2244 |
return -TARGET_EFAULT;
|
|
2245 | 2245 |
/* ??? Should this by byteswapped? */ |
2246 | 2246 |
memcpy(p, ldt_table, size); |
2247 | 2247 |
unlock_user(p, ptr, size); |
... | ... | |
2249 | 2249 |
} |
2250 | 2250 |
|
2251 | 2251 |
/* XXX: add locking support */ |
2252 |
/* write_ldt() returns host errnos */ |
|
2253 |
static int write_ldt(CPUX86State *env, |
|
2254 |
abi_ulong ptr, unsigned long bytecount, int oldmode) |
|
2252 |
static abi_long write_ldt(CPUX86State *env, |
|
2253 |
abi_ulong ptr, unsigned long bytecount, int oldmode) |
|
2255 | 2254 |
{ |
2256 | 2255 |
struct target_modify_ldt_ldt_s ldt_info; |
2257 | 2256 |
struct target_modify_ldt_ldt_s *target_ldt_info; |
... | ... | |
2260 | 2259 |
uint32_t *lp, entry_1, entry_2; |
2261 | 2260 |
|
2262 | 2261 |
if (bytecount != sizeof(ldt_info)) |
2263 |
return -EINVAL; |
|
2262 |
return -TARGET_EINVAL;
|
|
2264 | 2263 |
if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1)) |
2265 |
return -EFAULT; |
|
2264 |
return -TARGET_EFAULT;
|
|
2266 | 2265 |
ldt_info.entry_number = tswap32(target_ldt_info->entry_number); |
2267 | 2266 |
ldt_info.base_addr = tswapl(target_ldt_info->base_addr); |
2268 | 2267 |
ldt_info.limit = tswap32(target_ldt_info->limit); |
... | ... | |
2270 | 2269 |
unlock_user_struct(target_ldt_info, ptr, 0); |
2271 | 2270 |
|
2272 | 2271 |
if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) |
2273 |
return -EINVAL; |
|
2272 |
return -TARGET_EINVAL;
|
|
2274 | 2273 |
seg_32bit = ldt_info.flags & 1; |
2275 | 2274 |
contents = (ldt_info.flags >> 1) & 3; |
2276 | 2275 |
read_exec_only = (ldt_info.flags >> 3) & 1; |
... | ... | |
2280 | 2279 |
|
2281 | 2280 |
if (contents == 3) { |
2282 | 2281 |
if (oldmode) |
2283 |
return -EINVAL; |
|
2282 |
return -TARGET_EINVAL;
|
|
2284 | 2283 |
if (seg_not_present == 0) |
2285 |
return -EINVAL; |
|
2284 |
return -TARGET_EINVAL;
|
|
2286 | 2285 |
} |
2287 | 2286 |
/* allocate the LDT */ |
2288 | 2287 |
if (!ldt_table) { |
2289 | 2288 |
ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); |
2290 | 2289 |
if (!ldt_table) |
2291 |
return -ENOMEM; |
|
2290 |
return -TARGET_ENOMEM;
|
|
2292 | 2291 |
memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); |
2293 | 2292 |
env->ldt.base = h2g(ldt_table); |
2294 | 2293 |
env->ldt.limit = 0xffff; |
... | ... | |
2333 | 2332 |
} |
2334 | 2333 |
|
2335 | 2334 |
/* specific and weird i386 syscalls */ |
2336 |
/* do_modify_ldt() returns host errnos (it is inconsistent with the |
|
2337 |
other do_*() functions which return target errnos). */ |
|
2338 |
int do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, unsigned long bytecount) |
|
2335 |
abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, |
|
2336 |
unsigned long bytecount) |
|
2339 | 2337 |
{ |
2340 |
int ret = -ENOSYS;
|
|
2338 |
abi_long ret;
|
|
2341 | 2339 |
|
2342 | 2340 |
switch (func) { |
2343 | 2341 |
case 0: |
... | ... | |
2349 | 2347 |
case 0x11: |
2350 | 2348 |
ret = write_ldt(env, ptr, bytecount, 0); |
2351 | 2349 |
break; |
2350 |
default: |
|
2351 |
ret = -TARGET_ENOSYS; |
|
2352 |
break; |
|
2352 | 2353 |
} |
2353 | 2354 |
return ret; |
2354 | 2355 |
} |
... | ... | |
4174 | 4175 |
break; |
4175 | 4176 |
#ifdef TARGET_I386 |
4176 | 4177 |
case TARGET_NR_modify_ldt: |
4177 |
ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3));
|
|
4178 |
ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
|
|
4178 | 4179 |
break; |
4179 | 4180 |
#if !defined(TARGET_X86_64) |
4180 | 4181 |
case TARGET_NR_vm86old: |
Also available in: Unified diff