diff options
Diffstat (limited to 'libc/sysdeps/linux/powerpc')
-rw-r--r-- | libc/sysdeps/linux/powerpc/Makefile | 13 | ||||
-rw-r--r-- | libc/sysdeps/linux/powerpc/crt0.S | 11 | ||||
-rw-r--r-- | libc/sysdeps/linux/powerpc/mcount.S | 100 |
3 files changed, 120 insertions, 4 deletions
diff --git a/libc/sysdeps/linux/powerpc/Makefile b/libc/sysdeps/linux/powerpc/Makefile index 9b79644e6..8e979a1e8 100644 --- a/libc/sysdeps/linux/powerpc/Makefile +++ b/libc/sysdeps/linux/powerpc/Makefile @@ -21,9 +21,13 @@ include $(TOPDIR)Rules.mak ASFLAGS=$(CFLAGS) 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 +ifeq ($(strip $(UCLIBC_PROFILING)),y) +SSRC+=mcount.S +endif SOBJS=$(patsubst %.S,%.o, $(SSRC)) CSRC=_mmap.c vfork.c __syscall_error.c pread_write.c ioctl.c @@ -52,6 +56,13 @@ $(COBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -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: diff --git a/libc/sysdeps/linux/powerpc/crt0.S b/libc/sysdeps/linux/powerpc/crt0.S index 47fe7e786..24110850d 100644 --- a/libc/sysdeps/linux/powerpc/crt0.S +++ b/libc/sysdeps/linux/powerpc/crt0.S @@ -68,14 +68,14 @@ _start: add r5,r5,r4 /* 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 addi r6,r6,_init@l # load bottom 16 bits lis r7,_fini@ha # load top 16 bits of &msg addi r7,r7,_fini@l # load bottom 16 bits bl __uClibc_start_main +#else + bl __uClibc_main #endif .size _start,.-_start @@ -83,3 +83,8 @@ _start: .globl __data_start __data_start: +#if defined L_gcrt1 && defined __UCLIBC_PROFILING__ +# include "./gmon-start.S" +#endif + + diff --git a/libc/sysdeps/linux/powerpc/mcount.S b/libc/sysdeps/linux/powerpc/mcount.S new file mode 100644 index 000000000..a9e3677a1 --- /dev/null +++ b/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 + |