Lines 122-127
Link Here
|
122 |
#include "qapi/error.h" |
122 |
#include "qapi/error.h" |
123 |
#include "fd-trans.h" |
123 |
#include "fd-trans.h" |
124 |
#include "tcg/tcg.h" |
124 |
#include "tcg/tcg.h" |
|
|
125 |
#include "syscall_proc.h" |
125 |
|
126 |
|
126 |
#ifndef CLONE_IO |
127 |
#ifndef CLONE_IO |
127 |
#define CLONE_IO 0x80000000 /* Clone io context */ |
128 |
#define CLONE_IO 0x80000000 /* Clone io context */ |
Lines 1104-1110
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
Link Here
|
1104 |
{ |
1105 |
{ |
1105 |
abi_ulong target_rlim_swap; |
1106 |
abi_ulong target_rlim_swap; |
1106 |
rlim_t result; |
1107 |
rlim_t result; |
1107 |
|
1108 |
|
1108 |
target_rlim_swap = tswapal(target_rlim); |
1109 |
target_rlim_swap = tswapal(target_rlim); |
1109 |
if (target_rlim_swap == TARGET_RLIM_INFINITY) |
1110 |
if (target_rlim_swap == TARGET_RLIM_INFINITY) |
1110 |
return RLIM_INFINITY; |
1111 |
return RLIM_INFINITY; |
Lines 1112-1118
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
Link Here
|
1112 |
result = target_rlim_swap; |
1113 |
result = target_rlim_swap; |
1113 |
if (target_rlim_swap != (rlim_t)result) |
1114 |
if (target_rlim_swap != (rlim_t)result) |
1114 |
return RLIM_INFINITY; |
1115 |
return RLIM_INFINITY; |
1115 |
|
1116 |
|
1116 |
return result; |
1117 |
return result; |
1117 |
} |
1118 |
} |
1118 |
#endif |
1119 |
#endif |
Lines 1122-1134
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
Link Here
|
1122 |
{ |
1123 |
{ |
1123 |
abi_ulong target_rlim_swap; |
1124 |
abi_ulong target_rlim_swap; |
1124 |
abi_ulong result; |
1125 |
abi_ulong result; |
1125 |
|
1126 |
|
1126 |
if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) |
1127 |
if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) |
1127 |
target_rlim_swap = TARGET_RLIM_INFINITY; |
1128 |
target_rlim_swap = TARGET_RLIM_INFINITY; |
1128 |
else |
1129 |
else |
1129 |
target_rlim_swap = rlim; |
1130 |
target_rlim_swap = rlim; |
1130 |
result = tswapal(target_rlim_swap); |
1131 |
result = tswapal(target_rlim_swap); |
1131 |
|
1132 |
|
1132 |
return result; |
1133 |
return result; |
1133 |
} |
1134 |
} |
1134 |
#endif |
1135 |
#endif |
Lines 1615-1623
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
Link Here
|
1615 |
abi_ulong target_cmsg_addr; |
1616 |
abi_ulong target_cmsg_addr; |
1616 |
struct target_cmsghdr *target_cmsg, *target_cmsg_start; |
1617 |
struct target_cmsghdr *target_cmsg, *target_cmsg_start; |
1617 |
socklen_t space = 0; |
1618 |
socklen_t space = 0; |
1618 |
|
1619 |
|
1619 |
msg_controllen = tswapal(target_msgh->msg_controllen); |
1620 |
msg_controllen = tswapal(target_msgh->msg_controllen); |
1620 |
if (msg_controllen < sizeof (struct target_cmsghdr)) |
1621 |
if (msg_controllen < sizeof (struct target_cmsghdr)) |
1621 |
goto the_end; |
1622 |
goto the_end; |
1622 |
target_cmsg_addr = tswapal(target_msgh->msg_control); |
1623 |
target_cmsg_addr = tswapal(target_msgh->msg_control); |
1623 |
target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); |
1624 |
target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); |
Lines 1703-1709
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
Link Here
|
1703 |
socklen_t space = 0; |
1704 |
socklen_t space = 0; |
1704 |
|
1705 |
|
1705 |
msg_controllen = tswapal(target_msgh->msg_controllen); |
1706 |
msg_controllen = tswapal(target_msgh->msg_controllen); |
1706 |
if (msg_controllen < sizeof (struct target_cmsghdr)) |
1707 |
if (msg_controllen < sizeof (struct target_cmsghdr)) |
1707 |
goto the_end; |
1708 |
goto the_end; |
1708 |
target_cmsg_addr = tswapal(target_msgh->msg_control); |
1709 |
target_cmsg_addr = tswapal(target_msgh->msg_control); |
1709 |
target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); |
1710 |
target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); |
Lines 5750-5756
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
Link Here
|
5750 |
} |
5751 |
} |
5751 |
unlock_user_struct(target_ldt_info, ptr, 1); |
5752 |
unlock_user_struct(target_ldt_info, ptr, 1); |
5752 |
|
5753 |
|
5753 |
if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || |
5754 |
if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || |
5754 |
ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX) |
5755 |
ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX) |
5755 |
return -TARGET_EINVAL; |
5756 |
return -TARGET_EINVAL; |
5756 |
seg_32bit = ldt_info.flags & 1; |
5757 |
seg_32bit = ldt_info.flags & 1; |
Lines 5828-5834
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
Link Here
|
5828 |
lp = (uint32_t *)(gdt_table + idx); |
5829 |
lp = (uint32_t *)(gdt_table + idx); |
5829 |
entry_1 = tswap32(lp[0]); |
5830 |
entry_1 = tswap32(lp[0]); |
5830 |
entry_2 = tswap32(lp[1]); |
5831 |
entry_2 = tswap32(lp[1]); |
5831 |
|
5832 |
|
5832 |
read_exec_only = ((entry_2 >> 9) & 1) ^ 1; |
5833 |
read_exec_only = ((entry_2 >> 9) & 1) ^ 1; |
5833 |
contents = (entry_2 >> 10) & 3; |
5834 |
contents = (entry_2 >> 10) & 3; |
5834 |
seg_not_present = ((entry_2 >> 15) & 1) ^ 1; |
5835 |
seg_not_present = ((entry_2 >> 15) & 1) ^ 1; |
Lines 5844-5851
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
Link Here
|
5844 |
(read_exec_only << 3) | (limit_in_pages << 4) | |
5845 |
(read_exec_only << 3) | (limit_in_pages << 4) | |
5845 |
(seg_not_present << 5) | (useable << 6) | (lm << 7); |
5846 |
(seg_not_present << 5) | (useable << 6) | (lm << 7); |
5846 |
limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000); |
5847 |
limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000); |
5847 |
base_addr = (entry_1 >> 16) | |
5848 |
base_addr = (entry_1 >> 16) | |
5848 |
(entry_2 & 0xff000000) | |
5849 |
(entry_2 & 0xff000000) | |
5849 |
((entry_2 & 0xff) << 16); |
5850 |
((entry_2 & 0xff) << 16); |
5850 |
target_ldt_info->base_addr = tswapal(base_addr); |
5851 |
target_ldt_info->base_addr = tswapal(base_addr); |
5851 |
target_ldt_info->limit = tswap32(limit); |
5852 |
target_ldt_info->limit = tswap32(limit); |
Lines 7353-7390
static int open_self_auxv(void *cpu_env, int fd)
Link Here
|
7353 |
return 0; |
7354 |
return 0; |
7354 |
} |
7355 |
} |
7355 |
|
7356 |
|
7356 |
static int is_proc_myself(const char *filename, const char *entry) |
|
|
7357 |
{ |
7358 |
if (!strncmp(filename, "/proc/", strlen("/proc/"))) { |
7359 |
filename += strlen("/proc/"); |
7360 |
if (!strncmp(filename, "self/", strlen("self/"))) { |
7361 |
filename += strlen("self/"); |
7362 |
} else if (*filename >= '1' && *filename <= '9') { |
7363 |
char myself[80]; |
7364 |
snprintf(myself, sizeof(myself), "%d/", getpid()); |
7365 |
if (!strncmp(filename, myself, strlen(myself))) { |
7366 |
filename += strlen(myself); |
7367 |
} else { |
7368 |
return 0; |
7369 |
} |
7370 |
} else { |
7371 |
return 0; |
7372 |
} |
7373 |
if (!strcmp(filename, entry)) { |
7374 |
return 1; |
7375 |
} |
7376 |
} |
7377 |
return 0; |
7378 |
} |
7379 |
|
7380 |
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \ |
7381 |
defined(TARGET_SPARC) || defined(TARGET_M68K) |
7382 |
static int is_proc(const char *filename, const char *entry) |
7383 |
{ |
7384 |
return strcmp(filename, entry) == 0; |
7385 |
} |
7386 |
#endif |
7387 |
|
7388 |
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) |
7357 |
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) |
7389 |
static int open_net_route(void *cpu_env, int fd) |
7358 |
static int open_net_route(void *cpu_env, int fd) |
7390 |
{ |
7359 |
{ |
Lines 7460-7477
static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
Link Here
|
7460 |
{ "auxv", open_self_auxv, is_proc_myself }, |
7429 |
{ "auxv", open_self_auxv, is_proc_myself }, |
7461 |
{ "cmdline", open_self_cmdline, is_proc_myself }, |
7430 |
{ "cmdline", open_self_cmdline, is_proc_myself }, |
7462 |
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) |
7431 |
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) |
7463 |
{ "/proc/net/route", open_net_route, is_proc }, |
7432 |
{ "net/route", open_net_route, is_proc }, |
7464 |
#endif |
7433 |
#endif |
7465 |
#if defined(TARGET_SPARC) |
7434 |
#if defined(TARGET_SPARC) |
7466 |
{ "/proc/cpuinfo", open_cpuinfo, is_proc }, |
7435 |
{ "cpuinfo", open_cpuinfo, is_proc }, |
7467 |
#endif |
7436 |
#endif |
7468 |
#if defined(TARGET_M68K) |
7437 |
#if defined(TARGET_M68K) |
7469 |
{ "/proc/hardware", open_hardware, is_proc }, |
7438 |
{ "hardware", open_hardware, is_proc }, |
7470 |
#endif |
7439 |
#endif |
7471 |
{ NULL, NULL, NULL } |
7440 |
{ NULL, NULL, NULL } |
7472 |
}; |
7441 |
}; |
7473 |
|
7442 |
|
7474 |
if (is_proc_myself(pathname, "exe")) { |
7443 |
if (is_proc_myself_exe(pathname)) { |
7475 |
int execfd = qemu_getauxval(AT_EXECFD); |
7444 |
int execfd = qemu_getauxval(AT_EXECFD); |
7476 |
return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); |
7445 |
return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); |
7477 |
} |
7446 |
} |
Lines 9031-9037
static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Link Here
|
9031 |
} else if (!arg3) { |
9000 |
} else if (!arg3) { |
9032 |
/* Short circuit this for the magic exe check. */ |
9001 |
/* Short circuit this for the magic exe check. */ |
9033 |
ret = -TARGET_EINVAL; |
9002 |
ret = -TARGET_EINVAL; |
9034 |
} else if (is_proc_myself((const char *)p, "exe")) { |
9003 |
} else if (is_proc_myself_exe((const char *)p)) { |
9035 |
char real[PATH_MAX], *temp; |
9004 |
char real[PATH_MAX], *temp; |
9036 |
temp = realpath(exec_path, real); |
9005 |
temp = realpath(exec_path, real); |
9037 |
/* Return value is # of bytes that we wrote to the buffer. */ |
9006 |
/* Return value is # of bytes that we wrote to the buffer. */ |
Lines 9060-9066
static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Link Here
|
9060 |
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); |
9029 |
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); |
9061 |
if (!p || !p2) { |
9030 |
if (!p || !p2) { |
9062 |
ret = -TARGET_EFAULT; |
9031 |
ret = -TARGET_EFAULT; |
9063 |
} else if (is_proc_myself((const char *)p, "exe")) { |
9032 |
} else if (is_proc_myself_exe((const char *)p)) { |
9064 |
char real[PATH_MAX], *temp; |
9033 |
char real[PATH_MAX], *temp; |
9065 |
temp = realpath(exec_path, real); |
9034 |
temp = realpath(exec_path, real); |
9066 |
ret = temp == NULL ? get_errno(-1) : strlen(real) ; |
9035 |
ret = temp == NULL ? get_errno(-1) : strlen(real) ; |
Lines 10847-10853
static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Link Here
|
10847 |
return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); |
10816 |
return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); |
10848 |
#if defined(TARGET_NR_fchownat) |
10817 |
#if defined(TARGET_NR_fchownat) |
10849 |
case TARGET_NR_fchownat: |
10818 |
case TARGET_NR_fchownat: |
10850 |
if (!(p = lock_user_string(arg2))) |
10819 |
if (!(p = lock_user_string(arg2))) |
10851 |
return -TARGET_EFAULT; |
10820 |
return -TARGET_EFAULT; |
10852 |
ret = get_errno(fchownat(arg1, p, low2highuid(arg3), |
10821 |
ret = get_errno(fchownat(arg1, p, low2highuid(arg3), |
10853 |
low2highgid(arg4), arg5)); |
10822 |
low2highgid(arg4), arg5)); |