diff mbox series

[v8,10/17] linux-user: Define ELF_ET_DYN_BASE in $guest/target_mman.h

Message ID 20230804014517.6361-11-richard.henderson@linaro.org
State Superseded
Headers show
Series linux-user: brk fixes | expand

Commit Message

Richard Henderson Aug. 4, 2023, 1:45 a.m. UTC
Copy each guest kernel's default value, then bound it
against reserved_va or the host address space.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/aarch64/target_mman.h     |  3 +++
 linux-user/alpha/target_mman.h       |  3 +++
 linux-user/arm/target_mman.h         |  3 +++
 linux-user/cris/target_mman.h        |  3 +++
 linux-user/hexagon/target_mman.h     |  3 +++
 linux-user/hppa/target_mman.h        |  3 +++
 linux-user/i386/target_mman.h        |  3 +++
 linux-user/loongarch64/target_mman.h |  3 +++
 linux-user/m68k/target_mman.h        |  2 ++
 linux-user/microblaze/target_mman.h  |  3 +++
 linux-user/mips/target_mman.h        |  3 +++
 linux-user/nios2/target_mman.h       |  3 +++
 linux-user/openrisc/target_mman.h    |  3 +++
 linux-user/ppc/target_mman.h         |  7 +++++++
 linux-user/riscv/target_mman.h       |  3 +++
 linux-user/s390x/target_mman.h       | 10 ++++++++++
 linux-user/sh4/target_mman.h         |  3 +++
 linux-user/sparc/target_mman.h       | 11 +++++++++++
 linux-user/user-mmap.h               |  1 +
 linux-user/x86_64/target_mman.h      |  3 +++
 linux-user/xtensa/target_mman.h      |  4 ++++
 linux-user/main.c                    | 15 +++++++++++++++
 linux-user/mmap.c                    |  1 +
 23 files changed, 96 insertions(+)

Comments

Akihiko Odaki Aug. 4, 2023, 5:20 a.m. UTC | #1
On 2023/08/04 10:45, Richard Henderson wrote:
> Copy each guest kernel's default value, then bound it
> against reserved_va or the host address space.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   linux-user/aarch64/target_mman.h     |  3 +++
>   linux-user/alpha/target_mman.h       |  3 +++
>   linux-user/arm/target_mman.h         |  3 +++
>   linux-user/cris/target_mman.h        |  3 +++
>   linux-user/hexagon/target_mman.h     |  3 +++
>   linux-user/hppa/target_mman.h        |  3 +++
>   linux-user/i386/target_mman.h        |  3 +++
>   linux-user/loongarch64/target_mman.h |  3 +++
>   linux-user/m68k/target_mman.h        |  2 ++
>   linux-user/microblaze/target_mman.h  |  3 +++
>   linux-user/mips/target_mman.h        |  3 +++
>   linux-user/nios2/target_mman.h       |  3 +++
>   linux-user/openrisc/target_mman.h    |  3 +++
>   linux-user/ppc/target_mman.h         |  7 +++++++
>   linux-user/riscv/target_mman.h       |  3 +++
>   linux-user/s390x/target_mman.h       | 10 ++++++++++
>   linux-user/sh4/target_mman.h         |  3 +++
>   linux-user/sparc/target_mman.h       | 11 +++++++++++
>   linux-user/user-mmap.h               |  1 +
>   linux-user/x86_64/target_mman.h      |  3 +++
>   linux-user/xtensa/target_mman.h      |  4 ++++
>   linux-user/main.c                    | 15 +++++++++++++++
>   linux-user/mmap.c                    |  1 +
>   23 files changed, 96 insertions(+)
> 
> diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h
> index 4d3eecfb26..69ec5d5739 100644
> --- a/linux-user/aarch64/target_mman.h
> +++ b/linux-user/aarch64/target_mman.h
> @@ -14,6 +14,9 @@
>    */
>   #define TASK_UNMAPPED_BASE      (1ull << (48 - 2))
>   
> +/* arch/arm64/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE         TARGET_PAGE_ALIGN((1ull << 48) / 3 * 2)
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h
> index c90b493711..8edfe2b88c 100644
> --- a/linux-user/alpha/target_mman.h
> +++ b/linux-user/alpha/target_mman.h
> @@ -28,6 +28,9 @@
>    */
>   #define TASK_UNMAPPED_BASE      0x20000000000ull
>   
> +/* arch/alpha/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x1000000)
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h
> index 76275b2c7e..51005da869 100644
> --- a/linux-user/arm/target_mman.h
> +++ b/linux-user/arm/target_mman.h
> @@ -6,4 +6,7 @@
>    */
>   #define TASK_UNMAPPED_BASE   0x40000000
>   
> +/* arch/arm/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE      0x00400000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h
> index 9df7b1eda5..9ace8ac292 100644
> --- a/linux-user/cris/target_mman.h
> +++ b/linux-user/cris/target_mman.h
> @@ -7,4 +7,7 @@
>    */
>   #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0xb0000000 / 3)
>   
> +/* arch/cris/include/uapi/asm/elf.h */
> +#define ELF_ET_DYN_BASE    (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h
> index c5ae336e07..e6b5e2ca36 100644
> --- a/linux-user/hexagon/target_mman.h
> +++ b/linux-user/hexagon/target_mman.h
> @@ -8,4 +8,7 @@
>    */
>   #define TASK_UNMAPPED_BASE   0x40000000
>   
> +/* arch/hexagon/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE      0x08000000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h
> index 6459e7dbdd..ccda46e842 100644
> --- a/linux-user/hppa/target_mman.h
> +++ b/linux-user/hppa/target_mman.h
> @@ -27,6 +27,9 @@
>   /* arch/parisc/include/asm/processor.h: DEFAULT_MAP_BASE32 */
>   #define TASK_UNMAPPED_BASE      0x40000000
>   
> +/* arch/parisc/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h
> index cc3382007f..e3b8e1eaa6 100644
> --- a/linux-user/i386/target_mman.h
> +++ b/linux-user/i386/target_mman.h
> @@ -11,4 +11,7 @@
>    */
>   #define TASK_UNMAPPED_BASE    0x40000000
>   
> +/* arch/x86/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       0x00400000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h
> index d70e44d44c..8c2a3d5596 100644
> --- a/linux-user/loongarch64/target_mman.h
> +++ b/linux-user/loongarch64/target_mman.h
> @@ -6,4 +6,7 @@
>   #define TASK_UNMAPPED_BASE \
>       TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>   
> +/* arch/loongarch/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h
> index d3eceb663b..20cfe750c5 100644
> --- a/linux-user/m68k/target_mman.h
> +++ b/linux-user/m68k/target_mman.h
> @@ -1,4 +1,6 @@
>   /* arch/m68k/include/asm/processor.h */
>   #define TASK_UNMAPPED_BASE      0xC0000000
> +/* arch/m68k/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE         0xD0000000
>   
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h
> index ffee869db4..6b3dd54f89 100644
> --- a/linux-user/microblaze/target_mman.h
> +++ b/linux-user/microblaze/target_mman.h
> @@ -6,4 +6,7 @@
>    */
>   #define TASK_UNMAPPED_BASE      0x48000000
>   
> +/* arch/microblaze/include/uapi/asm/elf.h */
> +#define ELF_ET_DYN_BASE         0x08000000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h
> index fe1eec2d0b..b84fe1e8a8 100644
> --- a/linux-user/mips/target_mman.h
> +++ b/linux-user/mips/target_mman.h
> @@ -21,6 +21,9 @@
>   #define TASK_UNMAPPED_BASE \
>       TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>   
> +/* arch/mips/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h
> index ce18f4f871..ab16ad4f03 100644
> --- a/linux-user/nios2/target_mman.h
> +++ b/linux-user/nios2/target_mman.h
> @@ -5,4 +5,7 @@
>    */
>   #define TASK_UNMAPPED_BASE    TARGET_PAGE_ALIGN(0x7FFF0000 / 3)
>   
> +/* arch/nios2/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       0xD0000000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h
> index f1aaad809d..243c1d5f26 100644
> --- a/linux-user/openrisc/target_mman.h
> +++ b/linux-user/openrisc/target_mman.h
> @@ -5,4 +5,7 @@
>    */
>   #define TASK_UNMAPPED_BASE      0x30000000
>   
> +/* arch/openrisc/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE         0x08000000
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h
> index 04f99c6077..646d1ccae7 100644
> --- a/linux-user/ppc/target_mman.h
> +++ b/linux-user/ppc/target_mman.h
> @@ -17,6 +17,13 @@
>   #define TASK_UNMAPPED_BASE      0x40000000
>   #endif
>   
> +/* arch/powerpc/include/asm/elf.h */
> +#ifdef TARGET_PPC64
> +#define ELF_ET_DYN_BASE         0x100000000ull
> +#else
> +#define ELF_ET_DYN_BASE         0x000400000
> +#endif
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h
> index 0f06dadbd4..3049bcc67d 100644
> --- a/linux-user/riscv/target_mman.h
> +++ b/linux-user/riscv/target_mman.h
> @@ -5,4 +5,7 @@
>   #define TASK_UNMAPPED_BASE \
>       TARGET_PAGE_ALIGN((1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) / 3)
>   
> +/* arch/riscv/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h
> index 40d149b329..c82435e381 100644
> --- a/linux-user/s390x/target_mman.h
> +++ b/linux-user/s390x/target_mman.h
> @@ -8,4 +8,14 @@
>    */
>   #define TASK_UNMAPPED_BASE      (1ull << 41)
>   
> +/*
> + * arch/s390/include/asm/elf.h:
> + * ELF_ET_DYN_BASE              (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)
> + *
> + * arch/s390/include/asm/processor.h:
> + * STACK_TOP                    VDSO_LIMIT - VDSO_SIZE - PAGE_SIZE
> + * VDSO_LIMIT                   _REGION2_SIZE
> + */
> +#define ELF_ET_DYN_BASE         (((1ull << 42) / 3 * 2) & ~0xffffffffull)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
> index bbbc223398..dd9016081e 100644
> --- a/linux-user/sh4/target_mman.h
> +++ b/linux-user/sh4/target_mman.h
> @@ -2,4 +2,7 @@
>   #define TASK_UNMAPPED_BASE \
>       TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>   
> +/* arch/sh/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h
> index 692ebf9dd7..696ca73fe4 100644
> --- a/linux-user/sparc/target_mman.h
> +++ b/linux-user/sparc/target_mman.h
> @@ -19,6 +19,17 @@
>   #define TASK_UNMAPPED_BASE      (1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 2))
>   #endif
>   
> +/*
> + * arch/sparc/include/asm/elf_64.h
> + * Except that COMPAT_ELF_ET_DYN_BASE exactly matches TASK_UNMAPPED_BASE,
> + * so move it up a bit.
> + */
> +#ifdef TARGET_ABI32
> +#define ELF_ET_DYN_BASE         0x78000000
> +#else
> +#define ELF_ET_DYN_BASE         0x0000010000000000ull
> +#endif
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h
> index bae49059e0..5dd48a458d 100644
> --- a/linux-user/user-mmap.h
> +++ b/linux-user/user-mmap.h
> @@ -20,6 +20,7 @@
>   
>   extern abi_ulong task_unmapped_base;
>   extern abi_ulong mmap_next_start;
> +extern abi_ulong elf_et_dyn_base;
>   
>   int target_mprotect(abi_ulong start, abi_ulong len, int prot);
>   abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
> diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h
> index f9ff652b37..48fbf20b42 100644
> --- a/linux-user/x86_64/target_mman.h
> +++ b/linux-user/x86_64/target_mman.h
> @@ -10,4 +10,7 @@
>   #define TASK_UNMAPPED_BASE \
>       TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>   
> +/* arch/x86/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> +
>   #include "../generic/target_mman.h"
> diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h
> index c4f671adb7..8fa6337a97 100644
> --- a/linux-user/xtensa/target_mman.h
> +++ b/linux-user/xtensa/target_mman.h
> @@ -20,6 +20,10 @@
>    */
>   #define TASK_UNMAPPED_BASE      (1u << (TARGET_VIRT_ADDR_SPACE_BITS - 1))
>   
> +/* arch/xtensa/include/asm/elf.h */
> +#define ELF_ET_DYN_BASE \
> +    TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
> +
>   #include "../generic/target_mman.h"
>   
>   #endif
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 52809c260a..e089123cfa 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -839,6 +839,21 @@ int main(int argc, char **argv, char **envp)
>       }
>       mmap_next_start = task_unmapped_base;
>   
> +    /* Similarly for elf_et_dyn_base. */
> +    if (reserved_va) {
> +        if (ELF_ET_DYN_BASE < reserved_va) {
> +            elf_et_dyn_base = ELF_ET_DYN_BASE;
> +        } else {
> +            /* The most common default formula is TASK_SIZE / 3 * 2. */
> +            task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2;

This assigns a value to task_unmapped_base and that does not seem correct.

> +        }
> +    } else if (ELF_ET_DYN_BASE < UINTPTR_MAX) {
> +        elf_et_dyn_base = ELF_ET_DYN_BASE;
> +    } else {
> +        /* 32-bit host: pick something medium size. */
> +        task_unmapped_base = 0x18000000;
> +    }
> +
>       {
>           Error *err = NULL;
>           if (seed_optarg != NULL) {
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 84436d45c8..949c4090f3 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -301,6 +301,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
>   
>   abi_ulong task_unmapped_base;
>   abi_ulong mmap_next_start;
> +abi_ulong elf_et_dyn_base;
>   
>   /*
>    * Subroutine of mmap_find_vma, used when we have pre-allocated
Helge Deller Aug. 4, 2023, 9:50 a.m. UTC | #2
On 8/4/23 03:45, Richard Henderson wrote:
> Copy each guest kernel's default value, then bound it
> against reserved_va or the host address space.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   linux-user/aarch64/target_mman.h     |  3 +++
>   linux-user/alpha/target_mman.h       |  3 +++
> ...

I've successfully tested the whole series on the following
chroots (on x86 host):
alpha, arm64, armhf, hppa, m68k, mips64el, mipsel
powerpc, ppc64, ppc64el, s390x, sh4, sparc64.
Both static and dynamically linked programs work as expected.

It's a big step forward compared to qemu v8.0, so feel free
to add to the whole series:
Tested-by: Helge Deller <deller@gmx.de>

For this patch:
Reviewed-by: Helge Deller <deller@gmx.de>

One thing to mention here is, that those values (ELF_ET_DYN_BASE)
reflects the legacy (standard) memory layout of the kernel only.
The process personality defines which layout should be used,
ADDR_COMPAT_LAYOUT means to use the legacy (standard) memory layout.

The Linux kernel on 390, parisc, sparc and x86 doesn't use by
default the legacy memory model, but instead allocates new mappings
from top downwards. This leaves much more space for heap.
Search for mmap_is_legacy() in the kernel sources.

That said, we should implement the top-downwards allocation
after qemu 8.1.
In this regard, could you please include my latest patch titled:

    linux-user: Show heap address in /proc/pid/maps

in your patch series? I sent an updated version today to the mailing
list, which applies to your series. .

If applied, the "[heap]" entry is visible in /proc/cpuinfo output, and
it's much easier to see potential future memory isses, e.g.

armhf-chroot:
-> heap is limited in region 21000 to 00400000.
-> 00421000 to 40000000 would give much more space for heap.
-> arm32 doesn't seem to support non-legacy memory model yet...
Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 armv7l GNU/Linux
00021000-00042000 rw-p 00000000 00:00 0                                  [heap]
00400000-00406000 r-xp 00000000 fd:00 675877                             /usr/bin/cat
00406000-0041f000 ---p 00000000 00:00 0
0041f000-00420000 r--p 0000f000 fd:00 675877                             /usr/bin/cat
00420000-00421000 rw-p 00010000 fd:00 675877                             /usr/bin/cat
40000000-40001000 ---p 00000000 00:00 0
40001000-40801000 rw-p 00000000 00:00 0                                  [stack]
40801000-4081d000 r-xp 00000000 fd:00 682674                             /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3
4081d000-4081e000 r--p 0001c000 fd:00 682674                             /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3
4081e000-4081f000 rw-p 0001d000 fd:00 682674                             /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3
4081f000-40820000 r-xp 00000000 00:00 0
40820000-40822000 rw-p 00000000 00:00 0
40822000-4092b000 r-xp 00000000 fd:00 682677                             /usr/lib/arm-linux-gnueabihf/libc.so.6
4092b000-4092d000 r--p 00108000 fd:00 682677                             /usr/lib/arm-linux-gnueabihf/libc.so.6
4092d000-4092e000 rw-p 0010a000 fd:00 682677                             /usr/lib/arm-linux-gnueabihf/libc.so.6
4092e000-40938000 rw-p 00000000 00:00 0
ffff0000-ffff1000 r-xp 00000000 00:00 0

mipsel-chroot
-> heap is locked in from 00021000 to 2aaab000
Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 mips GNU/Linux
00021000-00042000 rw-p 00000000 00:00 0                                  [heap]
2aaab000-2aaac000 ---p 00000000 00:00 0
2aaac000-2b2ac000 rwxp 00000000 00:00 0                                  [stack]
2b2ac000-2b2d8000 r-xp 00000000 fd:00 816208                             /usr/lib/mipsel-linux-gnu/ld.so.1
2b2d8000-2b2eb000 ---p 00000000 00:00 0
2b2eb000-2b2ec000 r--p 0002f000 fd:00 816208                             /usr/lib/mipsel-linux-gnu/ld.so.1
2b2ec000-2b2ed000 rw-p 00030000 fd:00 816208                             /usr/lib/mipsel-linux-gnu/ld.so.1
2b2ed000-2b2ee000 r-xp 00000000 00:00 0
2b2ee000-2b2f0000 rw-p 00000000 00:00 0
2b2f0000-2b4ae000 r-xp 00000000 fd:00 816216                             /usr/lib/mipsel-linux-gnu/libc.so.6
2b4ae000-2b4bd000 ---p 001be000 fd:00 816216                             /usr/lib/mipsel-linux-gnu/libc.so.6
2b4bd000-2b4c0000 r--p 001bd000 fd:00 816216                             /usr/lib/mipsel-linux-gnu/libc.so.6
2b4c0000-2b4c3000 rw-p 001c0000 fd:00 816216                             /usr/lib/mipsel-linux-gnu/libc.so.6
2b4c3000-2b4cd000 rw-p 00000000 00:00 0
55550000-55559000 r-xp 00000000 fd:00 818831                             /usr/bin/cat
55559000-5556f000 ---p 00000000 00:00 0
5556f000-55570000 r--p 0000f000 fd:00 818831                             /usr/bin/cat
55570000-55571000 rw-p 00010000 fd:00 818831                             /usr/bin/cat


hppa-chroot
-> heap & stack is ok.
-> heap could greatly benefit if qemu later supports top-down mmap allocation,
    because then the shared libs will be mapped >fa000000 and heap&stack can grow
    from 0001a000 up to fa000000.
Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 parisc GNU/Linux
00000000-00001000 --xp 00000000 00:00 0
00010000-00019000 r-xp 00000000 fd:00 1061893                            /usr/bin/cat
00019000-0001a000 rwxp 00009000 fd:00 1061893                            /usr/bin/cat
0001a000-0003b000 rw-p 00000000 00:00 0                                  [heap]
40000000-45000000 rwxp 00000000 00:00 0                                  [stack]
45000000-4502f000 r-xp 00000000 fd:00 1069300                            /usr/lib/hppa-linux-gnu/ld.so.1
4502f000-45030000 r--p 0002f000 fd:00 1069300                            /usr/lib/hppa-linux-gnu/ld.so.1
45030000-45034000 rwxp 00030000 fd:00 1069300                            /usr/lib/hppa-linux-gnu/ld.so.1
45034000-45035000 r-xp 00000000 00:00 0
45037000-45039000 rw-p 00000000 00:00 0
45039000-451f5000 r-xp 00000000 fd:00 1069303                            /usr/lib/hppa-linux-gnu/libc.so.6
451f5000-451f7000 r--p 001bc000 fd:00 1069303                            /usr/lib/hppa-linux-gnu/libc.so.6
451f7000-451fc000 rwxp 001be000 fd:00 1069303                            /usr/lib/hppa-linux-gnu/libc.so.6

Thanks!
Helge
Richard Henderson Aug. 4, 2023, 2:09 p.m. UTC | #3
On 8/4/23 02:50, Helge Deller wrote:
> In this regard, could you please include my latest patch titled:
> 
>     linux-user: Show heap address in /proc/pid/maps
> 
> in your patch series?

No, as it's not a bug fix.  It can wait for 8.2.


> If applied, the "[heap]" entry is visible in /proc/cpuinfo output, and
> it's much easier to see potential future memory isses, e.g.

Anyway, changing the guest /proc/cpuinfo output seems much less useful than improving -d 
page (which misses out on logging lots of the PAGE_* bits).


r~
Richard Henderson Aug. 4, 2023, 2:09 p.m. UTC | #4
On 8/3/23 22:20, Akihiko Odaki wrote:
>> +    if (reserved_va) {
>> +        if (ELF_ET_DYN_BASE < reserved_va) {
>> +            elf_et_dyn_base = ELF_ET_DYN_BASE;
>> +        } else {
>> +            /* The most common default formula is TASK_SIZE / 3 * 2. */
>> +            task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2;
> 
> This assigns a value to task_unmapped_base and that does not seem correct.
> 

Gah, I fixed this on a different copy of my branch, then lost it.


r~
diff mbox series

Patch

diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h
index 4d3eecfb26..69ec5d5739 100644
--- a/linux-user/aarch64/target_mman.h
+++ b/linux-user/aarch64/target_mman.h
@@ -14,6 +14,9 @@ 
  */
 #define TASK_UNMAPPED_BASE      (1ull << (48 - 2))
 
+/* arch/arm64/include/asm/elf.h */
+#define ELF_ET_DYN_BASE         TARGET_PAGE_ALIGN((1ull << 48) / 3 * 2)
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h
index c90b493711..8edfe2b88c 100644
--- a/linux-user/alpha/target_mman.h
+++ b/linux-user/alpha/target_mman.h
@@ -28,6 +28,9 @@ 
  */
 #define TASK_UNMAPPED_BASE      0x20000000000ull
 
+/* arch/alpha/include/asm/elf.h */
+#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x1000000)
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h
index 76275b2c7e..51005da869 100644
--- a/linux-user/arm/target_mman.h
+++ b/linux-user/arm/target_mman.h
@@ -6,4 +6,7 @@ 
  */
 #define TASK_UNMAPPED_BASE   0x40000000
 
+/* arch/arm/include/asm/elf.h */
+#define ELF_ET_DYN_BASE      0x00400000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h
index 9df7b1eda5..9ace8ac292 100644
--- a/linux-user/cris/target_mman.h
+++ b/linux-user/cris/target_mman.h
@@ -7,4 +7,7 @@ 
  */
 #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0xb0000000 / 3)
 
+/* arch/cris/include/uapi/asm/elf.h */
+#define ELF_ET_DYN_BASE    (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h
index c5ae336e07..e6b5e2ca36 100644
--- a/linux-user/hexagon/target_mman.h
+++ b/linux-user/hexagon/target_mman.h
@@ -8,4 +8,7 @@ 
  */
 #define TASK_UNMAPPED_BASE   0x40000000
 
+/* arch/hexagon/include/asm/elf.h */
+#define ELF_ET_DYN_BASE      0x08000000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h
index 6459e7dbdd..ccda46e842 100644
--- a/linux-user/hppa/target_mman.h
+++ b/linux-user/hppa/target_mman.h
@@ -27,6 +27,9 @@ 
 /* arch/parisc/include/asm/processor.h: DEFAULT_MAP_BASE32 */
 #define TASK_UNMAPPED_BASE      0x40000000
 
+/* arch/parisc/include/asm/elf.h */
+#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h
index cc3382007f..e3b8e1eaa6 100644
--- a/linux-user/i386/target_mman.h
+++ b/linux-user/i386/target_mman.h
@@ -11,4 +11,7 @@ 
  */
 #define TASK_UNMAPPED_BASE    0x40000000
 
+/* arch/x86/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       0x00400000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h
index d70e44d44c..8c2a3d5596 100644
--- a/linux-user/loongarch64/target_mman.h
+++ b/linux-user/loongarch64/target_mman.h
@@ -6,4 +6,7 @@ 
 #define TASK_UNMAPPED_BASE \
     TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
 
+/* arch/loongarch/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h
index d3eceb663b..20cfe750c5 100644
--- a/linux-user/m68k/target_mman.h
+++ b/linux-user/m68k/target_mman.h
@@ -1,4 +1,6 @@ 
 /* arch/m68k/include/asm/processor.h */
 #define TASK_UNMAPPED_BASE      0xC0000000
+/* arch/m68k/include/asm/elf.h */
+#define ELF_ET_DYN_BASE         0xD0000000
 
 #include "../generic/target_mman.h"
diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h
index ffee869db4..6b3dd54f89 100644
--- a/linux-user/microblaze/target_mman.h
+++ b/linux-user/microblaze/target_mman.h
@@ -6,4 +6,7 @@ 
  */
 #define TASK_UNMAPPED_BASE      0x48000000
 
+/* arch/microblaze/include/uapi/asm/elf.h */
+#define ELF_ET_DYN_BASE         0x08000000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h
index fe1eec2d0b..b84fe1e8a8 100644
--- a/linux-user/mips/target_mman.h
+++ b/linux-user/mips/target_mman.h
@@ -21,6 +21,9 @@ 
 #define TASK_UNMAPPED_BASE \
     TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
 
+/* arch/mips/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h
index ce18f4f871..ab16ad4f03 100644
--- a/linux-user/nios2/target_mman.h
+++ b/linux-user/nios2/target_mman.h
@@ -5,4 +5,7 @@ 
  */
 #define TASK_UNMAPPED_BASE    TARGET_PAGE_ALIGN(0x7FFF0000 / 3)
 
+/* arch/nios2/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       0xD0000000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h
index f1aaad809d..243c1d5f26 100644
--- a/linux-user/openrisc/target_mman.h
+++ b/linux-user/openrisc/target_mman.h
@@ -5,4 +5,7 @@ 
  */
 #define TASK_UNMAPPED_BASE      0x30000000
 
+/* arch/openrisc/include/asm/elf.h */
+#define ELF_ET_DYN_BASE         0x08000000
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h
index 04f99c6077..646d1ccae7 100644
--- a/linux-user/ppc/target_mman.h
+++ b/linux-user/ppc/target_mman.h
@@ -17,6 +17,13 @@ 
 #define TASK_UNMAPPED_BASE      0x40000000
 #endif
 
+/* arch/powerpc/include/asm/elf.h */
+#ifdef TARGET_PPC64
+#define ELF_ET_DYN_BASE         0x100000000ull
+#else
+#define ELF_ET_DYN_BASE         0x000400000
+#endif
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h
index 0f06dadbd4..3049bcc67d 100644
--- a/linux-user/riscv/target_mman.h
+++ b/linux-user/riscv/target_mman.h
@@ -5,4 +5,7 @@ 
 #define TASK_UNMAPPED_BASE \
     TARGET_PAGE_ALIGN((1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) / 3)
 
+/* arch/riscv/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h
index 40d149b329..c82435e381 100644
--- a/linux-user/s390x/target_mman.h
+++ b/linux-user/s390x/target_mman.h
@@ -8,4 +8,14 @@ 
  */
 #define TASK_UNMAPPED_BASE      (1ull << 41)
 
+/*
+ * arch/s390/include/asm/elf.h:
+ * ELF_ET_DYN_BASE              (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)
+ *
+ * arch/s390/include/asm/processor.h:
+ * STACK_TOP                    VDSO_LIMIT - VDSO_SIZE - PAGE_SIZE
+ * VDSO_LIMIT                   _REGION2_SIZE
+ */
+#define ELF_ET_DYN_BASE         (((1ull << 42) / 3 * 2) & ~0xffffffffull)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
index bbbc223398..dd9016081e 100644
--- a/linux-user/sh4/target_mman.h
+++ b/linux-user/sh4/target_mman.h
@@ -2,4 +2,7 @@ 
 #define TASK_UNMAPPED_BASE \
     TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
 
+/* arch/sh/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h
index 692ebf9dd7..696ca73fe4 100644
--- a/linux-user/sparc/target_mman.h
+++ b/linux-user/sparc/target_mman.h
@@ -19,6 +19,17 @@ 
 #define TASK_UNMAPPED_BASE      (1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 2))
 #endif
 
+/*
+ * arch/sparc/include/asm/elf_64.h
+ * Except that COMPAT_ELF_ET_DYN_BASE exactly matches TASK_UNMAPPED_BASE,
+ * so move it up a bit.
+ */
+#ifdef TARGET_ABI32
+#define ELF_ET_DYN_BASE         0x78000000
+#else
+#define ELF_ET_DYN_BASE         0x0000010000000000ull
+#endif
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h
index bae49059e0..5dd48a458d 100644
--- a/linux-user/user-mmap.h
+++ b/linux-user/user-mmap.h
@@ -20,6 +20,7 @@ 
 
 extern abi_ulong task_unmapped_base;
 extern abi_ulong mmap_next_start;
+extern abi_ulong elf_et_dyn_base;
 
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
 abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h
index f9ff652b37..48fbf20b42 100644
--- a/linux-user/x86_64/target_mman.h
+++ b/linux-user/x86_64/target_mman.h
@@ -10,4 +10,7 @@ 
 #define TASK_UNMAPPED_BASE \
     TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
 
+/* arch/x86/include/asm/elf.h */
+#define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
+
 #include "../generic/target_mman.h"
diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h
index c4f671adb7..8fa6337a97 100644
--- a/linux-user/xtensa/target_mman.h
+++ b/linux-user/xtensa/target_mman.h
@@ -20,6 +20,10 @@ 
  */
 #define TASK_UNMAPPED_BASE      (1u << (TARGET_VIRT_ADDR_SPACE_BITS - 1))
 
+/* arch/xtensa/include/asm/elf.h */
+#define ELF_ET_DYN_BASE \
+    TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
+
 #include "../generic/target_mman.h"
 
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 52809c260a..e089123cfa 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -839,6 +839,21 @@  int main(int argc, char **argv, char **envp)
     }
     mmap_next_start = task_unmapped_base;
 
+    /* Similarly for elf_et_dyn_base. */
+    if (reserved_va) {
+        if (ELF_ET_DYN_BASE < reserved_va) {
+            elf_et_dyn_base = ELF_ET_DYN_BASE;
+        } else {
+            /* The most common default formula is TASK_SIZE / 3 * 2. */
+            task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2;
+        }
+    } else if (ELF_ET_DYN_BASE < UINTPTR_MAX) {
+        elf_et_dyn_base = ELF_ET_DYN_BASE;
+    } else {
+        /* 32-bit host: pick something medium size. */
+        task_unmapped_base = 0x18000000;
+    }
+
     {
         Error *err = NULL;
         if (seed_optarg != NULL) {
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 84436d45c8..949c4090f3 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -301,6 +301,7 @@  static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
 
 abi_ulong task_unmapped_base;
 abi_ulong mmap_next_start;
+abi_ulong elf_et_dyn_base;
 
 /*
  * Subroutine of mmap_find_vma, used when we have pre-allocated