... | ... |
@@ -59,9 +59,18 @@ uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx, uint32_t a) |
59 | 59 |
|
60 | 60 |
int32_t cli_bcapi_read(struct cli_bc_ctx* ctx, uint8_t *data, int32_t size) |
61 | 61 |
{ |
62 |
+ int n; |
|
62 | 63 |
if (!ctx->fmap) |
63 | 64 |
return -1; |
64 |
- return fmap_readn(ctx->fmap, data, ctx->off, size); |
|
65 |
+ if (size < 0) { |
|
66 |
+ cli_errmsg("bytecode: negative read size: %d\n", size); |
|
67 |
+ return -1; |
|
68 |
+ } |
|
69 |
+ n = fmap_readn(ctx->fmap, data, ctx->off, size); |
|
70 |
+ if (n <= 0) |
|
71 |
+ return n; |
|
72 |
+ ctx->off += n; |
|
73 |
+ return n; |
|
65 | 74 |
} |
66 | 75 |
|
67 | 76 |
int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) |
... | ... |
@@ -81,7 +81,7 @@ uint32_t test1(uint32_t, uint32_t); |
81 | 81 |
|
82 | 82 |
/** |
83 | 83 |
* @brief Reads specified amount of bytes from the current file |
84 |
- * into a buffer. |
|
84 |
+ * into a buffer. Also moves current position in the file. |
|
85 | 85 |
* |
86 | 86 |
* @param[in] size amount of bytes to read |
87 | 87 |
* @param[out] data pointer to buffer where data is read into |
... | ... |
@@ -182,6 +182,9 @@ static void* noUnknownFunctions(const std::string& name) { |
182 | 182 |
.Case("__ashrdi3", (void*)(intptr_t)rtlib_sra_i64) |
183 | 183 |
.Case("__ashldi3", (void*)(intptr_t)rtlib_shl_i64) |
184 | 184 |
.Case("__lshrdi3", (void*)(intptr_t)rtlib_srl_i64) |
185 |
+ .Case("memmove", (void*)(intptr_t)memmove) |
|
186 |
+ .Case("memcpy", (void*)(intptr_t)memcpy) |
|
187 |
+ .Case("memset", (void*)(intptr_t)memset) |
|
185 | 188 |
.Default(0); |
186 | 189 |
if (addr) |
187 | 190 |
return addr; |
... | ... |
@@ -1132,7 +1135,17 @@ public: |
1132 | 1132 |
Store(inst->dest, C); |
1133 | 1133 |
break; |
1134 | 1134 |
} |
1135 |
- |
|
1135 |
+ case OP_BC_PTRDIFF32: |
|
1136 |
+ { |
|
1137 |
+ Value *P1 = convertOperand(func, inst, inst->u.binop[0]); |
|
1138 |
+ Value *P2 = convertOperand(func, inst, inst->u.binop[1]); |
|
1139 |
+ P1 = Builder.CreatePtrToInt(P1, Type::getInt64Ty(Context)); |
|
1140 |
+ P2 = Builder.CreatePtrToInt(P2, Type::getInt64Ty(Context)); |
|
1141 |
+ Value *R = Builder.CreateSub(P1, P2); |
|
1142 |
+ R = Builder.CreateTrunc(R, Type::getInt32Ty(Context)); |
|
1143 |
+ Store(inst->dest, R); |
|
1144 |
+ break; |
|
1145 |
+ } |
|
1136 | 1146 |
default: |
1137 | 1147 |
errs() << MODULE << "JIT doesn't implement opcode " << |
1138 | 1148 |
inst->opcode << " yet!\n"; |
... | ... |
@@ -83,6 +83,7 @@ enum bc_opcode { |
83 | 83 |
OP_BC_BSWAP16, |
84 | 84 |
OP_BC_BSWAP32, |
85 | 85 |
OP_BC_BSWAP64, |
86 |
+ OP_BC_PTRDIFF32, |
|
86 | 87 |
OP_BC_INVALID /* last */ |
87 | 88 |
}; |
88 | 89 |
|
... | ... |
@@ -108,8 +109,8 @@ static const unsigned char operand_counts[] = { |
108 | 108 |
3, 3, 3, 3, |
109 | 109 |
/* OP_BC_ISBIGENDIAN */ |
110 | 110 |
0, |
111 |
- /* OP_BC_ABORT, OP_BSWAP* */ |
|
112 |
- 0, 1, 1, 1 |
|
111 |
+ /* OP_BC_ABORT, OP_BSWAP*, OP_PTRDIFF32 */ |
|
112 |
+ 0, 1, 1, 1, 2 |
|
113 | 113 |
}; |
114 | 114 |
|
115 | 115 |
enum bc_global { |