Skip to contentSkip to conversation

Gcov-kernel patch update for 2.6.0-test3

PATCH Paul Larson 1 participant 1 message Aug 19, 2003

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
diff -Naurp linux-2.6.0-test3/Makefile linux-2.6.0-test3-gcov/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/arch/i386/Kconfig linux-2.6.0-test3-gcov/arch/i386/Kconfig
@@ -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
diff -Naurp linux-2.6.0-test3/arch/i386/boot/compressed/Makefile linux-2.6.0-test3-gcov/arch/i386/boot/compressed/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/arch/i386/kernel/head.S linux-2.6.0-test3-gcov/arch/i386/kernel/head.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/Kconfig linux-2.6.0-test3-gcov/arch/ppc/Kconfig
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/boot/openfirmware/common.c linux-2.6.0-test3-gcov/arch/ppc/boot/openfirmware/common.c
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/boot/prep/misc.c linux-2.6.0-test3-gcov/arch/ppc/boot/prep/misc.c
@@ -71,6 +71,10 @@ extern unsigned long serial_init(int cha
 extern 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
diff -Naurp linux-2.6.0-test3/arch/ppc/kernel/Makefile linux-2.6.0-test3-gcov/arch/ppc/kernel/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/kernel/entry.S linux-2.6.0-test3-gcov/arch/ppc/kernel/entry.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/kernel/head.S linux-2.6.0-test3-gcov/arch/ppc/kernel/head.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc/syslib/prom_init.c linux-2.6.0-test3-gcov/arch/ppc/syslib/prom_init.c
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc64/Kconfig linux-2.6.0-test3-gcov/arch/ppc64/Kconfig
@@ -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
diff -Naurp linux-2.6.0-test3/arch/ppc64/kernel/head.S linux-2.6.0-test3-gcov/arch/ppc64/kernel/head.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/s390/Kconfig linux-2.6.0-test3-gcov/arch/s390/Kconfig
@@ -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
diff -Naurp linux-2.6.0-test3/arch/s390/kernel/head.S linux-2.6.0-test3-gcov/arch/s390/kernel/head.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/s390/kernel/head64.S linux-2.6.0-test3-gcov/arch/s390/kernel/head64.S
@@ -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
diff -Naurp linux-2.6.0-test3/arch/x86_64/Kconfig linux-2.6.0-test3-gcov/arch/x86_64/Kconfig
@@ -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
diff -Naurp linux-2.6.0-test3/arch/x86_64/kernel/head.S linux-2.6.0-test3-gcov/arch/x86_64/kernel/head.S
@@ -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
diff -Naurp linux-2.6.0-test3/drivers/Makefile linux-2.6.0-test3-gcov/drivers/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/drivers/gcov/Makefile linux-2.6.0-test3-gcov/drivers/gcov/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/include/linux/module.h linux-2.6.0-test3-gcov/include/linux/module.h
@@ -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
diff -Naurp linux-2.6.0-test3/init/main.c linux-2.6.0-test3-gcov/init/main.c
@@ -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
diff -Naurp linux-2.6.0-test3/kernel/Makefile linux-2.6.0-test3-gcov/kernel/Makefile
@@ -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
diff -Naurp linux-2.6.0-test3/kernel/module.c linux-2.6.0-test3-gcov/kernel/module.c
@@ -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
diff -Naurp linux-2.6.0-test3/scripts/Makefile.build linux-2.6.0-test3-gcov/scripts/Makefile.build
@@ -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);				\
 									\