linux-user: fix mremap for 64bit targets on 32bit hosts
PATCH 1/1 linux-user: fix mremap for 64bit targets on 32bit hosts
--- linux-user/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
linux-user/mmap.c +2 -2
@@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,if (flags &MREMAP_FIXED ) { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags,g2h (new_addr));
@@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, host_addr =MAP_FAILED ; }else { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags |MREMAP_FIXED ,g2h (mmap_start));if (reserved_va) {
Signature · 1 line
2.7.3
Hi,
Quoted 1 line · Felix Janda
Signed-off-by Felix Janda <[email protected]>
Have you run the mremap tests of ltp with this on your host/guest combo?
Quoted 29 lines
--- linux-user/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)linux-user/mmap.c +2
-2@@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,if (flags &MREMAP_FIXED ) { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags,g2h (new_addr));@@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, host_addr =MAP_FAILED ; }else { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags |MREMAP_FIXED ,g2h (mmap_start));if (reserved_va) {Signature · 1 line
2.7.3
Quoted 7 lines · Riku Voipio
Hi,
Quoted 1 line · Felix Janda
Signed-off-by Felix Janda <[email protected]>Have you run the mremap tests of ltp with this on your host/guest combo?
I have just run the tests. My host is arm and my guest is aarch64. Without the patch all but mremap02 fail. With the patch all but mremap04 pass. The mremap04 test indicates that shmat is broken.
Quoted 29 lines
Quoted 29 lines
--- linux-user/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)linux-user/mmap.c +2
-2@@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,if (flags &MREMAP_FIXED ) { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags,g2h (new_addr));@@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, host_addr =MAP_FAILED ; }else { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags |MREMAP_FIXED ,g2h (mmap_start));if (reserved_va) {Signature · 1 line
2.7.3
Quoted 28 lines · Felix Janda
Signed-off-by Felix Janda <[email protected]>--- linux-user/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)linux-user/mmap.c +2
-3@@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,if (flags &MREMAP_FIXED ) { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags,g2h (new_addr));@@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, host_addr =MAP_FAILED ; }else { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags |MREMAP_FIXED ,g2h (mmap_start));if (reserved_va) { --
Quoted 1 line
2.7.3
Rather than this, I think it would be better to switch to using the mremap() library call rather than direct syscall here, which then matches the other mremap()s later in the function. (That will work right because mremap()'s prototype says it takes size_t arguments, whereas syscall() is a generic thing which doesn't, and so the C default promotions do the wrong thing with the abi_ulongs.)
The use of syscall(__NR_mremap, ...) originally dates back to 2008:
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01087.html
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg00480.html
and was to permit compilation with glibc 2.4 which didn't support the 5-argument mremap() or define MREMAP_FIXED.
Since glibc 2.4 dates back to a decade ago now, we no longer need to carry this ugly (and buggy) workaround for it.
thanks
-- PMM
Quoted 43 lines · Peter Maydell
Quoted 28 lines · Felix Janda
Signed-off-by Felix Janda <[email protected]>--- linux-user/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)linux-user/mmap.c +2
-3@@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,if (flags &MREMAP_FIXED ) { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags,g2h (new_addr));@@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, host_addr =MAP_FAILED ; }else { host_addr = (void *)syscall (__NR_mremap,g2h (old_addr), - old_size, new_size, + (size_t ) old_size, (size_t ) new_size, flags |MREMAP_FIXED ,g2h (mmap_start));if (reserved_va) { --Quoted 1 line
2.7.3
Rather than this, I think it would be better to switch to using the
mremap()library call rather than direct syscall here, which then matches the other mremap()s later in the function. (That will work right because mremap()'s prototype says it takessize_targuments, whereassyscall()is a generic thing which doesn't, and so the C default promotions do the wrong thing with theabi_ulongs.)The use of
syscall(__NR_mremap, ...)originally dates back to 2008:
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01087.html
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg00480.html
Quoted 5 lines
and was to permit compilation with glibc 2.4 which didn't support the 5-argument
mremap()or defineMREMAP_FIXED.Since glibc 2.4 dates back to a decade ago now, we no longer need to carry this ugly (and buggy) workaround for it.
This sounds like a good idea. Thanks also for digging up the history.
I will prepare a new patch.
Thanks,
Felix