| 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 |  | 
|---|