Gcov-kernel patch update for 2.6.0-test3
Subsystems (3)
Here's another resync of the kernel patch (originally by Hubertus Franke and Rajan Ravindran) to allow the gcov coverage analysis tool to be used on Linux kernel code.
This is mostly just an update for 2.6.0-test3 but also includes the port to s390/s390x, but I have not been able to test this yet.
These patche is attached, and can also be downloaded from:
https://sourceforge.net/project/showfiles.php?group_id=3382
The LCOV tools to analyze the results that come out of this can also be downloaded there. For more information about this patch, please see:
http://ltp.sourceforge.net/coverage/gcov-kernel.php
Thanks,
Paul Larson
# Makefile | 12 # arch/i386/Kconfig | 30 + # arch/i386/boot/compressed/Makefile | 1 # arch/i386/kernel/head.S | 21 + # arch/ppc/Kconfig | 30 + # arch/ppc/boot/openfirmware/common.c | 4 # arch/ppc/boot/prep/misc.c | 4 # arch/ppc/kernel/Makefile | 4 # arch/ppc/kernel/entry.S | 16 # arch/ppc/kernel/head.S | 22 + # arch/ppc/syslib/prom_init.c | 4 # arch/ppc64/Kconfig | 31 + # arch/ppc64/kernel/head.S | 21 + # arch/s390/Kconfig | 30 + # arch/s390/kernel/head.S | 20 + # arch/s390/kernel/head64.S | 20 + # arch/x86_64/Kconfig | 31 + # arch/x86_64/kernel/head.S | 20 + # drivers/Makefile | 1 # drivers/gcov/Makefile | 8 # drivers/gcov/gcov-proc.c | 713 ++++++++++++++++++++++++++++++++++++ # include/linux/module.h | 5 # init/main.c | 4 # kernel/Makefile | 6 # kernel/gcov.c | 158 +++++++ # kernel/module.c | 23 + # scripts/Makefile.build | 24 +
# 27 files changed, 1257 insertions(+), 6 deletions(-)
Makefile +11 -1
@@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -test3 +EXTRAVERSION = -test3-gcov # *DOCUMENTATION* # To see a list of typical targets execute "make help"
@@ -76,6 +76,8 @@ HOSTCXX = g++ HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer HOSTCXXFLAGS = -O2 +GCOV_FLAGS = -fprofile-arcs -ftest-coverage + # That's our default target when none is given on the command line # Note that 'modules' will be added as a prerequisite as well,
@@ -235,6 +237,8 @@ export VERSION PATCHLEVEL SUBLEVEL EXTRA export CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE +export CFLAGS_NOGCOV + export MODVERDIR := .tmp_versions
@@ -534,6 +538,11 @@ depend dep: # --------------------------------------------------------------------------- # Modules +CFLAGS_NOGCOV := $(CFLAGS) +ifdef CONFIG_GCOV_ALL +CFLAGS += $(GCOV_FLAGS) +endif + ifdef CONFIG_MODULES # By default, build modules as well
@@ -716,6 +725,7 @@ clean: archclean $(clean-dirs) $(call cmd,rmclean) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -type f -print | xargs rm -f
arch/i386/Kconfig +30 -0
@@ -1245,6 +1245,36 @@ source "net/bluetooth/Kconfig" source "arch/i386/oprofile/Kconfig" +menu "GCOV coverage profiling" + +config GCOV_PROFILE + bool "GCOV coverage profiling" + ---help--- + Provide infrastructure for coverage support for the kernel. This + will not compile the kernel by default with the necessary flags. + To obtain coverage information for the entire kernel, one should + enable the subsequent option (Profile entire kernel). If only + particular files or directories of the kernel are desired, then + one must provide the following compile options for such targets: + "-fprofile-arcs -ftest-coverage" in the CFLAGS. To obtain + access to the coverage data one must insmod the gcov-proc kernel + module. + +config GCOV_ALL + bool "GCOV_ALL" + depends on GCOV_PROFILE + ---help--- + If you say Y here, it will compile the entire kernel with coverage + option enabled. + +config GCOV_PROC + tristate "gcov-proc module" + depends on GCOV_PROFILE && PROC_FS + ---help--- + This is the gcov-proc module that exposes gcov data through the + /proc filesystem + +endmenu menu "Kernel hacking"
arch/i386/boot/compressed/Makefile +1 -0
@@ -7,6 +7,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o EXTRA_AFLAGS := -traditional +CFLAGS := $(CFLAGS_NOGCOV) LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 $(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
arch/i386/kernel/head.S +21 -0
@@ -487,3 +487,24 @@ ENTRY(cpu_gdt_table) .fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPU's GDT */ #endif +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif +
arch/ppc/Kconfig +30 -0
@@ -1378,6 +1378,36 @@ source "net/bluetooth/Kconfig" source "lib/Kconfig" +menu "GCOV coverage profiling" + +config GCOV_PROFILE + bool "GCOV coverage profiling" + ---help--- + Provide infrastructure for coverage support for the kernel. This + will not compile the kernel by default with the necessary flags. + To obtain coverage information for the entire kernel, one should + enable the subsequent option (Profile entire kernel). If only + particular files or directories of the kernel are desired, then + one must provide the following compile options for such targets: + "-fprofile-arcs -ftest-coverage" in the CFLAGS. To obtain + access to the coverage data one must insmod the gcov-prof kernel + module. + +config GCOV_ALL + bool "GCOV_ALL" + depends on GCOV_PROFILE + ---help--- + If you say Y here, it will compile the entire kernel with coverage + option enabled. + +config GCOV_PROC + tristate "gcov-proc module" + depends on GCOV_PROFILE && PROC_FS + ---help--- + This is the gcov-proc module that exposes gcov data through the + /proc filesystem + +endmenu menu "Kernel hacking"
arch/ppc/boot/openfirmware/common.c +4 -0
@@ -30,6 +30,10 @@ struct memchunk {static struct memchunk *freechunks; +#ifdef CONFIG_GCOV_PROFILE +void __bb_init_func (void *ptr/* struct bb *blocks */ ) { } +#endif +static void *zalloc (void *x,unsigned items,unsigned size) {void *p;
arch/ppc/boot/prep/misc.c +4 -0
@@ -71,6 +71,10 @@ extern unsigned long serial_init(int chaextern void serial_fixups (void );extern unsigned long get_mem_size (void ); +#ifdef CONFIG_GCOV_PROFILE +void __bb_init_func (void *ptr/* struct bb *blocks */ ) { } +#endif +void writel (unsigned int val,unsigned int address) {
arch/ppc/kernel/Makefile +2 -2
@@ -15,8 +15,8 @@ extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o -obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ - process.o signal.o ptrace.o align.o \ +obj-y := entry.o ptrace.o traps.o irq.o idle.o time.o misc.o \ + process.o signal.o align.o \ semaphore.o syscalls.o setup.o \ cputable.o ppc_htab.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
arch/ppc/kernel/entry.S +16 -0
@@ -106,10 +106,26 @@ transfer_to_handler: mfspr r11,SPRN_HID0 mtcr r11 BEGIN_FTR_SECTION +#ifdef CONFIG_GCOV_PROFILE + bt- 8,near1_power_save_6xx_restore /* Check DOZE */ + b skip1_power_save_6xx_restore +near1_power_save_6xx_restore: + b power_save_6xx_restore +skip1_power_save_6xx_restore: +#else bt- 8,power_save_6xx_restore /* Check DOZE */ +#endif END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) BEGIN_FTR_SECTION +#ifdef CONFIG_GCOV_PROFILE + bt- 9,near2_power_save_6xx_restore /* Check NAP */ + b skip2_power_save_6xx_restore +near2_power_save_6xx_restore: + b power_save_6xx_restore +skip2_power_save_6xx_restore: +#else bt- 9,power_save_6xx_restore /* Check NAP */ +#endif END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont
arch/ppc/kernel/head.S +22 -0
@@ -1643,3 +1643,25 @@ intercept_table: */ abatron_pteptrs: .space 8 + +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif +
arch/ppc/syslib/prom_init.c +4 -0
@@ -667,7 +667,11 @@ prom_instantiate_rtas(void)* Actually OF has bugs so we just arbitrarily * use memory at the 6MB point. */ +#ifdef CONFIG_GCOV_PROFILE + rtas_data =0x990000 ; +#else rtas_data =6 <<20 ; +#endif prom_print (" at " );prom_print_hex (rtas_data); }
arch/ppc64/Kconfig +31 -0
@@ -342,6 +342,37 @@ config VIOPATH source "arch/ppc64/oprofile/Kconfig" +menu "GCOV coverage profiling" + +config GCOV_PROFILE + bool "GCOV coverage profiling" + ---help--- + Provide infrastructure for coverage support for the kernel. This + will not compile the kernel by default with the necessary flags. + To obtain coverage information for the entire kernel, one should + enable the subsequent option (Profile entire kernel). If only + particular files or directories of the kernel are desired, then + one must provide the following compile options for such targets: + "-fprofile-arcs -ftest-coverage" in the CFLAGS. To obtain + access to the coverage data one must insmod the gcov-prof kernel + module. + +config GCOV_ALL + bool "GCOV_ALL" + depends on GCOV_PROFILE + ---help--- + If you say Y here, it will compile the entire kernel with coverage + option enabled. + +config GCOV_PROC + tristate "gcov-proc module" + depends on GCOV_PROFILE && PROC_FS + ---help--- + This is the gcov-proc module that exposes gcov data through the + /proc filesystem + +endmenu + menu "Kernel hacking" config DEBUG_KERNEL
arch/ppc64/kernel/head.S +21 -0
@@ -2015,3 +2015,24 @@ stab_array: .globl cmd_line cmd_line: .space 512 + +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif
arch/s390/Kconfig +30 -0
@@ -267,6 +267,36 @@ source "net/Kconfig" source "fs/Kconfig" +menu "GCOV coverage profiling" + +config GCOV_PROFILE + bool "GCOV coverage profiling" + ---help--- + Provide infrastructure for coverage support for the kernel. This + will not compile the kernel by default with the necessary flags. + To obtain coverage information for the entire kernel, one should + enable the subsequent option (Profile entire kernel). If only + particular files or directories of the kernel are desired, then + one must provide the following compile options for such targets: + "-fprofile-arcs -ftest-coverage" in the CFLAGS. To obtain + access to the coverage data one must insmod the gcov-proc kernel + module. + +config GCOV_ALL + bool "GCOV_ALL" + depends on GCOV_PROFILE + ---help--- + If you say Y here, it will compile the entire kernel with coverage + option enabled. + +config GCOV_PROC + tristate "gcov-proc module" + depends on GCOV_PROFILE && PROC_FS + ---help--- + This is the gcov-proc module that exposes gcov data through the + /proc filesystem + +endmenu menu "Kernel hacking"
arch/s390/kernel/head.S +20 -0
@@ -660,3 +660,23 @@ _stext: basr %r13,0 .Lstart: .long start_kernel .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif
arch/s390/kernel/head64.S +20 -0
@@ -666,3 +666,23 @@ _stext: basr %r13,0 .Ldw: .quad 0x0002000180000000,0x0000000000000000 .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif
arch/x86_64/Kconfig +31 -0
@@ -451,6 +451,37 @@ source "net/bluetooth/Kconfig" source "arch/x86_64/oprofile/Kconfig" +menu "GCOV coverage profiling" + +config GCOV_PROFILE + bool "GCOV coverage profiling" + ---help--- + Provide infrastructure for coverage support for the kernel. This + will not compile the kernel by default with the necessary flags. + To obtain coverage information for the entire kernel, one should + enable the subsequent option (Profile entire kernel). If only + particular files or directories of the kernel are desired, then + one must provide the following compile options for such targets: + "-fprofile-arcs -ftest-coverage" in the CFLAGS. To obtain + access to the coverage data one must insmod the gcov-prof kernel + module. + +config GCOV_ALL + bool "GCOV_ALL" + depends on GCOV_PROFILE + ---help--- + If you say Y here, it will compile the entire kernel with coverage + option enabled. + +config GCOV_PROC + tristate "gcov-proc module" + depends on GCOV_PROFILE && PROC_FS + ---help--- + This is the gcov-proc module that exposes gcov data through the + /proc filesystem + +endmenu + menu "Kernel hacking" config DEBUG_KERNEL
arch/x86_64/kernel/head.S +20 -0
@@ -383,3 +383,23 @@ ENTRY(idt_table) .quad 0 .endr +#ifdef CONFIG_GCOV_PROFILE +/* + * The .ctors-section contains a list of pointers to constructor + * functions which are used to initialize gcov structures. + * + * Because there is no NULL at the end of the constructor list + * in the kernel we need the addresses of both the constructor + * as well as the destructor list which are supposed to be + * adjacent. + */ + +.section ".ctors","aw" +.globl __CTOR_LIST__ +.type __CTOR_LIST__,@object +__CTOR_LIST__: +.section ".dtors","aw" +.globl __DTOR_LIST__ +.type __DTOR_LIST__,@object +__DTOR_LIST__: +#endif
drivers/Makefile +1 -0
@@ -49,3 +49,4 @@ obj-$(CONFIG_ISDN_BOOL) += isdn/ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ +obj-$(CONFIG_GCOV_PROC) += gcov/
drivers/gcov/Makefile +8 -0
@@ -0,0 +1,8 @@ +# +# Makefile for GCOV profiling kernel module +# + +obj-$(CONFIG_GCOV_PROC) += gcov-proc.o + +$(obj)/gcov-proc.o: $(obj)/gcov-proc.c +
drivers/gcov/gcov-proc.c +713 -0
713 lines not on this page · raw message
include/linux/module.h +5 -0
@@ -257,6 +257,11 @@ struct module/* The command line arguments (may be mangled). People like keeping pointers to this stuff */ char *args; + +#ifdef CONFIG_GCOV_PROFILE +const char *ctors_start;/* Pointer to start of .ctors-section */ +const char *ctors_end;/* Pointer to end of .ctors-section */ +#endif };/* FIXME: It'd be nice to isolate modules during init, too, so they
init/main.c +4 -0
@@ -115,6 +115,10 @@ char *execute_command;/* Setup configured maximum number of CPUs to activate */ static unsigned int max_cpus =NR_CPUS ; +#if defined(CONFIG_GCOV_PROFILE ) && (defined(CONFIG_PPC32 ) || defined(CONFIG_PPC64 )) +void __bb_fork_func (void ) { } +#endif +/* * Setup routine for controlling SMP activation *
kernel/Makefile +6 -0
@@ -8,6 +8,12 @@ obj-y = sched.o fork.o exec_domain.o signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o intermodule.o extable.o params.o posix-timers.o +ifdef CONFIG_GCOV_PROFILE +obj-y += gcov.o +export-objs += gcov.o +CFLAGS_gcov.o := -DGCOV_PATH='"$(TOPDIR)"' +endif + obj-$(CONFIG_FUTEX) += futex.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_SMP) += cpu.o
kernel/gcov.c +158 -0
158 lines not on this page · raw message
kernel/module.c +23 -0
@@ -83,6 +83,11 @@ int unregister_module_notifier(struct no }EXPORT_SYMBOL (unregister_module_notifier); +#ifdef CONFIG_GCOV_PROFILE +extern void remove_bb_link (struct module *); +extern void do_global_ctors (char *,char *,struct module *,int ); +#endif +/* We require a truly strong try_module_get() */ static inline int strong_try_module_get (struct module *mod) {
@@ -1082,6 +1087,11 @@ static void free_module(struct module *m/* Arch-specific cleanup. */ module_arch_cleanup (mod); +#ifdef CONFIG_GCOV_PROFILE +if (mod->ctors_start && mod->ctors_end) +remove_bb_link (mod); +#endif +/* Module unload stuff */ module_unload_free (mod);
@@ -1573,6 +1583,13 @@ static struct module *load_module(void _/* Module has been moved. */ mod = (void *)sechdrs[modindex].sh_addr; +#ifdef CONFIG_GCOV_PROFILE + modindex =find_sec (hdr, sechdrs, secstrings,".ctors" ); + mod->ctors_start = (char *)sechdrs[modindex].sh_addr; + mod->ctors_end = (char *)(mod->ctors_start + + sechdrs[modindex].sh_size); +#endif +/* Now we've moved module, initialize linked lists, etc. */ module_unload_init (mod);
@@ -1722,6 +1739,12 @@ sys_init_module(void __user *umod,/* Start the module */ ret = mod->init (); + +#ifdef CONFIG_GCOV_PROFILE +if (mod->ctors_start && mod->ctors_end) { +do_global_ctors (mod->ctors_start, mod->ctors_end, mod,1 ); + } +#endif if (ret <0 ) {/* Init routine failed: abort. Try to protect us from buggy refcounters. */
scripts/Makefile.build +21 -3
@@ -119,7 +119,16 @@ cmd_cc_i_c = $(CPP) $(c_flags) - quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ ifndef CONFIG_MODVERSIONS -cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< +new1_c_flags = $(c_flags:-I%=-I$(TOPDIR)/%) +new2_c_flags = $(new1_c_flags:-Wp%=) +PWD = $(TOPDIR) + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ +cmd_cc_o_c = $(CC) $(c_flags) -E -o $@ $< \ + && cd $(dir $<) \ + && $(CC) $(new2_c_flags) -c -o $(notdir $@) $(notdir $<) \ + && cd $(TOPDIR) +#cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< else # When module versioning is enabled the following steps are executed:
@@ -134,12 +143,21 @@ else # replace the unresolved symbols __crc_exported_symbol with # the actual value of the checksum generated by genksyms -cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< +new1_c_flags = $(c_flags:-I%=-I$(TOPDIR)/%) +new2_c_flags = $(new1_c_flags:-Wp%=) +PWD = $(TOPDIR) + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ +cmd_cc_o_c = $(CC) $(c_flags) -E -o $@ $< \ + && cd $(dir $<) \ + && $(CC) $(new2_c_flags) -c -o .tmp_$(@F) $(notdir $<) \ + && cd $(TOPDIR) +#cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ mv $(@D)/.tmp_$(@F) $@; \ else \ - $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + $(CPP) -D__GENKSYMS__ $(new2_c_flags) $< \ | $(GENKSYMS) \ > $(@D)/.tmp_$(@F:.o=.ver); \ \