From patchwork Fri Oct 17 09:48:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 400494 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6591F1400D2 for ; Fri, 17 Oct 2014 20:49:40 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=lsSQCyEzDXQPBoGl I1IVlzYfPTxAGjLE98Ma9j2Fjv7IJmDzfjl0fQZ5h7FxK5upgX9VJBb/gYjstPFC GFZGeeXaxLY5/qJCM6/1Y/+CwGZfBeEKrvJZ/uPN1mstkFHpR+aGbcVu0k2WBCTW d5yeuTOVI/1kaIIu+/LxKaOmaDI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=nryHmEUQjb58YlG59XJc4r RDj30=; b=rDW1teB5qHMfpR2QqeWcGZAtWaFsQebzAtc9CnTsh6B3qZPaz7+Ueu Zdzk3S6iqXWpLJn6S8HhA4PSeoiIHasL1vUV57izcE4J3p/y9SkCq3qn1EpBn8ez BkvjPPaaeph0F7jsOxmMILsSPKpy+J84uhO+aIsdyAN4DZQDmjIEY= Received: (qmail 16301 invoked by alias); 17 Oct 2014 09:49:31 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 16283 invoked by uid 89); 17 Oct 2014 09:49:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN autolearn=no version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 17 Oct 2014 09:49:28 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id EDCBE2759CBB for ; Fri, 17 Oct 2014 11:49:23 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h1f03c827CXL for ; Fri, 17 Oct 2014 11:49:23 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id A82B92751CD7 for ; Fri, 17 Oct 2014 11:49:23 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [RS6000] Fix -mlongcall with nested functions on AIX Date: Fri, 17 Oct 2014 11:48:26 +0200 Message-ID: <1769193.IvLGEjaLhA@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 Hi, -mlongcall miscompiles nested functions with the AIX ABI. The problem is that, when -mlongcall is in effect, rs6000_call_aix redirects all calls to: /* Handle indirect calls. */ if (GET_CODE (func_desc) != SYMBOL_REF || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func_desc))) and then /* A function pointer under AIX is a pointer to a data area whose first word contains the actual address of the function, whose second word contains a pointer to its TOC, and whose third word contains a value to place in the static chain register (r11). Note that if we load the static chain, our "trampoline" need not have any executable code. */ But, if the call was originally direct, no "trampoline" has been built, which means that the value loaded into the static chain register is garbage. That's sort of OK, except when the called function is nested because the static chain register has already been loaded with the proper static chain value by the generic code, so overwriting it with garbage breaks the program. Tested on PowerPC/AIX, OK for the mainline? 2014-10-17 Eric Botcazou * config/rs6000/rs6000.c (rs6000_call_aix): For the AIX ABI, do not load the static chain if the call was originally direct. 2014-10-17 Eric Botcazou * gcc.target/powerpc/longcall-2.c: New test. Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 216252) +++ config/rs6000/rs6000.c (working copy) @@ -32568,6 +32568,8 @@ rs6000_legitimate_constant_p (enum machi void rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) { + const bool direct_call_p + = GET_CODE (func_desc) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (func_desc); rtx toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM); rtx toc_load = NULL_RTX; rtx toc_restore = NULL_RTX; @@ -32636,8 +32638,11 @@ rs6000_call_aix (rtx value, rtx func_des func_toc_offset)); toc_load = gen_rtx_USE (VOIDmode, func_toc_mem); - /* If we have a static chain, load it up. */ - if (TARGET_POINTERS_TO_NESTED_FUNCTIONS) + /* If we have a static chain, load it up. But, if the call was + originally direct, the 3rd word has not been written since no + trampoline has been built, so we ought not to load it, lest we + override a static chain value. */ + if (!direct_call_p && TARGET_POINTERS_TO_NESTED_FUNCTIONS) { rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode));