On Wed, Jun 07, 2023 at 02:12:59PM +0200, Ahmad Fatoum wrote: > Our old definition of offsetof is not an Integer Constant Expression > with some more recent clang versions[1]. Let's adopt the Linux > definition as well as a number of new macros that were added as part of > the hardening of the kernel against common out-of-bound bugs: > > - offsetofend > - struct_group* > - DECLARE_FLEX_ARRAY > > Of course, we only benefit from the new macros once we start to use > them, but that can follow now that they are available. > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > --- > include/linux/stddef.h | 109 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 108 insertions(+), 1 deletion(-) Applied, thanks Sascha > > diff --git a/include/linux/stddef.h b/include/linux/stddef.h > index 1044571c3f45..88ff6f1733d2 100644 > --- a/include/linux/stddef.h > +++ b/include/linux/stddef.h > @@ -22,7 +22,7 @@ enum { > typedef unsigned short wchar_t; > > #undef offsetof > -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) > +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) > > /** > * sizeof_field() - Report the size of a struct field in bytes > @@ -32,4 +32,111 @@ typedef unsigned short wchar_t; > */ > #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) > > +/** > + * offsetofend() - Report the offset of a struct field within the struct > + * > + * @TYPE: The type of the structure > + * @MEMBER: The member within the structure to get the end offset of > + */ > +#define offsetofend(TYPE, MEMBER) \ > + (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) > + > +/** > + * __struct_group() - Create a mirrored named and anonyomous struct > + * > + * @TAG: The tag name for the named sub-struct (usually empty) > + * @NAME: The identifier name of the mirrored sub-struct > + * @ATTRS: Any struct attributes (usually empty) > + * @MEMBERS: The member declarations for the mirrored structs > + * > + * Used to create an anonymous union of two structs with identical layout > + * and size: one anonymous and one named. The former's members can be used > + * normally without sub-struct naming, and the latter can be used to > + * reason about the start, end, and size of the group of struct members. > + * The named struct can also be explicitly tagged for layer reuse, as well > + * as both having struct attributes appended. > + */ > +#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ > + union { \ > + struct { MEMBERS } ATTRS; \ > + struct TAG { MEMBERS } ATTRS NAME; \ > + } > + > +/** > + * struct_group() - Wrap a set of declarations in a mirrored struct > + * > + * @NAME: The identifier name of the mirrored sub-struct > + * @MEMBERS: The member declarations for the mirrored structs > + * > + * Used to create an anonymous union of two structs with identical > + * layout and size: one anonymous and one named. The former can be > + * used normally without sub-struct naming, and the latter can be > + * used to reason about the start, end, and size of the group of > + * struct members. > + */ > +#define struct_group(NAME, MEMBERS...) \ > + __struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS) > + > +/** > + * struct_group_attr() - Create a struct_group() with trailing attributes > + * > + * @NAME: The identifier name of the mirrored sub-struct > + * @ATTRS: Any struct attributes to apply > + * @MEMBERS: The member declarations for the mirrored structs > + * > + * Used to create an anonymous union of two structs with identical > + * layout and size: one anonymous and one named. The former can be > + * used normally without sub-struct naming, and the latter can be > + * used to reason about the start, end, and size of the group of > + * struct members. Includes structure attributes argument. > + */ > +#define struct_group_attr(NAME, ATTRS, MEMBERS...) \ > + __struct_group(/* no tag */, NAME, ATTRS, MEMBERS) > + > +/** > + * struct_group_tagged() - Create a struct_group with a reusable tag > + * > + * @TAG: The tag name for the named sub-struct > + * @NAME: The identifier name of the mirrored sub-struct > + * @MEMBERS: The member declarations for the mirrored structs > + * > + * Used to create an anonymous union of two structs with identical > + * layout and size: one anonymous and one named. The former can be > + * used normally without sub-struct naming, and the latter can be > + * used to reason about the start, end, and size of the group of > + * struct members. Includes struct tag argument for the named copy, > + * so the specified layout can be reused later. > + */ > +#define struct_group_tagged(TAG, NAME, MEMBERS...) \ > + __struct_group(TAG, NAME, /* no attrs */, MEMBERS) > + > +/** > + * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union > + * > + * @TYPE: The type of each flexible array element > + * @NAME: The name of the flexible array member > + * > + * In order to have a flexible array member in a union or alone in a > + * struct, it needs to be wrapped in an anonymous struct with at least 1 > + * named member, but that member can be empty. > + */ > +#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ > + struct { \ > + struct { } __empty_ ## NAME; \ > + TYPE NAME[]; \ > + } > + > +/** > + * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union > + * > + * @TYPE: The type of each flexible array element > + * @NAME: The name of the flexible array member > + * > + * In order to have a flexible array member in a union or alone in a > + * struct, it needs to be wrapped in an anonymous struct with at least 1 > + * named member, but that member can be empty. > + */ > +#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ > + __DECLARE_FLEX_ARRAY(TYPE, NAME) > + > #endif > -- > 2.39.2 > > > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |