linux-user pull for 2.2

Two last minute fixes uncovered and fixed by Tom Musta
 and Alexander Graf, thanks
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIVAwUAVGGuUrRIkN7ePJvAAQgR+Q/+MVD1IIFsk8VDwex0J4wQ+pgy60m/rgTv
 clgk4ZqxnKiWtQRM12UzmVsD7Z51cb/ijl8Bh7DawxCQmFmCSmfu2DMPSrXcRUEA
 dB1EdM16GoOuJutNhNIjquHKF8FT7KJf421nX3Wk4knKvEjFRRvCCpgxcXbqaek/
 KON1SLf9ABqNGbWuVoZBe3ltc5uAREhF32fWAxErRVcREg1nxUPKS4zgWaLSwksA
 CicjfRGO3bxVAejXi3SIH/kv2w5y0lqvlrCLynqPdZOc9jD2J05SfuVXG/4phSUy
 Ug8BAPYm3lZqm4ICH0l0+FRM4hOXfulYDTohbBNQnAdxas7c0mHdihBdCTsQCCRy
 RRaWX7FKDDo/vVep2dCyGWFzWSY4sgCZWifFsXPOdwtLUCnksOPld/78lmM83MXo
 cSJUYpuepQRxa5lUy6awkkHz6YPdLQ3jxSCnzjwCh7KSH+LFGATpNTw8PQbkxdVD
 AxWLgdxV4xGSyCW4gJkCJIYkpY9wSL4VH4Et4tl0RGZEacJx5R3CsBABbtmlM2bh
 K2gnB59GOg2vLcf0A8Wh7oDnc6HxWnhp+p6fPw2aPnVIc7QfVUuAM3OK0/XSQzH6
 zVKOnABSvFBNhjgGgYHZsIuBbg1Pdt7B6nE6bA+TMA8jggSjO/O75huTaZw9M1yl
 NWi+faoD4+4=
 =o8o5
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20141111' into staging

linux-user pull for 2.2

Two last minute fixes uncovered and fixed by Tom Musta
and Alexander Graf, thanks

# gpg: Signature made Tue 11 Nov 2014 06:36:02 GMT using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"

* remotes/riku/tags/pull-linux-user-20141111:
  linux-user: Fix up timer id handling
  linux-user: Do not subtract offset from end address

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-11-11 10:09:31 +00:00
commit 59c4f2ecef
3 changed files with 39 additions and 22 deletions

View File

@ -1824,7 +1824,7 @@ static void load_elf_image(const char *image_name, int image_fd,
if (a < loaddr) { if (a < loaddr) {
loaddr = a; loaddr = a;
} }
a += phdr[i].p_memsz; a = phdr[i].p_vaddr + phdr[i].p_memsz;
if (a > hiaddr) { if (a > hiaddr) {
hiaddr = a; hiaddr = a;
} }

View File

@ -5473,6 +5473,27 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
return get_errno(sys_openat(dirfd, path(pathname), flags, mode)); return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
} }
#define TIMER_MAGIC 0x0caf0000
#define TIMER_MAGIC_MASK 0xffff0000
/* Convert QEMU provided timer ID back to internal 16bit index format */
static target_timer_t get_timer_id(abi_long arg)
{
target_timer_t timerid = arg;
if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
return -TARGET_EINVAL;
}
timerid &= 0xffff;
if (timerid >= ARRAY_SIZE(g_posix_timers)) {
return -TARGET_EINVAL;
}
return timerid;
}
/* do_syscall() should always have a single exit point at the end so /* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed. that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */ All errnos that do_syscall() returns must be -TARGET_<errcode>. */
@ -9579,7 +9600,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
/* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */ /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL; struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
struct target_timer_t *ptarget_timer;
int clkid = arg1; int clkid = arg1;
int timer_index = next_free_host_timer(); int timer_index = next_free_host_timer();
@ -9601,11 +9621,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (ret) { if (ret) {
phtimer = NULL; phtimer = NULL;
} else { } else {
if (!lock_user_struct(VERIFY_WRITE, ptarget_timer, arg3, 1)) { if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
goto efault; goto efault;
} }
ptarget_timer->ptr = tswap32(0xcafe0000 | timer_index);
unlock_user_struct(ptarget_timer, arg3, 1);
} }
} }
break; break;
@ -9617,9 +9635,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
{ {
/* args: timer_t timerid, int flags, const struct itimerspec *new_value, /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
* struct itimerspec * old_value */ * struct itimerspec * old_value */
target_ulong timerid = arg1; target_timer_t timerid = get_timer_id(arg1);
if (arg3 == 0 || timerid >= ARRAY_SIZE(g_posix_timers)) { if (timerid < 0) {
ret = timerid;
} else if (arg3 == 0) {
ret = -TARGET_EINVAL; ret = -TARGET_EINVAL;
} else { } else {
timer_t htimer = g_posix_timers[timerid]; timer_t htimer = g_posix_timers[timerid];
@ -9638,12 +9658,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_gettime: case TARGET_NR_timer_gettime:
{ {
/* args: timer_t timerid, struct itimerspec *curr_value */ /* args: timer_t timerid, struct itimerspec *curr_value */
target_ulong timerid = arg1; target_timer_t timerid = get_timer_id(arg1);
if (!arg2) { if (timerid < 0) {
return -TARGET_EFAULT; ret = timerid;
} else if (timerid >= ARRAY_SIZE(g_posix_timers)) { } else if (!arg2) {
ret = -TARGET_EINVAL; ret = -TARGET_EFAULT;
} else { } else {
timer_t htimer = g_posix_timers[timerid]; timer_t htimer = g_posix_timers[timerid];
struct itimerspec hspec; struct itimerspec hspec;
@ -9661,10 +9681,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_getoverrun: case TARGET_NR_timer_getoverrun:
{ {
/* args: timer_t timerid */ /* args: timer_t timerid */
target_ulong timerid = arg1; target_timer_t timerid = get_timer_id(arg1);
if (timerid >= ARRAY_SIZE(g_posix_timers)) { if (timerid < 0) {
ret = -TARGET_EINVAL; ret = timerid;
} else { } else {
timer_t htimer = g_posix_timers[timerid]; timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_getoverrun(htimer)); ret = get_errno(timer_getoverrun(htimer));
@ -9677,10 +9697,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_delete: case TARGET_NR_timer_delete:
{ {
/* args: timer_t timerid */ /* args: timer_t timerid */
target_ulong timerid = arg1; target_timer_t timerid = get_timer_id(arg1);
if (timerid >= ARRAY_SIZE(g_posix_timers)) { if (timerid < 0) {
ret = -TARGET_EINVAL; ret = timerid;
} else { } else {
timer_t htimer = g_posix_timers[timerid]; timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_delete(htimer)); ret = get_errno(timer_delete(htimer));

View File

@ -2564,10 +2564,7 @@ struct target_ucred {
#endif #endif
typedef int32_t target_timer_t;
struct target_timer_t {
abi_ulong ptr;
};
#define TARGET_SIGEV_MAX_SIZE 64 #define TARGET_SIGEV_MAX_SIZE 64