1936cf61cSSami Tolvanen /* SPDX-License-Identifier: GPL-2.0 */ 2936cf61cSSami Tolvanen /* 3936cf61cSSami Tolvanen * Copyright (C) 2024 Google LLC 4936cf61cSSami Tolvanen * 5936cf61cSSami Tolvanen * Example macros for maintaining kABI stability. 6936cf61cSSami Tolvanen * 7936cf61cSSami Tolvanen * This file is based on android_kabi.h, which has the following notice: 8936cf61cSSami Tolvanen * 9936cf61cSSami Tolvanen * Heavily influenced by rh_kabi.h which came from the RHEL/CENTOS kernel 10936cf61cSSami Tolvanen * and was: 11936cf61cSSami Tolvanen * Copyright (c) 2014 Don Zickus 12936cf61cSSami Tolvanen * Copyright (c) 2015-2018 Jiri Benc 13936cf61cSSami Tolvanen * Copyright (c) 2015 Sabrina Dubroca, Hannes Frederic Sowa 14936cf61cSSami Tolvanen * Copyright (c) 2016-2018 Prarit Bhargava 15936cf61cSSami Tolvanen * Copyright (c) 2017 Paolo Abeni, Larry Woodman 16936cf61cSSami Tolvanen */ 17936cf61cSSami Tolvanen 18936cf61cSSami Tolvanen #ifndef __KABI_H__ 19936cf61cSSami Tolvanen #define __KABI_H__ 20936cf61cSSami Tolvanen 21936cf61cSSami Tolvanen /* Kernel macros for userspace testing. */ 22936cf61cSSami Tolvanen #ifndef __aligned 23936cf61cSSami Tolvanen #define __aligned(x) __attribute__((__aligned__(x))) 24936cf61cSSami Tolvanen #endif 25936cf61cSSami Tolvanen #ifndef __used 26936cf61cSSami Tolvanen #define __used __attribute__((__used__)) 27936cf61cSSami Tolvanen #endif 28936cf61cSSami Tolvanen #ifndef __section 29936cf61cSSami Tolvanen #define __section(section) __attribute__((__section__(section))) 30936cf61cSSami Tolvanen #endif 31936cf61cSSami Tolvanen #ifndef __PASTE 32936cf61cSSami Tolvanen #define ___PASTE(a, b) a##b 33936cf61cSSami Tolvanen #define __PASTE(a, b) ___PASTE(a, b) 34936cf61cSSami Tolvanen #endif 35936cf61cSSami Tolvanen #ifndef __stringify 36936cf61cSSami Tolvanen #define __stringify_1(x...) #x 37936cf61cSSami Tolvanen #define __stringify(x...) __stringify_1(x) 38936cf61cSSami Tolvanen #endif 39936cf61cSSami Tolvanen 40936cf61cSSami Tolvanen #define __KABI_RULE(hint, target, value) \ 41936cf61cSSami Tolvanen static const char __PASTE(__gendwarfksyms_rule_, \ 42936cf61cSSami Tolvanen __COUNTER__)[] __used __aligned(1) \ 43936cf61cSSami Tolvanen __section(".discard.gendwarfksyms.kabi_rules") = \ 44936cf61cSSami Tolvanen "1\0" #hint "\0" #target "\0" #value 45936cf61cSSami Tolvanen 46*a9369418SSami Tolvanen #define __KABI_NORMAL_SIZE_ALIGN(_orig, _new) \ 47*a9369418SSami Tolvanen union { \ 48*a9369418SSami Tolvanen _Static_assert( \ 49*a9369418SSami Tolvanen sizeof(struct { _new; }) <= sizeof(struct { _orig; }), \ 50*a9369418SSami Tolvanen __FILE__ ":" __stringify(__LINE__) ": " __stringify( \ 51*a9369418SSami Tolvanen _new) " is larger than " __stringify(_orig)); \ 52*a9369418SSami Tolvanen _Static_assert( \ 53*a9369418SSami Tolvanen __alignof__(struct { _new; }) <= \ 54*a9369418SSami Tolvanen __alignof__(struct { _orig; }), \ 55*a9369418SSami Tolvanen __FILE__ ":" __stringify(__LINE__) ": " __stringify( \ 56*a9369418SSami Tolvanen _orig) " is not aligned the same as " __stringify(_new)); \ 57*a9369418SSami Tolvanen } 58*a9369418SSami Tolvanen 59*a9369418SSami Tolvanen #define __KABI_REPLACE(_orig, _new) \ 60*a9369418SSami Tolvanen union { \ 61*a9369418SSami Tolvanen _new; \ 62*a9369418SSami Tolvanen struct { \ 63*a9369418SSami Tolvanen _orig; \ 64*a9369418SSami Tolvanen }; \ 65*a9369418SSami Tolvanen __KABI_NORMAL_SIZE_ALIGN(_orig, _new); \ 66*a9369418SSami Tolvanen } 67*a9369418SSami Tolvanen 68936cf61cSSami Tolvanen /* 69936cf61cSSami Tolvanen * KABI_DECLONLY(fqn) 70936cf61cSSami Tolvanen * Treat the struct/union/enum fqn as a declaration, i.e. even if 71936cf61cSSami Tolvanen * a definition is available, don't expand the contents. 72936cf61cSSami Tolvanen */ 73936cf61cSSami Tolvanen #define KABI_DECLONLY(fqn) __KABI_RULE(declonly, fqn, ) 74936cf61cSSami Tolvanen 75936cf61cSSami Tolvanen /* 76936cf61cSSami Tolvanen * KABI_ENUMERATOR_IGNORE(fqn, field) 77936cf61cSSami Tolvanen * When expanding enum fqn, skip the provided field. This makes it 78936cf61cSSami Tolvanen * possible to hide added enum fields from versioning. 79936cf61cSSami Tolvanen */ 80936cf61cSSami Tolvanen #define KABI_ENUMERATOR_IGNORE(fqn, field) \ 81936cf61cSSami Tolvanen __KABI_RULE(enumerator_ignore, fqn field, ) 82936cf61cSSami Tolvanen 83936cf61cSSami Tolvanen /* 84936cf61cSSami Tolvanen * KABI_ENUMERATOR_VALUE(fqn, field, value) 85936cf61cSSami Tolvanen * When expanding enum fqn, use the provided value for the 86936cf61cSSami Tolvanen * specified field. This makes it possible to override enumerator 87936cf61cSSami Tolvanen * values when calculating versions. 88936cf61cSSami Tolvanen */ 89936cf61cSSami Tolvanen #define KABI_ENUMERATOR_VALUE(fqn, field, value) \ 90936cf61cSSami Tolvanen __KABI_RULE(enumerator_value, fqn field, value) 91936cf61cSSami Tolvanen 92*a9369418SSami Tolvanen /* 93*a9369418SSami Tolvanen * KABI_RESERVE 94*a9369418SSami Tolvanen * Reserve some "padding" in a structure for use by LTS backports. 95*a9369418SSami Tolvanen * This is normally placed at the end of a structure. 96*a9369418SSami Tolvanen * number: the "number" of the padding variable in the structure. Start with 97*a9369418SSami Tolvanen * 1 and go up. 98*a9369418SSami Tolvanen */ 99*a9369418SSami Tolvanen #define KABI_RESERVE(n) unsigned long __kabi_reserved##n 100*a9369418SSami Tolvanen 101*a9369418SSami Tolvanen /* 102*a9369418SSami Tolvanen * KABI_RESERVE_ARRAY 103*a9369418SSami Tolvanen * Same as _BACKPORT_RESERVE but allocates an array with the specified 104*a9369418SSami Tolvanen * size in bytes. 105*a9369418SSami Tolvanen */ 106*a9369418SSami Tolvanen #define KABI_RESERVE_ARRAY(n, s) \ 107*a9369418SSami Tolvanen unsigned char __aligned(8) __kabi_reserved##n[s] 108*a9369418SSami Tolvanen 109*a9369418SSami Tolvanen /* 110*a9369418SSami Tolvanen * KABI_IGNORE 111*a9369418SSami Tolvanen * Add a new field that's ignored in versioning. 112*a9369418SSami Tolvanen */ 113*a9369418SSami Tolvanen #define KABI_IGNORE(n, _new) \ 114*a9369418SSami Tolvanen union { \ 115*a9369418SSami Tolvanen _new; \ 116*a9369418SSami Tolvanen unsigned char __kabi_ignored##n; \ 117*a9369418SSami Tolvanen } 118*a9369418SSami Tolvanen 119*a9369418SSami Tolvanen /* 120*a9369418SSami Tolvanen * KABI_REPLACE 121*a9369418SSami Tolvanen * Replace a field with a compatible new field. 122*a9369418SSami Tolvanen */ 123*a9369418SSami Tolvanen #define KABI_REPLACE(_oldtype, _oldname, _new) \ 124*a9369418SSami Tolvanen __KABI_REPLACE(_oldtype __kabi_renamed##_oldname, struct { _new; }) 125*a9369418SSami Tolvanen 126*a9369418SSami Tolvanen /* 127*a9369418SSami Tolvanen * KABI_USE(number, _new) 128*a9369418SSami Tolvanen * Use a previous padding entry that was defined with KABI_RESERVE 129*a9369418SSami Tolvanen * number: the previous "number" of the padding variable 130*a9369418SSami Tolvanen * _new: the variable to use now instead of the padding variable 131*a9369418SSami Tolvanen */ 132*a9369418SSami Tolvanen #define KABI_USE(number, _new) __KABI_REPLACE(KABI_RESERVE(number), _new) 133*a9369418SSami Tolvanen 134*a9369418SSami Tolvanen /* 135*a9369418SSami Tolvanen * KABI_USE2(number, _new1, _new2) 136*a9369418SSami Tolvanen * Use a previous padding entry that was defined with KABI_RESERVE for 137*a9369418SSami Tolvanen * two new variables that fit into 64 bits. This is good for when you do not 138*a9369418SSami Tolvanen * want to "burn" a 64bit padding variable for a smaller variable size if not 139*a9369418SSami Tolvanen * needed. 140*a9369418SSami Tolvanen */ 141*a9369418SSami Tolvanen #define KABI_USE2(number, _new1, _new2) \ 142*a9369418SSami Tolvanen __KABI_REPLACE( \ 143*a9369418SSami Tolvanen KABI_RESERVE(number), struct { \ 144*a9369418SSami Tolvanen _new1; \ 145*a9369418SSami Tolvanen _new2; \ 146*a9369418SSami Tolvanen }) 147*a9369418SSami Tolvanen /* 148*a9369418SSami Tolvanen * KABI_USE_ARRAY(number, bytes, _new) 149*a9369418SSami Tolvanen * Use a previous padding entry that was defined with KABI_RESERVE_ARRAY 150*a9369418SSami Tolvanen * number: the previous "number" of the padding variable 151*a9369418SSami Tolvanen * bytes: the size in bytes reserved for the array 152*a9369418SSami Tolvanen * _new: the variable to use now instead of the padding variable 153*a9369418SSami Tolvanen */ 154*a9369418SSami Tolvanen #define KABI_USE_ARRAY(number, bytes, _new) \ 155*a9369418SSami Tolvanen __KABI_REPLACE(KABI_RESERVE_ARRAY(number, bytes), _new) 156*a9369418SSami Tolvanen 157936cf61cSSami Tolvanen #endif /* __KABI_H__ */ 158