struct atom *new_exprs(struct expr *arg) { struct atom *atom; atom = chunkpool_malloc(s->atom_pool); atom->type = ATOM_TYPE_EXPRS; atom->u.exprs = chunkpool_malloc(s->vec_pool); vec_init(atom->u.exprs, sizeof(struct expr*)); exprs_add(atom, arg); return atom; }
matchp match_new(match_ctx ctx, /* IN/OUT */ matchp *mpp, int len, int offset) { matchp m = chunkpool_malloc(ctx->m_pool); if(len == 0) { int a; LOG(LOG_ERROR, ("tried to allocate len0 match.\n")); a = *(int*)0; } if(len > 65535) { len = 65535; } m->len = len; m->offset = offset; /* insert new node in list */ m->next = *mpp; *mpp = m; return m; }
struct atom *new_incbin(const char *name, struct expr *skip, struct expr *len) { struct atom *atom; long length; i32 len32; i32 skip32; struct membuf *in; /* find out how long the file is */ in = get_named_buffer(s->named_buffer, name); length = membuf_memlen(in); skip32 = 0; if(skip != NULL) { skip32 = resolve_expr(skip); } if(skip32 < 0) { skip32 += length; } if(skip32 < 0 || skip32 > length) { LOG(LOG_ERROR, ("Can't read from offset %d in file \"%s\".\n", skip32, name)); exit(-1); } length -= skip32; len32 = 0; if(len != NULL) { len32 = resolve_expr(len); } if(len32 < 0) { len32 += length; } if(len32 < 0 || len32 > length) { LOG(LOG_ERROR, ("Can't read %d bytes from offset %d from file \"%s\".\n", len32, skip32, name)); exit(-1); } atom = chunkpool_malloc(s->atom_pool); atom->type = ATOM_TYPE_BUFFER; atom->u.buffer.name = name; atom->u.buffer.length = len32; atom->u.buffer.skip = skip32; if(len != NULL) { pc_add(len32); } return atom; }
struct atom *new_res(struct expr *len, struct expr *value) { struct atom *atom; atom = chunkpool_malloc(s->atom_pool); atom->type = ATOM_TYPE_RES; atom->u.res.length = len; atom->u.res.value = value; pc_add_expr(len); return atom; }
struct expr *new_expr_symref(const char *symbol) { struct expr *val; val = chunkpool_malloc(s_expr_pool); val->expr_op = SYMBOL; val->type.symref = symbol; expr_dump(LOG_DEBUG, val); return val; }
struct expr *new_expr_number(i32 number) { struct expr *val; LOG(LOG_DEBUG, ("creating new number %d\n", number)); val = chunkpool_malloc(s_expr_pool); val->expr_op = NUMBER; val->type.number = number; expr_dump(LOG_DEBUG, val); return val; }
matchp match_new(match_ctx ctx, /* IN/OUT */ matchp *mpp, unsigned short int len, unsigned short int offset) { matchp m = chunkpool_malloc(ctx->m_pool); m->len = len; m->offset = offset; /* insert new node in list */ m->next = *mpp; *mpp = m; return m; }
struct expr *new_expr_op1(i16 op, struct expr *arg) { struct expr *val; if(op != vNEG && op != LNOT) { /* error, invalid unary operator */ LOG(LOG_ERROR, ("%d not allowed as unary operator\n", op)); exit(1); } val = chunkpool_malloc(s_expr_pool); val->expr_op = op; val->type.arg1 = arg; expr_dump(LOG_DEBUG, val); return val; }
struct atom *new_op(u8 op_code, u8 atom_op_type, struct expr *op_arg) { struct atom *atom; atom = chunkpool_malloc(s->atom_pool); atom->type = atom_op_type; atom->u.op.code = op_code; atom->u.op.arg = op_arg; switch(atom_op_type) { case ATOM_TYPE_OP_ARG_NONE: pc_add(1); break; case ATOM_TYPE_OP_ARG_U8: pc_add(2); break; case ATOM_TYPE_OP_ARG_U16: pc_add(3); break; case ATOM_TYPE_OP_ARG_I8: pc_add(2); atom->u.op.arg = new_expr_op2(MINUS, atom->u.op.arg, pc_get()); break; case ATOM_TYPE_OP_ARG_UI8: pc_add(2); break; default: LOG(LOG_ERROR, ("invalid op arg range %d\n", atom_op_type)); exit(1); } pc_dump(LOG_DEBUG); return atom; }
struct expr *new_expr_op2(i16 op, struct expr *arg1, struct expr *arg2) { struct expr *val; if(op == vNEG || op == LNOT || op == NUMBER || op == SYMBOL) { /* error, invalid binary operator */ printf("op %d, vNEG %d, NUMBER %d, SYMBOL %d\n", op, vNEG, NUMBER, SYMBOL); LOG(LOG_ERROR, ("%d not allowed as binary operator\n", op)); exit(1); } val = chunkpool_malloc(s_expr_pool); val->expr_op = op; val->type.arg1 = arg1; val->expr_arg2 = arg2; expr_dump(LOG_DEBUG, val); return val; }
void match_ctx_init(match_ctx ctx, /* IN/OUT */ struct membuf *inbuf, /* IN */ int max_offset) { struct match_node *np; struct progress prog[1]; int buf_len = membuf_memlen(inbuf); const unsigned char *buf = membuf_get(inbuf); int c, i; int val; ctx->info = calloc(buf_len + 1, sizeof(*ctx->info)); ctx->rle = calloc(buf_len + 1, sizeof(*ctx->rle)); ctx->rle_r = calloc(buf_len + 1, sizeof(*ctx->rle_r)); chunkpool_init(ctx->m_pool, sizeof(match)); ctx->max_offset = max_offset; ctx->buf = buf; ctx->len = buf_len; val = buf[0]; for (i = 1; i < buf_len; ++i) { if (buf[i] == val) { int len = ctx->rle[i - 1] + 1; if(len > 65535) { len = 0; } ctx->rle[i] = len; } else { ctx->rle[i] = 0; } val = buf[i]; } for (i = buf_len - 2; i >= 0; --i) { if (ctx->rle[i] < ctx->rle[i + 1]) { ctx->rle_r[i] = ctx->rle_r[i + 1] + 1; } else { ctx->rle_r[i] = 0; } } /* add extra nodes to rle sequences */ for(c = 0; c < 256; ++c) { static char rle_map[65536]; struct match_node *prev_np; unsigned short int rle_len; /* for each possible rle char */ memset(rle_map, 0, sizeof(rle_map)); prev_np = NULL; for (i = 0; i < buf_len; ++i) { /* must be the correct char */ if(buf[i] != c) { continue; } rle_len = ctx->rle[i]; if(!rle_map[rle_len] && ctx->rle_r[i] > 16) { /* no previous lengths and not our primary length*/ continue; } np = chunkpool_malloc(ctx->m_pool); np->index = i; np->next = NULL; rle_map[rle_len] = 1; LOG(LOG_DUMP, ("0) c = %d, added np idx %d -> %d\n", c, i, 0)); /* if we have a previous entry, let's chain it together */ if(prev_np != NULL) { LOG(LOG_DUMP, ("1) c = %d, pointed np idx %d -> %d\n", c, prev_np->index, i)); prev_np->next = np; } ctx->info[i]->single = np; prev_np = np; } memset(rle_map, 0, sizeof(rle_map)); prev_np = NULL; for (i = buf_len - 1; i >= 0; --i) { /* must be the correct char */ if(buf[i] != c) { continue; } rle_len = ctx->rle_r[i]; np = ctx->info[i]->single; if(np == NULL) { if(rle_map[rle_len] && prev_np != NULL && rle_len > 0) { np = chunkpool_malloc(ctx->m_pool); np->index = i; np->next = prev_np; ctx->info[i]->single = np; LOG(LOG_DEBUG, ("2) c = %d, added np idx %d -> %d\n", c, i, prev_np->index)); } } else { prev_np = np; } if(ctx->rle_r[i] > 0) { continue; } rle_len = ctx->rle[i] + 1; rle_map[rle_len] = 1; } } progress_init(prog, "building.directed.acyclic.graph.", buf_len - 1, 0); for (i = buf_len - 1; i >= 0; --i) { const_matchp matches; /* let's populate the cache */ matches = matches_calc(ctx, i); /* add to cache */ ctx->info[i]->cache = matches; progress_bump(prog, i); } LOG(LOG_NORMAL, ("\n")); progress_free(prog); }
void match_ctx_init(match_ctx ctx, /* IN/OUT */ const unsigned char *buf, /* IN */ int buf_len, /* IN */ int max_offset) { struct match_node *np; struct chunkpool map_pool[1]; int c, i; int val; memset(ctx->info, 0, sizeof(ctx->info)); memset(ctx->rle, 0, sizeof(ctx->rle)); memset(ctx->rle_r, 0, sizeof(ctx->rle_r)); chunkpool_init(ctx->m_pool, sizeof(match)); chunkpool_init(map_pool, sizeof(match)); ctx->max_offset = max_offset; ctx->buf = buf; ctx->len = buf_len; val = buf[0]; for (i = 1; i < buf_len; ++i) { if (buf[i] == val) { ctx->rle[i] = ctx->rle[i - 1] + 1; } else { ctx->rle[i] = 0; } val = buf[i]; } val = buf[buf_len - 1]; for (i = buf_len - 2; i >= 0; --i) { if (buf[i] == val) { ctx->rle_r[i] = ctx->rle_r[i + 1] + 1; } else { ctx->rle_r[i] = 0; } val = buf[i]; } /* add extra nodes to rle sequences */ for(c = 0; c < 256; ++c) { static char rle_map[65536]; struct match_node *prev_np; int rle_len; /* for each possible rle char */ memset(rle_map, 0, sizeof(rle_map)); prev_np = NULL; for (i = 0; i < buf_len; ++i) { /* must be the correct char */ if(buf[i] != c) { continue; } rle_len = ctx->rle[i]; if(!rle_map[rle_len] && ctx->rle_r[i] > 16) { /* no previous lengths and not our primary length*/ continue; } np = chunkpool_malloc(ctx->m_pool); np->index = i; np->next = NULL; rle_map[rle_len] = 1; LOG(LOG_DEBUG, ("0) c = %d, added np idx %d -> %d\n", c, i, 0)); /* if we have a previous entry, let's chain it together */ if(prev_np != NULL) { LOG(LOG_DEBUG, ("1) c = %d, pointed np idx %d -> %d\n", c, prev_np->index, i)); prev_np->next = np; } ctx->info[i]->single = np; prev_np = np; } memset(rle_map, 0, sizeof(rle_map)); prev_np = NULL; for (i = buf_len - 1; i >= 0; --i) { /* must be the correct char */ if(buf[i] != c) { continue; } rle_len = ctx->rle_r[i]; np = ctx->info[i]->single; if(np == NULL) { if(rle_map[rle_len] && prev_np != NULL && rle_len > 0) { np = chunkpool_malloc(ctx->m_pool); np->index = i; np->next = prev_np; ctx->info[i]->single = np; LOG(LOG_DEBUG, ("2) c = %d, added np idx %d -> %d\n", c, i, prev_np->index)); } } else { prev_np = np; } if(ctx->rle_r[i] > 0) { continue; } rle_len = ctx->rle[i] + 1; rle_map[rle_len] = 1; } } for (i = buf_len - 1; i >= 0; --i) { const_matchp matches; /* let's populate the cache */ matches = matches_calc(ctx, (unsigned short) i); /* add to cache */ ctx->info[i]->cache = matches; if (!(i & 0xFF)) { LOG(LOG_NORMAL, (".")); } } LOG(LOG_NORMAL, ("\n")); chunkpool_free(map_pool); }