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