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-7479
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 |
return execfd; |
7476 |
return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); |
|
|
7477 |
} |
7445 |
} |
7478 |
|
7446 |
|
7479 |
for (fake_open = fakes; fake_open->filename; fake_open++) { |
7447 |
for (fake_open = fakes; fake_open->filename; fake_open++) { |
Lines 7728-7735
static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Link Here
|
7728 |
return ret; |
7696 |
return ret; |
7729 |
#endif |
7697 |
#endif |
7730 |
case TARGET_NR_close: |
7698 |
case TARGET_NR_close: |
7731 |
fd_trans_unregister(arg1); |
7699 |
{ |
7732 |
return get_errno(close(arg1)); |
7700 |
int fd = arg1; |
|
|
7701 |
if (fd == execfd) { |
7702 |
// We don't need to close execfd. |
7703 |
// It will be closed on qemu exit. |
7704 |
return 0; |
7705 |
} |
7706 |
|
7707 |
fd_trans_unregister(fd); |
7708 |
return get_errno(close(fd)); |
7709 |
} |
7733 |
|
7710 |
|
7734 |
case TARGET_NR_brk: |
7711 |
case TARGET_NR_brk: |
7735 |
return do_brk(arg1); |
7712 |
return do_brk(arg1); |
Lines 9031-9037
static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Link Here
|
9031 |
} else if (!arg3) { |
9008 |
} else if (!arg3) { |
9032 |
/* Short circuit this for the magic exe check. */ |
9009 |
/* Short circuit this for the magic exe check. */ |
9033 |
ret = -TARGET_EINVAL; |
9010 |
ret = -TARGET_EINVAL; |
9034 |
} else if (is_proc_myself((const char *)p, "exe")) { |
9011 |
} else if (is_proc_myself_exe((const char *)p)) { |
9035 |
char real[PATH_MAX], *temp; |
9012 |
char real[PATH_MAX], *temp; |
9036 |
temp = realpath(exec_path, real); |
9013 |
temp = realpath(exec_path, real); |
9037 |
/* Return value is # of bytes that we wrote to the buffer. */ |
9014 |
/* 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); |
9037 |
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); |
9061 |
if (!p || !p2) { |
9038 |
if (!p || !p2) { |
9062 |
ret = -TARGET_EFAULT; |
9039 |
ret = -TARGET_EFAULT; |
9063 |
} else if (is_proc_myself((const char *)p, "exe")) { |
9040 |
} else if (is_proc_myself_exe((const char *)p)) { |
9064 |
char real[PATH_MAX], *temp; |
9041 |
char real[PATH_MAX], *temp; |
9065 |
temp = realpath(exec_path, real); |
9042 |
temp = realpath(exec_path, real); |
9066 |
ret = temp == NULL ? get_errno(-1) : strlen(real) ; |
9043 |
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))); |
10824 |
return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); |
10848 |
#if defined(TARGET_NR_fchownat) |
10825 |
#if defined(TARGET_NR_fchownat) |
10849 |
case TARGET_NR_fchownat: |
10826 |
case TARGET_NR_fchownat: |
10850 |
if (!(p = lock_user_string(arg2))) |
10827 |
if (!(p = lock_user_string(arg2))) |
10851 |
return -TARGET_EFAULT; |
10828 |
return -TARGET_EFAULT; |
10852 |
ret = get_errno(fchownat(arg1, p, low2highuid(arg3), |
10829 |
ret = get_errno(fchownat(arg1, p, low2highuid(arg3), |
10853 |
low2highgid(arg4), arg5)); |
10830 |
low2highgid(arg4), arg5)); |