x86_64 defines MAP_32BIT which forces `mmap()` to return a 32-bit address. This commit adds support for this flag if supported by the host.
Signed-off-by: Jean-Christian CÎRSTEA <[email protected]> --- include/user/abitypes.h | 2 ++ include/user/thunk.h | 3 ++ linux-user/strace.c | 26 ++++++++++++++++- linux-user/strace.list | 4 +-- linux-user/syscall.c | 50 ++++++++++++++++----------------- linux-user/x86_64/target_mman.h | 3 ++ 6 files changed, 59 insertions(+), 29 deletions(-) diff --git a/include/user/abitypes.h b/include/user/abitypes.h index be7a876523..0228e1b77c 100644 --- a/include/user/abitypes.h +++ b/include/user/abitypes.h @@ -47,6 +47,8 @@ typedef uint32_t abi_uint __attribute__((aligned(ABI_INT_ALIGNMENT))); typedef int64_t abi_llong __attribute__((aligned(ABI_LLONG_ALIGNMENT))); typedef uint64_t abi_ullong __attribute__((aligned(ABI_LLONG_ALIGNMENT))); +#define TARGET_ABI_FMT_x "%08x" + #ifdef TARGET_ABI32 typedef uint32_t abi_ulong __attribute__((aligned(ABI_LONG_ALIGNMENT))); typedef int32_t abi_long __attribute__((aligned(ABI_LONG_ALIGNMENT))); diff --git a/include/user/thunk.h b/include/user/thunk.h index 2a2104b568..e4cfb5fe46 100644 --- a/include/user/thunk.h +++ b/include/user/thunk.h @@ -73,6 +73,9 @@ typedef struct bitmask_transtbl { unsigned int host_bits; } bitmask_transtbl; +#define BITMASK_BIT(target, host) \ + { target, target, host, host } + void thunk_register_struct(int id, const char *name, const argtype *types); void thunk_register_struct_direct(int id, const char *name, const StructEntry *se1); diff --git a/linux-user/strace.c b/linux-user/strace.c index 758c5d32b6..616c801e6b 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -802,6 +802,27 @@ print_syscall_ret_addr(CPUArchState *cpu_env, const struct syscallname *name, qemu_log("\n"); } +static void +print_mmap_ret(CPUArchState *cpu_env, const struct syscallname *name, + abi_long ret, abi_long arg0, abi_long arg1, + abi_long arg2, abi_long arg3, abi_long arg4, + abi_long arg5) +{ + if (!print_syscall_err(ret)) { + const abi_ulong mmap_flags = (abi_ulong)arg3; + /* + * If MAP_32BIT is set, print the address as a 32-bit value. This is + * consistent with strace output + */ + if (mmap_flags & MAP_32BIT) { + qemu_log("0x" TARGET_ABI_FMT_x, (abi_uint)ret); + } else { + qemu_log("0x" TARGET_ABI_FMT_lx, ret); + } + } + qemu_log("\n"); +} + #if 0 /* currently unused */ static void print_syscall_ret_raw(struct syscallname *name, abi_long ret) @@ -1196,8 +1217,11 @@ UNUSED static const struct flags mmap_flags[] = { FLAG_TARGET(MAP_POPULATE), FLAG_TARGET(MAP_STACK), FLAG_TARGET(MAP_SYNC), -#if TARGET_MAP_UNINITIALIZED != 0 +#ifdef TARGET_MAP_UNINITIALIZED FLAG_TARGET(MAP_UNINITIALIZED), +#endif +#ifdef TARGET_MAP_32BIT + FLAG_TARGET(MAP_32BIT), #endif FLAG_END, }; diff --git a/linux-user/strace.list b/linux-user/strace.list index 51b5ead969..7a8d18ba96 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -602,10 +602,10 @@ { TARGET_NR_mlockall, "mlockall" , NULL, print_mlockall, NULL }, #endif #ifdef TARGET_NR_mmap -{ TARGET_NR_mmap, "mmap" , NULL, print_mmap, print_syscall_ret_addr }, +{ TARGET_NR_mmap, "mmap" , NULL, print_mmap, print_mmap_ret }, #endif #ifdef TARGET_NR_mmap2 -{ TARGET_NR_mmap2, "mmap2" , NULL, print_mmap2, print_syscall_ret_addr }, +{ TARGET_NR_mmap2, "mmap2" , NULL, print_mmap2, print_mmap_ret }, #endif #ifdef TARGET_NR_modify_ldt { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL }, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 2060e561a2..0bb56e7a8e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5896,32 +5896,6 @@ static const StructEntry struct_termios_def = { #define MAP_UNINITIALIZED 0 #endif -static const bitmask_transtbl mmap_flags_tbl[] = { - { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, - { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, - MAP_ANONYMOUS, MAP_ANONYMOUS }, - { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, - MAP_GROWSDOWN, MAP_GROWSDOWN }, - { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, - MAP_DENYWRITE, MAP_DENYWRITE }, - { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, - MAP_EXECUTABLE, MAP_EXECUTABLE }, - { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED }, - { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, - MAP_NORESERVE, MAP_NORESERVE }, - { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB }, - /* MAP_STACK had been ignored by the kernel for quite some time. - Recognize it for the target insofar as we do not want to pass - it through to the host. */ - { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 }, - { TARGET_MAP_NONBLOCK, TARGET_MAP_NONBLOCK, MAP_NONBLOCK, MAP_NONBLOCK }, - { TARGET_MAP_POPULATE, TARGET_MAP_POPULATE, MAP_POPULATE, MAP_POPULATE }, - { TARGET_MAP_FIXED_NOREPLACE, TARGET_MAP_FIXED_NOREPLACE, - MAP_FIXED_NOREPLACE, MAP_FIXED_NOREPLACE }, - { TARGET_MAP_UNINITIALIZED, TARGET_MAP_UNINITIALIZED, - MAP_UNINITIALIZED, MAP_UNINITIALIZED }, -}; - /* * Arrange for legacy / undefined architecture specific flags to be * ignored by mmap handling code. @@ -5936,6 +5910,30 @@ static const bitmask_transtbl mmap_flags_tbl[] = { #define TARGET_MAP_HUGE_1GB 0 #endif +static const bitmask_transtbl mmap_flags_tbl[] = { + BITMASK_BIT(TARGET_MAP_FIXED, MAP_FIXED), + BITMASK_BIT(TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS), + BITMASK_BIT(TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN), + BITMASK_BIT(TARGET_MAP_DENYWRITE, MAP_DENYWRITE), + BITMASK_BIT(TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE), + BITMASK_BIT(TARGET_MAP_LOCKED, MAP_LOCKED), + BITMASK_BIT(TARGET_MAP_NORESERVE, MAP_NORESERVE), + BITMASK_BIT(TARGET_MAP_HUGETLB, MAP_HUGETLB), + /* + * MAP_STACK had been ignored by the kernel for quite some time. + * Recognize it for the target insofar as we do not want to pass + * it through to the host. + */ + BITMASK_BIT(TARGET_MAP_STACK, 0), + BITMASK_BIT(TARGET_MAP_NONBLOCK, MAP_NONBLOCK), + BITMASK_BIT(TARGET_MAP_POPULATE, MAP_POPULATE), + BITMASK_BIT(TARGET_MAP_FIXED_NOREPLACE, MAP_FIXED_NOREPLACE), + BITMASK_BIT(TARGET_MAP_UNINITIALIZED, MAP_UNINITIALIZED), +#if TARGET_MAP_32BIT != 0 + BITMASK_BIT(TARGET_MAP_32BIT, MAP_32BIT), +#endif +}; + static abi_long do_mmap(abi_ulong addr, abi_ulong len, int prot, int target_flags, int fd, off_t offset) { diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h index 48fbf20b42..14c29203f9 100644 --- a/linux-user/x86_64/target_mman.h +++ b/linux-user/x86_64/target_mman.h @@ -13,4 +13,7 @@ /* arch/x86/include/asm/elf.h */ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) +/* arch/x86/include/uapi/asm/mman.h */ +#define TARGET_MAP_32BIT 0x40 + #include "../generic/target_mman.h" -- 2.51.0
