* [PATCH 1/6] kernel: call constructors
@ 2008-06-02 13:34 Peter Oberparleiter
0 siblings, 0 replies; only message in thread
From: Peter Oberparleiter @ 2008-06-02 13:34 UTC (permalink / raw)
To: linux-kernel
Cc: ltp-coverage, Andrew Morton, Sam Ravnborg, Rusty Russell,
Peter Oberparleiter
From: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Call constructors during kernel init and module load. Required by the
gcov profiling infrastructure: gcc's profiling code uses constructors
to register profiling data structures.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
---
arch/powerpc/kernel/vmlinux.lds.S | 3 +++
include/asm-generic/sections.h | 1 +
include/asm-generic/vmlinux.lds.h | 5 +++++
include/linux/init.h | 2 ++
include/linux/module.h | 3 +++
init/main.c | 10 ++++++++++
kernel/module.c | 13 +++++++++++++
7 files changed, 37 insertions(+)
Index: linux-2.6.26-rc4/include/asm-generic/vmlinux.lds.h
===================================================================
--- linux-2.6.26-rc4.orig/include/asm-generic/vmlinux.lds.h
+++ linux-2.6.26-rc4/include/asm-generic/vmlinux.lds.h
@@ -352,3 +352,8 @@
*(.data.percpu.shared_aligned) \
} \
__per_cpu_end = .;
+
+#define CONSTRUCTORS \
+ VMLINUX_SYMBOL(__ctor_start) = .; \
+ *(.ctors) \
+ VMLINUX_SYMBOL(__ctor_end) = .;
Index: linux-2.6.26-rc4/arch/powerpc/kernel/vmlinux.lds.S
===================================================================
--- linux-2.6.26-rc4.orig/arch/powerpc/kernel/vmlinux.lds.S
+++ linux-2.6.26-rc4/arch/powerpc/kernel/vmlinux.lds.S
@@ -193,6 +193,9 @@ SECTIONS
*(.toc)
}
#endif
+ .data.gcov : {
+ CONSTRUCTORS
+ }
. = ALIGN(PAGE_SIZE);
_edata = .;
Index: linux-2.6.26-rc4/include/asm-generic/sections.h
===================================================================
--- linux-2.6.26-rc4.orig/include/asm-generic/sections.h
+++ linux-2.6.26-rc4/include/asm-generic/sections.h
@@ -13,5 +13,6 @@ extern char __per_cpu_start[], __per_cpu
extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
+extern char __ctor_start[], __ctor_end[];
#endif /* _ASM_GENERIC_SECTIONS_H_ */
Index: linux-2.6.26-rc4/include/linux/module.h
===================================================================
--- linux-2.6.26-rc4.orig/include/linux/module.h
+++ linux-2.6.26-rc4/include/linux/module.h
@@ -342,6 +342,9 @@ struct module
struct marker *markers;
unsigned int num_markers;
#endif
+ /* Constructor calls. */
+ ctorcall_t *ctors;
+ unsigned long num_ctors;
};
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
Index: linux-2.6.26-rc4/kernel/module.c
===================================================================
--- linux-2.6.26-rc4.orig/kernel/module.c
+++ linux-2.6.26-rc4/kernel/module.c
@@ -1770,6 +1770,7 @@ static struct module *load_module(void _
unsigned int unusedgplcrcindex;
unsigned int markersindex;
unsigned int markersstringsindex;
+ unsigned int ctorsindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1866,6 +1867,7 @@ static struct module *load_module(void _
#ifdef ARCH_UNWIND_SECTION_NAME
unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME);
#endif
+ ctorsindex = find_sec(hdr, sechdrs, secstrings, ".ctors");
/* Don't keep modinfo and version sections. */
sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
@@ -2076,6 +2078,8 @@ static struct module *load_module(void _
mod->num_markers =
sechdrs[markersindex].sh_size / sizeof(*mod->markers);
#endif
+ mod->ctors = (void *) sechdrs[ctorsindex].sh_addr;
+ mod->num_ctors = sechdrs[ctorsindex].sh_size / sizeof(*mod->ctors);
/* Find duplicate symbols */
err = verify_export_symbols(mod);
@@ -2188,6 +2192,14 @@ static struct module *load_module(void _
goto free_hdr;
}
+static void do_mod_ctors(struct module *mod)
+{
+ unsigned long i;
+
+ for (i = 0; i < mod->num_ctors; i++)
+ mod->ctors[i]();
+}
+
/* This is where the real work happens */
asmlinkage long
sys_init_module(void __user *umod,
@@ -2218,6 +2230,7 @@ sys_init_module(void __user *umod,
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_COMING, mod);
+ do_mod_ctors(mod);
/* Start the module */
if (mod->init != NULL)
ret = mod->init();
Index: linux-2.6.26-rc4/init/main.c
===================================================================
--- linux-2.6.26-rc4.orig/init/main.c
+++ linux-2.6.26-rc4/init/main.c
@@ -684,6 +684,15 @@ asmlinkage void __init start_kernel(void
rest_init();
}
+static void __init do_ctors(void)
+{
+ ctorcall_t *call;
+
+ for (call = (ctorcall_t *) __ctor_start;
+ call < (ctorcall_t *) __ctor_end; call++)
+ (*call)();
+}
+
static int __initdata initcall_debug;
static int __init initcall_debug_setup(char *str)
@@ -763,6 +772,7 @@ static void __init do_basic_setup(void)
usermodehelper_init();
driver_init();
init_irq_proc();
+ do_ctors();
do_initcalls();
}
Index: linux-2.6.26-rc4/include/linux/init.h
===================================================================
--- linux-2.6.26-rc4.orig/include/linux/init.h
+++ linux-2.6.26-rc4/include/linux/init.h
@@ -138,6 +138,8 @@ typedef void (*exitcall_t)(void);
extern initcall_t __con_initcall_start[], __con_initcall_end[];
extern initcall_t __security_initcall_start[], __security_initcall_end[];
+typedef void (*ctorcall_t)(void);
+
/* Defined in init/main.c */
extern char __initdata boot_command_line[];
extern char *saved_command_line;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-06-02 13:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-02 13:34 [PATCH 1/6] kernel: call constructors Peter Oberparleiter
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.