Subject: port-arm32/8462: Minor enhancement to profiling
To: None <gnats-bugs@gnats.netbsd.org>
From: Richard Earnshaw <rearnsha@cambridge.arm.com>
List: netbsd-bugs
Date: 09/21/1999 04:49:57
>Number:         8462
>Category:       port-arm32
>Synopsis:       Minor enhancement to profiling
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-arm32-maintainer (NetBSD/arm32 Portmaster)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 21 03:05:01 1999
>Last-Modified:
>Originator:     Richard Earnshaw
>Organization:
ARM
-- 
>Release:        current
>Environment:
	
System: NetBSD shark1 1.4K NetBSD 1.4K (SHARK) #45: Mon Sep 13 18:56:20 BST 1999 rearnsha@shark1:/usr/src/sys/arch/arm32/compile/SHARK arm32


>Description:
	The tiny patch below enhances the mcount function so that it 
	preserves the return address register of the caller.  This makes 
	it easier to add profiling to functions that don't push anything 
	onto the stack (many of the assembler routines in the kernel are
	like this).
	
>How-To-Repeat:
	Try to add the following to an assembler function such as
	sa110_cache_purgeID.  Note that without the fix the lr would be
	corrupted causing the machine to go belly-up.

		ENTRY(sa110_cache_purgeID)
		#ifdef GPROF
			mov	ip, lr
			bl	mcount
		#endif
			...
	The patch avoids the need to push/pop the lr around the call to
	mcount, which would make these stubs significantly more complex.
	Adding stubs like the above to many of the assembler routines in
	the kernel will complete the flow graph when using a profiled 
	kernel and reduce the number of "spontaneous" function calls.
	
>Fix:
	Patch appended:
Index: profile.h
===================================================================
RCS file: /home/rearnsha/netbsd/cvs/src/sys/arch/arm32/include/profile.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 profile.h
--- profile.h	1998/05/12 18:29:07	1.1.1.1
+++ profile.h	1999/09/21 09:37:58
@@ -45,7 +45,7 @@
 	/*								\
 	 * Preserve registers that are trashed during mcount		\
 	 */								\
-	__asm__("stmfd	sp!, {r0-r3, lr}");				\
+	__asm__("stmfd	sp!, {r0-r3, ip, lr}");				\
 	/*								\
 	 * find the return address for mcount,				\
 	 * and the return address for mcount's caller.			\
@@ -64,7 +64,7 @@
 	/*								\
 	 * Restore registers that were trashed during mcount		\
 	 */								\
-	__asm__("ldmfd	sp!, {r0-r3, pc}");
+	__asm__("ldmfd	sp!, {r0-r3, lr, pc}");
 
 #ifdef _KERNEL
 #include <machine/cpufunc.h>

	
>Audit-Trail:
>Unformatted: