From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 113897 invoked by alias); 12 Jul 2016 10:39:19 -0000 Mailing-List: contact java-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-patches-owner@gcc.gnu.org Received: (qmail 113805 invoked by uid 89); 12 Jul 2016 10:39:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,LIKELY_SPAM_BODY,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=no version=3.3.2 spammy=Method, rx, gr, ja X-Spam-User: qpsmtpd, 2 recipients X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 12 Jul 2016 10:39:08 +0000 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Forcepoint Email with ESMTPS id 80EFEDC58D27A; Tue, 12 Jul 2016 11:39:01 +0100 (IST) Received: from HHMAIL01.hh.imgtec.org ([fe80::710b:f219:72bc:e0b3]) by hhmail02.hh.imgtec.org ([fe80::5400:d33e:81a4:f775%25]) with mapi id 14.03.0294.000; Tue, 12 Jul 2016 11:39:04 +0100 From: Matthew Fortune To: "'gcc-patches@gcc.gnu.org' (gcc-patches@gcc.gnu.org)" , "java-patches@gcc.gnu.org" CC: Tom Tromey , "aurelien@aurel32.net" Subject: [PATCH] Fix FFI return type for proxy classes Date: Tue, 12 Jul 2016 10:39:00 -0000 Message-ID: <6D39441BF12EF246A7ABCE6654B023537E474A5F@HHMAIL01.hh.imgtec.org> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-SW-Source: 2016-q3/txt/msg00001.txt.bz2 Hi, As mentioned in: https://gcc.gnu.org/ml/gcc-patches/2016-06/msg01827.html there is a bug in lang/reflect/natVMProxy.cc where the return types are not promoted to ffi_arg for integer types smaller than a word. This bug will not show up on little endian architectures as the issue gets fixed by _Jv_CallAnyMethodA which casts the (corrupted) return value down to the correct type again effectively discarding the upper corrupt bits. On big endian this does not work as the valid bits are in the wrong position so the casts in _Jv_CallAnyMethodA just make a bad value worse. Many thanks to Tom for explaining how to trigger the affected code. I've added a test that has proxied functions returning each of the integer types to cover this issue. All being well that will be sufficient to prevent regressions in this area as it was somewhat tricky to get to the root of this! I hope the coding style of the test is OK, I don't know the rules for java formatting in GNU projects. Tested on: x86_64-pc-linux-gnu (default and -m32), mips-linux-gnu mipsel-linux-gnuabi64 with no regressions. The new test only failed on mips-linux-gnu prior to patching libjava. Thanks, Matthew libjava/ * java/lang/reflect/natVMProxy.cc (unbox): Use ffi_arg for integer return types smaller than a word. * testsuite/libjava.jar/ReturnInvocationHandler.java: New file. * testsuite/libjava.jar/ReturnProxyTest.jar: Likewise. * testsuite/libjava.jar/ReturnProxyTest.java: Likewise. * testsuite/libjava.jar/ReturnProxyTest.out: Likewise. * testsuite/libjava.jar/ReturnProxyTest.xfail: Likewise. * testsuite/libjava.jar/ReturnTypes.java: Likewise. * testsuite/libjava.jar/ReturnTypesImpl.java: Likewise. --- libjava/java/lang/reflect/natVMProxy.cc | 10 ++++---- .../libjava.jar/ReturnInvocationHandler.java | 24 ++++++++++++++++++ libjava/testsuite/libjava.jar/ReturnProxyTest.jar | Bin 0 -> 2671 bytes libjava/testsuite/libjava.jar/ReturnProxyTest.java | 27 +++++++++++++++++= ++++ libjava/testsuite/libjava.jar/ReturnProxyTest.out | 12 +++++++++ .../testsuite/libjava.jar/ReturnProxyTest.xfail | 1 + libjava/testsuite/libjava.jar/ReturnTypes.java | 9 +++++++ libjava/testsuite/libjava.jar/ReturnTypesImpl.java | 27 +++++++++++++++++= ++++ 8 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 libjava/testsuite/libjava.jar/ReturnInvocationHandler.j= ava create mode 100644 libjava/testsuite/libjava.jar/ReturnProxyTest.jar create mode 100644 libjava/testsuite/libjava.jar/ReturnProxyTest.java create mode 100644 libjava/testsuite/libjava.jar/ReturnProxyTest.out create mode 100644 libjava/testsuite/libjava.jar/ReturnProxyTest.xfail create mode 100644 libjava/testsuite/libjava.jar/ReturnTypes.java create mode 100644 libjava/testsuite/libjava.jar/ReturnTypesImpl.java diff --git a/libjava/java/lang/reflect/natVMProxy.cc b/libjava/java/lang/re= flect/natVMProxy.cc index e46263d..19cde20 100644 --- a/libjava/java/lang/reflect/natVMProxy.cc +++ b/libjava/java/lang/reflect/natVMProxy.cc @@ -272,17 +272,17 @@ unbox (jobject o, jclass klass, void *rvalue, FFI_TYP= E type) if (klass =3D=3D JvPrimClass (byte)) { _Jv_CheckCast (&Byte::class$, o); - *(jbyte*)rvalue =3D ((Byte*)o)->byteValue(); + *(ffi_arg*)rvalue =3D ((Byte*)o)->byteValue(); } else if (klass =3D=3D JvPrimClass (short)) { _Jv_CheckCast (&Short::class$, o); - *(jshort*)rvalue =3D ((Short*)o)->shortValue(); + *(ffi_arg*)rvalue =3D ((Short*)o)->shortValue(); } else if (klass =3D=3D JvPrimClass (int)) { _Jv_CheckCast (&Integer::class$, o); - *(jint*)rvalue =3D ((Integer*)o)->intValue(); + *(ffi_arg*)rvalue =3D ((Integer*)o)->intValue(); } else if (klass =3D=3D JvPrimClass (long)) { @@ -302,12 +302,12 @@ unbox (jobject o, jclass klass, void *rvalue, FFI_TYP= E type) else if (klass =3D=3D JvPrimClass (boolean)) { _Jv_CheckCast (&Boolean::class$, o); - *(jboolean*)rvalue =3D ((Boolean*)o)->booleanValue(); + *(ffi_arg*)rvalue =3D ((Boolean*)o)->booleanValue(); } else if (klass =3D=3D JvPrimClass (char)) { _Jv_CheckCast (&Character::class$, o); - *(jchar*)rvalue =3D ((Character*)o)->charValue(); + *(ffi_arg*)rvalue =3D ((Character*)o)->charValue(); } else JvFail ("Bad ffi type in proxy"); diff --git a/libjava/testsuite/libjava.jar/ReturnInvocationHandler.java b/l= ibjava/testsuite/libjava.jar/ReturnInvocationHandler.java new file mode 100644 index 0000000..18b52b7 --- /dev/null +++ b/libjava/testsuite/libjava.jar/ReturnInvocationHandler.java @@ -0,0 +1,24 @@ +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class ReturnInvocationHandler implements InvocationHandler +{ + private Object obj; + public ReturnInvocationHandler(Object obj) + { + this.obj =3D obj; + } + public Object invoke(Object proxy, Method m, Object[] args) throws Throw= able + { + Object result; + try + { + result =3D m.invoke(obj, args); + } + catch (Exception e) + { + throw e; + } + return result; + } +} diff --git a/libjava/testsuite/libjava.jar/ReturnProxyTest.jar b/libjava/te= stsuite/libjava.jar/ReturnProxyTest.jar new file mode 100644 index 0000000000000000000000000000000000000000..00daabeccc8f28d1ccde9d8bea7= 63874ab9351a7 GIT binary patch literal 2671 zcma);3p`Y5AIA^Ir7`3-xs*_u#$_}mvr!Cf_&zw1{9|G6S5%flTu|LZO@ZF2O!ncL}s?seNT#a+=3DfkH>}m-yRCVy zMu(*#Z5{%oRicwlsPBfXT!fFHE`Z#>uBLF+j1GUG)n2&s%_8z~iB^)Uin?job8c8S zi`#X7;V=3D1U{I23eIoPCQ;}i3JT?PA0kKYf+5Q;`JvZ46gMzU8{LE-osPDBN}e9llP z=3D{8xqF(u2GV=3D*j!p>jY8ZFmCZ4iT2s_$~xWW{!7FW=3Dcs=3D9#l9f?4BNX&~>~ro*4^~ z%g5nUtV?~i(~H9W9fKcMXQgFhl$|w+xE)5^*86?f&}T*odI0(6aCsPLTkfUIG~&d2)a4UknWmWlt#itxnRZ-h&D6y_GMCY8tYP?>C35U3)tip9@cK z=3DtSE8xL!qo)Uk~VmDGCb<&XbUxpMEz6-Pr~OO$N)mz4S?eL}ikP1I-sgSm43N#yf$ z45S}ddjOFc1tO>J=3D0#{j48j@A-?l-Q=3D-JsQwpG$d^h zcu~j~ zLQT-sbC`VZ404lce(QBozjlj?)3qTCzrqK?@e}#NnqB5uzankmoXxyPQ0gy{L5rOm zez=3D3GWtY|2wXJ%aypXK|w^zp-9?+Z4AVtUiR>){m{^JPy)muV!n|(8a{Zag@yc>Qm!G#8A~*xZpzeyY=3DoZ z##3nIu|7Xn2iM;xGXlc4jPddjmZJ3vDVHAYRy9kg?~ltz z=3D+7kO7w!;UU?1{)b;dQKP3R|u6EFV+~0-#qNumbEdb#`e~XvC~|* zLC(2Xx9PC{a?;h)tlm`F>(2#9!tII8il^8OT5`SRJ*7SOk(Qd4KOp zsFgi3ck?cjq4KFSvyjO-oYvKw64w-a)Mwe=3D*DoE~b}Z&B>klRMMjsYMB+E8E7-C6} zL$*lx?_hZd>k^*oJ2PiXRu-|Cc%gb+o)x$F`;DS|N%M>gR@||Yu02tj(|x76@l(#7 z^we_SxQ)n%=3D;Zgt7FE{SaE4wAEo5G~!A@tSx46+BYvm2-7>HEaA+{AhH~9s}=3DT?gs zILu-Jyap_H^I%i{oDjsw5K7p$lYwxCpcsQziz`|LVz9-Wp5#^|YoD0So0UDL45`*T z_r|uxmGNHyYddF=3DtLvHff-R0`cE6dCscP%9OKIM|;(*61fuOCWJ-T_*Y`UyIXHQ7O zs&xY}X9Ody>{R8u0Sj`~twg$)<{1mc)hJj3Y*nanJyT$*lW_<3TvLFlBpTFh9gHux z9UvJ-)TW)EJ;B8UX`enBb2tSLPpIl~zdEX+-E1ZzA7R9l^lGx^o6$wTw+Lm$H=3Dx$A zOaD8t!drn=3D;Y&sMumO%iAxFNw3Gu0Sont>#c7u0UiTema^&v$jM+B?YgM4DBThF$~ z*Yli_3ffwb^y}#+`!nlaNU)GITdG_z`lAB#H&J2i(Ps;fRh!J&h^_2FZeqGa7bftf z-^Ia`Nh+~d|LA6^g^VZD9u)l4f#`(IV3D}F8=3DNTCtz4ZPfoTR}G_Tmk{#OZAI5d0S zRj|Rx!`5_4CWa?W8rl=3DLyZrSw7{Ux8zt#YI>n&4N{z(S|61mU6j+

o6cy&M7>Jj zou86#u?{KmU)fK;u_5cU5!SNKt?u!jqn2wFXUaEBqY~L{gZ;w0K;+VQUWGzmY&P>g!D%}@zweIHBMYj ze8hoX2J%nhmgB^<#s4FJIYPuG!6!qP$U`9c8v+5G;(v&PkH&wQLj06kK1DGYrC%wQ zPZ9d>(Bk>N9L<;hgci&Ge}@&%qUG3YGGf@}IrUFyX>bSt$bh#dxLj+wrLVsMqYL[] { ReturnTypes.class }, + new ReturnInvocationHandler(orig)); + ReturnTypes rt =3D (ReturnTypes)o; + + System.out.println(orig.getBoolean()); + System.out.println(orig.getChar()); + System.out.println(orig.getByte()); + System.out.println(orig.getShort()); + System.out.println(orig.getInt()); + System.out.println(orig.getLong()); + + System.out.println(rt.getBoolean()); + System.out.println(rt.getChar()); + System.out.println(rt.getByte()); + System.out.println(rt.getShort()); + System.out.println(rt.getInt()); + System.out.println(rt.getLong()); + } +} diff --git a/libjava/testsuite/libjava.jar/ReturnProxyTest.out b/libjava/te= stsuite/libjava.jar/ReturnProxyTest.out new file mode 100644 index 0000000..b141f06 --- /dev/null +++ b/libjava/testsuite/libjava.jar/ReturnProxyTest.out @@ -0,0 +1,12 @@ +false +a +-1 +-1 +-1 +-1 +false +a +-1 +-1 +-1 +-1 diff --git a/libjava/testsuite/libjava.jar/ReturnProxyTest.xfail b/libjava/= testsuite/libjava.jar/ReturnProxyTest.xfail new file mode 100644 index 0000000..73ffe1d --- /dev/null +++ b/libjava/testsuite/libjava.jar/ReturnProxyTest.xfail @@ -0,0 +1 @@ +main=3DReturnProxyTest diff --git a/libjava/testsuite/libjava.jar/ReturnTypes.java b/libjava/tests= uite/libjava.jar/ReturnTypes.java new file mode 100644 index 0000000..9fbd6bd --- /dev/null +++ b/libjava/testsuite/libjava.jar/ReturnTypes.java @@ -0,0 +1,9 @@ +public interface ReturnTypes +{ + public short getShort(); + public char getChar(); + public byte getByte(); + public int getInt(); + public long getLong(); + public boolean getBoolean(); +} diff --git a/libjava/testsuite/libjava.jar/ReturnTypesImpl.java b/libjava/t= estsuite/libjava.jar/ReturnTypesImpl.java new file mode 100644 index 0000000..33fab1b --- /dev/null +++ b/libjava/testsuite/libjava.jar/ReturnTypesImpl.java @@ -0,0 +1,27 @@ +public class ReturnTypesImpl implements ReturnTypes +{ + public short getShort() + { + return -1; + } + public char getChar() + { + return 'a'; + } + public byte getByte() + { + return -1; + } + public int getInt() + { + return -1; + } + public long getLong() + { + return -1; + } + public boolean getBoolean() + { + return false; + } +} --=20 2.2.1