From fd48aee6393bda1e4eda9f9e52e6d9f818b77211 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 20 Oct 2015 12:34:30 +1100 Subject: [PATCH] tcon: Encode integer values into "type" canaries Add the ability to encode, as well as types, integer values (must be positive, compile time constant and in the range of size_t) into TCON constructed "type" canaries. Signed-off-by: David Gibson --- ccan/tcon/tcon.h | 22 +++++++++++++ ccan/tcon/test/compile_ok-value.c | 51 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 ccan/tcon/test/compile_ok-value.c diff --git a/ccan/tcon/tcon.h b/ccan/tcon/tcon.h index 62bacf53..c33070d6 100644 --- a/ccan/tcon/tcon.h +++ b/ccan/tcon/tcon.h @@ -166,6 +166,28 @@ */ #define tcon_sizeof(x, canary) sizeof((x)->_tcon[0].canary) +/** + * TCON_VALUE - encode an integer value in a type canary + * @canary: name of the value canary + * @val: positive integer compile time constant value + * + * This macro can be included inside the declarations in a TCON() or + * TCON_WRAP(), constructing a special "type" canary which encodes the + * integer value @val (which must be a compile time constant, and a + * positive integer in the range of size_t). + */ +#define TCON_VALUE(canary, val) char _value_##canary[val] + +/** + * tcon_value - retrieve the value of a TCON_VALUE canary + * @x: the structure containing the TCON + * @canary: name of the value canary + * + * This macros expands to the value previously encoded into a TCON + * using TCON_VALUE(). + */ +#define tcon_value(x, canary) tcon_sizeof(x, _value_##canary) + /** * tcon_ptr_type - pointer to the type within a container (or void *) * @x: the structure containing the TCON. diff --git a/ccan/tcon/test/compile_ok-value.c b/ccan/tcon/test/compile_ok-value.c new file mode 100644 index 00000000..d9c911e6 --- /dev/null +++ b/ccan/tcon/test/compile_ok-value.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +struct container { + void *p; +}; + +struct val_container { + struct container raw; + TCON(TCON_VALUE(fixed_val, 17)); +}; + +struct other_struct { + char junk1; + int x1; + long junk2; + char *x2; + short junk3; +}; + +struct offs_container { + struct container raw; + TCON(TCON_VALUE(off1, offsetof(struct other_struct, x1)); + TCON_VALUE(off2, offsetof(struct other_struct, x2))); +}; + +int main(int argc, char *argv[]) +{ + struct val_container valcon; + struct offs_container offscon; + TCON_WRAP(struct container, TCON_VALUE(fixed_val, 17)) valconw; + TCON_WRAP(struct container, + TCON_VALUE(off1, offsetof(struct other_struct, x1)); + TCON_VALUE(off2, offsetof(struct other_struct, x2))) offsconw; + + BUILD_ASSERT(tcon_value(&valcon, fixed_val) == 17); + BUILD_ASSERT(tcon_value(&valconw, fixed_val) == 17); + + BUILD_ASSERT(tcon_value(&offscon, off1) + == offsetof(struct other_struct, x1)); + BUILD_ASSERT(tcon_value(&offscon, off2) + == offsetof(struct other_struct, x2)); + BUILD_ASSERT(tcon_value(&offsconw, off1) + == offsetof(struct other_struct, x1)); + BUILD_ASSERT(tcon_value(&offsconw, off2) + == offsetof(struct other_struct, x2)); + + return 0; +} -- 2.39.2