Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 793cf029ed8fa198abf49a9bf9cb846bf82cddc5)
+++ kernel/Makefile	(revision 263bda21cd3cd48db6a7af349e737c62847da815)
@@ -160,4 +160,5 @@
 	CFLAGS = $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION = -finstrument-functions
 endif
 
@@ -165,4 +166,5 @@
 	CFLAGS = $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION = -finstrument-functions
 endif
 
@@ -170,4 +172,5 @@
 	CFLAGS = $(ICC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION =
 endif
 
@@ -176,4 +179,5 @@
 	DEFS += $(CONFIG_DEFS)
 	DEPEND_DEFS = $(DEFS)
+	INSTRUMENTATION =
 endif
 
@@ -181,4 +185,5 @@
 	CFLAGS = $(CLANG_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION =
 endif
 
@@ -202,4 +207,5 @@
 	generic/src/debug/stacktrace.c \
 	generic/src/debug/panic.c \
+	generic/src/debug/debug.c \
 	generic/src/interrupt/interrupt.c \
 	generic/src/main/main.c \
@@ -355,4 +361,13 @@
 endif
 
+## Sources where instrumentation is enabled
+#
+
+ifeq ($(CONFIG_LOG),y)
+INSTRUMENTED_SOURCES = \
+	generic/src/cpu/cpu.c \
+	generic/src/main/kinit.c
+endif
+
 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
@@ -414,5 +429,5 @@
 
 %.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c -o $@ $<
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) $(if $(findstring $<,$(INSTRUMENTED_SOURCES)),$(INSTRUMENTATION)) -c -o $@ $<
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision 793cf029ed8fa198abf49a9bf9cb846bf82cddc5)
+++ kernel/generic/include/debug.h	(revision 263bda21cd3cd48db6a7af349e737c62847da815)
@@ -93,28 +93,17 @@
 #define LOG(format, ...) \
 	do { \
-		printf("%s->%s() at %s:%u: " format "\n", symtab_fmt_name_lookup(CALLER), \
-		    __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
+		printf("%s() from %s at %s:%u: " format "\n", __func__, \
+		    symtab_fmt_name_lookup(CALLER), __FILE__, __LINE__, \
+		    ##__VA_ARGS__); \
 	} while (0)
 
-/** Extensive logging execute macro
- *
- * If CONFIG_LOG is set, the LOG_EXEC() macro
- * will print an information about calling a given
- * function and call it.
- *
- */
-#define LOG_EXEC(fnc) \
-	do { \
-		printf("%s->%s() at %s:%u: " #fnc "\n", symtab_fmt_name_lookup(CALLER), \
-		    __func__, __FILE__, __LINE__); \
-		fnc; \
-	} while (0)
+extern void __cyg_profile_func_enter(void *, void *);
+extern void __cyg_profile_func_exit(void *, void *);
 
 #else /* CONFIG_LOG */
 
 #define LOG(format, ...)
-#define LOG_EXEC(fnc)     fnc
 
-#endif /* CONFOG_LOG */
+#endif /* CONFIG_LOG */
 
 #endif
Index: kernel/generic/src/debug/debug.c
===================================================================
--- kernel/generic/src/debug/debug.c	(revision 263bda21cd3cd48db6a7af349e737c62847da815)
+++ kernel/generic/src/debug/debug.c	(revision 263bda21cd3cd48db6a7af349e737c62847da815)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Kernel instrumentation functions.
+ */
+
+#ifdef CONFIG_LOG
+
+#include <debug.h>
+#include <symtab.h>
+#include <errno.h>
+#include <print.h>
+
+void __cyg_profile_func_enter(void *fn, void *call_site)
+{
+	const char *fn_sym = symtab_fmt_name_lookup((uintptr_t) fn);
+	
+	const char *call_site_sym;
+	uintptr_t call_site_off;
+	
+	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
+	    &call_site_off) == EOK)
+		printf("%s:%p->%s\n", call_site_sym, call_site_off, fn_sym);
+	else
+		printf("->%s\n", fn_sym);
+}
+
+void __cyg_profile_func_exit(void *fn, void *call_site)
+{
+	const char *fn_sym = symtab_fmt_name_lookup((uintptr_t) fn);
+	
+	const char *call_site_sym;
+	uintptr_t call_site_off;
+	
+	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
+	    &call_site_off) == EOK)
+		printf("%s:%p<-%s\n", call_site_sym, call_site_off, fn_sym);
+	else
+		printf("<-%s\n", fn_sym);
+}
+
+#endif /* CONFIG_LOG */
+
+/** @}
+ */
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 793cf029ed8fa198abf49a9bf9cb846bf82cddc5)
+++ kernel/generic/src/main/main.c	(revision 263bda21cd3cd48db6a7af349e737c62847da815)
@@ -104,5 +104,5 @@
 
 /** Lowest safe stack virtual address. */
-uintptr_t stack_safe = 0;		
+uintptr_t stack_safe = 0;
 
 /*
@@ -113,9 +113,10 @@
  */
 static void main_bsp_separated_stack(void);
+
 #ifdef CONFIG_SMP
 static void main_ap_separated_stack(void);
 #endif
 
-#define CONFIG_STACK_SIZE	((1 << STACK_FRAMES) * STACK_SIZE)
+#define CONFIG_STACK_SIZE  ((1 << STACK_FRAMES) * STACK_SIZE)
 
 /** Main kernel routine for bootstrap CPU.
@@ -151,5 +152,5 @@
 			    init.tasks[i].size, config.stack_size);
 	}
-
+	
 	/* Avoid placing stack on top of boot allocations. */
 	if (ballocs.size) {
@@ -170,5 +171,4 @@
 }
 
-
 /** Main kernel routine for bootstrap CPU using new stack.
  *
@@ -176,5 +176,5 @@
  *
  */
-void main_bsp_separated_stack(void) 
+void main_bsp_separated_stack(void)
 {
 	/* Keep this the first thing. */
@@ -194,5 +194,5 @@
 	 * commands.
 	 */
-	LOG_EXEC(kconsole_init());
+	kconsole_init();
 #endif
 	
@@ -201,40 +201,40 @@
 	 * starts adding its own handlers
 	 */
-	LOG_EXEC(exc_init());
+	exc_init();
 	
 	/*
 	 * Memory management subsystems initialization.
 	 */
-	LOG_EXEC(arch_pre_mm_init());
-	LOG_EXEC(frame_init());
+	arch_pre_mm_init();
+	frame_init();
 	
 	/* Initialize at least 1 memory segment big enough for slab to work. */
-	LOG_EXEC(slab_cache_init());
-	LOG_EXEC(sysinfo_init());
-	LOG_EXEC(btree_init());
-	LOG_EXEC(as_init());
-	LOG_EXEC(page_init());
-	LOG_EXEC(tlb_init());
-	LOG_EXEC(ddi_init());
-	LOG_EXEC(tasklet_init());
-	LOG_EXEC(arch_post_mm_init());
-	LOG_EXEC(arch_pre_smp_init());
-	LOG_EXEC(smp_init());
+	slab_cache_init();
+	sysinfo_init();
+	btree_init();
+	as_init();
+	page_init();
+	tlb_init();
+	ddi_init();
+	tasklet_init();
+	arch_post_mm_init();
+	arch_pre_smp_init();
+	smp_init();
 	
 	/* Slab must be initialized after we know the number of processors. */
-	LOG_EXEC(slab_enable_cpucache());
+	slab_enable_cpucache();
 	
 	printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
 	    config.cpu_count, SIZE2MB(zones_total_size()));
-
-	LOG_EXEC(cpu_init());
-	
-	LOG_EXEC(calibrate_delay_loop());
-	LOG_EXEC(clock_counter_init());
-	LOG_EXEC(timeout_init());
-	LOG_EXEC(scheduler_init());
-	LOG_EXEC(task_init());
-	LOG_EXEC(thread_init());
-	LOG_EXEC(futex_init());
+	
+	cpu_init();
+	
+	calibrate_delay_loop();
+	clock_counter_init();
+	timeout_init();
+	scheduler_init();
+	task_init();
+	thread_init();
+	futex_init();
 	
 	if (init.cnt > 0) {
@@ -247,8 +247,8 @@
 		printf("No init binaries found.\n");
 	
-	LOG_EXEC(ipc_init());
-	LOG_EXEC(event_init());
-	LOG_EXEC(klog_init());
-	LOG_EXEC(stats_init());
+	ipc_init();
+	event_init();
+	klog_init();
+	stats_init();
 	
 	/*
@@ -266,5 +266,5 @@
 	if (!kinit_thread)
 		panic("Cannot create kinit thread.");
-	LOG_EXEC(thread_ready(kinit_thread));
+	thread_ready(kinit_thread);
 	
 	/*
@@ -276,6 +276,6 @@
 }
 
-
 #ifdef CONFIG_SMP
+
 /** Main kernel routine for application CPUs.
  *
@@ -296,5 +296,5 @@
 	 */
 	config.cpu_active++;
-
+	
 	/*
 	 * The THE structure is well defined because ctx.sp is used as stack.
@@ -311,7 +311,7 @@
 	calibrate_delay_loop();
 	arch_post_cpu_init();
-
+	
 	the_copy(THE, (the_t *) CPU->stack);
-
+	
 	/*
 	 * If we woke kmp up before we left the kernel stack, we could
@@ -326,5 +326,4 @@
 }
 
-
 /** Main kernel routine for application CPUs using new stack.
  *
@@ -338,9 +337,10 @@
 	 */
 	timeout_init();
-
+	
 	waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
 	scheduler();
 	/* not reached */
 }
+
 #endif /* CONFIG_SMP */
 
