OSDN Git Service

Fix for 3326: Incorrect return value from native library in dalvik
authorBill Buzbee <buzbee@google.com>
Mon, 27 Jul 2009 22:51:54 +0000 (15:51 -0700)
committerBill Buzbee <buzbee@google.com>
Tue, 28 Jul 2009 16:33:08 +0000 (09:33 -0700)
Really a workaround for a gcc bug in 4.3.  Don't trust the C compiler
to properly clear high bits from < 32-bit JNI return values.

vm/JniInternal.h
vm/arch/x86/Call386ABI.S
vm/oo/Class.c

index 36ff46b..df3ca54 100644 (file)
@@ -74,13 +74,18 @@ typedef struct JavaVMExt {
  * Native function return type; used by dvmPlatformInvoke().
  *
  * This is part of Method.jniArgInfo, and must fit in 3 bits.
+ * Note: Assembly code in arch/<arch>/Call<arch>.S relies on
+ * the enum values defined here.
  */
 typedef enum DalvikJniReturnType {
     DALVIK_JNI_RETURN_VOID = 0,     /* must be zero */
-    DALVIK_JNI_RETURN_FLOAT,
-    DALVIK_JNI_RETURN_DOUBLE,
-    DALVIK_JNI_RETURN_S8,
-    DALVIK_JNI_RETURN_S4
+    DALVIK_JNI_RETURN_FLOAT = 1,
+    DALVIK_JNI_RETURN_DOUBLE = 2,
+    DALVIK_JNI_RETURN_S8 = 3,
+    DALVIK_JNI_RETURN_S4 = 4,
+    DALVIK_JNI_RETURN_S2 = 5,
+    DALVIK_JNI_RETURN_U2 = 6,
+    DALVIK_JNI_RETURN_S1 = 7
 } DalvikJniReturnType;
 
 #define DALVIK_JNI_NO_ARG_INFO  0x80000000
index 9e32bdd..6cb680c 100644 (file)
@@ -131,12 +131,31 @@ isClass:
     /* Is FP? */
     cmpl     $2,%ebx
     jle      isFP
-    /* No need to distinguish between 32/64 - just save both */
+    cmpl     $4,%ebx  /* smaller than 32-bits? */
+    jg       isSmall
+storeRetval:
+    /* Blindly storing 64-bits won't hurt 32-bit case */
     movl     %eax,(%ecx)
     movl     %edx,4(%ecx)
     jmp      cleanUpAndExit
+isSmall:
+    cmpl     $7,%ebx  /* S1? */
+    jne      checkShort
+    movsbl   %al,%eax
+    movl     %eax,(%ecx)
+    jmp      cleanUpAndExit
+checkShort:
+    cmpl     $6,%eax  /* U2? */
+    jne      isSignedShort
+    movzwl   %ax,%eax
+    movl     %eax,(%ecx)
+    jmp      cleanUpAndExit
+isSignedShort:
+    /* Must be S2 */
+    movswl   %ax,%eax
+    jmp      cleanUpAndExit
 isFP:
-    /* Is single? */
+    /* Is Float? */
     cmpl    $1,%ebx
     je       saveFloat
     fstpl    (%ecx)
index 23ffb0b..a2c485f 100644 (file)
@@ -2201,6 +2201,16 @@ static int computeJniArgInfo(const DexProto* proto)
     case 'J':
         returnType = DALVIK_JNI_RETURN_S8;
         break;
+    case 'Z':
+    case 'B':
+        returnType = DALVIK_JNI_RETURN_S1;
+        break;
+    case 'C':
+        returnType = DALVIK_JNI_RETURN_U2;
+        break;
+    case 'S':
+        returnType = DALVIK_JNI_RETURN_S2;
+        break;
     default:
         returnType = DALVIK_JNI_RETURN_S4;
         break;