From 8491026a08b417b2d4070f7c373dcb43134c5312 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 5 Nov 2024 16:15:24 +0100 Subject: linux-user: Fix setreuid and setregid to use direct syscalls The commit fd6f7798ac30 ("linux-user: Use direct syscalls for setuid(), etc") added direct syscall wrappers for setuid(), setgid(), etc since the system calls have different semantics than the libc functions. Add and use the corresponding wrappers for setreuid and setregid which were missed in that commit. This fixes the build of the debian package of the uid_wrapper library (https://cwrap.org/uid_wrapper.html) when running linux-user. Cc: qemu-stable@nongnu.org Signed-off-by: Helge Deller Reviewed-by: Richard Henderson Reviewed-by: Ilya Leoshkevich Message-ID: Signed-off-by: Richard Henderson --- linux-user/syscall.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'linux-user') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 59b2080..0279f23 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7233,12 +7233,24 @@ static inline int tswapid(int id) #else #define __NR_sys_setgroups __NR_setgroups #endif +#ifdef __NR_sys_setreuid32 +#define __NR_sys_setreuid __NR_setreuid32 +#else +#define __NR_sys_setreuid __NR_setreuid +#endif +#ifdef __NR_sys_setregid32 +#define __NR_sys_setregid __NR_setregid32 +#else +#define __NR_sys_setregid __NR_setregid +#endif _syscall1(int, sys_setuid, uid_t, uid) _syscall1(int, sys_setgid, gid_t, gid) _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) _syscall2(int, sys_setgroups, int, size, gid_t *, grouplist) +_syscall2(int, sys_setreuid, uid_t, ruid, uid_t, euid); +_syscall2(int, sys_setregid, gid_t, rgid, gid_t, egid); void syscall_init(void) { @@ -11932,9 +11944,9 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, return get_errno(high2lowgid(getegid())); #endif case TARGET_NR_setreuid: - return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); + return get_errno(sys_setreuid(low2highuid(arg1), low2highuid(arg2))); case TARGET_NR_setregid: - return get_errno(setregid(low2highgid(arg1), low2highgid(arg2))); + return get_errno(sys_setregid(low2highgid(arg1), low2highgid(arg2))); case TARGET_NR_getgroups: { /* the same code as for TARGET_NR_getgroups32 */ int gidsetsize = arg1; @@ -12264,11 +12276,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_setreuid32 case TARGET_NR_setreuid32: - return get_errno(setreuid(arg1, arg2)); + return get_errno(sys_setreuid(arg1, arg2)); #endif #ifdef TARGET_NR_setregid32 case TARGET_NR_setregid32: - return get_errno(setregid(arg1, arg2)); + return get_errno(sys_setregid(arg1, arg2)); #endif #ifdef TARGET_NR_getgroups32 case TARGET_NR_getgroups32: -- cgit v1.1 From fb7f3572b111ffb6c2dd2c7f6c5b4dc57dd8a3f5 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 23 Oct 2024 02:24:31 +0200 Subject: linux-user: Tolerate CONFIG_LSM_MMAP_MIN_ADDR Running qemu-i386 on a system running with SELinux in enforcing mode (more precisely: s390x trixie container on Fedora 40) fails with: qemu-i386: tests/tcg/i386-linux-user/sigreturn-sigmask: Unable to find a guest_base to satisfy all guest address mapping requirements 00000000-ffffffff The reason is that main() determines mmap_min_addr from /proc/sys/vm/mmap_min_addr, but SELinux additionally defines CONFIG_LSM_MMAP_MIN_ADDR, which is normally larger: 32K or 64K, but, in general, can be anything. There is no portable way to query its value: /boot/config, /proc/config and /proc/config.gz are distro- and environment-specific. Once the identity map fails, the magnitude of guest_base does not matter, so fix by starting the search from 1M or 1G. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2598 Suggested-by: Richard Henderson Signed-off-by: Ilya Leoshkevich Message-ID: <20241023002558.34589-1-iii@linux.ibm.com> Signed-off-by: Richard Henderson --- linux-user/elfload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-user') diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 6cef8db..d6ad77d 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2898,7 +2898,7 @@ static uintptr_t pgb_try_itree(const PGBAddrs *ga, uintptr_t base, static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root, uintptr_t align, uintptr_t brk) { - uintptr_t last = mmap_min_addr; + uintptr_t last = sizeof(uintptr_t) == 4 ? MiB : GiB; uintptr_t base, skip; while (true) { -- cgit v1.1 From c81d1fafa6233448bcc2d8fcd2ba63a4ae834f3a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:32:01 -0800 Subject: linux-user: Honor elf alignment when placing images Most binaries don't actually depend on more than page alignment, but any binary can request it. Not honoring this was a bug. This became obvious when gdb reported Failed to read a valid object file image from memory when examining some vdso which are marked as needing more than page alignment. Signed-off-by: Richard Henderson --- linux-user/elfload.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'linux-user') diff --git a/linux-user/elfload.c b/linux-user/elfload.c index d6ad77d..90e79a0 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -3179,7 +3179,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src, char **pinterp_name) { g_autofree struct elf_phdr *phdr = NULL; - abi_ulong load_addr, load_bias, loaddr, hiaddr, error; + abi_ulong load_addr, load_bias, loaddr, hiaddr, error, align; + size_t reserve_size, align_size; int i, prot_exec; Error *err = NULL; @@ -3263,6 +3264,9 @@ static void load_elf_image(const char *image_name, const ImageSource *src, load_addr = loaddr; + align = pow2ceil(info->alignment); + info->alignment = align; + if (pinterp_name != NULL) { if (ehdr->e_type == ET_EXEC) { /* @@ -3271,8 +3275,6 @@ static void load_elf_image(const char *image_name, const ImageSource *src, */ probe_guest_base(image_name, loaddr, hiaddr); } else { - abi_ulong align; - /* * The binary is dynamic, but we still need to * select guest_base. In this case we pass a size. @@ -3290,10 +3292,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src, * Since we do not have complete control over the guest * address space, we prefer the kernel to choose some address * rather than force the use of LOAD_ADDR via MAP_FIXED. - * But without MAP_FIXED we cannot guarantee alignment, - * only suggest it. */ - align = pow2ceil(info->alignment); if (align) { load_addr &= -align; } @@ -3317,13 +3316,35 @@ static void load_elf_image(const char *image_name, const ImageSource *src, * In both cases, we will overwrite pages in this range with mappings * from the executable. */ - load_addr = target_mmap(load_addr, (size_t)hiaddr - loaddr + 1, PROT_NONE, + reserve_size = (size_t)hiaddr - loaddr + 1; + align_size = reserve_size; + + if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) { + align_size += align - 1; + } + + load_addr = target_mmap(load_addr, align_size, PROT_NONE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | (ehdr->e_type == ET_EXEC ? MAP_FIXED_NOREPLACE : 0), -1, 0); if (load_addr == -1) { goto exit_mmap; } + + if (align_size != reserve_size) { + abi_ulong align_addr = ROUND_UP(load_addr, align); + abi_ulong align_end = align_addr + reserve_size; + abi_ulong load_end = load_addr + align_size; + + if (align_addr != load_addr) { + target_munmap(load_addr, align_addr - load_addr); + } + if (align_end != load_end) { + target_munmap(align_end, load_end - align_end); + } + load_addr = align_addr; + } + load_bias = load_addr - loaddr; if (elf_is_fdpic(ehdr)) { -- cgit v1.1 From dff406754efdb13f401e2b39f869541286903619 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:33:38 -0800 Subject: linux-user: Drop image_info.alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This field is write-only. Use only the function-local variable within load_elf_image. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/elfload.c | 7 +++---- linux-user/qemu.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'linux-user') diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 90e79a0..ef9cffb 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -3220,7 +3220,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src, * amount of memory to handle that. Locate the interpreter, if any. */ loaddr = -1, hiaddr = 0; - info->alignment = 0; + align = 0; info->exec_stack = EXSTACK_DEFAULT; for (i = 0; i < ehdr->e_phnum; ++i) { struct elf_phdr *eppnt = phdr + i; @@ -3234,7 +3234,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src, hiaddr = a; } ++info->nsegs; - info->alignment |= eppnt->p_align; + align |= eppnt->p_align; } else if (eppnt->p_type == PT_INTERP && pinterp_name) { g_autofree char *interp_name = NULL; @@ -3264,8 +3264,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src, load_addr = loaddr; - align = pow2ceil(info->alignment); - info->alignment = align; + align = pow2ceil(align); if (pinterp_name != NULL) { if (ehdr->e_type == ET_EXEC) { diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 895bdd7..67bc81b 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -44,7 +44,6 @@ struct image_info { abi_ulong file_string; uint32_t elf_flags; int personality; - abi_ulong alignment; bool exec_stack; /* Generic semihosting knows about these pointers. */ -- cgit v1.1 From f19ec28ddc383143573e828d34f190cdda7e9669 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:50:39 -0800 Subject: linux-user/aarch64: Reduce vdso alignment to 4k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce vdso alignment to minimum page size. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/aarch64/Makefile.vdso | 5 +++-- linux-user/aarch64/vdso-be.so | Bin 3224 -> 3224 bytes linux-user/aarch64/vdso-le.so | Bin 3224 -> 3224 bytes 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'linux-user') diff --git a/linux-user/aarch64/Makefile.vdso b/linux-user/aarch64/Makefile.vdso index 5999581..c33a679 100644 --- a/linux-user/aarch64/Makefile.vdso +++ b/linux-user/aarch64/Makefile.vdso @@ -5,8 +5,9 @@ VPATH += $(SUBDIR) all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so -LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \ - -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld +LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 \ + -Wl,--build-id=sha1 -Wl,--hash-style=both \ + -Wl,-z,max-page-size=4096 -Wl,-T,$(SUBDIR)/vdso.ld $(SUBDIR)/vdso-be.so: vdso.S vdso.ld $(CC) -o $@ $(LDFLAGS) -mbig-endian $< diff --git a/linux-user/aarch64/vdso-be.so b/linux-user/aarch64/vdso-be.so index 808206a..d43c3b1 100755 Binary files a/linux-user/aarch64/vdso-be.so and b/linux-user/aarch64/vdso-be.so differ diff --git a/linux-user/aarch64/vdso-le.so b/linux-user/aarch64/vdso-le.so index 941aaf2..aaedc9d 100755 Binary files a/linux-user/aarch64/vdso-le.so and b/linux-user/aarch64/vdso-le.so differ -- cgit v1.1 From f7150b2151398c9274686d06c2c1e24618aa4cd6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:51:00 -0800 Subject: linux-user/arm: Reduce vdso alignment to 4k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce vdso alignment to minimum page size. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/arm/Makefile.vdso | 2 +- linux-user/arm/vdso-be.so | Bin 2648 -> 2648 bytes linux-user/arm/vdso-le.so | Bin 2648 -> 2648 bytes 3 files changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-user') diff --git a/linux-user/arm/Makefile.vdso b/linux-user/arm/Makefile.vdso index 2d098a5..8a24b0e 100644 --- a/linux-user/arm/Makefile.vdso +++ b/linux-user/arm/Makefile.vdso @@ -6,7 +6,7 @@ VPATH += $(SUBDIR) all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so # Adding -use-blx disables unneeded interworking without actually using blx. -LDFLAGS = -nostdlib -shared -Wl,-use-blx \ +LDFLAGS = -nostdlib -shared -Wl,-use-blx -Wl,-z,max-page-size=4096 \ -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \ -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld diff --git a/linux-user/arm/vdso-be.so b/linux-user/arm/vdso-be.so index 69cafbb..bed0280 100755 Binary files a/linux-user/arm/vdso-be.so and b/linux-user/arm/vdso-be.so differ diff --git a/linux-user/arm/vdso-le.so b/linux-user/arm/vdso-le.so index ad05a12..38d3d51 100755 Binary files a/linux-user/arm/vdso-le.so and b/linux-user/arm/vdso-le.so differ -- cgit v1.1 From 399c8082ca0d410a84b8367a8569cee48f1440dd Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:51:22 -0800 Subject: linux-user/loongarch64: Reduce vdso alignment to 4k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce vdso alignment to minimum page size. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/loongarch64/Makefile.vdso | 3 ++- linux-user/loongarch64/vdso.so | Bin 3560 -> 3560 bytes 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'linux-user') diff --git a/linux-user/loongarch64/Makefile.vdso b/linux-user/loongarch64/Makefile.vdso index 369de13..1d760b1 100644 --- a/linux-user/loongarch64/Makefile.vdso +++ b/linux-user/loongarch64/Makefile.vdso @@ -8,4 +8,5 @@ all: $(SUBDIR)/vdso.so $(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h $(CC) -o $@ -nostdlib -shared -fpic -Wl,-h,linux-vdso.so.1 \ -Wl,--build-id=sha1 -Wl,--hash-style=both \ - -Wl,--no-warn-rwx-segments -Wl,-T,$(SUBDIR)/vdso.ld $< + -Wl,--no-warn-rwx-segments -Wl,-z,max-page-size=4096 \ + -Wl,-T,$(SUBDIR)/vdso.ld $< diff --git a/linux-user/loongarch64/vdso.so b/linux-user/loongarch64/vdso.so index bfaa26f..7c2de6c 100755 Binary files a/linux-user/loongarch64/vdso.so and b/linux-user/loongarch64/vdso.so differ -- cgit v1.1 From 180692a1a15319ed71eda3346f706f6ec4bccbc0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 Nov 2024 11:51:36 -0800 Subject: linux-user/ppc: Reduce vdso alignment to 4k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce vdso alignment to minimum page size. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/ppc/Makefile.vdso | 6 ++++-- linux-user/ppc/vdso-32.so | Bin 3020 -> 3020 bytes linux-user/ppc/vdso-64.so | Bin 3896 -> 3896 bytes linux-user/ppc/vdso-64le.so | Bin 3896 -> 3896 bytes 4 files changed, 4 insertions(+), 2 deletions(-) (limited to 'linux-user') diff --git a/linux-user/ppc/Makefile.vdso b/linux-user/ppc/Makefile.vdso index 3ca3c6b..e2b8fac 100644 --- a/linux-user/ppc/Makefile.vdso +++ b/linux-user/ppc/Makefile.vdso @@ -6,9 +6,11 @@ VPATH += $(SUBDIR) all: $(SUBDIR)/vdso-32.so $(SUBDIR)/vdso-64.so $(SUBDIR)/vdso-64le.so LDFLAGS32 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-32.ld \ - -Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 + -Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both \ + -Wl,--build-id=sha1 -Wl,-z,max-page-size=4096 LDFLAGS64 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-64.ld \ - -Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 + -Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both \ + -Wl,--build-id=sha1 -Wl,-z,max-page-size=4096 $(SUBDIR)/vdso-32.so: vdso.S vdso-32.ld vdso-asmoffset.h $(CC) -o $@ $(LDFLAGS32) -m32 $< diff --git a/linux-user/ppc/vdso-32.so b/linux-user/ppc/vdso-32.so index b19baaf..0dc55e0 100755 Binary files a/linux-user/ppc/vdso-32.so and b/linux-user/ppc/vdso-32.so differ diff --git a/linux-user/ppc/vdso-64.so b/linux-user/ppc/vdso-64.so index 913c831..ac1ab25 100755 Binary files a/linux-user/ppc/vdso-64.so and b/linux-user/ppc/vdso-64.so differ diff --git a/linux-user/ppc/vdso-64le.so b/linux-user/ppc/vdso-64le.so index 258a03b..424abb4 100755 Binary files a/linux-user/ppc/vdso-64le.so and b/linux-user/ppc/vdso-64le.so differ -- cgit v1.1 From 95c9e2209cc09453cfd49e91321df254ccbf466f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 13 Nov 2024 08:59:54 -0800 Subject: linux-user/arm: Select vdso for be8 and be32 modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In be8 mode, instructions are little-endian. In be32 mode, instructions are big-endian. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2333 Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/arm/Makefile.vdso | 9 ++++++--- linux-user/arm/meson.build | 13 ++++++++++--- linux-user/arm/vdso-be.so | Bin 2648 -> 0 bytes linux-user/arm/vdso-be32.so | Bin 0 -> 2648 bytes linux-user/arm/vdso-be8.so | Bin 0 -> 2648 bytes linux-user/elfload.c | 31 +++++++++++++++++++++++++------ 6 files changed, 41 insertions(+), 12 deletions(-) delete mode 100755 linux-user/arm/vdso-be.so create mode 100755 linux-user/arm/vdso-be32.so create mode 100755 linux-user/arm/vdso-be8.so (limited to 'linux-user') diff --git a/linux-user/arm/Makefile.vdso b/linux-user/arm/Makefile.vdso index 8a24b0e..ede489e 100644 --- a/linux-user/arm/Makefile.vdso +++ b/linux-user/arm/Makefile.vdso @@ -3,15 +3,18 @@ include $(BUILD_DIR)/tests/tcg/arm-linux-user/config-target.mak SUBDIR = $(SRC_PATH)/linux-user/arm VPATH += $(SUBDIR) -all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so +all: $(SUBDIR)/vdso-be8.so $(SUBDIR)/vdso-be32.so $(SUBDIR)/vdso-le.so # Adding -use-blx disables unneeded interworking without actually using blx. LDFLAGS = -nostdlib -shared -Wl,-use-blx -Wl,-z,max-page-size=4096 \ -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \ -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld -$(SUBDIR)/vdso-be.so: vdso.S vdso.ld vdso-asmoffset.h - $(CC) -o $@ $(LDFLAGS) -mbig-endian $< +$(SUBDIR)/vdso-be8.so: vdso.S vdso.ld vdso-asmoffset.h + $(CC) -o $@ $(LDFLAGS) -mbig-endian -mbe8 $< + +$(SUBDIR)/vdso-be32.so: vdso.S vdso.ld vdso-asmoffset.h + $(CC) -o $@ $(LDFLAGS) -mbig-endian -mbe32 $< $(SUBDIR)/vdso-le.so: vdso.S vdso.ld vdso-asmoffset.h $(CC) -o $@ $(LDFLAGS) -mlittle-endian $< diff --git a/linux-user/arm/meson.build b/linux-user/arm/meson.build index c4bb9af..348ffb8 100644 --- a/linux-user/arm/meson.build +++ b/linux-user/arm/meson.build @@ -10,10 +10,17 @@ syscall_nr_generators += { # is always true as far as source_set.apply() is concerned. Always build # both header files and include the right one via #if. -vdso_be_inc = gen_vdso.process('vdso-be.so', - extra_args: ['-s', 'sigreturn_codes']) +vdso_be8_inc = gen_vdso.process('vdso-be8.so', + extra_args: ['-s', 'sigreturn_codes', + '-p', 'vdso_be8']) + +vdso_be32_inc = gen_vdso.process('vdso-be32.so', + extra_args: ['-s', 'sigreturn_codes', + '-p', 'vdso_be32']) vdso_le_inc = gen_vdso.process('vdso-le.so', extra_args: ['-s', 'sigreturn_codes']) -linux_user_ss.add(when: 'TARGET_ARM', if_true: [vdso_be_inc, vdso_le_inc]) +linux_user_ss.add(when: 'TARGET_ARM', if_true: [ + vdso_be8_inc, vdso_be32_inc, vdso_le_inc +]) diff --git a/linux-user/arm/vdso-be.so b/linux-user/arm/vdso-be.so deleted file mode 100755 index bed0280..0000000 Binary files a/linux-user/arm/vdso-be.so and /dev/null differ diff --git a/linux-user/arm/vdso-be32.so b/linux-user/arm/vdso-be32.so new file mode 100755 index 0000000..b896d3d Binary files /dev/null and b/linux-user/arm/vdso-be32.so differ diff --git a/linux-user/arm/vdso-be8.so b/linux-user/arm/vdso-be8.so new file mode 100755 index 0000000..784b7bd Binary files /dev/null and b/linux-user/arm/vdso-be8.so differ diff --git a/linux-user/elfload.c b/linux-user/elfload.c index ef9cffb..471a384 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -659,6 +659,23 @@ static const char *get_elf_platform(void) #undef END } +#if TARGET_BIG_ENDIAN +#include "elf.h" +#include "vdso-be8.c.inc" +#include "vdso-be32.c.inc" + +static const VdsoImageInfo *vdso_image_info(uint32_t elf_flags) +{ + return (EF_ARM_EABI_VERSION(elf_flags) >= EF_ARM_EABI_VER4 + && (elf_flags & EF_ARM_BE8) + ? &vdso_be8_image_info + : &vdso_be32_image_info); +} +#define vdso_image_info vdso_image_info +#else +# define VDSO_HEADER "vdso-le.c.inc" +#endif + #else /* 64 bit ARM definitions */ @@ -958,14 +975,14 @@ const char *elf_hwcap2_str(uint32_t bit) #undef GET_FEATURE_ID -#endif /* not TARGET_AARCH64 */ - #if TARGET_BIG_ENDIAN # define VDSO_HEADER "vdso-be.c.inc" #else # define VDSO_HEADER "vdso-le.c.inc" #endif +#endif /* not TARGET_AARCH64 */ + #endif /* TARGET_ARM */ #ifdef TARGET_SPARC @@ -3524,12 +3541,14 @@ static void load_elf_interp(const char *filename, struct image_info *info, load_elf_image(filename, &src, info, &ehdr, NULL); } +#ifndef vdso_image_info #ifdef VDSO_HEADER #include VDSO_HEADER -#define vdso_image_info() &vdso_image_info +#define vdso_image_info(flags) &vdso_image_info #else -#define vdso_image_info() NULL -#endif +#define vdso_image_info(flags) NULL +#endif /* VDSO_HEADER */ +#endif /* vdso_image_info */ static void load_elf_vdso(struct image_info *info, const VdsoImageInfo *vdso) { @@ -3860,7 +3879,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) * Load a vdso if available, which will amongst other things contain the * signal trampolines. Otherwise, allocate a separate page for them. */ - const VdsoImageInfo *vdso = vdso_image_info(); + const VdsoImageInfo *vdso = vdso_image_info(info->elf_flags); if (vdso) { load_elf_vdso(&vdso_info, vdso); info->vdso = vdso_info.load_bias; -- cgit v1.1