From nobody Sat May 18 23:23:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1498582668857351.5444657925974; Tue, 27 Jun 2017 09:57:48 -0700 (PDT) Received: from localhost ([::1]:57108 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dPtoB-0002N6-65 for importer@patchew.org; Tue, 27 Jun 2017 12:57:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52366) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dPtkK-0006q3-5h for qemu-devel@nongnu.org; Tue, 27 Jun 2017 12:53:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dPtgn-0006CB-Jg for qemu-devel@nongnu.org; Tue, 27 Jun 2017 12:50:12 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37355) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dPtgn-00066m-Ax for qemu-devel@nongnu.org; Tue, 27 Jun 2017 12:50:09 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1dPtgd-0000Ki-MJ; Tue, 27 Jun 2017 17:49:59 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 27 Jun 2017 17:49:58 +0100 Message-Id: <1498582198-6649-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH] linux-user: Put PPC AT_IGNOREPPC auxv entries in the right place X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , Richard Henderson , Laurent Vivier , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The 32-bit PPC auxv is a bit complicated because in the mists of time it used to be 16-aligned rather than directly after the environment. Older glibc versions had code to try to probe for whether it needed alignment or not: https://sourceware.org/git/?p=3Dglibc.git;a=3Dblob;f=3Dsysdeps/unix/sysv/li= nux/powerpc/dl-sysdep.c;hb=3De84eabb3871c9b39e59323bf3f6b98c2ca9d1cd0 and the kernel has code which puts some magic entries at the bottom to ensure that the alignment probe fails: http://elixir.free-electrons.com/linux/latest/source/arch/powerpc/include/a= sm/elf.h#L158 QEMU has similar code too, but it was broken by commit 7c4ee5bcc82e64, which changed elfload.c from filling in the auxv starting at the highest address and working down to starting at the lowest address and working up. This means that the ARCH_DLINFO hook must now be invoked first rather than last, and the entries in it for PPC must be reversed so that the magic AT_IGNOREPPC entries come at the lowest address in the auxv as they should. The effect of this was that if running a guest binary that used an old glibc with the alignment probing the guest ld.so code would segfault if the size of the guest environment and argv happened to put the auxv at an address that triggered the alignment code in the guest glibc. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Tested-by: Richard Henderson --- linux-user/elfload.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index ce77317..2a902f7 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -802,14 +802,15 @@ static uint32_t get_elf_hwcap2(void) #define ARCH_DLINFO \ do { \ PowerPCCPU *cpu =3D POWERPC_CPU(thread_cpu); \ - NEW_AUX_ENT(AT_DCACHEBSIZE, cpu->env.dcache_line_size); \ - NEW_AUX_ENT(AT_ICACHEBSIZE, cpu->env.icache_line_size); \ - NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \ /* \ - * Now handle glibc compatibility. \ + * Handle glibc compatibility: these magic entries must \ + * be at the lowest addresses in the final auxv. \ */ \ NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ + NEW_AUX_ENT(AT_DCACHEBSIZE, cpu->env.dcache_line_size); \ + NEW_AUX_ENT(AT_ICACHEBSIZE, cpu->env.icache_line_size); \ + NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \ } while (0) =20 static inline void init_thread(struct target_pt_regs *_regs, struct image_= info *infop) @@ -1760,6 +1761,13 @@ static abi_ulong create_elf_tables(abi_ulong p, int = argc, int envc, } while(0) =20 /* There must be exactly DLINFO_ITEMS entries here. */ +#ifdef ARCH_DLINFO + /* + * ARCH_DLINFO must come first so platform specific code can enforce + * special alignment requirements on the AUXV if necessary (eg. PPC). + */ + ARCH_DLINFO; +#endif NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff)); NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); @@ -1782,13 +1790,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int = argc, int envc, if (u_platform) { NEW_AUX_ENT(AT_PLATFORM, u_platform); } -#ifdef ARCH_DLINFO - /* - * ARCH_DLINFO must come last so platform specific code can enforce - * special alignment requirements on the AUXV if necessary (eg. PPC). - */ - ARCH_DLINFO; -#endif NEW_AUX_ENT (AT_NULL, 0); #undef NEW_AUX_ENT =20 --=20 2.7.4