summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Krause <minipli@googlemail.com>2015-07-06 11:49:38 -0400
committerPaul Moore <pmoore@redhat.com>2015-07-06 11:49:38 -0400
commit30dee894a4feaa12cdbf49f5db18cae246689c7a (patch)
tree3b90905761e39a4a60bb3f111c07326d3167fb49
parenta967e9dd328881bfefda2b1aa112c95f0b847935 (diff)
downloadlibseccomp-30dee894a4feaa12cdbf49f5db18cae246689c7a.tar.gz
db: optimize masked compares
If the masked compare is a tautology we don't need to generate instructions for the runtime test. It'll always be true. This patch handles the case for 32 bit arches and partially for 64 bit arches. The cases where either the upper half or the lower half is a tautology is still TODO. Signed-off-by: Mathias Krause <minipli@googlemail.com> [PM: minor function name changes to better match existing style] Signed-off-by: Paul Moore <pmoore@redhat.com> (imported from commit 1ff6f3e6521d787e52fe328b862094898fc0b77e)
-rw-r--r--src/db.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c
index d6580ee..604d058 100644
--- a/src/db.c
+++ b/src/db.c
@@ -825,6 +825,38 @@ int db_syscall_priority(struct db_filter *db,
}
/**
+ * Test if the argument filter can be skipped because it's a tautology
+ * @param arg argument filter
+ *
+ * If this argument filter applied to the lower 32 bit can be skipped this
+ * function returns false.
+ *
+ */
+static bool _db_arg_cmp_need_lo(const struct db_api_arg *arg)
+{
+ if (arg->op == SCMP_CMP_MASKED_EQ && D64_LO(arg->mask) == 0)
+ return false;
+
+ return true;
+}
+
+/**
+ * Test if the argument filter can be skipped because it's a tautology
+ * @param arg argument filter
+ *
+ * If this argument filter applied to the upper 32 bit can be skipped this
+ * function returns false.
+ *
+ */
+static bool _db_arg_cmp_need_hi(const struct db_api_arg *arg)
+{
+ if (arg->op == SCMP_CMP_MASKED_EQ && D64_HI(arg->mask) == 0)
+ return false;
+
+ return true;
+}
+
+/**
* Fixup the node based on the op/mask
* @param node the chain node
*
@@ -873,6 +905,13 @@ static struct db_sys_list *_db_rule_gen_64(const struct arch_def *arch,
if (chain[iter].valid == 0)
continue;
+ /* TODO: handle the case were either hi or lo isn't needed */
+
+ /* skip generating instruction which are no-ops */
+ if (!_db_arg_cmp_need_hi(&chain[iter]) &&
+ !_db_arg_cmp_need_lo(&chain[iter]))
+ continue;
+
c_iter_hi = malloc(sizeof(*c_iter_hi));
if (c_iter_hi == NULL)
goto gen_64_failure;
@@ -1005,6 +1044,10 @@ static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch,
if (chain[iter].valid == 0)
continue;
+ /* skip generating instructions which are no-ops */
+ if (!_db_arg_cmp_need_lo(&chain[iter]))
+ continue;
+
c_iter = malloc(sizeof(*c_iter));
if (c_iter == NULL)
goto gen_32_failure;
@@ -1013,6 +1056,7 @@ static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch,
c_iter->arg = chain[iter].arg;
c_iter->arg_offset = arch_arg_offset(arch, c_iter->arg);
c_iter->op = chain[iter].op;
+ /* implicitly strips off the upper 32 bit */
c_iter->mask = chain[iter].mask;
c_iter->datum = chain[iter].datum;