Browse Source

Finish off gmon based profiling for powerpc

Eric Andersen 22 years ago
parent
commit
f8a0787647

+ 12 - 1
libc/sysdeps/linux/powerpc/Makefile

@@ -21,9 +21,13 @@ include $(TOPDIR)Rules.mak
 ASFLAGS=$(CFLAGS)
 ASFLAGS=$(CFLAGS)
 
 
 CRT0_SRC = crt0.S
 CRT0_SRC = crt0.S
-CRT0_OBJ = crt0.o crt1.o
+CRT0_OBJ = crt0.o crt1.o gcrt1.o
+CRT0_DEPS=gmon-start.S
 
 
 SSRC=__longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S clone.S __uClibc_syscall.S
 SSRC=__longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S clone.S __uClibc_syscall.S
+ifeq ($(strip $(UCLIBC_PROFILING)),y)
+SSRC+=mcount.S
+endif
 SOBJS=$(patsubst %.S,%.o, $(SSRC))
 SOBJS=$(patsubst %.S,%.o, $(SSRC))
 
 
 CSRC=_mmap.c vfork.c __syscall_error.c pread_write.c ioctl.c
 CSRC=_mmap.c vfork.c __syscall_error.c pread_write.c ioctl.c
@@ -52,6 +56,13 @@ $(COBJS): %.o : %.c
 	$(CC) $(CFLAGS) -c $< -o $@
 	$(CC) $(CFLAGS) -c $< -o $@
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 
+ifeq ($(strip $(UCLIBC_PROFILING)),y)
+SAFECFLAGS := $(subst -g,,$(CFLAGS))
+gmon-start.S: ../common/gmon-start.c
+	$(CC) $(SAFECFLAGS) -c $< -S -o $*.S
+gcrt1.o: $(CRT0_DEPS)
+endif
+
 headers:
 headers:
 
 
 
 

+ 8 - 3
libc/sysdeps/linux/powerpc/crt0.S

@@ -68,14 +68,14 @@ _start:
 	add	r5,r5,r4
 	add	r5,r5,r4
 
 
 	/* Ok, now run uClibc's main() -- shouldn't return */
 	/* Ok, now run uClibc's main() -- shouldn't return */
-#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__
-	bl	__uClibc_main
-#else
+#if (defined L_crt1 || defined L_gcrt1 ) && defined __UCLIBC_CTOR_DTOR__
 	lis     r6,_init@ha	# load top 16 bits
 	lis     r6,_init@ha	# load top 16 bits
 	addi    r6,r6,_init@l	# load bottom 16 bits
 	addi    r6,r6,_init@l	# load bottom 16 bits
 	lis     r7,_fini@ha	# load top 16 bits of &msg
 	lis     r7,_fini@ha	# load top 16 bits of &msg
 	addi    r7,r7,_fini@l	# load bottom 16 bits
 	addi    r7,r7,_fini@l	# load bottom 16 bits
 	bl	__uClibc_start_main
 	bl	__uClibc_start_main
+#else
+	bl	__uClibc_main
 #endif
 #endif
 .size _start,.-_start
 .size _start,.-_start
 
 
@@ -83,3 +83,8 @@ _start:
 	.globl  __data_start
 	.globl  __data_start
 __data_start:
 __data_start:
 
 
+#if defined L_gcrt1 && defined __UCLIBC_PROFILING__
+# include "./gmon-start.S"
+#endif
+
+

+ 100 - 0
libc/sysdeps/linux/powerpc/mcount.S

@@ -0,0 +1,100 @@
+/* PowerPC-specific implementation of profiling support.
+   Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <features.h>
+#include "ppc_asm.h"
+
+/* This would be bad.  */
+#ifdef PROF
+#undef PROF
+#endif
+
+
+/* We do profiling as described in the SYSV ELF ABI, _mcount is called
+   with the address of a data word in r0 (that is different for every
+   routine, initialised to 0, and otherwise unused).  The caller has put
+   the address the caller will return to in the usual place on the stack,
+   4(r1).  _mcount is responsible for ensuring that when it returns no
+   argument-passing registers are disturbed, and that the LR is set back
+   to (what the caller sees as) 4(r1).
+
+   This is intended so that the following code can be inserted at the
+   front of any routine without changing the routine:
+
+	.data
+	.align	2
+   0:	.long	0
+	.previous
+	mflr	r0
+	lis	r11,0b@ha
+	stw	r0,4(r1)
+	addi	r0,r11,0b@l
+	bl	_mcount
+*/
+
+
+.globl      _mcount;
+.type      _mcount, @function;
+.align  2;
+
+_mcount:
+	stwu	r1,-48(r1)
+/* We need to save the parameter-passing registers.  */
+	stw	r3, 12(r1)
+	stw	r4, 16(r1)
+	stw	r5, 20(r1)
+	stw	r6, 24(r1)
+	mflr	r4
+	lwz	r3, 52(r1)
+	mfcr	r5
+	stw	r7, 28(r1)
+	stw	r8, 32(r1)
+	stw	r9, 36(r1)
+	stw	r10,40(r1)
+	stw	r4, 44(r1)
+	stw	r5,  8(r1)
+#ifdef PIC
+	bl	__mcount_internal@plt
+#else
+	bl	__mcount_internal
+#endif
+	nop
+ /* Restore the registers...  */
+	lwz     r6,  8(r1)
+	lwz	r0, 44(r1)
+	lwz	r3, 12(r1)
+	mtctr	r0
+	lwz	r4, 16(r1)
+	mtcrf	0xff,r6
+	lwz	r5, 20(r1)
+	lwz	r6, 24(r1)
+	lwz	r0, 52(r1)
+	lwz	r7, 28(r1)
+	lwz	r8, 32(r1)
+	mtlr	r0
+	lwz	r9, 36(r1)
+	lwz	r10,40(r1)
+ /* ...unwind the stack frame, and return to your usual programming.  */
+	addi	r1,r1,48
+	bctr
+	.size _mcount,.-_mcount;
+
+#undef mcount
+.weak mcount ; mcount = _mcount
+