Browse code

fixed an issue where GEP with negative offset would invalidate pointer

Kevin Lin authored on 2014/01/17 07:56:12
Showing 1 changed files
... ...
@@ -1108,16 +1108,24 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
1108 1108
 		break;
1109 1109
 	    }
1110 1110
 	    DEFINE_OP(OP_BC_GEPZ) {
1111
-		int64_t ptr;
1111
+        int64_t ptr, iptr;
1112
+        int32_t off;
1113
+        READ32(off, inst->u.three[2]);
1114
+
1115
+        // negative values checking, valid for intermediate GEP calculations
1116
+        if (off < 0) {
1117
+          cli_dbgmsg("bytecode warning: found GEP with negative offset %d!\n", off);
1118
+        }
1119
+
1112 1120
 		if (!(inst->interp_op%5)) {
1113
-		    int32_t off;
1114
-		    READ32(off, inst->u.three[2]);
1121
+            // how do negative offsets affect pointer intialization?
1115 1122
 		    WRITE64(inst->dest, ptr_compose(stackid,
1116 1123
 						    inst->u.three[1]+off));
1117 1124
 		} else {
1118 1125
 		    int32_t off;
1119
-		    READ32(off, inst->u.three[2]);
1120 1126
 		    READ64(ptr, inst->u.three[1]);
1127
+            off += (ptr & 0x00000000ffffffff);
1128
+            iptr = (ptr & 0xffffffff00000000) + (uint64_t)(off);
1121 1129
 		    WRITE64(inst->dest, ptr+off);
1122 1130
 		}
1123 1131
 		break;
... ...
@@ -1211,21 +1219,34 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
1211 1211
 		WRITE64(inst->dest, ptr);
1212 1212
 		break;
1213 1213
 	    }
1214
-	    DEFINE_OP(OP_BC_GEP1) {
1215
-		int64_t ptr;
1216
-		if (!(inst->interp_op%5)) {
1217
-		    int32_t off;
1218
-		    READ32(off, inst->u.three[2]);
1219
-		    WRITE64(inst->dest, ptr_compose(stackid,
1220
-						    inst->u.three[1]+off*inst->u.three[0]));
1221
-		} else {
1222
-		    int32_t off;
1223
-		    READ32(off, inst->u.three[2]);
1224
-		    READ64(ptr, inst->u.three[1]);
1225
-		    WRITE64(inst->dest, ptr+off*inst->u.three[0]);
1226
-		}
1227
-		break;
1228
-	    }
1214
+        DEFINE_OP(OP_BC_GEP1) {
1215
+        int64_t ptr, iptr;
1216
+        int32_t off;
1217
+        READ32(off, inst->u.three[2]);
1218
+
1219
+        // negative values checking, valid for intermediate GEP calculations
1220
+        if (off < 0) {
1221
+            cli_dbgmsg("bytecode warning: GEP with negative offset %d!\n", off);
1222
+        }
1223
+        if (inst->u.three[0] < 0) {
1224
+            cli_dbgmsg("bytecode warning: GEP with negative size %d!\n", inst->u.three[0]);
1225
+        }
1226
+
1227
+        if (!(inst->interp_op%5)) {
1228
+            // how do negative offsets affect pointer intialization?
1229
+            cli_dbgmsg("bytecode warning: untested case for GEP1\n");
1230
+            off *= inst->u.three[0];
1231
+            WRITE64(inst->dest, ptr_compose(stackid,
1232
+                                            inst->u.three[1]+off));
1233
+        } else {
1234
+            READ64(ptr, inst->u.three[1]);
1235
+            off *= inst->u.three[0];
1236
+            off += (ptr & 0x00000000ffffffff);
1237
+            iptr = (ptr & 0xffffffff00000000) + (uint64_t)(off);
1238
+            WRITE64(inst->dest, iptr);
1239
+        }
1240
+        break;
1241
+        }
1229 1242
 	    /* TODO: implement OP_BC_GEP1, OP_BC_GEP2, OP_BC_GEPN */
1230 1243
 	    default:
1231 1244
 		cli_errmsg("Opcode %u of type %u is not implemented yet!\n",