int32_t cli_bcapi_read_number(struct cli_bc_ctx *ctx, uint32_t radix) { unsigned i; const char *p; int32_t result; if ((radix != 10 && radix != 16) || !ctx->fmap) return -1; cli_event_int(EV, BCEV_OFFSET, ctx->off); while ((p = fmap_need_off_once(ctx->fmap, ctx->off, BUF))) { for (i=0;i<BUF;i++) { if ((p[i] >= '0' && p[i] <= '9') || (radix == 16 && ((p[i] >= 'a' && p[i] <= 'f') || (p[i] >= 'A' && p[i] <= 'F')))) { char *endptr; p = fmap_need_ptr_once(ctx->fmap, p+i, 16); if (!p) return -1; result = strtoul(p, &endptr, radix); ctx->off += i + (endptr - p); return result; } } ctx->off += BUF; } return -1; }
int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) { off_t off; if (!ctx->fmap) { cli_dbgmsg("bcapi_seek: no fmap\n"); API_MISUSE(); return -1; } switch (whence) { case 0: off = pos; break; case 1: off = ctx->off + pos; break; case 2: off = ctx->file_size + pos; break; default: API_MISUSE(); cli_dbgmsg("bcapi_seek: invalid whence value\n"); return -1; } if (off < 0 || off > ctx->file_size) { cli_dbgmsg("bcapi_seek: out of file: %ld (max %d)\n", off, ctx->file_size); return -1; } cli_event_int(EV, BCEV_OFFSET, off); ctx->off = off; return off; }
int32_t cli_bcapi_file_find_limit(struct cli_bc_ctx *ctx , const uint8_t* data, uint32_t len, int32_t limit) { char buf[4096]; fmap_t *map = ctx->fmap; uint32_t off = ctx->off; int n; if (!map || len > sizeof(buf)/4 || len <= 0 || limit <= 0) { cli_dbgmsg("bcapi_file_find_limit preconditions not met\n"); API_MISUSE(); return -1; } cli_event_int(EV, BCEV_OFFSET, off); cli_event_fastdata(EV, BCEV_FIND, data, len); for (;;) { const char *p; int32_t readlen = sizeof(buf); if (off + readlen > limit) { readlen = limit - off; if (readlen < 0) return -1; } n = fmap_readn(map, buf, off, readlen); if ((unsigned)n < len || n < 0) return -1; p = cli_memmem(buf, n, data, len); if (p) return off + p - buf; off += n; } return -1; }
uint32_t cli_bcapi_debug_print_uint(struct cli_bc_ctx *ctx, uint32_t a) { cli_event_int(EV, BCEV_DBG_INT, a); if (!cli_debug_flag) return 0; return fprintf(stderr, "%d", a); }
int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t off) { unsigned char c; if (!ctx->fmap) { cli_dbgmsg("bcapi_file_byteat: no fmap\n"); return -1; } cli_event_int(EV, BCEV_OFFSET, off); if (fmap_readn(ctx->fmap, &c, off, 1) != 1) { cli_dbgmsg("bcapi_file_byteat: fmap_readn failed at %u\n", off); return -1; } return c; }
int32_t cli_bcapi_read(struct cli_bc_ctx* ctx, uint8_t *data, int32_t size) { int n; if (!ctx->fmap) { API_MISUSE(); return -1; } if (size < 0 || size > CLI_MAX_ALLOCATION) { cli_warnmsg("bytecode: negative read size: %d\n", size); API_MISUSE(); return -1; } n = fmap_readn(ctx->fmap, data, ctx->off, size); if (n <= 0) { cli_dbgmsg("bcapi_read: fmap_readn failed (requested %d)\n", size); cli_event_count(EV, BCEV_READ_ERR); return n; } cli_event_int(EV, BCEV_OFFSET, ctx->off); cli_event_fastdata(EV, BCEV_READ, data, size); //cli_event_data(EV, BCEV_READ, data, n); ctx->off += n; return n; }
void cli_event_count(cli_events_t *ctx, unsigned id) { cli_event_int(ctx, id, 1); }