Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.18-rc6 360 lines 10 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * kabi_ex.h 4 * 5 * Copyright (C) 2024 Google LLC 6 * 7 * Examples for kABI stability features with --stable. 8 */ 9 10/* 11 * The comments below each example contain the expected gendwarfksyms 12 * output, which can be verified using LLVM's FileCheck tool: 13 * 14 * https://llvm.org/docs/CommandGuide/FileCheck.html 15 * 16 * Usage: 17 * 18 * $ gcc -g -c examples/kabi_ex.c -o examples/kabi_ex.o 19 * 20 * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \ 21 * ./gendwarfksyms --stable --dump-dies \ 22 * examples/kabi_ex.o 2>&1 >/dev/null | \ 23 * FileCheck examples/kabi_ex.h --check-prefix=STABLE 24 25 * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \ 26 * ./gendwarfksyms --stable --dump-versions \ 27 * examples/kabi_ex.o 2>&1 >/dev/null | \ 28 * sort | \ 29 * FileCheck examples/kabi_ex.h --check-prefix=VERSIONS 30 */ 31 32#ifndef __KABI_EX_H__ 33#define __KABI_EX_H__ 34 35#include "kabi.h" 36 37/* 38 * Example: kABI rules 39 */ 40 41struct s { 42 int a; 43}; 44 45KABI_DECLONLY(s); 46 47/* 48 * STABLE: variable structure_type s { 49 * STABLE-NEXT: } 50 */ 51 52enum e { 53 A, 54 B, 55 C, 56 D, 57}; 58 59KABI_ENUMERATOR_IGNORE(e, B); 60KABI_ENUMERATOR_IGNORE(e, C); 61KABI_ENUMERATOR_VALUE(e, D, 123456789); 62 63/* 64 * STABLE: variable enumeration_type e { 65 * STABLE-NEXT: enumerator A = 0 , 66 * STABLE-NEXT: enumerator D = 123456789 67 * STABLE-NEXT: } byte_size(4) 68*/ 69 70/* 71 * Example: Reserved fields 72 */ 73struct ex0a { 74 int a; 75 KABI_RESERVE(0); 76 KABI_RESERVE(1); 77}; 78 79/* 80 * STABLE: variable structure_type ex0a { 81 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 82 * STABLE-NEXT: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) data_member_location(8) , 83 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16) 84 * STABLE-NEXT: } byte_size(24) 85 */ 86 87struct ex0b { 88 int a; 89 KABI_RESERVE(0); 90 KABI_USE2(1, int b, int c); 91}; 92 93/* 94 * STABLE: variable structure_type ex0b { 95 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 96 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) , 97 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16) 98 * STABLE-NEXT: } byte_size(24) 99 */ 100 101struct ex0c { 102 int a; 103 KABI_USE(0, void *p); 104 KABI_USE2(1, int b, int c); 105}; 106 107/* 108 * STABLE: variable structure_type ex0c { 109 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 110 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) , 111 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16) 112 * STABLE-NEXT: } byte_size(24) 113 */ 114 115/* 116 * Example: A reserved array 117 */ 118 119struct ex1a { 120 unsigned int a; 121 KABI_RESERVE_ARRAY(0, 64); 122}; 123 124/* 125 * STABLE: variable structure_type ex1a { 126 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) , 127 * STABLE-NEXT: member array_type[64] { 128 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8) 129 * STABLE-NEXT: } data_member_location(8) 130 * STABLE-NEXT: } byte_size(72) 131 */ 132 133struct ex1b { 134 unsigned int a; 135 KABI_USE_ARRAY( 136 0, 64, struct { 137 void *p; 138 KABI_RESERVE_ARRAY(1, 56); 139 }); 140}; 141 142/* 143 * STABLE: variable structure_type ex1b { 144 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) , 145 * STABLE-NEXT: member array_type[64] { 146 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8) 147 * STABLE-NEXT: } data_member_location(8) 148 * STABLE-NEXT: } byte_size(72) 149 */ 150 151struct ex1c { 152 unsigned int a; 153 KABI_USE_ARRAY(0, 64, void *p[8]); 154}; 155 156/* 157 * STABLE: variable structure_type ex1c { 158 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) , 159 * STABLE-NEXT: member array_type[64] { 160 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8) 161 * STABLE-NEXT: } data_member_location(8) 162 * STABLE-NEXT: } byte_size(72) 163 */ 164 165/* 166 * Example: An ignored field added to an alignment hole 167 */ 168 169struct ex2a { 170 int a; 171 unsigned long b; 172 int c; 173 unsigned long d; 174}; 175 176/* 177 * STABLE: variable structure_type ex2a { 178 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 179 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8) 180 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) , 181 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24) 182 * STABLE-NEXT: } byte_size(32) 183 */ 184 185struct ex2b { 186 int a; 187 KABI_IGNORE(0, unsigned int n); 188 unsigned long b; 189 int c; 190 unsigned long d; 191}; 192 193_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2b), "ex2a size doesn't match ex2b"); 194 195/* 196 * STABLE: variable structure_type ex2b { 197 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 198 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8) 199 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) , 200 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24) 201 * STABLE-NEXT: } byte_size(32) 202 */ 203 204struct ex2c { 205 int a; 206 KABI_IGNORE(0, unsigned int n); 207 unsigned long b; 208 int c; 209 KABI_IGNORE(1, unsigned int m); 210 unsigned long d; 211}; 212 213_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2c), "ex2a size doesn't match ex2c"); 214 215/* 216 * STABLE: variable structure_type ex2c { 217 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) , 218 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8) 219 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) , 220 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24) 221 * STABLE-NEXT: } byte_size(32) 222 */ 223 224 225/* 226 * Example: A replaced field 227 */ 228 229struct ex3a { 230 unsigned long a; 231 unsigned long unused; 232}; 233 234/* 235 * STABLE: variable structure_type ex3a { 236 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0) 237 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8) 238 * STABLE-NEXT: } byte_size(16) 239 */ 240 241struct ex3b { 242 unsigned long a; 243 KABI_REPLACE(unsigned long, unused, unsigned long renamed); 244}; 245 246_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3b), "ex3a size doesn't match ex3b"); 247 248/* 249 * STABLE: variable structure_type ex3b { 250 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0) 251 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8) 252 * STABLE-NEXT: } byte_size(16) 253 */ 254 255struct ex3c { 256 unsigned long a; 257 KABI_REPLACE(unsigned long, unused, long replaced); 258}; 259 260_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3c), "ex3a size doesn't match ex3c"); 261 262/* 263 * STABLE: variable structure_type ex3c { 264 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0) 265 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8) 266 * STABLE-NEXT: } byte_size(16) 267 */ 268 269/* 270 * Example: An ignored field added to an end of a partially opaque struct, 271 * while keeping the byte_size attribute unchanged. 272 */ 273 274struct ex4a { 275 unsigned long a; 276 KABI_IGNORE(0, unsigned long b); 277}; 278 279/* 280 * This may be safe if the structure allocation is managed by the core kernel 281 * and the layout remains unchanged except for appended new members. 282 */ 283KABI_BYTE_SIZE(ex4a, 8); 284 285/* 286 * STABLE: variable structure_type ex4a { 287 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0) 288 * STABLE-NEXT: } byte_size(8) 289 */ 290 291/* 292 * Example: A type string override. 293 */ 294 295struct ex5a { 296 unsigned long a; 297}; 298 299/* 300 * This may be safe if the structure is fully opaque to modules, even though 301 * its definition has inadvertently become part of the ABI. 302 */ 303KABI_TYPE_STRING( 304 "s#ex5a", 305 "structure_type ex5a { member pointer_type { s#ex4a } byte_size(8) p data_member_location(0) } byte_size(8)"); 306 307/* 308 * Make sure the fully expanded type string includes ex4a. 309 * 310 * VERSIONS: ex5a variable structure_type ex5a { 311 * VERSIONS-SAME: member pointer_type { 312 * VERSIONS-SAME: structure_type ex4a { 313 * VERSIONS-SAME: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0) 314 * VERSIONS-SAME: } byte_size(8) 315 * VERSIONS-SAME: } byte_size(8) p data_member_location(0) 316 * VERSIONS-SAME: } byte_size(8) 317 */ 318 319/* 320 * Example: A type string definition for a non-existent type. 321 */ 322 323struct ex5b { 324 unsigned long a; 325}; 326 327/* Replace the type string for struct ex5b */ 328KABI_TYPE_STRING( 329 "s#ex5b", 330 "structure_type ex5b { member pointer_type { s#ex5c } byte_size(8) p data_member_location(0) } byte_size(8)"); 331 332/* Define a type string for a non-existent struct ex5c */ 333KABI_TYPE_STRING( 334 "s#ex5c", 335 "structure_type ex5c { member base_type int byte_size(4) encoding(5) n data_member_location(0) } byte_size(8)"); 336 337/* 338 * Make sure the fully expanded type string includes the definition for ex5c. 339 * 340 * VERSIONS: ex5b variable structure_type ex5b { 341 * VERSIONS-SAME: member pointer_type { 342 * VERSIONS-SAME: structure_type ex5c { 343 * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0) 344 * VERSIONS-SAME: } byte_size(8) 345 * VERSIONS-SAME: } byte_size(8) p data_member_location(0) 346 * VERSIONS-SAME: } byte_size(8) 347 */ 348 349/* 350 * Example: A type string override for a symbol. 351 */ 352 353KABI_TYPE_STRING("ex6a", "variable s#ex5c"); 354 355/* 356 * VERSIONS: ex6a variable structure_type ex5c { 357 * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0) 358 * VERSIONS-SAME: } byte_size(8) 359 */ 360#endif /* __KABI_EX_H__ */