From: Helge Deller <deller@gmx.de>
To: Richard Henderson <richard.henderson@linaro.org>, qemu-devel@nongnu.org
Cc: Laurent Vivier <laurent@vivier.eu>,
Paolo Bonzini <pbonzini@redhat.com>,
Joel Stanley <joel@jms.id.au>,
Akihiko Odaki <akihiko.odaki@daynix.com>
Subject: Re: [PATCH v6 7/8] linux-user: Optimize memory layout for static and dynamic executables
Date: Wed, 2 Aug 2023 21:51:33 +0200 [thread overview]
Message-ID: <07af035f-8ce0-7002-2fda-ab89cc2853d4@gmx.de> (raw)
In-Reply-To: <bdf9ebc2-ef7a-7dd4-a742-8bbf5e836aea@linaro.org>
On 8/2/23 20:25, Richard Henderson wrote:
> On 8/1/23 16:27, Helge Deller wrote:
>> Reorganize the guest memory layout to get as much memory as possible for
>> heap for the guest application.
>>
>> This patch optimizes the memory layout by loading pie executables
>> into lower memory and shared libs into higher memory (at
>> TASK_UNMAPPED_BASE). This leaves a bigger memory area usable for heap
>> space which will be located directly after the executable.
>> Up to now, pie executable and shared libs were loaded directly behind
>> each other in the area at TASK_UNMAPPED_BASE, which leaves very little
>> space for heap.
>>
>> I tested this patchset with chroots of alpha, arm, armel, arm64, hppa, m68k,
>> mips64el, mipsel, powerpc, ppc64, ppc64el, s390x, sh4 and sparc64 on a x86-64
>> host, and with a static armhf binary (which fails to run without this patch).
>>
>> This patch temporarily breaks the Thread Sanitizer (TSan) application
>> which expects specific boundary definitions for memory mappings on
>> different platforms [1], see commit aab613fb9597 ("linux-user: Update
>> TASK_UNMAPPED_BASE for aarch64") for aarch64. The follow-up patch fixes it
>> again.
>>
>> [1] https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
>>
>> Signed-off-by: Helge Deller <deller@gmx.de>
>> ---
>> linux-user/elfload.c | 55 +++++++++++++-------------------------------
>> linux-user/mmap.c | 8 ++++---
>> 2 files changed, 21 insertions(+), 42 deletions(-)
>>
>> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
>> index 2aee2298ec..47a118e430 100644
>> --- a/linux-user/elfload.c
>> +++ b/linux-user/elfload.c
>> @@ -3023,6 +3023,7 @@ static void load_elf_image(const char *image_name, int image_fd,
>> abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
>> int i, retval, prot_exec;
>> Error *err = NULL;
>> + bool is_main_executable;
>>
>> /* First of all, some simple consistency checks */
>> if (!elf_check_ident(ehdr)) {
>> @@ -3106,28 +3107,8 @@ static void load_elf_image(const char *image_name, int image_fd,
>> }
>> }
>>
>> - if (pinterp_name != NULL) {
>> - /*
>> - * This is the main executable.
>> - *
>> - * Reserve extra space for brk.
>> - * We hold on to this space while placing the interpreter
>> - * and the stack, lest they be placed immediately after
>> - * the data segment and block allocation from the brk.
>> - *
>> - * 16MB is chosen as "large enough" without being so large as
>> - * to allow the result to not fit with a 32-bit guest on a
>> - * 32-bit host. However some 64 bit guests (e.g. s390x)
>> - * attempt to place their heap further ahead and currently
>> - * nothing stops them smashing into QEMUs address space.
>> - */
>> -#if TARGET_LONG_BITS == 64
>> - info->reserve_brk = 32 * MiB;
>> -#else
>> - info->reserve_brk = 16 * MiB;
>> -#endif
>> - hiaddr += info->reserve_brk;
>> -
>> + is_main_executable = (pinterp_name != NULL);
>
> This will be false for static main executables.
[deller@p100 qemu-helge-user-armhf]$ file fstype
fstype: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, interpreter /lib/klibc-PupSAGgtpafMlSLXOLgje1kXFo8.so, BuildID[sha1]=45aac32edcd204fd6fa06febf3abff274ab39b26, stripped
And for real static binaries (without interpreter), the "loadaddr" is set in the mmap below,
and MAP_FIX isn't needed then.
>> + if (is_main_executable) {
>> if (ehdr->e_type == ET_EXEC) {
>> /*
>> * Make sure that the low address does not conflict with
>> @@ -3136,7 +3117,7 @@ static void load_elf_image(const char *image_name, int image_fd,
>> probe_guest_base(image_name, loaddr, hiaddr);
>> } else {
>> /*
>> - * The binary is dynamic, but we still need to
>> + * The binary is dynamic (pie-executabe), but we still need to
>> * select guest_base. In this case we pass a size.
>> */
>> probe_guest_base(image_name, 0, hiaddr - loaddr);
>> @@ -3159,7 +3140,7 @@ static void load_elf_image(const char *image_name, int image_fd,
>> */
>> load_addr = target_mmap(loaddr, (size_t)hiaddr - loaddr + 1, PROT_NONE,
>> MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
>> - (ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
>> + (is_main_executable ? MAP_FIXED : 0),
>
> This is definitely wrong, as all ET_EXEC require FIXED.
Not if the PIE flag is set too and even here the loadaddr defines where
it will be loaded then.
> (In addition to static, it is possible to write an ET_EXEC interpreter.)
>
>> --- a/linux-user/mmap.c
>> +++ b/linux-user/mmap.c
>> @@ -299,14 +299,16 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
>> #ifdef TARGET_AARCH64
>> # define TASK_UNMAPPED_BASE 0x5500000000
>> #else
>> -# define TASK_UNMAPPED_BASE (1ul << 38)
>> +# define TASK_UNMAPPED_BASE 0x4000000000
>> #endif
>> -#else
>> +#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
>> #ifdef TARGET_HPPA
>> # define TASK_UNMAPPED_BASE 0xfa000000
>> #else
>> -# define TASK_UNMAPPED_BASE 0x40000000
>> +# define TASK_UNMAPPED_BASE 0xe0000000
>> #endif
>> +#else /* HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 32 */
>> +# define TASK_UNMAPPED_BASE 0x40000000
>> #endif
>> abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
>
> This should be a separate change.
>
> While we're at it, we should move this to e.g.
> linux-user/$GUEST/target_mman.h, and make this match each guest
> kernel's TASK_UNMAPPED_BASE. It really shouldn't depend on the host
> at all.
I think it matters if you want to run a 32-bit guest on 32-bit host?
Those TASK_UNMAPPED_BASE are actually TARGET_TASK_UNMAPPED_BASE values.
Helge
next prev parent reply other threads:[~2023-08-02 19:52 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-01 23:27 [PATCH v6 0/8] linux-user: brk fixes Helge Deller
2023-08-01 23:27 ` [PATCH v6 1/8] linux-user: Unset MAP_FIXED_NOREPLACE for host Helge Deller
2023-08-01 23:40 ` Richard Henderson
2023-08-01 23:27 ` [PATCH v6 2/8] linux-user: Do not call get_errno() in do_brk() Helge Deller
2023-08-01 23:27 ` [PATCH v6 3/8] linux-user: Use MAP_FIXED_NOREPLACE for do_brk() Helge Deller
2023-08-01 23:27 ` [PATCH v6 4/8] linux-user: Do nothing if too small brk is specified Helge Deller
2023-08-01 23:27 ` [PATCH v6 5/8] linux-user: Do not align brk with host page size Helge Deller
2023-08-01 23:27 ` [PATCH v6 6/8] linux-user: Show heap address in /proc/pid/maps Helge Deller
2023-08-02 5:41 ` Philippe Mathieu-Daudé
2023-08-02 6:07 ` Helge Deller
2023-08-01 23:27 ` [PATCH v6 7/8] linux-user: Optimize memory layout for static and dynamic executables Helge Deller
2023-08-02 18:25 ` Richard Henderson
2023-08-02 19:51 ` Helge Deller [this message]
2023-08-02 19:57 ` Richard Henderson
2023-08-02 20:06 ` Helge Deller
2023-08-01 23:27 ` [PATCH v6 8/8] linux-user: Load pie executables at upper memory Helge Deller
2023-08-02 7:49 ` Akihiko Odaki
2023-08-02 8:42 ` Helge Deller
2023-08-02 8:44 ` Akihiko Odaki
2023-08-02 9:34 ` Helge Deller
2023-08-02 9:58 ` Akihiko Odaki
2023-08-02 10:35 ` Helge Deller
2023-08-02 18:36 ` Richard Henderson
2023-08-02 19:57 ` Helge Deller
2023-08-02 2:21 ` [PATCH v6 0/8] linux-user: brk fixes Joel Stanley
2023-08-02 6:10 ` Helge Deller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=07af035f-8ce0-7002-2fda-ab89cc2853d4@gmx.de \
--to=deller@gmx.de \
--cc=akihiko.odaki@daynix.com \
--cc=joel@jms.id.au \
--cc=laurent@vivier.eu \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).