939
static inline double myround(double a)
946
int32_t cli_bcapi_ilog2(struct cli_bc_ctx *ctx, uint32_t a, uint32_t b)
951
/* log(a/b) is -32..32, so 2^26*32=2^31 covers the entire range of int32 */
952
f = (1<<26)*log((double)a / b) / log(2);
953
return (int32_t)myround(f);
956
int32_t cli_bcapi_ipow(struct cli_bc_ctx *ctx, int32_t a, int32_t b, int32_t c)
960
return (int32_t)myround(c*pow(a,b));
963
uint32_t cli_bcapi_iexp(struct cli_bc_ctx *ctx, int32_t a, int32_t b, int32_t c)
968
f= c*exp((double)a/b);
969
return (uint32_t)myround(f);
972
int32_t cli_bcapi_isin(struct cli_bc_ctx *ctx, int32_t a, int32_t b, int32_t c)
977
f = c*sin((double)a/b);
978
return (int32_t)myround(f);
981
int32_t cli_bcapi_icos(struct cli_bc_ctx *ctx, int32_t a, int32_t b, int32_t c)
986
f = c*cos((double)a/b);
987
return (int32_t)myround(f);
990
int32_t cli_bcapi_memstr(struct cli_bc_ctx *ctx, const uint8_t* h, int32_t hs,
991
const uint8_t*n, int32_t ns)
994
if (!h || !n || hs < 0 || ns < 0)
996
s = (const uint8_t*) cli_memstr((const char*)h, hs, (const char*)n, ns);
1002
int32_t cli_bcapi_hex2ui(struct cli_bc_ctx *ctx, uint32_t ah, uint32_t bh)
1005
unsigned char in[2];
1009
if (cli_hex2str_to((const char*)in, &result, 2) == -1)
1014
int32_t cli_bcapi_atoi(struct cli_bc_ctx *ctx, const uint8_t* str, int32_t len)
1017
const uint8_t *end = str + len;
1018
while (isspace(*str) && str < end) str++;
1020
return -1;/* all spaces */
1021
if (*str == '+') str++;
1023
return -1;/* all spaces and +*/
1025
return -1;/* only positive numbers */
1028
while (isdigit(*str) && str < end) {
1029
number = number*10 + (*str - '0');
1034
uint32_t cli_bcapi_debug_print_str_start(struct cli_bc_ctx *ctx , const uint8_t* s, uint32_t len)
1038
cli_dbgmsg("bytecode debug: %.*s", len, s);
1042
uint32_t cli_bcapi_debug_print_str_nonl(struct cli_bc_ctx *ctx , const uint8_t* s, uint32_t len)
1046
if (!cli_debug_flag)
1048
return fwrite(s, 1, len, stderr);
1051
uint32_t cli_bcapi_entropy_buffer(struct cli_bc_ctx *ctx , uint8_t* s, int32_t len)
1053
uint32_t probTable[256];
1056
double log2 = log(2);
1060
memset(probTable, 0, sizeof(probTable));
1061
for (i=0;i<len;i++) {
1064
for (i=0;i<256;i++) {
1068
p = (double)probTable[i] / len;
1069
entropy += -p*log(p)/log2;
1072
return (uint32_t)entropy;
1075
int32_t cli_bcapi_map_new(struct cli_bc_ctx *ctx, int32_t keysize, int32_t valuesize)
1077
unsigned n = ctx->nmaps+1;
1081
s = cli_realloc(ctx->maps, sizeof(*ctx->maps)*n);
1087
cli_map_init(s, keysize, valuesize, 16);
1091
static struct cli_map *get_hashtab(struct cli_bc_ctx *ctx, int32_t id)
1093
if (id < 0 || id >= ctx->nmaps || !ctx->maps)
1095
return &ctx->maps[id];
1098
int32_t cli_bcapi_map_addkey(struct cli_bc_ctx *ctx , const uint8_t* key, int32_t keysize, int32_t id)
1100
struct cli_map *s = get_hashtab(ctx, id);
1103
return cli_map_addkey(s, key, keysize);
1106
int32_t cli_bcapi_map_setvalue(struct cli_bc_ctx *ctx, const uint8_t* value, int32_t valuesize, int32_t id)
1108
struct cli_map *s = get_hashtab(ctx, id);
1111
return cli_map_setvalue(s, value, valuesize);
1114
int32_t cli_bcapi_map_remove(struct cli_bc_ctx *ctx , const uint8_t* key, int32_t keysize, int32_t id)
1116
struct cli_map *s = get_hashtab(ctx, id);
1119
return cli_map_removekey(s, key, keysize);
1122
int32_t cli_bcapi_map_find(struct cli_bc_ctx *ctx , const uint8_t* key, int32_t keysize, int32_t id)
1124
struct cli_map *s = get_hashtab(ctx, id);
1127
return cli_map_find(s, key, keysize);
1130
int32_t cli_bcapi_map_getvaluesize(struct cli_bc_ctx *ctx, int32_t id)
1132
struct cli_map *s = get_hashtab(ctx, id);
1135
return cli_map_getvalue_size(s);
1138
uint8_t* cli_bcapi_map_getvalue(struct cli_bc_ctx *ctx , int32_t id, int32_t valuesize)
1140
struct cli_map *s = get_hashtab(ctx, id);
1143
if (cli_map_getvalue_size(s) != valuesize)
1145
return cli_map_getvalue(s);
1148
int32_t cli_bcapi_map_done(struct cli_bc_ctx *ctx , int32_t id)
1150
struct cli_map *s = get_hashtab(ctx, id);
1154
if (id == ctx->nmaps-1) {
1160
s = cli_realloc(ctx->maps, ctx->nmaps*(sizeof(*s)));
1168
uint32_t cli_bcapi_engine_functionality_level(struct cli_bc_ctx *ctx)
1170
return cl_retflevel();
1173
uint32_t cli_bcapi_engine_dconf_level(struct cli_bc_ctx *ctx)
1175
return CL_FLEVEL_DCONF;
1178
uint32_t cli_bcapi_engine_scan_options(struct cli_bc_ctx *ctx)
1180
cli_ctx *cctx = (cli_ctx*)ctx->ctx;
1181
return cctx->options;
1184
uint32_t cli_bcapi_engine_db_options(struct cli_bc_ctx *ctx)
1186
cli_ctx *cctx = (cli_ctx*)ctx->ctx;
1187
return cctx->engine->dboptions;
1190
int32_t cli_bcapi_extract_set_container(struct cli_bc_ctx *ctx, uint32_t ftype)
1192
if (ftype > CL_TYPE_IGNORED)
1194
ctx->containertype = ftype;
1198
int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx , int32_t extracted_file)
1201
if (ctx->extracted_file_input == extracted_file)
1203
if (!extracted_file) {
1204
cli_dbgmsg("bytecode api: input switched back to main file\n");
1205
ctx->fmap = ctx->save_map;
1206
ctx->extracted_file_input = 0;
1211
map = fmap(ctx->outfd, 0, 0);
1213
cli_warnmsg("can't mmap() extracted temporary file %s\n", ctx->tempfile);
1216
ctx->save_map = ctx->fmap;
1217
cli_bytecode_context_setfile(ctx, map);
1218
ctx->extracted_file_input = 1;
1219
cli_dbgmsg("bytecode api: input switched to extracted file\n");
1223
uint32_t cli_bcapi_get_environment(struct cli_bc_ctx *ctx , struct cli_environment* env, uint32_t len)
1225
if (len > sizeof(*env)) {
1226
cli_dbgmsg("cli_bcapi_get_environment len %u > %lu\n", len, sizeof(*env));
1229
memcpy(env, ctx->env, len);
1233
uint32_t cli_bcapi_disable_bytecode_if(struct cli_bc_ctx *ctx , const int8_t* reason, uint32_t len, uint32_t cond)
1235
if (ctx->bc->kind != BC_STARTUP) {
1236
cli_dbgmsg("Bytecode must be BC_STARTUP to call disable_bytecode_if\n");
1240
return ctx->bytecode_disable_status;
1242
cli_warnmsg("Bytecode: disabling completely because %s\n", reason+1);
1244
cli_dbgmsg("Bytecode: disabling completely because %s\n", reason);
1245
ctx->bytecode_disable_status = 2;
1246
return ctx->bytecode_disable_status;
1249
uint32_t cli_bcapi_disable_jit_if(struct cli_bc_ctx *ctx , const int8_t* reason, uint32_t len, uint32_t cond)
1251
if (ctx->bc->kind != BC_STARTUP) {
1252
cli_dbgmsg("Bytecode must be BC_STARTUP to call disable_jit_if\n");
1256
return ctx->bytecode_disable_status;
1258
cli_warnmsg("Bytecode: disabling JIT because %s\n", reason+1);
1260
cli_dbgmsg("Bytecode: disabling JIT because %s\n", reason);
1261
if (ctx->bytecode_disable_status != 2) /* no reenabling */
1262
ctx->bytecode_disable_status = 1;
1263
return ctx->bytecode_disable_status;
1266
int32_t cli_bcapi_version_compare(struct cli_bc_ctx *ctx , const uint8_t* lhs, uint32_t lhs_len,
1267
const uint8_t* rhs, uint32_t rhs_len)
1269
unsigned i = 0, j = 0;
1270
unsigned long li=0, ri=0;
1272
while (i < lhs_len && j < rhs_len && lhs[i] == rhs[j] &&
1273
!isdigit(lhs[i]) && !isdigit(rhs[j])) {
1276
if (i == lhs_len && j == rhs_len)
1282
if (!isdigit(lhs[i]) || !isdigit(rhs[j]))
1283
return lhs[i] < rhs[j] ? -1 : 1;
1284
while (isdigit(lhs[i]) && i < lhs_len)
1285
li = 10*li + (lhs[i] - '0');
1286
while (isdigit(rhs[j]) && j < rhs_len)
1287
ri = 10*ri + (rhs[j] - '0');
1295
static int check_bits(uint32_t query, uint32_t value, uint8_t shift, uint8_t mask)
1297
uint8_t q = (query >> shift)&mask;
1298
uint8_t v = (value >> shift)&mask;
1299
/* q == mask -> ANY */
1300
if (q == v || q == mask)
1305
uint32_t cli_bcapi_check_platform(struct cli_bc_ctx *ctx , uint32_t a, uint32_t b , uint32_t c)
1308
check_bits(a, ctx->env->platform_id_a, 24, 0xff) &&
1309
check_bits(a, ctx->env->platform_id_a, 20, 0xf) &&
1310
check_bits(a, ctx->env->platform_id_a, 16, 0xf) &&
1311
check_bits(a, ctx->env->platform_id_a, 8, 0xff) &&
1312
check_bits(a, ctx->env->platform_id_a, 0, 0xff) &&
1313
check_bits(b, ctx->env->platform_id_b, 28, 0xf) &&
1314
check_bits(b, ctx->env->platform_id_b, 24, 0xf) &&
1315
check_bits(b, ctx->env->platform_id_b, 16, 0xff) &&
1316
check_bits(b, ctx->env->platform_id_b, 8, 0xff) &&
1317
check_bits(b, ctx->env->platform_id_b, 0, 0xff) &&
1318
check_bits(c, ctx->env->platform_id_c, 24, 0xff) &&
1319
check_bits(c, ctx->env->platform_id_c, 16, 0xff) &&
1320
check_bits(c, ctx->env->platform_id_c, 8, 0xff) &&
1321
check_bits(c, ctx->env->platform_id_c, 0, 0xff);
1323
cli_dbgmsg("check_platform(0x%08x,0x%08x,0x%08x) = match\n",a,b,c);
1328
int cli_bytecode_context_setpdf(struct cli_bc_ctx *ctx, unsigned phase,
1330
struct pdf_obj *objs, uint32_t *pdf_flags,
1331
uint32_t pdfsize, uint32_t pdfstartoff)
1333
ctx->pdf_nobjs = nobjs;
1334
ctx->pdf_objs = objs;
1335
ctx->pdf_flags = pdf_flags;
1336
ctx->pdf_size = pdfsize;
1337
ctx->pdf_startoff = pdfstartoff;
1338
ctx->pdf_phase = phase;
1342
int32_t cli_bcapi_pdf_get_obj_num(struct cli_bc_ctx *ctx)
1344
if (!ctx->pdf_phase)
1346
return ctx->pdf_nobjs;
1349
int32_t cli_bcapi_pdf_get_flags(struct cli_bc_ctx *ctx)
1351
if (!ctx->pdf_phase)
1353
return *ctx->pdf_flags;
1356
int32_t cli_bcapi_pdf_set_flags(struct cli_bc_ctx *ctx , int32_t flags)
1358
if (!ctx->pdf_phase)
1360
cli_dbgmsg("cli_pdf: bytecode set_flags %08x -> %08x\n",
1363
*ctx->pdf_flags = flags;
1367
int32_t cli_bcapi_pdf_lookupobj(struct cli_bc_ctx *ctx , uint32_t objid)
1370
if (!ctx->pdf_phase)
1372
for (i=0;i<ctx->pdf_nobjs;i++) {
1373
if (ctx->pdf_objs[i].id == objid)
1379
uint32_t cli_bcapi_pdf_getobjsize(struct cli_bc_ctx *ctx , int32_t objidx)
1381
if (!ctx->pdf_phase ||
1382
objidx >= ctx->pdf_nobjs ||
1383
ctx->pdf_phase == PDF_PHASE_POSTDUMP /* map is obj itself, no access to pdf anymore */
1386
if (objidx + 1 == ctx->pdf_nobjs)
1387
return ctx->pdf_size - ctx->pdf_objs[objidx].start;
1388
return ctx->pdf_objs[objidx+1].start - ctx->pdf_objs[objidx].start - 4;
1391
uint8_t* cli_bcapi_pdf_getobj(struct cli_bc_ctx *ctx , int32_t objidx, uint32_t amount)
1393
uint32_t size = cli_bcapi_pdf_getobjsize(ctx, objidx);
1396
return fmap_need_off(ctx->fmap, ctx->pdf_objs[objidx].start, amount);
1399
int32_t cli_bcapi_pdf_getobjid(struct cli_bc_ctx *ctx , int32_t objidx)
1401
if (!ctx->pdf_phase ||
1402
objidx >= ctx->pdf_nobjs)
1404
return ctx->pdf_objs[objidx].id;
1407
int32_t cli_bcapi_pdf_getobjflags(struct cli_bc_ctx *ctx , int32_t objidx)
1409
if (!ctx->pdf_phase ||
1410
objidx >= ctx->pdf_nobjs)
1412
return ctx->pdf_objs[objidx].flags;
1415
int32_t cli_bcapi_pdf_setobjflags(struct cli_bc_ctx *ctx , int32_t objidx, int32_t flags)
1417
if (!ctx->pdf_phase ||
1418
objidx >= ctx->pdf_nobjs)
1420
cli_dbgmsg("cli_pdf: bytecode setobjflags %08x -> %08x\n",
1421
ctx->pdf_objs[objidx].flags,
1423
ctx->pdf_objs[objidx].flags = flags;
1427
int32_t cli_bcapi_pdf_get_offset(struct cli_bc_ctx *ctx , int32_t objidx)
1429
if (!ctx->pdf_phase ||
1430
objidx >= ctx->pdf_nobjs)
1432
return ctx->pdf_startoff + ctx->pdf_objs[objidx].start;
1435
int32_t cli_bcapi_pdf_get_phase(struct cli_bc_ctx *ctx)
1437
return ctx->pdf_phase;
1440
int32_t cli_bcapi_pdf_get_dumpedobjid(struct cli_bc_ctx *ctx)
1442
if (ctx->pdf_phase != PDF_PHASE_POSTDUMP)
1444
return ctx->pdf_dumpedid;