From patchwork Mon Jul 24 17:48:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 1812024 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=gmx.de header.i=deller@gmx.de header.a=rsa-sha256 header.s=s31663417 header.b=jTDCb7++; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R8nhs6mpNz1yYc for ; Tue, 25 Jul 2023 03:49:01 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qNzfm-00027r-8Q; Mon, 24 Jul 2023 13:48:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qNzfk-00026g-Ti for qemu-devel@nongnu.org; Mon, 24 Jul 2023 13:48:40 -0400 Received: from mout.gmx.net ([212.227.15.19]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qNzfi-0005aj-QU for qemu-devel@nongnu.org; Mon, 24 Jul 2023 13:48:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1690220914; x=1690825714; i=deller@gmx.de; bh=HpumHCLzVgzNVhx++hvH34XbHa4cwh14+xIUXetvqV8=; h=X-UI-Sender-Class:Date:From:To:Subject; b=jTDCb7++iQkZoPjCKmVVPlkq1eCw8b67sH6aH5M813gBzJNk0QO2ZZsy4Tvxi4Qiap0sLU5 uODyko8Ruk/8BKnhkKUpNgKd1mXLsjDgodCCgSIumHUNC5VqvjD+sue+NPLPuuNHFlP+KD+lA 94+g8a3v5I4ik6o2vLwmFIG7BOigEKshNRCB9SKyaugspOnkQuKsfawmXUUmv6yywXEMfSocJ VSOl7ykkIdScxsZhP2velibL85M21jIswQDjnwjad2ze6LES7u4NpIYIIainzEKmz/7lIV4df 6wKkt+VuEqHIkTbWcWfnAHgEe/ocQbkGqQe4uPMOKzFnj8BhLekg== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from p100 ([94.134.154.236]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MbAh0-1pmRzu0u6q-00ba7D; Mon, 24 Jul 2023 19:48:34 +0200 Date: Mon, 24 Jul 2023 19:48:31 +0200 From: Helge Deller To: Peter Maydell , Michael Tokarev , qemu-devel@nongnu.org, Andreas Schwab , Richard Henderson , Laurent Vivier Subject: [PATCH v3] linux-user: Fix qemu-arm to run static armhf binaries Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Provags-ID: V03:K1:3E4RRd+3oPZbj8II6RroDc56T+Ax1X1ZG3GUVk4g1P/I9P6OT28 NLgotH7skzz33h+8cFZhoxryNuydhs4XVJSiY3y5gqHvj/IZy75v/JnqstwzF3b8klV10Oh Ev+RINxQmTFjn8fLcsbnC87zjpDcnuvIIYdK/800G2qZTCOZE5NdSG5j2AU6zUWOTcxKfNY 4uyR1GBPl8h7OiYPTJUwQ== UI-OutboundReport: notjunk:1;M01:P0:TiSq9sPGV2M=;c/Ja7A4yHcwAqf2z9dAInkbGsoE Q1hMWcHIPgHWI0SBAA8qnAil3xole64/4CllW07ZBzNK7qEVoiZFHuAXhX+WNvsZENZjUjXDk U7xzbE/tyzI8+PNG86cdecOUB6nUkE+L0wNeh2PLoA2yDWvKO3bUSvg+/o5epy75rLv+GKuvL 9prCtnL5E0WPG/2EjuFYRy1Aod6D9+Qcsg7/euzS3UQjaCTJV4M7we1d3ixfkUzWwETb99g94 tDhpKng/xGtlhsHQIMuSw7vZUbSFZj4Z7vpfA2j9WsBV1qxZEeH232SbpgLlOEmCB8DToq0Xy aqMmLYbM75w29swlClQMQT9x6WvDCFHhly/fp9ksWolfCd9qI09AGQR/lPhXIVv2NEXGRnb29 OCz60JLyKDAJ13wH65o5GKLqM5ibyUJH3ZtjbfNIJPrqLNHDq0gSiHnVx2Vkleg08I4qPKRW3 bvH8K4ZbMHSBsbiPaVRWBa51P9+hELHE7X8bVc3d6/C1vMwvdjEm92JLcJegjrYJ814al1cLP 1NfdBLsG8klpVcm34a60M+SmjeChh50bvQR4EQvRBOfsSo4tSswToiBj050+uKJLuB0xYct+H gsw7dh+/crMcfiTNdqPfsgUb995SrFea05zk9EiCkZfcJGjEwb/l3lDQdabYVVTdj57x7UACJ R1Fqq+VO6r4k3N3PAMyEblqY4k6CUCEBv91QAAAbGXmBaU0KHOMKf2wvIKBX0tbfx132tHz+5 7C2rMMhu2JO8shLl5JWxO/K44sOvG8MSwsGBF629hPy9RK3nT+ANWsASBye9eL88XQSi4ZzPF 21A9XFpB00ST4O0VEkG1bN+2KdYdtAvcFZ2ayoZxG9oJ3O0mMvb+bwci0LedvNwOTwt+1uhcf sVt5R2pQwMh0xI/NE4mRNVyvPF1o8x5ot2q7Fyta9eHvviQfvMXIST7DJAcQc+7y8/iRPeORw Xk4C4w== Received-SPF: pass client-ip=212.227.15.19; envelope-from=deller@gmx.de; helo=mout.gmx.net X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The last attempt to fix linux-user to be able to run static armhf binaries fixed armhf, but broke arm64, ppc64el and s390x. This patch takes another approach to fix the issue. Instead of pre-allocatig a 16/32 MiB memory region for heap, the loader tracks the highest address of both executable and interpreter. Then it compares both values and chooses the highest address from the executable as brk starting point, if the starting address of the interpreter leaves at least 16 MiB for the heap. If not, qemu will choose the highest address of the interpreter as brk start. I've tested this patch on arm64 and hppa (both with chroot), and with a static armhf binary. It applies on top of git head, where the previous patch was reverted. Signed-off-by: Helge Deller diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 861ec07abc..710ba03862 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -3107,27 +3107,6 @@ 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; - if (ehdr->e_type == ET_EXEC) { /* * Make sure that the low address does not conflict with @@ -3194,7 +3173,8 @@ static void load_elf_image(const char *image_name, int image_fd, info->end_code = 0; info->start_data = -1; info->end_data = 0; - info->brk = 0; + /* put possible start for brk behind all sections of this ELF file. */ + info->brk = load_bias + TARGET_PAGE_ALIGN(hiaddr); info->elf_flags = ehdr->e_flags; prot_exec = PROT_EXEC; @@ -3288,9 +3268,6 @@ static void load_elf_image(const char *image_name, int image_fd, info->end_data = vaddr_ef; } } - if (vaddr_em > info->brk) { - info->brk = vaddr_em; - } #ifdef TARGET_MIPS } else if (eppnt->p_type == PT_MIPS_ABIFLAGS) { Mips_elf_abiflags_v0 abiflags; @@ -3618,6 +3595,15 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) if (elf_interpreter) { load_elf_interp(elf_interpreter, &interp_info, bprm->buf); + /* + * Use brk address of interpreter if it was loaded above the + * executable and leaves less than 16 MB for heap. + * This happens e.g. with static binaries on armhf. + */ + if (interp_info.brk > info->brk && + info->load_bias + interp_info.load_addr - info->brk < 16 * MiB) { + info->brk = interp_info.brk; + } /* If the program interpreter is one of these two, then assume an iBCS2 image. Otherwise assume a native linux image. */ @@ -3672,17 +3658,6 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) bprm->core_dump = &elf_core_dump; #endif - /* - * If we reserved extra space for brk, release it now. - * The implementation of do_brk in syscalls.c expects to be able - * to mmap pages in this space. - */ - if (info->reserve_brk) { - abi_ulong start_brk = HOST_PAGE_ALIGN(info->brk); - abi_ulong end_brk = HOST_PAGE_ALIGN(info->brk + info->reserve_brk); - target_munmap(start_brk, end_brk - start_brk); - } - return 0; }