aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common.h
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2017-01-10 16:45:52 +0100
committerAndrey Konovalov <andreyknvl@google.com>2017-01-17 13:25:33 +0100
commit54e0cede4384b7c1655f9183577bfccc11d9a7d5 (patch)
tree68e1f734a5e82ac7ecbe2968942d9983650ed8f8 /executor/common.h
parentf6c7b90523285663e51fc6804ae2c0c171bb390c (diff)
prog: add bitfields to templates
Now it's possible to use `int32:18` to denote a bitfield of size 18 as a struct field. This fixes #72.
Diffstat (limited to 'executor/common.h')
-rw-r--r--executor/common.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/executor/common.h b/executor/common.h
index 004dcc341..40b2bf8d0 100644
--- a/executor/common.h
+++ b/executor/common.h
@@ -158,6 +158,18 @@ static void install_segv_handler()
__atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
}
+#define BITMASK_LEN(type, bf_len) (type)((1ul << bf_len) - 1)
+
+#define BITMASK_LEN_OFF(type, bf_off, bf_len) (type)(BITMASK_LEN(type, bf_len) << bf_off)
+
+#define STORE_BY_BITMASK(type, addr, val, bf_off, bf_len) \
+ do { \
+ type new_val = *(type*)addr; \
+ new_val &= ~BITMASK_LEN_OFF(type, bf_off, bf_len); \
+ new_val |= ((type)val & BITMASK_LEN(type, bf_len)) << bf_off; \
+ *(type*)addr = new_val; \
+ } while (0)
+
#ifdef __NR_syz_emit_ethernet
static void vsnprintf_check(char* str, size_t size, const char* format, va_list args)
{