Commit fd48aee6 authored by David Gibson's avatar David Gibson

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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent cc3db07e
...@@ -166,6 +166,28 @@ ...@@ -166,6 +166,28 @@
*/ */
#define tcon_sizeof(x, canary) sizeof((x)->_tcon[0].canary) #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 *) * tcon_ptr_type - pointer to the type within a container (or void *)
* @x: the structure containing the TCON. * @x: the structure containing the TCON.
......
#include <ccan/tcon/tcon.h>
#include <ccan/build_assert/build_assert.h>
#include <stdlib.h>
#include <stddef.h>
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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment