aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2006-09-26 02:32:26 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:55 -0400
commit9c9b8b388296ad5a306ab238dc677cfe6ff4cb12 (patch)
tree997b14216fa77db77052766b38dd0ef4cd829648
parent461a9afff5e731d6337c0f5b08a1e727ccd57e0a (diff)
[PATCH] x86: put .note.* sections into a PT_NOTE segment in vmlinux
This patch will pack any .note.* section into a PT_NOTE segment in the output file. To do this, we tell ld that we need a PT_NOTE segment. This requires us to start explicitly mapping sections to segments, so we also need to explicitly create PT_LOAD segments for text and data, and map the sections to them appropriately. Fortunately, each section will default to its previous section's segment, so it doesn't take many changes to vmlinux.lds.S. This only changes i386 for now, but I presume the corresponding changes for other architectures will be as simple. This change also adds <linux/elfnote.h>, which defines C and Assembler macros for actually creating ELF notes. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/vmlinux.lds.S12
-rw-r--r--include/asm-generic/vmlinux.lds.h3
-rw-r--r--include/linux/elfnote.h88
3 files changed, 101 insertions, 2 deletions
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 2d4f1386e2b1..1e7ac1c44ddc 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
13OUTPUT_ARCH(i386) 13OUTPUT_ARCH(i386)
14ENTRY(phys_startup_32) 14ENTRY(phys_startup_32)
15jiffies = jiffies_64; 15jiffies = jiffies_64;
16
17PHDRS {
18 text PT_LOAD FLAGS(5); /* R_E */
19 data PT_LOAD FLAGS(7); /* RWE */
20 note PT_NOTE FLAGS(4); /* R__ */
21}
16SECTIONS 22SECTIONS
17{ 23{
18 . = __KERNEL_START; 24 . = __KERNEL_START;
@@ -26,7 +32,7 @@ SECTIONS
26 KPROBES_TEXT 32 KPROBES_TEXT
27 *(.fixup) 33 *(.fixup)
28 *(.gnu.warning) 34 *(.gnu.warning)
29 } = 0x9090 35 } :text = 0x9090
30 36
31 _etext = .; /* End of text section */ 37 _etext = .; /* End of text section */
32 38
@@ -48,7 +54,7 @@ SECTIONS
48 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ 54 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
49 *(.data) 55 *(.data)
50 CONSTRUCTORS 56 CONSTRUCTORS
51 } 57 } :data
52 58
53 . = ALIGN(4096); 59 . = ALIGN(4096);
54 __nosave_begin = .; 60 __nosave_begin = .;
@@ -184,4 +190,6 @@ SECTIONS
184 STABS_DEBUG 190 STABS_DEBUG
185 191
186 DWARF_DEBUG 192 DWARF_DEBUG
193
194 NOTES
187} 195}
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index db5a3732f106..253ae1328271 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -194,3 +194,6 @@
194 .stab.index 0 : { *(.stab.index) } \ 194 .stab.index 0 : { *(.stab.index) } \
195 .stab.indexstr 0 : { *(.stab.indexstr) } \ 195 .stab.indexstr 0 : { *(.stab.indexstr) } \
196 .comment 0 : { *(.comment) } 196 .comment 0 : { *(.comment) }
197
198#define NOTES \
199 .notes : { *(.note.*) } :note
diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h
new file mode 100644
index 000000000000..16f9f8ebffd9
--- /dev/null
+++ b/include/linux/elfnote.h
@@ -0,0 +1,88 @@
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
34 * desc data with appropriate padding. The 'desc' argument includes
35 * the assembler pseudo op defining the type of the data: .asciz
36 * "hello, world"
37 */
38.macro ELFNOTE name type desc:vararg
39.pushsection ".note.\name"
40 .align 4
41 .long 2f - 1f /* namesz */
42 .long 4f - 3f /* descsz */
43 .long \type
441:.asciz "\name"
452:.align 4
463:\desc
474:.align 4
48.popsection
49.endm
50#else /* !__ASSEMBLER__ */
51#include <linux/elf.h>
52/*
53 * Use an anonymous structure which matches the shape of
54 * Elf{32,64}_Nhdr, but includes the name and desc data. The size and
55 * type of name and desc depend on the macro arguments. "name" must
56 * be a literal string, and "desc" must be passed by value. You may
57 * only define one note per line, since __LINE__ is used to generate
58 * unique symbols.
59 */
60#define _ELFNOTE_PASTE(a,b) a##b
61#define _ELFNOTE(size, name, unique, type, desc) \
62 static const struct { \
63 struct elf##size##_note _nhdr; \
64 unsigned char _name[sizeof(name)] \
65 __attribute__((aligned(sizeof(Elf##size##_Word)))); \
66 typeof(desc) _desc \
67 __attribute__((aligned(sizeof(Elf##size##_Word)))); \
68 } _ELFNOTE_PASTE(_note_, unique) \
69 __attribute_used__ \
70 __attribute__((section(".note." name), \
71 aligned(sizeof(Elf##size##_Word)), \
72 unused)) = { \
73 { \
74 sizeof(name), \
75 sizeof(desc), \
76 type, \
77 }, \
78 name, \
79 desc \
80 }
81#define ELFNOTE(size, name, type, desc) \
82 _ELFNOTE(size, name, __LINE__, type, desc)
83
84#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc)
85#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc)
86#endif /* __ASSEMBLER__ */
87
88#endif /* _LINUX_ELFNOTE_H */