Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,174 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2024 Google LLC
*
* Example macros for maintaining kABI stability.
*
* This file is based on android_kabi.h, which has the following notice:
*
* Heavily influenced by rh_kabi.h which came from the RHEL/CENTOS kernel
* and was:
* Copyright (c) 2014 Don Zickus
* Copyright (c) 2015-2018 Jiri Benc
* Copyright (c) 2015 Sabrina Dubroca, Hannes Frederic Sowa
* Copyright (c) 2016-2018 Prarit Bhargava
* Copyright (c) 2017 Paolo Abeni, Larry Woodman
*/
#ifndef __KABI_H__
#define __KABI_H__
/* Kernel macros for userspace testing. */
#ifndef __aligned
#define __aligned(x) __attribute__((__aligned__(x)))
#endif
#ifndef __used
#define __used __attribute__((__used__))
#endif
#ifndef __section
#define __section(section) __attribute__((__section__(section)))
#endif
#ifndef __PASTE
#define ___PASTE(a, b) a##b
#define __PASTE(a, b) ___PASTE(a, b)
#endif
#ifndef __stringify
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
#endif
#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
#define __KABI_RULE(hint, target, value) \
___KABI_RULE(hint, #target, #value)
#define __KABI_NORMAL_SIZE_ALIGN(_orig, _new) \
union { \
_Static_assert( \
sizeof(struct { _new; }) <= sizeof(struct { _orig; }), \
__FILE__ ":" __stringify(__LINE__) ": " __stringify( \
_new) " is larger than " __stringify(_orig)); \
_Static_assert( \
__alignof__(struct { _new; }) <= \
__alignof__(struct { _orig; }), \
__FILE__ ":" __stringify(__LINE__) ": " __stringify( \
_orig) " is not aligned the same as " __stringify(_new)); \
}
#define __KABI_REPLACE(_orig, _new) \
union { \
_new; \
struct { \
_orig; \
}; \
__KABI_NORMAL_SIZE_ALIGN(_orig, _new); \
}
/*
* KABI_DECLONLY(fqn)
* Treat the struct/union/enum fqn as a declaration, i.e. even if
* a definition is available, don't expand the contents.
*/
#define KABI_DECLONLY(fqn) __KABI_RULE(declonly, fqn, )
/*
* KABI_ENUMERATOR_IGNORE(fqn, field)
* When expanding enum fqn, skip the provided field. This makes it
* possible to hide added enum fields from versioning.
*/
#define KABI_ENUMERATOR_IGNORE(fqn, field) \
__KABI_RULE(enumerator_ignore, fqn field, )
/*
* KABI_ENUMERATOR_VALUE(fqn, field, value)
* When expanding enum fqn, use the provided value for the
* specified field. This makes it possible to override enumerator
* values when calculating versions.
*/
#define KABI_ENUMERATOR_VALUE(fqn, field, value) \
__KABI_RULE(enumerator_value, fqn field, value)
/*
* KABI_BYTE_SIZE(fqn, value)
* Set the byte_size attribute for the struct/union/enum fqn to
* value bytes.
*/
#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.
* number: the "number" of the padding variable in the structure. Start with
* 1 and go up.
*/
#define KABI_RESERVE(n) unsigned long __kabi_reserved##n
/*
* KABI_RESERVE_ARRAY
* Same as _BACKPORT_RESERVE but allocates an array with the specified
* size in bytes.
*/
#define KABI_RESERVE_ARRAY(n, s) \
unsigned char __aligned(8) __kabi_reserved##n[s]
/*
* KABI_IGNORE
* Add a new field that's ignored in versioning.
*/
#define KABI_IGNORE(n, _new) \
union { \
_new; \
unsigned char __kabi_ignored##n; \
}
/*
* KABI_REPLACE
* Replace a field with a compatible new field.
*/
#define KABI_REPLACE(_oldtype, _oldname, _new) \
__KABI_REPLACE(_oldtype __kabi_renamed##_oldname, struct { _new; })
/*
* KABI_USE(number, _new)
* Use a previous padding entry that was defined with KABI_RESERVE
* number: the previous "number" of the padding variable
* _new: the variable to use now instead of the padding variable
*/
#define KABI_USE(number, _new) __KABI_REPLACE(KABI_RESERVE(number), _new)
/*
* KABI_USE2(number, _new1, _new2)
* Use a previous padding entry that was defined with KABI_RESERVE for
* two new variables that fit into 64 bits. This is good for when you do not
* want to "burn" a 64bit padding variable for a smaller variable size if not
* needed.
*/
#define KABI_USE2(number, _new1, _new2) \
__KABI_REPLACE( \
KABI_RESERVE(number), struct { \
_new1; \
_new2; \
})
/*
* KABI_USE_ARRAY(number, bytes, _new)
* Use a previous padding entry that was defined with KABI_RESERVE_ARRAY
* number: the previous "number" of the padding variable
* bytes: the size in bytes reserved for the array
* _new: the variable to use now instead of the padding variable
*/
#define KABI_USE_ARRAY(number, bytes, _new) \
__KABI_REPLACE(KABI_RESERVE_ARRAY(number, bytes), _new)
#endif /* __KABI_H__ */
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0
/*
* kabi_ex.c
*
* Copyright (C) 2024 Google LLC
*
* Examples for kABI stability features with --stable. See kabi_ex.h
* for details.
*/
#include "kabi_ex.h"
struct s e0;
enum e e1;
struct ex0a ex0a;
struct ex0b ex0b;
struct ex0c ex0c;
struct ex1a ex1a;
struct ex1b ex1b;
struct ex1c ex1c;
struct ex2a ex2a;
struct ex2b ex2b;
struct ex2c ex2c;
struct ex3a ex3a;
struct ex3b ex3b;
struct ex3c ex3c;
struct ex4a ex4a;
struct ex5a ex5a;
struct ex5b ex5b;
int ex6a;
@@ -0,0 +1,360 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* kabi_ex.h
*
* Copyright (C) 2024 Google LLC
*
* Examples for kABI stability features with --stable.
*/
/*
* The comments below each example contain the expected gendwarfksyms
* output, which can be verified using LLVM's FileCheck tool:
*
* https://llvm.org/docs/CommandGuide/FileCheck.html
*
* Usage:
*
* $ gcc -g -c examples/kabi_ex.c -o examples/kabi_ex.o
*
* $ nm examples/kabi_ex.o | awk '{ print $NF }' | \
* ./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__
#define __KABI_EX_H__
#include "kabi.h"
/*
* Example: kABI rules
*/
struct s {
int a;
};
KABI_DECLONLY(s);
/*
* STABLE: variable structure_type s {
* STABLE-NEXT: }
*/
enum e {
A,
B,
C,
D,
};
KABI_ENUMERATOR_IGNORE(e, B);
KABI_ENUMERATOR_IGNORE(e, C);
KABI_ENUMERATOR_VALUE(e, D, 123456789);
/*
* STABLE: variable enumeration_type e {
* STABLE-NEXT: enumerator A = 0 ,
* STABLE-NEXT: enumerator D = 123456789
* STABLE-NEXT: } byte_size(4)
*/
/*
* Example: Reserved fields
*/
struct ex0a {
int a;
KABI_RESERVE(0);
KABI_RESERVE(1);
};
/*
* STABLE: variable structure_type ex0a {
* 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) data_member_location(8) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
* STABLE-NEXT: } byte_size(24)
*/
struct ex0b {
int a;
KABI_RESERVE(0);
KABI_USE2(1, int b, int c);
};
/*
* STABLE: variable structure_type ex0b {
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
* STABLE-NEXT: } byte_size(24)
*/
struct ex0c {
int a;
KABI_USE(0, void *p);
KABI_USE2(1, int b, int c);
};
/*
* STABLE: variable structure_type ex0c {
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
* STABLE-NEXT: } byte_size(24)
*/
/*
* Example: A reserved array
*/
struct ex1a {
unsigned int a;
KABI_RESERVE_ARRAY(0, 64);
};
/*
* STABLE: variable structure_type ex1a {
* STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
* STABLE-NEXT: member array_type[64] {
* STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
* STABLE-NEXT: } data_member_location(8)
* STABLE-NEXT: } byte_size(72)
*/
struct ex1b {
unsigned int a;
KABI_USE_ARRAY(
0, 64, struct {
void *p;
KABI_RESERVE_ARRAY(1, 56);
});
};
/*
* STABLE: variable structure_type ex1b {
* STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
* STABLE-NEXT: member array_type[64] {
* STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
* STABLE-NEXT: } data_member_location(8)
* STABLE-NEXT: } byte_size(72)
*/
struct ex1c {
unsigned int a;
KABI_USE_ARRAY(0, 64, void *p[8]);
};
/*
* STABLE: variable structure_type ex1c {
* STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
* STABLE-NEXT: member array_type[64] {
* STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
* STABLE-NEXT: } data_member_location(8)
* STABLE-NEXT: } byte_size(72)
*/
/*
* Example: An ignored field added to an alignment hole
*/
struct ex2a {
int a;
unsigned long b;
int c;
unsigned long d;
};
/*
* 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]] 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)
*/
struct ex2b {
int a;
KABI_IGNORE(0, unsigned int n);
unsigned long b;
int c;
unsigned long d;
};
_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2b), "ex2a size doesn't match ex2b");
/*
* STABLE: variable structure_type ex2b {
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
* 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)
*/
struct ex2c {
int a;
KABI_IGNORE(0, unsigned int n);
unsigned long b;
int c;
KABI_IGNORE(1, unsigned int m);
unsigned long d;
};
_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2c), "ex2a size doesn't match ex2c");
/*
* STABLE: variable structure_type ex2c {
* STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
* 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)
*/
/*
* Example: A replaced field
*/
struct ex3a {
unsigned long a;
unsigned long unused;
};
/*
* STABLE: variable structure_type ex3a {
* 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)
*/
struct ex3b {
unsigned long a;
KABI_REPLACE(unsigned long, unused, unsigned long renamed);
};
_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3b), "ex3a size doesn't match ex3b");
/*
* STABLE: variable structure_type ex3b {
* 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)
*/
struct ex3c {
unsigned long a;
KABI_REPLACE(unsigned long, unused, long replaced);
};
_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3c), "ex3a size doesn't match ex3c");
/*
* STABLE: variable structure_type ex3c {
* 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)
*/
/*
* Example: An ignored field added to an end of a partially opaque struct,
* while keeping the byte_size attribute unchanged.
*/
struct ex4a {
unsigned long a;
KABI_IGNORE(0, unsigned long b);
};
/*
* This may be safe if the structure allocation is managed by the core kernel
* and the layout remains unchanged except for appended new members.
*/
KABI_BYTE_SIZE(ex4a, 8);
/*
* STABLE: variable structure_type ex4a {
* STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
* 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__ */
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2024 Google LLC
*
* Example for symbol pointers. When compiled with Clang, gendwarfkyms
* uses a symbol pointer for `f`.
*
* $ clang -g -c examples/symbolptr.c -o examples/symbolptr.o
* $ echo -e "f\ng\np" | ./gendwarfksyms -d examples/symbolptr.o
*/
/* Kernel macros for userspace testing. */
#ifndef __used
#define __used __attribute__((__used__))
#endif
#ifndef __section
#define __section(section) __attribute__((__section__(section)))
#endif
#define __GENDWARFKSYMS_EXPORT(sym) \
static typeof(sym) *__gendwarfksyms_ptr_##sym __used \
__section(".discard.gendwarfksyms") = &sym;
extern void f(unsigned int arg);
void g(int *arg);
void g(int *arg) {}
struct s;
extern struct s *p;
__GENDWARFKSYMS_EXPORT(f);
__GENDWARFKSYMS_EXPORT(g);
__GENDWARFKSYMS_EXPORT(p);