From 5db8d219b03597a23ad037bd7b940d73282dc4fa Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 22 Aug 2006 12:20:43 +0100 Subject: [LINUX] Support creating ELF note segments in the kernel ELF image. i386 version is taken from 2.6.18-rc4-mm1 and x86_64 version has been submitted for inclusion. Signed-off-by: Ian Campbell --- patches/linux-2.6.16.13/series | 2 + ...ections-into-a-pt_note-segment-in-vmlinux.patch | 174 +++++++++++++++++++++ ...ections-into-a-pt_note-segment-in-vmlinux.patch | 40 +++++ 3 files changed, 216 insertions(+) create mode 100644 patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch create mode 100644 patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch (limited to 'patches') diff --git a/patches/linux-2.6.16.13/series b/patches/linux-2.6.16.13/series index c6f5dd27c9..12af0f7312 100644 --- a/patches/linux-2.6.16.13/series +++ b/patches/linux-2.6.16.13/series @@ -18,3 +18,5 @@ tpm_plugin_2.6.17.patch x86-increase-interrupt-vector-range.patch xen-hotplug.patch xenoprof-generic.patch +x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch +x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch diff --git a/patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch b/patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch new file mode 100644 index 0000000000..6f2422f517 --- /dev/null +++ b/patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch @@ -0,0 +1,174 @@ +Taken from 2.6.18-rc4-mm1. + +From: Jeremy Fitzhardinge + +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 , which defines C and Assembler macros +for actually creating ELF notes. + +Signed-off-by: Jeremy Fitzhardinge +Cc: Eric W. Biederman +Cc: Hollis Blanchard +Signed-off-by: Andrew Morton +--- + + arch/i386/kernel/vmlinux.lds.S | 12 +++ + include/asm-generic/vmlinux.lds.h | 3 + include/linux/elfnote.h | 88 ++++++++++++++++++++++++++++ + 3 files changed, 101 insertions(+), 2 deletions(-) + +diff -puN arch/i386/kernel/vmlinux.lds.S~x86-put-note-sections-into-a-pt_note-segment-in-vmlinux arch/i386/kernel/vmlinux.lds.S +--- a/arch/i386/kernel/vmlinux.lds.S~x86-put-note-sections-into-a-pt_note-segment-in-vmlinux ++++ a/arch/i386/kernel/vmlinux.lds.S +@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386" + OUTPUT_ARCH(i386) + ENTRY(phys_startup_32) + jiffies = jiffies_64; ++ ++PHDRS { ++ text PT_LOAD FLAGS(5); /* R_E */ ++ data PT_LOAD FLAGS(7); /* RWE */ ++ note PT_NOTE FLAGS(4); /* R__ */ ++} + SECTIONS + { + . = __KERNEL_START; +@@ -26,7 +32,7 @@ SECTIONS + KPROBES_TEXT + *(.fixup) + *(.gnu.warning) +- } = 0x9090 ++ } :text = 0x9090 + + _etext = .; /* End of text section */ + +@@ -50,7 +56,7 @@ SECTIONS + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ + *(.data) + CONSTRUCTORS +- } ++ } :data + + . = ALIGN(4096); + __nosave_begin = .; +@@ -186,4 +192,6 @@ SECTIONS + STABS_DEBUG + + DWARF_DEBUG ++ ++ NOTES + } +diff -puN include/asm-generic/vmlinux.lds.h~x86-put-note-sections-into-a-pt_note-segment-in-vmlinux include/asm-generic/vmlinux.lds.h +--- a/include/asm-generic/vmlinux.lds.h~x86-put-note-sections-into-a-pt_note-segment-in-vmlinux ++++ a/include/asm-generic/vmlinux.lds.h +@@ -194,3 +194,6 @@ + .stab.index 0 : { *(.stab.index) } \ + .stab.indexstr 0 : { *(.stab.indexstr) } \ + .comment 0 : { *(.comment) } ++ ++#define NOTES \ ++ .notes : { *(.note.*) } :note +diff -puN /dev/null include/linux/elfnote.h +--- /dev/null ++++ a/include/linux/elfnote.h +@@ -0,0 +1,88 @@ ++#ifndef _LINUX_ELFNOTE_H ++#define _LINUX_ELFNOTE_H ++/* ++ * Helper macros to generate ELF Note structures, which are put into a ++ * PT_NOTE segment of the final vmlinux image. These are useful for ++ * including name-value pairs of metadata into the kernel binary (or ++ * modules?) for use by external programs. ++ * ++ * Each note has three parts: a name, a type and a desc. The name is ++ * intended to distinguish the note's originator, so it would be a ++ * company, project, subsystem, etc; it must be in a suitable form for ++ * use in a section name. The type is an integer which is used to tag ++ * the data, and is considered to be within the "name" namespace (so ++ * "FooCo"'s type 42 is distinct from "BarProj"'s type 42). The ++ * "desc" field is the actual data. There are no constraints on the ++ * desc field's contents, though typically they're fairly small. ++ * ++ * All notes from a given NAME are put into a section named ++ * .note.NAME. When the kernel image is finally linked, all the notes ++ * are packed into a single .notes section, which is mapped into the ++ * PT_NOTE segment. Because notes for a given name are grouped into ++ * the same section, they'll all be adjacent the output file. ++ * ++ * This file defines macros for both C and assembler use. Their ++ * syntax is slightly different, but they're semantically similar. ++ * ++ * See the ELF specification for more detail about ELF notes. ++ */ ++ ++#ifdef __ASSEMBLER__ ++/* ++ * Generate a structure with the same shape as Elf{32,64}_Nhdr (which ++ * turn out to be the same size and shape), followed by the name and ++ * desc data with appropriate padding. The 'desc' argument includes ++ * the assembler pseudo op defining the type of the data: .asciz ++ * "hello, world" ++ */ ++.macro ELFNOTE name type desc:vararg ++.pushsection ".note.\name" ++ .align 4 ++ .long 2f - 1f /* namesz */ ++ .long 4f - 3f /* descsz */ ++ .long \type ++1:.asciz "\name" ++2:.align 4 ++3:\desc ++4:.align 4 ++.popsection ++.endm ++#else /* !__ASSEMBLER__ */ ++#include ++/* ++ * Use an anonymous structure which matches the shape of ++ * Elf{32,64}_Nhdr, but includes the name and desc data. The size and ++ * type of name and desc depend on the macro arguments. "name" must ++ * be a literal string, and "desc" must be passed by value. You may ++ * only define one note per line, since __LINE__ is used to generate ++ * unique symbols. ++ */ ++#define _ELFNOTE_PASTE(a,b) a##b ++#define _ELFNOTE(size, name, unique, type, desc) \ ++ static const struct { \ ++ struct elf##size##_note _nhdr; \ ++ unsigned char _name[sizeof(name)] \ ++ __attribute__((aligned(sizeof(Elf##size##_Word)))); \ ++ typeof(desc) _desc \ ++ __attribute__((aligned(sizeof(Elf##size##_Word)))); \ ++ } _ELFNOTE_PASTE(_note_, unique) \ ++ __attribute_used__ \ ++ __attribute__((section(".note." name), \ ++ aligned(sizeof(Elf##size##_Word)), \ ++ unused)) = { \ ++ { \ ++ sizeof(name), \ ++ sizeof(desc), \ ++ type, \ ++ }, \ ++ name, \ ++ desc \ ++ } ++#define ELFNOTE(size, name, type, desc) \ ++ _ELFNOTE(size, name, __LINE__, type, desc) ++ ++#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc) ++#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc) ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* _LINUX_ELFNOTE_H */ +_ diff --git a/patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch b/patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch new file mode 100644 index 0000000000..d2a1ac9cda --- /dev/null +++ b/patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch @@ -0,0 +1,40 @@ +diff -urN ref-linux-2.6.16.13/arch/x86_64/kernel/vmlinux.lds.S x86-64_elfnotes/arch/x86_64/kernel/vmlinux.lds.S +--- ref-linux-2.6.16.13/arch/x86_64/kernel/vmlinux.lds.S 2006-05-02 22:38:44.000000000 +0100 ++++ x86-64_elfnotes/arch/x86_64/kernel/vmlinux.lds.S 2006-08-22 11:39:14.000000000 +0100 +@@ -14,6 +14,11 @@ + OUTPUT_ARCH(i386:x86-64) + ENTRY(phys_startup_64) + jiffies_64 = jiffies; ++PHDRS { ++ text PT_LOAD FLAGS(5); /* R_E */ ++ data PT_LOAD FLAGS(7); /* RWE */ ++ note PT_NOTE FLAGS(4); /* R__ */ ++} + SECTIONS + { + . = __START_KERNEL; +@@ -26,7 +31,7 @@ + KPROBES_TEXT + *(.fixup) + *(.gnu.warning) +- } = 0x9090 ++ } :text = 0x9090 + /* out-of-line lock text */ + .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } + +@@ -43,7 +48,7 @@ + .data : AT(ADDR(.data) - LOAD_OFFSET) { + *(.data) + CONSTRUCTORS +- } ++ } :data + + _edata = .; /* End of data section */ + +@@ -201,4 +206,6 @@ + STABS_DEBUG + + DWARF_DEBUG ++ ++ NOTES + } -- cgit v1.2.3