...
|
...
|
@@ -46,7 +46,13 @@ static int bcfail(const char *msg, long a, long b,
|
46
|
46
|
bcfail("Values "#a" and "#b" don't match!",(a),(b),__FILE__,__LINE__); } while(0)
|
47
|
47
|
#define CHECK_GT(a, b) do {if ((a) <= (b)) return \
|
48
|
48
|
bcfail("Condition failed "#a" > "#b,(a),(b), __FILE__, __LINE__); } while(0)
|
|
49
|
+#define TRACE_R(x) cli_dbgmsg("bytecode trace: %u, read %llx\n", pc, (long long)x);
|
|
50
|
+#define TRACE_W(x, w, p) cli_dbgmsg("bytecode trace: %u, write%d @%u %llx\n", pc, p, w, (long long)x);
|
|
51
|
+#define TRACE_EXEC(id, dest, ty, stack) cli_dbgmsg("bytecode trace: executing %d, -> %u (%u); %u\n", id, dest, ty, stack)
|
49
|
52
|
#else
|
|
53
|
+#define TRACE_R(x)
|
|
54
|
+#define TRACE_W(x, w, p)
|
|
55
|
+#define TRACE_EXEC(id, dest, ty, stack, c)
|
50
|
56
|
#define CHECK_UNREACHABLE return CL_EBYTECODE
|
51
|
57
|
#define CHECK_FUNCID(x);
|
52
|
58
|
#define CHECK_EQ(a,b)
|
...
|
...
|
@@ -229,42 +235,55 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
|
229
|
229
|
CHECK_EQ((p)&7, 0);
|
230
|
230
|
*/
|
231
|
231
|
#define WRITE8(p, x) CHECK_GT(func->numBytes, p);\
|
|
232
|
+ TRACE_W(x, p, 8);\
|
232
|
233
|
*(uint8_t*)&values[p] = x
|
233
|
234
|
#define WRITE16(p, x) CHECK_GT(func->numBytes, p+1);\
|
234
|
235
|
CHECK_EQ((p)&1, 0);\
|
|
236
|
+ TRACE_W(x, p, 16);\
|
235
|
237
|
*(uint16_t*)&values[p] = x
|
236
|
238
|
#define WRITE32(p, x) CHECK_GT(func->numBytes, p+3);\
|
237
|
239
|
CHECK_EQ((p)&3, 0);\
|
|
240
|
+ TRACE_W(x, p, 32);\
|
238
|
241
|
*(uint32_t*)&values[p] = x
|
239
|
242
|
#define WRITE64(p, x) CHECK_GT(func->numBytes, p+7);\
|
240
|
243
|
CHECK_EQ((p)&7, 0);\
|
241
|
|
- *(uint32_t*)&values[p] = x
|
|
244
|
+ TRACE_W(x, p, 64);\
|
|
245
|
+ *(uint64_t*)&values[p] = x
|
242
|
246
|
|
243
|
247
|
#define READ1(x, p) CHECK_GT(func->numBytes, p);\
|
244
|
|
- x = (*(uint8_t*)&values[p])&1
|
|
248
|
+ x = (*(uint8_t*)&values[p])&1;\
|
|
249
|
+ TRACE_R(x)
|
245
|
250
|
#define READ8(x, p) CHECK_GT(func->numBytes, p);\
|
246
|
|
- x = *(uint8_t*)&values[p]
|
|
251
|
+ x = *(uint8_t*)&values[p];\
|
|
252
|
+ TRACE_R(x)
|
247
|
253
|
#define READ16(x, p) CHECK_GT(func->numBytes, p+1);\
|
248
|
254
|
CHECK_EQ((p)&1, 0);\
|
249
|
|
- x = *(uint16_t*)&values[p]
|
|
255
|
+ x = *(uint16_t*)&values[p];\
|
|
256
|
+ TRACE_R(x)
|
250
|
257
|
#define READ32(x, p) CHECK_GT(func->numBytes, p+3);\
|
251
|
258
|
CHECK_EQ((p)&3, 0);\
|
252
|
|
- x = *(uint32_t*)&values[p]
|
|
259
|
+ x = *(uint32_t*)&values[p];\
|
|
260
|
+ TRACE_R(x)
|
253
|
261
|
#define READ64(x, p) CHECK_GT(func->numBytes, p+7);\
|
254
|
262
|
CHECK_EQ((p)&7, 0);\
|
255
|
|
- x = *(uint64_t*)&values[p]
|
|
263
|
+ x = *(uint64_t*)&values[p];\
|
|
264
|
+ TRACE_R(x)
|
256
|
265
|
|
257
|
266
|
#define READOLD8(x, p) CHECK_GT(func->numBytes, p);\
|
258
|
|
- x = *(uint8_t*)&old_values[p]
|
|
267
|
+ x = *(uint8_t*)&old_values[p];\
|
|
268
|
+ TRACE_R(x)
|
259
|
269
|
#define READOLD16(x, p) CHECK_GT(func->numBytes, p+1);\
|
260
|
270
|
CHECK_EQ((p)&1, 0);\
|
261
|
|
- x = *(uint16_t*)&old_values[p]
|
|
271
|
+ x = *(uint16_t*)&old_values[p];\
|
|
272
|
+ TRACE_R(x)
|
262
|
273
|
#define READOLD32(x, p) CHECK_GT(func->numBytes, p+3);\
|
263
|
274
|
CHECK_EQ((p)&3, 0);\
|
264
|
|
- x = *(uint32_t*)&old_values[p]
|
|
275
|
+ x = *(uint32_t*)&old_values[p];\
|
|
276
|
+ TRACE_R(x)
|
265
|
277
|
#define READOLD64(x, p) CHECK_GT(func->numBytes, p+7);\
|
266
|
278
|
CHECK_EQ((p)&7, 0);\
|
267
|
|
- x = *(uint64_t*)&old_values[p]
|
|
279
|
+ x = *(uint64_t*)&old_values[p];\
|
|
280
|
+ TRACE_R(x)
|
268
|
281
|
|
269
|
282
|
#define BINOP(i) inst->u.binop[i]
|
270
|
283
|
|
...
|
...
|
@@ -312,8 +331,8 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
|
312
|
312
|
case opc*5+4: {\
|
313
|
313
|
uint64_t op0, op1, res;\
|
314
|
314
|
int64_t sop0, sop1;\
|
315
|
|
- READ32(op0, BINOP(0));\
|
316
|
|
- READ32(op1, BINOP(1));\
|
|
315
|
+ READ64(op0, BINOP(0));\
|
|
316
|
+ READ64(op1, BINOP(1));\
|
317
|
317
|
sop0 = op0; sop1 = op1;\
|
318
|
318
|
OP;\
|
319
|
319
|
W4(inst->dest, res);\
|
...
|
...
|
@@ -406,7 +425,7 @@ static always_inline int check_sdivops(int64_t op0, int64_t op1)
|
406
|
406
|
int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst)
|
407
|
407
|
{
|
408
|
408
|
uint64_t tmp;
|
409
|
|
- unsigned i, j, stack_depth=0, bb_inst=0, stop=0 ;
|
|
409
|
+ unsigned i, j, stack_depth=0, bb_inst=0, stop=0, pc=0;
|
410
|
410
|
struct cli_bc_func *func2;
|
411
|
411
|
struct stack stack;
|
412
|
412
|
struct stack_entry *stack_entry = NULL;
|
...
|
...
|
@@ -416,6 +435,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
|
416
|
416
|
|
417
|
417
|
memset(&stack, 0, sizeof(stack));
|
418
|
418
|
do {
|
|
419
|
+ pc++;
|
419
|
420
|
switch (inst->interp_op) {
|
420
|
421
|
DEFINE_BINOP(OP_ADD, res = op0 + op1);
|
421
|
422
|
DEFINE_BINOP(OP_SUB, res = op0 - op1);
|
...
|
...
|
@@ -544,8 +564,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
|
544
|
544
|
stack_entry = allocate_stack(&stack, stack_entry, func2, func, inst->dest,
|
545
|
545
|
bb, bb_inst);
|
546
|
546
|
values = stack_entry->values;
|
547
|
|
-// cli_dbgmsg("Executing %d, -> %u (%u); %u\n", inst->u.ops.funcid,
|
548
|
|
-// inst->dest, inst->type, stack_depth);
|
|
547
|
+ TRACE_EXEC(inst->u.ops.funcid, inst->dest, inst->type, stack_depth);
|
549
|
548
|
if (stack_depth > 10000) {
|
550
|
549
|
cli_errmsg("bytecode: stack depth exceeded\n");
|
551
|
550
|
stop = CL_EBYTECODE;
|