summaryrefslogtreecommitdiff
path: root/scripts/gendwarfksyms/examples
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2025-05-07 23:14:07 +0000
committerMasahiro Yamada <masahiroy@kernel.org>2025-05-25 18:12:23 +0900
commitc9083467f7b97e7c06b7a9038c4f18095329bd37 (patch)
treeea6e74c8041c837d58e3f10c7a171337a22c3b8d /scripts/gendwarfksyms/examples
parentdb59d74e5da144111fc133fb1bf72e6392bdb04e (diff)
gendwarfksyms: Add a kABI rule to override type strings
In rare situations where distributions must make significant changes to otherwise opaque data structures that have inadvertently been included in the published ABI, keeping symbol versions stable using the existing kABI macros can become tedious. For example, Android decided to switch to a newer io_uring implementation in the 5.10 GKI kernel "to resolve a huge number of potential, and known, problems with the codebase," requiring "horrible hacks" with genksyms: "A number of the io_uring structures get used in other core kernel structures, only as "opaque" pointers, so there is not any real ABI breakage. But, due to the visibility of the structures going away, the CRC values of many scheduler variables and functions were changed." -- https://r.android.com/2425293 While these specific changes probably could have been hidden from gendwarfksyms using the existing kABI macros, this may not always be the case. Add a last resort kABI rule that allows distribution maintainers to fully override a type string for a symbol or a type. Also add a more informative error message in case we find a non-existent type references when calculating versions. Suggested-by: Giuliano Procida <gprocida@google.com> Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Diffstat (limited to 'scripts/gendwarfksyms/examples')
-rw-r--r--scripts/gendwarfksyms/examples/kabi.h14
-rw-r--r--scripts/gendwarfksyms/examples/kabi_ex.c5
-rw-r--r--scripts/gendwarfksyms/examples/kabi_ex.h79
3 files changed, 94 insertions, 4 deletions
diff --git a/scripts/gendwarfksyms/examples/kabi.h b/scripts/gendwarfksyms/examples/kabi.h
index 86f4428e0479..170733a3fba4 100644
--- a/scripts/gendwarfksyms/examples/kabi.h
+++ b/scripts/gendwarfksyms/examples/kabi.h
@@ -37,11 +37,14 @@
#define __stringify(x...) __stringify_1(x)
#endif
-#define __KABI_RULE(hint, target, value) \
+#define ___KABI_RULE(hint, target, value) \
static const char __PASTE(__gendwarfksyms_rule_, \
__COUNTER__)[] __used __aligned(1) \
__section(".discard.gendwarfksyms.kabi_rules") = \
- "1\0" #hint "\0" #target "\0" #value
+ "1\0" #hint "\0" target "\0" value
+
+#define __KABI_RULE(hint, target, value) \
+ ___KABI_RULE(hint, #target, #value)
#define __KABI_NORMAL_SIZE_ALIGN(_orig, _new) \
union { \
@@ -97,6 +100,13 @@
#define KABI_BYTE_SIZE(fqn, value) __KABI_RULE(byte_size, fqn, value)
/*
+ * KABI_TYPE_STRING(type, str)
+ * For the given type, override the type string used in symtypes
+ * output and version calculation with str.
+ */
+#define KABI_TYPE_STRING(type, str) ___KABI_RULE(type_string, type, str)
+
+/*
* KABI_RESERVE
* Reserve some "padding" in a structure for use by LTS backports.
* This is normally placed at the end of a structure.
diff --git a/scripts/gendwarfksyms/examples/kabi_ex.c b/scripts/gendwarfksyms/examples/kabi_ex.c
index b73ee5399a59..1f799eb7c756 100644
--- a/scripts/gendwarfksyms/examples/kabi_ex.c
+++ b/scripts/gendwarfksyms/examples/kabi_ex.c
@@ -30,3 +30,8 @@ struct ex3b ex3b;
struct ex3c ex3c;
struct ex4a ex4a;
+
+struct ex5a ex5a;
+struct ex5b ex5b;
+
+int ex6a;
diff --git a/scripts/gendwarfksyms/examples/kabi_ex.h b/scripts/gendwarfksyms/examples/kabi_ex.h
index 092c8cb7bcd7..785b211d9c58 100644
--- a/scripts/gendwarfksyms/examples/kabi_ex.h
+++ b/scripts/gendwarfksyms/examples/kabi_ex.h
@@ -21,6 +21,12 @@
* ./gendwarfksyms --stable --dump-dies \
* examples/kabi_ex.o 2>&1 >/dev/null | \
* FileCheck examples/kabi_ex.h --check-prefix=STABLE
+
+ * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \
+ * ./gendwarfksyms --stable --dump-versions \
+ * examples/kabi_ex.o 2>&1 >/dev/null | \
+ * sort | \
+ * FileCheck examples/kabi_ex.h --check-prefix=VERSIONS
*/
#ifndef __KABI_EX_H__
@@ -170,7 +176,7 @@ struct ex2a {
/*
* STABLE: variable structure_type ex2a {
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
- * STABLE-NEXT: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) b data_member_location(8)
+ * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
* STABLE-NEXT: } byte_size(32)
@@ -227,7 +233,7 @@ struct ex3a {
/*
* STABLE: variable structure_type ex3a {
- * STABLE-NEXT: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0)
+ * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
* STABLE-NEXT: } byte_size(16)
*/
@@ -282,4 +288,73 @@ KABI_BYTE_SIZE(ex4a, 8);
* STABLE-NEXT: } byte_size(8)
*/
+/*
+ * Example: A type string override.
+ */
+
+struct ex5a {
+ unsigned long a;
+};
+
+/*
+ * This may be safe if the structure is fully opaque to modules, even though
+ * its definition has inadvertently become part of the ABI.
+ */
+KABI_TYPE_STRING(
+ "s#ex5a",
+ "structure_type ex5a { member pointer_type { s#ex4a } byte_size(8) p data_member_location(0) } byte_size(8)");
+
+/*
+ * Make sure the fully expanded type string includes ex4a.
+ *
+ * VERSIONS: ex5a variable structure_type ex5a {
+ * VERSIONS-SAME: member pointer_type {
+ * VERSIONS-SAME: structure_type ex4a {
+ * VERSIONS-SAME: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0)
+ * VERSIONS-SAME: } byte_size(8)
+ * VERSIONS-SAME: } byte_size(8) p data_member_location(0)
+ * VERSIONS-SAME: } byte_size(8)
+ */
+
+/*
+ * Example: A type string definition for a non-existent type.
+ */
+
+struct ex5b {
+ unsigned long a;
+};
+
+/* Replace the type string for struct ex5b */
+KABI_TYPE_STRING(
+ "s#ex5b",
+ "structure_type ex5b { member pointer_type { s#ex5c } byte_size(8) p data_member_location(0) } byte_size(8)");
+
+/* Define a type string for a non-existent struct ex5c */
+KABI_TYPE_STRING(
+ "s#ex5c",
+ "structure_type ex5c { member base_type int byte_size(4) encoding(5) n data_member_location(0) } byte_size(8)");
+
+/*
+ * Make sure the fully expanded type string includes the definition for ex5c.
+ *
+ * VERSIONS: ex5b variable structure_type ex5b {
+ * VERSIONS-SAME: member pointer_type {
+ * VERSIONS-SAME: structure_type ex5c {
+ * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0)
+ * VERSIONS-SAME: } byte_size(8)
+ * VERSIONS-SAME: } byte_size(8) p data_member_location(0)
+ * VERSIONS-SAME: } byte_size(8)
+ */
+
+/*
+ * Example: A type string override for a symbol.
+ */
+
+KABI_TYPE_STRING("ex6a", "variable s#ex5c");
+
+/*
+ * VERSIONS: ex6a variable structure_type ex5c {
+ * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0)
+ * VERSIONS-SAME: } byte_size(8)
+ */
#endif /* __KABI_EX_H__ */