... | ... |
@@ -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", |