From patchwork Thu Aug 1 17:11:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 264064 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 89E8D2C0092 for ; Fri, 2 Aug 2013 03:12:16 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=rrpTRBuLRfaKpkUzti4KLSmoh2YwRYIG9dOKuqCKUi8nmHLAiB sNLRhrDI7N+dEzF+1CvcImAQIQcyzSaSIU8+l8xWk0j5qoj4o5EmbNMQJvUjUMCq YpCgqPCsbBTurv2pywWac/DrXei4kT5NlLHsgb1WpROpRB6q6HTuNWza4= 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:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=eCucJB4hpPCpOTSfv4YAiunxHVs=; b=Rlp95DZrQ4wYVTgOMFUN Zx8zSrkzHXQ3jLV9ODIKVdXW2Rc8FKsod7hL0mvo7knGjlGsFSJ9hZfPy1v52KM9 5nsiPYz6fBWFdGWZJUqbEa8uC9qEo+aGUqoHH10qxigYfL0S1iqxcFo2LiOTcZw2 6ZP2xi3Wb07Ua7iOnWcPKIk= Received: (qmail 4859 invoked by alias); 1 Aug 2013 17:12:08 -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 4848 invoked by uid 89); 1 Aug 2013 17:12:08 -0000 X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_50, KHOP_RCVD_UNTRUST, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RDNS_NONE autolearn=no version=3.3.1 Received: from Unknown (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 01 Aug 2013 17:12:06 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1V4wPt-000348-Sb from Maciej_Rozycki@mentor.com ; Thu, 01 Aug 2013 10:11:57 -0700 Received: from SVR-IES-FEM-02.mgc.mentorg.com ([137.202.0.106]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Thu, 1 Aug 2013 10:11:57 -0700 Received: from [172.30.64.204] (137.202.0.76) by SVR-IES-FEM-02.mgc.mentorg.com (137.202.0.106) with Microsoft SMTP Server id 14.2.247.3; Thu, 1 Aug 2013 18:11:56 +0100 Date: Thu, 1 Aug 2013 18:11:49 +0100 From: "Maciej W. Rozycki" To: CC: Richard Sandiford , Catherine Moore Subject: [PATCH] MIPS/libgcc: Avoid the PLT in MIPS16 stub calls Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Hi, As originally signalled here: http://gcc.gnu.org/ml/gcc-patches/2012-02/msg00140.html here is a change to prevent MIPS16 stub calls from being made through the PLT by making them hidden. This is needed to avoid $2 and possibly $3 from being clobbered by MIPS16 code in the PLT. Originally I thought only return stubs were affected, but I have since realised all the libgcc stubs rely on $2, so none can be called via the PLT. This breakage can be triggered by linking with the `-shared-libgcc' option; otherwise libgcc.a code is used avoiding the problem. Since these stubs are a preexisting interface I have decided there is no need to go through the pain of link-once functions as you did for __mips16_rdhwr. I think we'd only need them if we changed the API, at which point we'd have to keep current libgcc bits for preexisting object code anyway. For the same reason this change retains libgcc_s.so bits for preexisting executables and shared libraries, but stops them being exported for new static links so that libgcc.a bits are always used instead. I have tested this change for the mips-linux-gnu target and o32/MIPS32r2 multilib with `-mips16' and `-shared-libgcc' options. There have been no regressions to a plain `-mips16' run whereas as it stands we have numerous. OK to apply? BTW, what's the "Check for MicroMIPS support." note seen in the config.host piece of the patch referring to? 2013-08-01 Maciej W. Rozycki Catherine Moore libgcc/ * config/mips/mips16.S (RET_FUNCTION): Rename to... (_RET_FUNCTION): ... this. (RET_FUNCTION): New macro. (CALL_STUB_NO_RET): Rename to... (_CALL_STUB_NO_RET): ... this. (CALL_STUB_NO_RET): New macro. (CALL_STUB_RET): Rename to... (_CALL_STUB_RET): ... this. (CALL_STUB_RET): New macro. * config.host : For non-R5900 add t-slibgcc-libgcc to tmake_file. Maciej gcc-mips16-hidden-stub.diff Index: gcc-fsf-trunk-quilt/libgcc/config.host =================================================================== --- gcc-fsf-trunk-quilt.orig/libgcc/config.host 2013-07-31 17:48:35.000000000 +0100 +++ gcc-fsf-trunk-quilt/libgcc/config.host 2013-07-31 17:50:02.438694583 +0100 @@ -742,13 +742,13 @@ mips*-*-linux*) # Linux MIPS, either tmake_file="${tmake_file} t-crtfm" # Check for MicroMIPS support. case ${host} in - mips64r5900* | mipsr5900*) - # The MIPS16 support code uses floating point - # instructions that are not supported on r5900. - ;; - *) - tmake_file="${tmake_file} mips/t-mips16" - ;; + mips64r5900* | mipsr5900*) + # The MIPS16 support code uses floating point + # instructions that are not supported on r5900. + ;; + *) + tmake_file="${tmake_file} mips/t-mips16 t-slibgcc-libgcc" + ;; esac md_unwind_header=mips/linux-unwind.h if test "${ac_cv_sizeof_long_double}" = 16; then Index: gcc-fsf-trunk-quilt/libgcc/config/mips/mips16.S =================================================================== --- gcc-fsf-trunk-quilt.orig/libgcc/config/mips/mips16.S 2013-07-31 17:48:35.000000000 +0100 +++ gcc-fsf-trunk-quilt/libgcc/config/mips/mips16.S 2013-07-31 17:58:30.058731920 +0100 @@ -479,14 +479,34 @@ STARTFN (__mips16_fix_truncdfsi) #endif #endif /* !__mips_single_float */ +/* We don't export stubs from libgcc_s.so and always require static + versions to be pulled from libgcc.a as needed because they use $2 + and possibly $3 as arguments, diverging from the standard SysV ABI, + and as such would require severe pessimisation of MIPS16 PLT entries + just for this single special case. + + For compatibility with old binaries that used safe standard MIPS PLT + entries and referred to these functions we still export them at + version GCC_4.4.0 for run-time loading only. /* + /* Define a function NAME that moves a return value of mode MODE from FPRs to GPRs. */ -#define RET_FUNCTION(NAME, MODE) \ +#define _RET_FUNCTION(NAME, MODE) \ STARTFN (NAME); \ MOVE_##MODE##_RET (t, $31); \ ENDFN (NAME) +#ifdef SHARED +#define RET_FUNCTION(NAME, MODE) \ + _RET_FUNCTION (NAME##_compat, MODE); \ + .symver NAME##_compat, NAME##@GCC_4.4.0 +#else +#define RET_FUNCTION(NAME, MODE) \ + _RET_FUNCTION (NAME, MODE); \ + .hidden NAME +#endif + #ifdef L_m16retsf RET_FUNCTION (__mips16_ret_sf, SF) #endif @@ -525,7 +545,7 @@ RET_FUNCTION (__mips16_ret_dc, DC) pointer. They must copy the floating point arguments from the GPRs to FPRs and then call function $2. */ -#define CALL_STUB_NO_RET(NAME, CODE) \ +#define _CALL_STUB_NO_RET(NAME, CODE) \ STARTFN (NAME); \ STUB_ARGS_##CODE; \ .set noreorder; \ @@ -534,6 +554,16 @@ STARTFN (NAME); \ .set reorder; \ ENDFN (NAME) +#ifdef SHARED +#define CALL_STUB_NO_RET(NAME, CODE) \ + _CALL_STUB_NO_RET (NAME##_compat, CODE); \ + .symver NAME##_compat, NAME##@GCC_4.4.0 +#else +#define CALL_STUB_NO_RET(NAME, CODE) \ + _CALL_STUB_NO_RET (NAME, CODE); \ + .hidden NAME +#endif + #ifdef L_m16stub1 CALL_STUB_NO_RET (__mips16_call_stub_1, 1) #endif @@ -574,7 +604,7 @@ CALL_STUB_NO_RET (__mips16_call_stub_10, being called is 16 bits, in which case the copy is unnecessary; however, it's faster to always do the copy. */ -#define CALL_STUB_RET(NAME, CODE, MODE) \ +#define _CALL_STUB_RET(NAME, CODE, MODE) \ STARTFN (NAME); \ .cfi_startproc; \ /* Create a fake CFA 4 bytes below the stack pointer. */ \ @@ -593,6 +623,16 @@ STARTFN (NAME); \ .cfi_endproc; \ ENDFN (NAME) +#ifdef SHARED +#define CALL_STUB_RET(NAME, CODE, MODE) \ + _CALL_STUB_RET (NAME##_compat, CODE, MODE); \ + .symver NAME##_compat, NAME##@GCC_4.4.0 +#else +#define CALL_STUB_RET(NAME, CODE, MODE) \ + _CALL_STUB_RET (NAME, CODE, MODE); \ + .hidden NAME +#endif + /* First, instantiate the single-float set. */ #ifdef L_m16stubsf0