1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_ELFNOTE_H |
3 | #define _LINUX_ELFNOTE_H |
4 | /* |
5 | * Helper macros to generate ELF Note structures, which are put into a |
6 | * PT_NOTE segment of the final vmlinux image. These are useful for |
7 | * including name-value pairs of metadata into the kernel binary (or |
8 | * modules?) for use by external programs. |
9 | * |
10 | * Each note has three parts: a name, a type and a desc. The name is |
11 | * intended to distinguish the note's originator, so it would be a |
12 | * company, project, subsystem, etc; it must be in a suitable form for |
13 | * use in a section name. The type is an integer which is used to tag |
14 | * the data, and is considered to be within the "name" namespace (so |
15 | * "FooCo"'s type 42 is distinct from "BarProj"'s type 42). The |
16 | * "desc" field is the actual data. There are no constraints on the |
17 | * desc field's contents, though typically they're fairly small. |
18 | * |
19 | * All notes from a given NAME are put into a section named |
20 | * .note.NAME. When the kernel image is finally linked, all the notes |
21 | * are packed into a single .notes section, which is mapped into the |
22 | * PT_NOTE segment. Because notes for a given name are grouped into |
23 | * the same section, they'll all be adjacent the output file. |
24 | * |
25 | * This file defines macros for both C and assembler use. Their |
26 | * syntax is slightly different, but they're semantically similar. |
27 | * |
28 | * See the ELF specification for more detail about ELF notes. |
29 | */ |
30 | |
31 | #ifdef __ASSEMBLER__ |
32 | /* |
33 | * Generate a structure with the same shape as Elf{32,64}_Nhdr (which |
34 | * turn out to be the same size and shape), followed by the name and |
35 | * desc data with appropriate padding. The 'desctype' argument is the |
36 | * assembler pseudo op defining the type of the data e.g. .asciz while |
37 | * 'descdata' is the data itself e.g. "hello, world". |
38 | * |
39 | * e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two") |
40 | * ELFNOTE(XYZCo, 12, .long, 0xdeadbeef) |
41 | */ |
42 | #define ELFNOTE_START(name, type, flags) \ |
43 | .pushsection .note.name, flags,@note ; \ |
44 | .balign 4 ; \ |
45 | .long 2f - 1f /* namesz */ ; \ |
46 | .long 4484f - 3f /* descsz */ ; \ |
47 | .long type ; \ |
48 | 1:.asciz #name ; \ |
49 | 2:.balign 4 ; \ |
50 | 3: |
51 | |
52 | #define ELFNOTE_END \ |
53 | 4484:.balign 4 ; \ |
54 | .popsection ; |
55 | |
56 | #define ELFNOTE(name, type, desc) \ |
57 | ELFNOTE_START(name, type, "a") \ |
58 | desc ; \ |
59 | ELFNOTE_END |
60 | |
61 | #else /* !__ASSEMBLER__ */ |
62 | #include <uapi/linux/elf.h> |
63 | /* |
64 | * Use an anonymous structure which matches the shape of |
65 | * Elf{32,64}_Nhdr, but includes the name and desc data. The size and |
66 | * type of name and desc depend on the macro arguments. "name" must |
67 | * be a literal string, and "desc" must be passed by value. You may |
68 | * only define one note per line, since __LINE__ is used to generate |
69 | * unique symbols. |
70 | */ |
71 | #define _ELFNOTE_PASTE(a,b) a##b |
72 | #define _ELFNOTE(size, name, unique, type, desc) \ |
73 | static const struct { \ |
74 | struct elf##size##_note _nhdr; \ |
75 | unsigned char _name[sizeof(name)] \ |
76 | __attribute__((aligned(sizeof(Elf##size##_Word)))); \ |
77 | typeof(desc) _desc \ |
78 | __attribute__((aligned(sizeof(Elf##size##_Word)))); \ |
79 | } _ELFNOTE_PASTE(_note_, unique) \ |
80 | __used \ |
81 | __attribute__((section(".note." name), \ |
82 | aligned(sizeof(Elf##size##_Word)), \ |
83 | unused)) = { \ |
84 | { \ |
85 | sizeof(name), \ |
86 | sizeof(desc), \ |
87 | type, \ |
88 | }, \ |
89 | name, \ |
90 | desc \ |
91 | } |
92 | #define ELFNOTE(size, name, type, desc) \ |
93 | _ELFNOTE(size, name, __LINE__, type, desc) |
94 | |
95 | #define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc) |
96 | #define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc) |
97 | #endif /* __ASSEMBLER__ */ |
98 | |
99 | #endif /* _LINUX_ELFNOTE_H */ |
100 | |