#include "fdr_internal.h"
#include "fdr_loadval.h"
#include "flood_runtime.h"
+#include "scratch.h"
#include "teddy.h"
#include "teddy_internal.h"
#include "util/arch.h"
static const u8 fake_history[FAKE_HISTORY_SIZE];
hwlm_error_t fdrExec(const struct FDR *fdr, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt,
- hwlm_group_t groups) {
+ size_t start, HWLMCallback cb,
+ struct hs_scratch *scratch, hwlm_group_t groups) {
// We guarantee (for safezone construction) that it is safe to read 16
// bytes before the end of the history buffer.
const u8 *hbuf = fake_history + FAKE_HISTORY_SIZE;
0,
start,
cb,
- ctxt,
+ scratch,
nextFloodDetect(buf, len, FLOOD_BACKOFF_START),
0
};
hwlm_error_t fdrExecStreaming(const struct FDR *fdr, const u8 *hbuf,
size_t hlen, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt,
+ size_t start, HWLMCallback cb,
+ struct hs_scratch *scratch,
hwlm_group_t groups) {
struct FDR_Runtime_Args a = {
buf,
hlen,
start,
cb,
- ctxt,
+ scratch,
nextFloodDetect(buf, len, FLOOD_BACKOFF_START),
/* we are guaranteed to always have 16 initialised bytes at the end of
* the history buffer (they may be garbage). */
/*
- * Copyright (c) 2015-2016, Intel Corporation
+ * Copyright (c) 2015-2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#endif
struct FDR;
+struct hs_scratch;
/**
* \brief Block-mode scan.
* \param len Length of buffer to scan.
* \param start First offset in buf at which a match may end.
* \param cb Callback to call when a match is found.
- * \param ctxt Caller-provided context pointer supplied to callback on match.
+ * \param scratch Scratch supplied to callback on match.
* \param groups Initial groups mask.
*/
hwlm_error_t fdrExec(const struct FDR *fdr, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt,
+ size_t start, HWLMCallback cb, struct hs_scratch *scratch,
hwlm_group_t groups);
/**
* \param len Length of buffer to scan (buf).
* \param start First offset in buf at which a match may end.
* \param cb Callback to call when a match is found.
- * \param ctxt Caller-provided context pointer supplied to callback on match.
+ * \param scratch Scratch supplied to callback on match.
* \param groups Initial groups mask.
*/
hwlm_error_t fdrExecStreaming(const struct FDR *fdr, const u8 *hbuf,
size_t hlen, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt,
+ size_t start, HWLMCallback cb,
+ struct hs_scratch *scratch,
hwlm_group_t groups);
#ifdef __cplusplus
}
*last_match = li->id;
- *control = a->cb(i, li->id, a->ctxt);
+ *control = a->cb(i, li->id, a->scratch);
out:
oldNext = li->next; // oldNext is either 0 or an 'adjust' value
li++;
#include "ue2common.h"
#include "hwlm/hwlm.h" // for hwlm_group_t, HWLMCallback
+struct hs_scratch;
+
typedef enum {
NOT_CAUTIOUS, //!< not near a boundary (quantify?)
VECTORING //!< potentially vectoring
size_t len_history;
size_t start_offset;
HWLMCallback cb;
- void *ctxt;
+ struct hs_scratch *scratch;
const u8 *firstFloodDetect;
const u64a histBytes;
};
const u8 * buf = a->buf;
const size_t len = a->len;
HWLMCallback cb = a->cb;
- void * ctxt = a->ctxt;
+ struct hs_scratch *scratch = a->scratch;
const u8 * ptr = *ptrPtr;
// tryFloodDetect is never put in places where unconditional
t += 4) {
DEBUG_PRINTF("aaa %u %llx\n", t, fl->groups[0]);
if (*control & fl->groups[0]) {
- *control = cb(i + t + 0, fl->ids[0], ctxt);
+ *control = cb(i + t + 0, fl->ids[0], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 1, fl->ids[0], ctxt);
+ *control = cb(i + t + 1, fl->ids[0], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 2, fl->ids[0], ctxt);
+ *control = cb(i + t + 2, fl->ids[0], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 3, fl->ids[0], ctxt);
+ *control = cb(i + t + 3, fl->ids[0], scratch);
}
}
break;
case 2:
for (u32 t = 0; t < floodSize && (*control & fl->allGroups); t += 4) {
if (*control & fl->groups[0]) {
- *control = cb(i + t, fl->ids[0], ctxt);
+ *control = cb(i + t, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t, fl->ids[1], ctxt);
+ *control = cb(i + t, fl->ids[1], scratch);
}
if (*control & fl->groups[0]) {
*control =
- cb(i + t + 1, fl->ids[0], ctxt);
+ cb(i + t + 1, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t + 1, fl->ids[1], ctxt);
+ *control = cb(i + t + 1, fl->ids[1], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 2, fl->ids[0], ctxt);
+ *control = cb(i + t + 2, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t + 2, fl->ids[1], ctxt);
+ *control = cb(i + t + 2, fl->ids[1], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 3, fl->ids[0], ctxt);
+ *control = cb(i + t + 3, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t + 3, fl->ids[1], ctxt);
+ *control = cb(i + t + 3, fl->ids[1], scratch);
}
}
break;
case 3:
for (u32 t = 0; t < floodSize && (*control & fl->allGroups); t += 2) {
if (*control & fl->groups[0]) {
- *control = cb(i + t, fl->ids[0], ctxt);
+ *control = cb(i + t, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t, fl->ids[1], ctxt);
+ *control = cb(i + t, fl->ids[1], scratch);
}
if (*control & fl->groups[2]) {
- *control = cb(i + t, fl->ids[2], ctxt);
+ *control = cb(i + t, fl->ids[2], scratch);
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 1, fl->ids[0], ctxt);
+ *control = cb(i + t + 1, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t + 1, fl->ids[1], ctxt);
+ *control = cb(i + t + 1, fl->ids[1], scratch);
}
if (*control & fl->groups[2]) {
- *control = cb(i + t + 1, fl->ids[2], ctxt);
+ *control = cb(i + t + 1, fl->ids[2], scratch);
}
}
break;
for (u32 t = 0; t < floodSize && (*control & fl->allGroups); t += 2) {
if (*control & fl->groups[0]) {
- *control = cb(i + t, fl->ids[0], ctxt);
+ *control = cb(i + t, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t, fl->ids[1], ctxt);
+ *control = cb(i + t, fl->ids[1], scratch);
}
if (*control & fl->groups[2]) {
- *control = cb(i + t, fl->ids[2], ctxt);
+ *control = cb(i + t, fl->ids[2], scratch);
}
if (*control & fl->groups[3]) {
- *control = cb(i + t, fl->ids[3], ctxt);
+ *control = cb(i + t, fl->ids[3], scratch);
}
for (u32 t2 = 4; t2 < fl->idCount; t2++) {
if (*control & fl->groups[t2]) {
- *control = cb(i + t, fl->ids[t2], ctxt);
+ *control = cb(i + t, fl->ids[t2], scratch);
}
}
if (*control & fl->groups[0]) {
- *control = cb(i + t + 1, fl->ids[0], ctxt);
+ *control = cb(i + t + 1, fl->ids[0], scratch);
}
if (*control & fl->groups[1]) {
- *control = cb(i + t + 1, fl->ids[1], ctxt);
+ *control = cb(i + t + 1, fl->ids[1], scratch);
}
if (*control & fl->groups[2]) {
- *control = cb(i + t + 1, fl->ids[2], ctxt);
+ *control = cb(i + t + 1, fl->ids[2], scratch);
}
if (*control & fl->groups[3]) {
- *control = cb(i + t + 1, fl->ids[3], ctxt);
+ *control = cb(i + t + 1, fl->ids[3], scratch);
}
for (u32 t2 = 4; t2 < fl->idCount; t2++) {
if (*control & fl->groups[t2]) {
- *control = cb(i + t + 1, fl->ids[t2], ctxt);
+ *control = cb(i + t + 1, fl->ids[t2], scratch);
}
}
}
for (u32 t = 0; t < floodSize && (*control & fl->allGroups); t++) {
for (u32 t2 = 0; t2 < fl->idCount; t2++) {
if (*control & fl->groups[t2]) {
- *control = cb(i + t, fl->ids[t2], ctxt);
+ *control = cb(i + t, fl->ids[t2], scratch);
}
}
}
}
hwlm_error_t hwlmExec(const struct HWLM *t, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt,
+ size_t start, HWLMCallback cb, struct hs_scratch *scratch,
hwlm_group_t groups) {
assert(t);
if (t->type == HWLM_ENGINE_NOOD) {
DEBUG_PRINTF("calling noodExec\n");
- return noodExec(HWLM_C_DATA(t), buf, len, start, cb, ctxt);
+ return noodExec(HWLM_C_DATA(t), buf, len, start, cb, scratch);
}
assert(t->type == HWLM_ENGINE_FDR);
}
do_accel_block(aa, buf, len, &start);
DEBUG_PRINTF("calling frankie (groups=%08llx, start=%zu)\n", groups, start);
- return fdrExec(HWLM_C_DATA(t), buf, len, start, cb, ctxt, groups);
+ return fdrExec(HWLM_C_DATA(t), buf, len, start, cb, scratch, groups);
}
-hwlm_error_t hwlmExecStreaming(const struct HWLM *t, struct hs_scratch *scratch,
- size_t len, size_t start, HWLMCallback cb,
- void *ctxt, hwlm_group_t groups) {
+hwlm_error_t hwlmExecStreaming(const struct HWLM *t, size_t len, size_t start,
+ HWLMCallback cb, struct hs_scratch *scratch,
+ hwlm_group_t groups) {
assert(t);
assert(scratch);
// If we've been handed a start offset, we can use a block mode scan at
// that offset.
if (start) {
- return noodExec(HWLM_C_DATA(t), buf, len, start, cb, ctxt);
+ return noodExec(HWLM_C_DATA(t), buf, len, start, cb, scratch);
} else {
return noodExecStreaming(HWLM_C_DATA(t), hbuf, hlen, buf, len, cb,
- ctxt);
+ scratch);
}
}
do_accel_streaming(aa, hbuf, hlen, buf, len, &start);
DEBUG_PRINTF("calling frankie (groups=%08llx, start=%zu)\n", groups, start);
return fdrExecStreaming(HWLM_C_DATA(t), hbuf, hlen, buf, len, start, cb,
- ctxt, groups);
+ scratch, groups);
}
* belonging to the literal which was active at the when the end match location
* was first reached.
*/
-typedef hwlmcb_rv_t (*HWLMCallback)(size_t end, u32 id, void *context);
+typedef hwlmcb_rv_t (*HWLMCallback)(size_t end, u32 id,
+ struct hs_scratch *scratch);
/** \brief Match strings in table.
*
* the first possible match of a literal which is in the initial group mask.
*/
hwlm_error_t hwlmExec(const struct HWLM *tab, const u8 *buf, size_t len,
- size_t start, HWLMCallback callback, void *context,
- hwlm_group_t groups);
+ size_t start, HWLMCallback callback,
+ struct hs_scratch *scratch, hwlm_group_t groups);
/** \brief As for \ref hwlmExec, but a streaming case across two buffers.
- *
- * \p scratch is used to access fdr_temp_buf and to access the history buffer,
- * history length and the main buffer.
*
* \p len is the length of the main buffer to be scanned.
*
* \p start is an advisory hint representing the first offset at which a match
* may start. Some underlying literal matches may not respect it.
*
+ * \p scratch is used to access the history buffer, history length and
+ * the main buffer.
+ *
* Two buffers/lengths are provided. Matches that occur entirely within
* the history buffer will not be reported by this function. The offsets
* reported for the main buffer are relative to the start of that buffer (a
* match at byte 10 of the main buffer is reported as 10). Matches that start
* in the history buffer will have starts reported with 'negative' values.
*/
-hwlm_error_t hwlmExecStreaming(const struct HWLM *tab,
- struct hs_scratch *scratch, size_t len,
- size_t start, HWLMCallback callback,
- void *context, hwlm_group_t groups);
+hwlm_error_t hwlmExecStreaming(const struct HWLM *tab, size_t len, size_t start,
+ HWLMCallback callback,
+ struct hs_scratch *scratch, hwlm_group_t groups);
#ifdef __cplusplus
} /* extern "C" */
#include "hwlm.h"
#include "noodle_engine.h"
#include "noodle_internal.h"
+#include "scratch.h"
#include "ue2common.h"
#include "util/arch.h"
#include "util/bitutils.h"
struct cb_info {
HWLMCallback cb; //!< callback function called on match
u32 id; //!< ID to pass to callback on match
- void *ctx; //!< caller-supplied context to pass to callback
+ struct hs_scratch *scratch; //!< scratch to pass to callback
size_t offsetAdj; //!< used in streaming mode
};
match:
pos -= cbi->offsetAdj;
DEBUG_PRINTF("match @ %zu\n", pos + n->key_offset);
- hwlmcb_rv_t rv = cbi->cb(pos + n->key_offset - 1, cbi->id, cbi->ctx);
+ hwlmcb_rv_t rv = cbi->cb(pos + n->key_offset - 1, cbi->id, cbi->scratch);
if (rv == HWLM_TERMINATE_MATCHING) {
return HWLM_TERMINATED;
}
/** \brief Block-mode scanner. */
hwlm_error_t noodExec(const struct noodTable *n, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt) {
+ size_t start, HWLMCallback cb,
+ struct hs_scratch *scratch) {
assert(n && buf);
- struct cb_info cbi = {cb, n->id, ctxt, 0};
+ struct cb_info cbi = {cb, n->id, scratch, 0};
DEBUG_PRINTF("nood scan of %zu bytes for %*s @ %p\n", len, n->msk_len,
(const char *)&n->cmp, buf);
/** \brief Streaming-mode scanner. */
hwlm_error_t noodExecStreaming(const struct noodTable *n, const u8 *hbuf,
size_t hlen, const u8 *buf, size_t len,
- HWLMCallback cb, void *ctxt) {
+ HWLMCallback cb, struct hs_scratch *scratch) {
assert(n);
if (len + hlen < n->msk_len) {
return HWLM_SUCCESS;
}
- struct cb_info cbi = {cb, n->id, ctxt, 0};
+ struct cb_info cbi = {cb, n->id, scratch, 0};
DEBUG_PRINTF("nood scan of %zu bytes (%zu hlen) for %*s @ %p\n", len, hlen,
n->msk_len, (const char *)&n->cmp, buf);
if ((v & n->msk) == n->cmp) {
size_t m_end = -tl1 + i + n->msk_len - 1;
DEBUG_PRINTF("match @ %zu (i %zu)\n", m_end, i);
- hwlmcb_rv_t rv = cb(m_end, n->id, ctxt);
+ hwlmcb_rv_t rv = cb(m_end, n->id, scratch);
if (rv == HWLM_TERMINATE_MATCHING) {
return HWLM_TERMINATED;
}
#endif
struct noodTable;
+struct hs_scratch;
/** \brief Block-mode scanner. */
hwlm_error_t noodExec(const struct noodTable *n, const u8 *buf, size_t len,
- size_t start, HWLMCallback cb, void *ctxt);
+ size_t start, HWLMCallback cb,
+ struct hs_scratch *scratch);
/** \brief Streaming-mode scanner. */
hwlm_error_t noodExecStreaming(const struct noodTable *n, const u8 *hbuf,
size_t hlen, const u8 *buf, size_t len,
- HWLMCallback cb, void *ctxt);
+ HWLMCallback cb, struct hs_scratch *scratch);
#ifdef __cplusplus
} /* extern "C" */
}
#endif
-hwlmcb_rv_t roseDelayRebuildCallback(size_t end, u32 id, void *ctx) {
- struct hs_scratch *scratch = ctx;
+hwlmcb_rv_t roseDelayRebuildCallback(size_t end, u32 id,
+ struct hs_scratch *scratch) {
struct RoseContext *tctx = &scratch->tctxt;
struct core_info *ci = &scratch->core_info;
const struct RoseEngine *t = ci->rose;
}
static really_inline
-hwlmcb_rv_t roseCallback_i(size_t end, u32 id, void *ctxt) {
- struct hs_scratch *scratch = ctxt;
+hwlmcb_rv_t roseCallback_i(size_t end, u32 id, struct hs_scratch *scratch) {
struct RoseContext *tctx = &scratch->tctxt;
const struct RoseEngine *t = scratch->core_info.rose;
return HWLM_TERMINATE_MATCHING;
}
-hwlmcb_rv_t roseCallback(size_t end, u32 id, void *ctxt) {
- return roseCallback_i(end, id, ctxt);
+hwlmcb_rv_t roseCallback(size_t end, u32 id, struct hs_scratch *scratch) {
+ return roseCallback_i(end, id, scratch);
}
-hwlmcb_rv_t roseFloatingCallback(size_t end, u32 id, void *ctxt) {
- struct hs_scratch *scratch = ctxt;
+hwlmcb_rv_t roseFloatingCallback(size_t end, u32 id,
+ struct hs_scratch *scratch) {
const struct RoseEngine *t = scratch->core_info.rose;
- return roseCallback_i(end, id, ctxt) & t->floating_group_mask;
+ return roseCallback_i(end, id, scratch) & t->floating_group_mask;
}
/**
/* Callbacks, defined in match.c */
-hwlmcb_rv_t roseCallback(size_t end, u32 id, void *ctx);
-hwlmcb_rv_t roseFloatingCallback(size_t end, u32 id, void *ctx);
-hwlmcb_rv_t roseDelayRebuildCallback(size_t end, u32 id, void *ctx);
+hwlmcb_rv_t roseCallback(size_t end, u32 id, struct hs_scratch *scratch);
+hwlmcb_rv_t roseFloatingCallback(size_t end, u32 id,
+ struct hs_scratch *scratch);
+hwlmcb_rv_t roseDelayRebuildCallback(size_t end, u32 id,
+ struct hs_scratch *scratch);
int roseAnchoredCallback(u64a start, u64a end, u32 id, void *ctx);
/* Common code, used all over Rose runtime */
void roseStreamEodExec(const struct RoseEngine *t, u64a offset,
struct hs_scratch *scratch);
-hwlmcb_rv_t roseCallback(size_t end, u32 id, void *context);
+hwlmcb_rv_t roseCallback(size_t end, u32 id, struct hs_scratch *scratch);
int roseReportAdaptor(u64a start, u64a end, ReportID id, void *context);
DEBUG_PRINTF("start=%zu\n", start);
DEBUG_PRINTF("BEGIN FLOATING (over %zu/%zu)\n", flen, length);
- hwlmExecStreaming(ftable, scratch, flen, start, roseFloatingCallback,
- scratch, tctxt->groups & t->floating_group_mask);
+ hwlmExecStreaming(ftable, flen, start, roseFloatingCallback, scratch,
+ tctxt->groups & t->floating_group_mask);
}
flush_delay_and_exit:
// start the match region at zero.
const size_t start = 0;
- hwlmExecStreaming(ftable, scratch, len2, start, roseCallback, scratch,
+ hwlmExecStreaming(ftable, len2, start, roseCallback, scratch,
rose->initialGroups & rose->floating_group_mask);
if (!told_to_stop_matching(scratch) &&
#include "util/alloc.h"
#include "database.h"
+#include "scratch.h"
#include "gtest/gtest.h"
#include <algorithm>
}
};
+vector<match> matches;
+
extern "C" {
static
-hwlmcb_rv_t decentCallback(size_t end, u32 id, void *ctxt) {
+hwlmcb_rv_t decentCallback(size_t end, u32 id,
+ UNUSED struct hs_scratch *scratch) {
DEBUG_PRINTF("match @%zu : %u\n", end, id);
- if (!ctxt) {
- return HWLM_CONTINUE_MATCHING;
- }
- vector<match> *out = (vector<match> *)ctxt;
- out->push_back(match(end, id));
+ matches.push_back(match(end, id));
return HWLM_CONTINUE_MATCHING;
}
static
-hwlmcb_rv_t decentCallbackT(size_t end, u32 id, void *ctxt) {
- if (!ctxt) {
- return HWLM_TERMINATE_MATCHING;
- }
-
- vector<match> *out = (vector<match> *)ctxt;
- out->push_back(match(end, id));
+hwlmcb_rv_t decentCallbackT(size_t end, u32 id,
+ UNUSED struct hs_scratch *scratch) {
+ matches.push_back(match(end, id));
return HWLM_TERMINATE_MATCHING;
}
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> matches;
+ struct hs_scratch scratch;
fdrExec(fdr.get(), (const u8 *)data, sizeof(data), 0, decentCallback,
- &matches, HWLM_ALL_GROUPS);
+ &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(3U, matches.size());
EXPECT_EQ(match(5, 0), matches[0]);
EXPECT_EQ(match(23, 0), matches[1]);
EXPECT_EQ(match(83, 0), matches[2]);
+ matches.clear();
}
TEST_P(FDRp, SimpleSingle) {
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> matches;
+ struct hs_scratch scratch;
fdrExec(fdr.get(), (const u8 *)data, sizeof(data) - 1 /* skip nul */, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(4U, matches.size());
EXPECT_EQ(match(0, 0), matches[0]);
EXPECT_EQ(match(18, 0), matches[1]);
EXPECT_EQ(match(78, 0), matches[2]);
EXPECT_EQ(match(80, 0), matches[3]);
+ matches.clear();
}
TEST_P(FDRp, MultiLocation) {
vector<u8> data(testSize, 0);
+ struct hs_scratch scratch;
for (u32 i = 0; i < testSize - 3; i++) {
memcpy(data.data() + i, "abc", 3);
- vector<match> matches;
- fdrExec(fdr.get(), data.data(), testSize, 0, decentCallback, &matches,
+ fdrExec(fdr.get(), data.data(), testSize, 0, decentCallback, &scratch,
HWLM_ALL_GROUPS);
ASSERT_EQ(1U, matches.size());
EXPECT_EQ(match(i + 2, 1), matches[0]);
memset(data.data() + i, 0, 3);
+ matches.clear();
}
}
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> matches;
+ struct hs_scratch scratch;
fdrExec(fdr.get(), (const u8 *)data, sizeof(data) - 1 /* skip nul */, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(1U, matches.size());
EXPECT_EQ(match(0, 0), matches[0]);
+ matches.clear();
}
TEST_P(FDRp, NoRepeat2) {
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> matches;
+ struct hs_scratch scratch;
fdrExec(fdr.get(), (const u8 *)data, sizeof(data) - 1 /* skip nul */, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(3U, matches.size());
EXPECT_EQ(match(0, 0), matches[0]);
EXPECT_EQ(match(78, 0), matches[2]);
+ matches.clear();
}
TEST_P(FDRp, NoRepeat3) {
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> matches;
+ struct hs_scratch scratch;
fdrExec(fdr.get(), (const u8 *)data, sizeof(data) - 1 /* skip nul */, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(1U, matches.size());
EXPECT_EQ(match(32, 0), matches[0]);
+ matches.clear();
}
/**
static
hwlm_error_t safeExecStreaming(const FDR *fdr, const u8 *hbuf, size_t hlen,
const u8 *buf, size_t len, size_t start,
- HWLMCallback cb, void *ctxt,
- hwlm_group_t groups) {
+ HWLMCallback cb, hwlm_group_t groups) {
array<u8, 16> wrapped_history = {{'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}};
if (hlen < 16) {
memcpy(new_hbuf, hbuf, hlen);
hbuf = new_hbuf;
}
- return fdrExecStreaming(fdr, hbuf, hlen, buf, len, start, cb, ctxt, groups);
+ struct hs_scratch scratch;
+ return fdrExecStreaming(fdr, hbuf, hlen, buf, len, start, cb, &scratch,
+ groups);
}
TEST_P(FDRp, SmallStreaming) {
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> expected, matches;
+ vector<match> expected;
expected.push_back(match(0, 1));
expected.push_back(match(1, 1));
expected.push_back(match(2, 1));
safeExecStreaming(fdr.get(), (const u8 *)"", 0, (const u8 *)"aaar", 4, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, HWLM_ALL_GROUPS);
for (u32 i = 0; i < MIN(expected.size(), matches.size()); i++) {
EXPECT_EQ(expected[i], matches[i]);
}
expected.push_back(match(8, 10));
safeExecStreaming(fdr.get(), (const u8 *)"aaar", 4, (const u8 *)"dvark", 5,
- 0, decentCallback, &matches, HWLM_ALL_GROUPS);
+ 0, decentCallback, HWLM_ALL_GROUPS);
for (u32 i = 0; i < MIN(expected.size(), matches.size()); i++) {
EXPECT_EQ(expected[i], matches[i] + 4);
}
ASSERT_EQ(expected.size(), matches.size());
+ matches.clear();
}
TEST_P(FDRp, SmallStreaming2) {
auto fdr = fdrBuildTableHinted(lits, false, hint, get_current_target(), Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- vector<match> expected, matches;
+ vector<match> expected;
expected.push_back(match(6,1));
expected.push_back(match(7,1));
expected.push_back(match(11,1));
expected.push_back(match(15,2));
safeExecStreaming(fdr.get(), (const u8 *)"foobar", 6,
- (const u8 *)"aardvarkkk", 10, 0, decentCallback, &matches,
+ (const u8 *)"aardvarkkk", 10, 0, decentCallback,
HWLM_ALL_GROUPS);
for (u32 i = 0; i < MIN(expected.size(), matches.size()); i++) {
EXPECT_EQ(expected[i], matches[i] + 6);
}
ASSERT_EQ(expected.size(), matches.size());
+ matches.clear();
}
TEST_P(FDRp, moveByteStream) {
}
// check matches
- vector<match> matches;
+ struct hs_scratch scratch;
hwlm_error_t fdrStatus = fdrExec(fdrTable.get(), (const u8 *)data,
- data_len, 0, decentCallback, &matches,
+ data_len, 0, decentCallback, &scratch,
HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
ASSERT_EQ(1U, matches.size());
EXPECT_EQ(match(17, 0), matches[0]);
+ matches.clear();
}
TEST_P(FDRp, Stream1) {
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
// check matches
- vector<match> matches;
fdrStatus = safeExecStreaming(fdr.get(), (const u8 *)data1, data_len1,
(const u8 *)data2, data_len2, 0,
- decentCallback, &matches, HWLM_ALL_GROUPS);
+ decentCallback, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
ASSERT_EQ(4U, matches.size());
for (size_t i = 0; i < matches.size(); i++) {
EXPECT_EQ(match(i, 0), matches[i]);
}
+ matches.clear();
}
INSTANTIATE_TEST_CASE_P(FDR, FDRp, ValuesIn(getValidFdrEngines()));
aligned_free_internal);
vector<hwlmLiteral> lits;
+ struct hs_scratch scratch;
for (size_t litLen = 1; litLen <= patLen; litLen++) {
// building literal from pattern substring of variable length 1-patLen
pattern.data(), litLen);
for (size_t j = 0; j <= litLen; j++) {
- vector<match> matches;
hwlm_error_t fdrStatus = fdrExec(fdr.get(),
(const u8 *)dataBufAligned.get() + i + j,
4 * buf_alignment - j * 2, 0, decentCallback,
- &matches, HWLM_ALL_GROUPS);
+ &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
// j == 0 means that start and end matches are entirely within
// searched buffer. Otherwise they are out of buffer boundaries
}
// run the literal matching through all generated literals
+ struct hs_scratch scratch;
for (size_t patIdx = 0; patIdx < pats.size();) {
// group them in the sets of 32
vector<hwlmLiteral> testSigs;
const string &buf = bufs[bufIdx];
size_t bufLen = buf.size();
- vector<match> matches;
hwlm_error_t fdrStatus = fdrExec(fdr.get(), (const u8 *)buf.data(),
- bufLen, 0, decentCallback, &matches, HWLM_ALL_GROUPS);
+ bufLen, 0, decentCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
// build the set of expected matches using standard
sort(expMatches.begin(), expMatches.end());
sort(matches.begin(), matches.end());
ASSERT_EQ(expMatches, matches);
+ matches.clear();
}
}
}
ASSERT_TRUE(fdr != nullptr);
// check matches
- vector<match> matches;
fdrStatus = safeExecStreaming(fdr.get(), (const u8 *)data1, data_len1,
(const u8 *)data2, data_len2, 0,
- decentCallbackT, &matches, HWLM_ALL_GROUPS);
+ decentCallbackT, HWLM_ALL_GROUPS);
ASSERT_EQ(HWLM_TERMINATED, fdrStatus);
ASSERT_EQ(1U, matches.size());
+ matches.clear();
}
TEST(FDR, FDRTermB) {
ASSERT_TRUE(fdr != nullptr);
// check matches
- vector<match> matches;
+ struct hs_scratch scratch;
fdrStatus = fdrExec(fdr.get(), (const u8 *)data1, data_len1,
- 0, decentCallbackT, &matches, HWLM_ALL_GROUPS);
+ 0, decentCallbackT, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(HWLM_TERMINATED, fdrStatus);
ASSERT_EQ(1U, matches.size());
+ matches.clear();
}
#include "fdr/fdr_engine_description.h"
#include "fdr/teddy_compile.h"
#include "fdr/teddy_engine_description.h"
+#include "scratch.h"
#include "util/alloc.h"
#include "util/bitutils.h"
return a;
}
+map<u32, int> matchesCounts;
+
extern "C" {
-static hwlmcb_rv_t countCallback(UNUSED size_t end, u32 id, void *cntxt) {
- if (cntxt) {
- map<u32, int> *matchesCounts = (map<u32, int> *)cntxt;
- (*matchesCounts)[id]++;
- }
+static hwlmcb_rv_t countCallback(UNUSED size_t end, u32 id,
+ UNUSED struct hs_scratch *scratch) {
+ matchesCounts[id]++;
return HWLM_CONTINUE_MATCHING;
}
vector<u8> data(dataSize);
u8 c = 0;
+ struct hs_scratch scratch;
while (1) {
SCOPED_TRACE((unsigned int)c);
u8 bit = 1 << (c & 0x7);
Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- map<u32, int> matchesCounts;
-
hwlm_error_t fdrStatus = fdrExec(fdr.get(), &data[0], dataSize,
- 0, countCallback, (void *)&matchesCounts, HWLM_ALL_GROUPS);
+ 0, countCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
for (u8 i = 0; i < 4; i++) {
matchesCounts.clear();
memset(&data[0], cAlt, dataSize);
fdrStatus = fdrExec(fdr.get(), &data[0], dataSize,
- 0, countCallback, (void *)&matchesCounts, HWLM_ALL_GROUPS);
+ 0, countCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
for (u8 i = 0; i < 4; i++) {
ASSERT_EQ(0, matchesCounts[i * 8 + 6]);
}
}
+ matchesCounts.clear();
if (++c == 0) {
break;
vector<u8> data(dataSize);
u8 c = '\0';
+ struct hs_scratch scratch;
while (1) {
u8 bit = 1 << (c & 0x7);
u8 cAlt = c ^ bit;
Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- map <u32, int> matchesCounts;
-
hwlm_error_t fdrStatus = fdrExec(fdr.get(), &data[0], dataSize,
- 0, countCallback, &matchesCounts, HWLM_ALL_GROUPS);
+ 0, countCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
const u32 cnt4 = dataSize - 4 + 1;
memset(&data[0], cAlt, dataSize);
matchesCounts.clear();
fdrStatus = fdrExec(fdr.get(), &data[0], dataSize,
- 0, countCallback, &matchesCounts, HWLM_ALL_GROUPS);
+ 0, countCallback, &scratch, HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
for (u8 i = 0; i < 4; i++) {
ASSERT_EQ(0, matchesCounts[i * 12 + 11]);
}
}
+ matchesCounts.clear();
if (++c == '\0') {
break;
vector<u8> tempdata(dataSize + fake_history_size); // headroom
u8 c = '\0';
+ struct hs_scratch scratch;
while (1) {
u8 bit = 1 << (c & 0x7);
u8 cAlt = c ^ bit;
Grey());
CHECK_WITH_TEDDY_OK_TO_FAIL(fdr, hint);
- map <u32, int> matchesCounts;
hwlm_error_t fdrStatus;
const u32 cnt4 = dataSize - 4 + 1;
// reference past the end of fake history to allow headroom
const u8 *fhist = fake_history.data() + fake_history_size;
fdrStatus = fdrExecStreaming(fdr.get(), fhist, 0, d, streamChunk, 0,
- countCallback, &matchesCounts,
+ countCallback, &scratch,
HWLM_ALL_GROUPS);
ASSERT_EQ(0, fdrStatus);
for (u32 j = streamChunk; j < dataSize; j += streamChunk) {
const u8 *tmp_d = tempdata.data() + fake_history_size;
fdrStatus = fdrExecStreaming(fdr.get(), tmp_d, j, tmp_d + j,
streamChunk, 0, countCallback,
- &matchesCounts,
- HWLM_ALL_GROUPS);
+ &scratch, HWLM_ALL_GROUPS);
} else {
fdrStatus = fdrExecStreaming(fdr.get(), d + j - 8, 8, d + j,
streamChunk, 0, countCallback,
- &matchesCounts,
- HWLM_ALL_GROUPS);
+ &scratch, HWLM_ALL_GROUPS);
}
ASSERT_EQ(0, fdrStatus);
}
break;
}
}
+ matchesCounts.clear();
}
INSTANTIATE_TEST_CASE_P(FDRFlood, FDRFloodp, ValuesIn(getValidFdrEngines()));
#include "hwlm/noodle_engine.h"
#include "hwlm/hwlm.h"
#include "hwlm/hwlm_literal.h"
+#include "scratch.h"
#include "util/alloc.h"
#include "util/ue2string.h"
to(end), id(identifier) {}
};
-typedef vector<hlmMatchEntry> hlmMatchRecord;
+vector<hlmMatchEntry> ctxt;
static
-hwlmcb_rv_t hlmSimpleCallback(size_t to, u32 id, void *context) {
- hlmMatchRecord *mr = (hlmMatchRecord *)context;
+hwlmcb_rv_t hlmSimpleCallback(size_t to, u32 id,
+ UNUSED struct hs_scratch *scratch) {
+ DEBUG_PRINTF("match @%zu = %u\n", to, id);
- DEBUG_PRINTF("match @%zu = %u,%p\n", to, id, context);
-
- mr->push_back(hlmMatchEntry(to, id));
+ ctxt.push_back(hlmMatchEntry(to, id));
return HWLM_CONTINUE_MATCHING;
}
static
void noodleMatch(const u8 *data, size_t data_len, const char *lit_str,
- size_t lit_len, char nocase, HWLMCallback cb, void *ctxt) {
+ size_t lit_len, char nocase, HWLMCallback cb) {
u32 id = 1000;
hwlmLiteral lit(std::string(lit_str, lit_len), nocase, id);
auto n = noodBuildTable(lit);
ASSERT_TRUE(n != nullptr);
hwlm_error_t rv;
- rv = noodExec(n.get(), data, data_len, 0, cb, ctxt);
+ struct hs_scratch scratch;
+ rv = noodExec(n.get(), data, data_len, 0, cb, &scratch);
ASSERT_EQ(HWLM_SUCCESS, rv);
}
TEST(Noodle, nood1) {
const size_t data_len = 1024;
unsigned int i, j;
- hlmMatchRecord ctxt;
u8 data[data_len];
memset(data, 'a', data_len);
- noodleMatch(data, data_len, "a", 1, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "a", 1, 0, hlmSimpleCallback);
ASSERT_EQ(1024U, ctxt.size());
for (i = 0; i < 1024; i++) {
ASSERT_EQ(i, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len, "A", 1, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "A", 1, 0, hlmSimpleCallback);
ASSERT_EQ(0U, ctxt.size());
ctxt.clear();
- noodleMatch(data, data_len, "A", 1, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "A", 1, 1, hlmSimpleCallback);
ASSERT_EQ(1024U, ctxt.size());
for (i = 0; i < 1024; i++) {
ASSERT_EQ(i, ctxt[i].to);
for (j = 0; j < 16; j++) {
ctxt.clear();
- noodleMatch(data + j, data_len - j, "A", 1, 1, hlmSimpleCallback,
- &ctxt);
+ noodleMatch(data + j, data_len - j, "A", 1, 1, hlmSimpleCallback);
ASSERT_EQ(1024 - j, ctxt.size());
for (i = 0; i < 1024 - j; i++) {
ASSERT_EQ(i, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len - j, "A", 1, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len - j, "A", 1, 1, hlmSimpleCallback);
ASSERT_EQ(1024 - j, ctxt.size());
for (i = 0; i < 1024 - j; i++) {
ASSERT_EQ(i, ctxt[i].to);
}
}
+ ctxt.clear();
}
TEST(Noodle, nood2) {
const size_t data_len = 1024;
unsigned int i, j;
- hlmMatchRecord ctxt;
u8 data[data_len];
memset(data, 'a', data_len);
- noodleMatch(data, data_len, "aa", 2, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aa", 2, 0, hlmSimpleCallback);
ASSERT_EQ(1023U, ctxt.size());
for (i = 0; i < 1023; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len, "aA", 2, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aA", 2, 0, hlmSimpleCallback);
ASSERT_EQ(0U, ctxt.size());
ctxt.clear();
- noodleMatch(data, data_len, "AA", 2, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "AA", 2, 0, hlmSimpleCallback);
ASSERT_EQ(0U, ctxt.size());
ctxt.clear();
- noodleMatch(data, data_len, "aa", 2, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aa", 2, 1, hlmSimpleCallback);
ASSERT_EQ(1023U, ctxt.size());
for (i = 0; i < 1023; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len, "Aa", 2, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "Aa", 2, 1, hlmSimpleCallback);
ASSERT_EQ(1023U, ctxt.size());
for (i = 0; i < 1023; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len, "AA", 2, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "AA", 2, 1, hlmSimpleCallback);
ASSERT_EQ(1023U, ctxt.size());
for (i = 0; i < 1023; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
for (j = 0; j < 16; j++) {
ctxt.clear();
- noodleMatch(data + j, data_len - j, "Aa", 2, 1, hlmSimpleCallback,
- &ctxt);
+ noodleMatch(data + j, data_len - j, "Aa", 2, 1, hlmSimpleCallback);
ASSERT_EQ(1023 - j, ctxt.size());
for (i = 0; i < 1023 - j; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len - j, "aA", 2, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len - j, "aA", 2, 1, hlmSimpleCallback);
ASSERT_EQ(1023 - j, ctxt.size());
for (i = 0; i < 1023 - j; i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
}
+ ctxt.clear();
}
TEST(Noodle, noodLong) {
const size_t data_len = 1024;
unsigned int i, j;
- hlmMatchRecord ctxt;
u8 data[data_len];
memset(data, 'a', data_len);
- noodleMatch(data, data_len, "aaaa", 4, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aaaa", 4, 0, hlmSimpleCallback);
ASSERT_EQ(1021U, ctxt.size());
for (i = 0; i < 1021; i++) {
ASSERT_EQ(i + 3, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data, data_len, "aaAA", 4, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aaAA", 4, 0, hlmSimpleCallback);
ASSERT_EQ(0U, ctxt.size());
ctxt.clear();
- noodleMatch(data, data_len, "aaAA", 4, 1, hlmSimpleCallback, &ctxt);
+ noodleMatch(data, data_len, "aaAA", 4, 1, hlmSimpleCallback);
ASSERT_EQ(1021U, ctxt.size());
for (i = 0; i < 1021; i++) {
ASSERT_EQ(i + 3, ctxt[i].to);
for (j = 0; j < 16; j++) {
ctxt.clear();
- noodleMatch(data + j, data_len - j, "AAaa", 4, 1, hlmSimpleCallback,
- &ctxt);
+ noodleMatch(data + j, data_len - j, "AAaa", 4, 1, hlmSimpleCallback);
ASSERT_EQ(1021 - j, ctxt.size());
for (i = 0; i < 1021 - j; i++) {
ASSERT_EQ(i + 3, ctxt[i].to);
}
ctxt.clear();
- noodleMatch(data + j, data_len - j, "aaaA", 4, 1, hlmSimpleCallback,
- &ctxt);
+ noodleMatch(data + j, data_len - j, "aaaA", 4, 1, hlmSimpleCallback);
ASSERT_EQ(1021 - j, ctxt.size());
for (i = 0; i < 1021 - j; i++) {
ASSERT_EQ(i + 3, ctxt[i].to);
}
}
+ ctxt.clear();
}
TEST(Noodle, noodCutoverSingle) {
const size_t max_data_len = 128;
- hlmMatchRecord ctxt;
u8 data[max_data_len + 15];
memset(data, 'a', max_data_len + 15);
for (u32 align = 0; align < 16; align++) {
for (u32 len = 0; len < max_data_len; len++) {
ctxt.clear();
- noodleMatch(data + align, len, "a", 1, 0, hlmSimpleCallback, &ctxt);
+ noodleMatch(data + align, len, "a", 1, 0, hlmSimpleCallback);
EXPECT_EQ(len, ctxt.size());
for (u32 i = 0; i < ctxt.size(); i++) {
ASSERT_EQ(i, ctxt[i].to);
}
}
}
+ ctxt.clear();
}
TEST(Noodle, noodCutoverDouble) {
const size_t max_data_len = 128;
- hlmMatchRecord ctxt;
u8 data[max_data_len + 15];
memset(data, 'a', max_data_len + 15);
for (u32 align = 0; align < 16; align++) {
for (u32 len = 0; len < max_data_len; len++) {
ctxt.clear();
- noodleMatch(data + align, len, "aa", 2, 0, hlmSimpleCallback,
- &ctxt);
+ noodleMatch(data + align, len, "aa", 2, 0, hlmSimpleCallback);
EXPECT_EQ(len ? len - 1 : 0U, ctxt.size());
for (u32 i = 0; i < ctxt.size(); i++) {
ASSERT_EQ(i + 1, ctxt[i].to);
}
}
}
+ ctxt.clear();
}