コード例 #1
0
ファイル: match.c プロジェクト: 01org/hyperscan
/**
 * \brief Run the program for the given literal ID, with the interpreter
 * out of line.
 *
 * Assumes not in_anchored.
 */
static really_inline
hwlmcb_rv_t roseProcessMatch(const struct RoseEngine *t,
                             struct hs_scratch *scratch, u64a end,
                             size_t match_len, u32 id) {
    DEBUG_PRINTF("id=%u\n", id);
    const u32 *programs = getByOffset(t, t->litProgramOffset);
    assert(id < t->literalCount);
    const u64a som = 0;
    const u8 flags = 0;
    return roseRunProgram(t, scratch, programs[id], som, end, match_len, flags);
}
コード例 #2
0
ファイル: match.c プロジェクト: starius/hyperscan
int roseAnchoredCallback(u64a start, u64a end, u32 id, void *ctx) {
    struct hs_scratch *scratch = ctx;
    assert(scratch && scratch->magic == SCRATCH_MAGIC);
    struct RoseContext *tctxt = &scratch->tctxt;
    struct core_info *ci = &scratch->core_info;
    const struct RoseEngine *t = ci->rose;

    u64a real_end = ci->buf_offset + end; // index after last byte

    DEBUG_PRINTF("MATCH id=%u offsets=[???,%llu]\n", id, real_end);
    DEBUG_PRINTF("STATE groups=0x%016llx\n", tctxt->groups);

    if (can_stop_matching(scratch)) {
        DEBUG_PRINTF("received a match when we're already dead!\n");
        return MO_HALT_MATCHING;
    }

    const size_t match_len = 0;

    /* delayed literals need to be delivered before real literals; however
     * delayed literals only come from the floating table so if we are going
     * to deliver a literal here it must be too early for a delayed literal */

    /* no history checks from anchored region and we are before the flush
     * boundary */

    if (real_end <= t->floatingMinLiteralMatchOffset) {
        roseFlushLastByteHistory(t, scratch, real_end);
        tctxt->lastEndOffset = real_end;
    }

    const u32 *programs = getByOffset(t, t->litProgramOffset);
    assert(id < t->literalCount);
    const u8 flags = ROSE_PROG_FLAG_IN_ANCHORED;
    if (roseRunProgram(t, scratch, programs[id], start, real_end, match_len,
                       flags) == HWLM_TERMINATE_MATCHING) {
        assert(can_stop_matching(scratch));
        DEBUG_PRINTF("caller requested termination\n");
        return MO_HALT_MATCHING;
    }

    DEBUG_PRINTF("DONE groups=0x%016llx\n", tctxt->groups);

    if (real_end > t->floatingMinLiteralMatchOffset) {
        recordAnchoredLiteralMatch(t, scratch, id, real_end);
    }

    return MO_CONTINUE_MATCHING;
}
コード例 #3
0
ファイル: match.c プロジェクト: starius/hyperscan
/**
 * \brief Match callback adaptor used for matches from pure-literal cases.
 *
 * Literal match IDs in this path run limited Rose programs that do not use
 * Rose state (which is not initialised in the pure-literal path). They can
 * still, for example, check lookarounds or literal masks.
 */
hwlmcb_rv_t rosePureLiteralCallback(size_t start, size_t end, u32 id,
                                    void *context) {
    DEBUG_PRINTF("start=%zu, end=%zu, id=%u\n", start, end, id);
    struct hs_scratch *scratch = context;
    struct core_info *ci = &scratch->core_info;
    const u64a real_end = (u64a)end + ci->buf_offset + 1;
    const u64a som = 0;
    const size_t match_len = end - start + 1;
    const struct RoseEngine *rose = ci->rose;
    const u32 *programs = getByOffset(rose, rose->litProgramOffset);
    assert(id < rose->literalCount);
    const u8 flags = 0;
    return roseRunProgram(rose, scratch, programs[id], som, real_end, match_len,
                          flags);
}
コード例 #4
0
ファイル: match.c プロジェクト: 01org/hyperscan
int roseReportAdaptor(u64a start, u64a end, ReportID id, void *context) {
    struct hs_scratch *scratch = context;
    assert(scratch && scratch->magic == SCRATCH_MAGIC);

    DEBUG_PRINTF("id=%u matched at [%llu,%llu]\n", id, start, end);

    const struct RoseEngine *rose = scratch->core_info.rose;

    // Our match ID is the program offset.
    const u32 program = id;
    const size_t match_len = 0; // Unused in this path.
    const u8 flags = ROSE_PROG_FLAG_SKIP_MPV_CATCHUP;
    hwlmcb_rv_t rv =
        roseRunProgram(rose, scratch, program, start, end, match_len, flags);
    if (rv == HWLM_TERMINATE_MATCHING) {
        return MO_HALT_MATCHING;
    }

    return can_stop_matching(scratch) ? MO_HALT_MATCHING : MO_CONTINUE_MATCHING;
}
コード例 #5
0
ファイル: stream.c プロジェクト: 01org/hyperscan
void roseStreamEodExec(const struct RoseEngine *t, u64a offset,
                       struct hs_scratch *scratch) {
    assert(scratch);
    assert(t->requiresEodCheck);
    DEBUG_PRINTF("ci buf %p/%zu his %p/%zu\n", scratch->core_info.buf,
                 scratch->core_info.len, scratch->core_info.hbuf,
                 scratch->core_info.hlen);

    // We should not have been called if we've already been told to terminate
    // matching.
    assert(!told_to_stop_matching(scratch));

    if (t->maxBiAnchoredWidth != ROSE_BOUND_INF
        && offset > t->maxBiAnchoredWidth) {
        DEBUG_PRINTF("bailing, we are beyond max width\n");
        /* also some of the history/state may be stale */
        return;
    }

    if (!t->eodProgramOffset) {
        DEBUG_PRINTF("no eod program\n");
        return;
    }

    roseStreamInitEod(t, offset, scratch);

    DEBUG_PRINTF("running eod program at %u\n", t->eodProgramOffset);

    // There should be no pending delayed literals.
    assert(!scratch->tctxt.filledDelayedSlots);

    const u64a som = 0;
    const size_t match_len = 0;
    const u8 flags = ROSE_PROG_FLAG_SKIP_MPV_CATCHUP;

    // Note: we ignore the result, as this is the last thing to ever happen on
    // a scan.
    roseRunProgram(t, scratch, t->eodProgramOffset, som, offset, match_len,
                   flags);
}
コード例 #6
0
ファイル: match.c プロジェクト: 01org/hyperscan
hwlmcb_rv_t roseDelayRebuildCallback(size_t start, size_t end, u32 id,
                                     void *ctx) {
    struct hs_scratch *scratch = ctx;
    struct RoseContext *tctx = &scratch->tctxt;
    struct core_info *ci = &scratch->core_info;
    const struct RoseEngine *t = ci->rose;
    size_t rb_len = MIN(ci->hlen, t->delayRebuildLength);

    u64a real_end = ci->buf_offset - rb_len + end + 1; // index after last byte

#ifdef DEBUG
    DEBUG_PRINTF("REBUILD MATCH id=%u offsets=[%llu,%llu]: ", id,
                 start + ci->buf_offset - rb_len, real_end);
    printMatch(ci, start + ci->buf_offset - rb_len, real_end);
    printf("\n");
#endif

    DEBUG_PRINTF("STATE groups=0x%016llx\n", tctx->groups);

    const u32 *delayRebuildPrograms =
        getByOffset(t, t->litDelayRebuildProgramOffset);
    assert(id < t->literalCount);
    const u32 program = delayRebuildPrograms[id];

    if (program) {
        const u64a som = 0;
        const size_t match_len = end - start + 1;
        const u8 flags = 0;
        UNUSED hwlmcb_rv_t rv = roseRunProgram(t, scratch, program, som,
                                               real_end, match_len, flags);
        assert(rv != HWLM_TERMINATE_MATCHING);
    }

    /* we are just repopulating the delay queue, groups should be
     * already set from the original scan. */

    return tctx->groups;
}
コード例 #7
0
ファイル: match.c プロジェクト: 01org/hyperscan
/**
 * \brief Execute a boundary report program.
 *
 * Returns MO_HALT_MATCHING if the stream is exhausted or the user has
 * instructed us to halt, or MO_CONTINUE_MATCHING otherwise.
 */
int roseRunBoundaryProgram(const struct RoseEngine *rose, u32 program,
                           u64a stream_offset, struct hs_scratch *scratch) {
    DEBUG_PRINTF("running boundary program at offset %u\n", program);

    if (can_stop_matching(scratch)) {
        DEBUG_PRINTF("can stop matching\n");
        return MO_HALT_MATCHING;
    }

    if (rose->hasSom && scratch->deduper.current_report_offset == ~0ULL) {
        /* we cannot delay the initialization of the som deduper logs any longer
         * as we are reporting matches. This is done explicitly as we are
         * shortcutting the som handling in the vacuous repeats as we know they
         * all come from non-som patterns. */
        fatbit_clear(scratch->deduper.som_log[0]);
        fatbit_clear(scratch->deduper.som_log[1]);
        scratch->deduper.som_log_dirty = 0;
    }

    // Keep assertions in program report path happy. At offset zero, there can
    // have been no earlier reports. At EOD, all earlier reports should have
    // been handled and we will have been caught up to the stream offset by the
    // time we are running boundary report programs.
    scratch->tctxt.minMatchOffset = stream_offset;

    const u64a som = 0;
    const size_t match_len = 0;
    const u8 flags = 0;
    hwlmcb_rv_t rv = roseRunProgram(rose, scratch, program, som, stream_offset,
                                    match_len, flags);
    if (rv == HWLM_TERMINATE_MATCHING) {
        return MO_HALT_MATCHING;
    }

    return MO_CONTINUE_MATCHING;
}