This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: new ppc32 GOT/PLT support for mcount
- From: Steve Munroe <sjmunroe at us dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com, Alan Modra <amodra at bigpond dot net dot au>, Jakub Jelinek <jakub at redhat dot com>
- Date: Thu, 09 Jun 2005 17:31:56 -0500
- Subject: Re: new ppc32 GOT/PLT support for mcount
- Reply-to: sjmunroe at vnet dot ibm dot com
Alan Modra <amodra@bigpond.net.au> wrote on 05/17/2005 09:33:53 AM:
> ...One problem remains: ppc32 calls
> _mcount before the function prologue, so it's not possible to set up
> registers to call _mcount via the plt in pic code. So for now, if you
> profile pic code using a dynamic _mcount, the call sequence used will
> force the old exec GOT/PLT. I'm thinking the best thing is to make
> _mcount available in libc_nonshared, and only keep _mcount in libc.so
> to satisfy explicit versions, but I'm open to suggestions.
>
Looking at the details, in the current powerpc32 implementation
gmon/mcount.c is aliased to __mcount_internal and the exported _mcount
symbol is defined by the stub in ppc-mcount.S. ppc-mount.S; stacks a
frame, saves the parameter register (r3-r10), does setup up the frompc
and seflpc parameters in r3/r4, before calling __mcount_internal.
Also gcc is still generating the -pg prologue as:
.data
.align 2
0: .long 0
.previous
func:
mflr r0
lis r11,0b@ha
stw r0,4(r1)
addi r0,r11,0b@l
bl _mcount
The .data word and its address in r0 are never used (by mcount.c or any
other code that I can find). Also this is a non-PIC sequence that we
should eliminate for the new ABI. The new -pg prologue would be:
func:
mflr r0
stw r0,4(r1)
bl _mcount@local
# we can assume that on return r0/lr are restored by _mcount
# to the entry value.
...
One possibility is to move a version of the ppc-mcount.S stub code into
libc_nonshared and have it establish the got (using the new ABI) before
calling __mcount_internal via the new PLT.
For compatibility we need to version _mcount. The old version in
ppc-mcount.S will be export _mcount@GLIBC_2.0. The new version
(ppc2-mcount.S) will export the default version _mcount@@GLIBC_2.4. The
new version will included in libc_nonshared.a so it can be called @local
from -pg prologues. The implementation of __mcount_internal
(gmon/mcount.c) will remain unchanged except for
making__mcount_internal@@GLIBC_PRIVATE.
The attached patch implements the glibc par this proposal. The gcc
portion should mostly clean up.
2005-02-07 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/powerpc/powerpc32/Dist: Add ppc2-mcount.S
* sysdeps/powerpc/powerpc32/Makefile: Add ppc2-mcount to
sysdep_routines and static-only-routine.
* sysdeps/powerpc/powerpc32/Versions: Add -msecure-plt version of
_mcount to GLIBC_2.4. Add __mcount_internal to GLIBC_PRIVATE.
* sysdeps/powerpc/powerpc32/ppc-mcount.S
[SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_4]{_old_mcount}:
Original version of powerpc32 _mcount.
* sysdeps/powerpc/powerpc32/ppc2-mcount.S: New file.
diff -urN libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Dist libc24/sysdeps/powerpc/powerpc32/Dist
--- libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Dist 2003-01-27 13:02:11.000000000 -0800
+++ libc24/sysdeps/powerpc/powerpc32/Dist 2005-06-08 10:58:51.590035552 -0700
@@ -2,6 +2,7 @@
dl-start.S
libgcc-compat.S
ppc-mcount.S
+ppc2-mcount.S
gprsave1.S
gprsave0.S
gprrest1.S
diff -urN libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Makefile libc24/sysdeps/powerpc/powerpc32/Makefile
--- libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Makefile 2003-10-22 14:30:02.000000000 -0700
+++ libc24/sysdeps/powerpc/powerpc32/Makefile 2005-06-09 13:52:29.987056184 -0700
@@ -38,6 +40,11 @@
endif
endif
+ifeq ($(subdir),gmon)
+sysdep_routines += ppc2-mcount
+static-only-routines = ppc2-mcount
+endif
+
ifeq ($(subdir),elf)
# extra shared linker files to link only into dl-allobjs.so
sysdep-rtld-routines += dl-start
diff -urN libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Versions libc24/sysdeps/powerpc/powerpc32/Versions
--- libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/Versions 2002-09-05 02:54:38.000000000 -0700
+++ libc24/sysdeps/powerpc/powerpc32/Versions 2005-06-09 14:39:02.533011496 -0700
@@ -1,4 +1,7 @@
libc {
+ GLIBC_2.4 {
+ _mcount;
+ }
GLIBC_2.0 {
# Functions from libgcc.
__divdi3; __moddi3; __udivdi3; __umoddi3;
@@ -8,6 +11,9 @@
__fixsfdi; __fixunssfdi;
__floatdidf; __floatdisf;
}
+ GLIBC_PRIVATE {
+ __mcount_internal;
+ }
}
libm {
diff -urN libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/ppc-mcount.S libc24/sysdeps/powerpc/powerpc32/ppc-mcount.S
--- libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/ppc-mcount.S 2005-05-21 12:27:07.000000000 -0700
+++ libc24/sysdeps/powerpc/powerpc32/ppc-mcount.S 2005-06-09 13:55:10.152935040 -0700
@@ -1,5 +1,5 @@
/* PowerPC-specific implementation of profiling support.
- Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999, 2005 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
@@ -44,9 +44,21 @@
stw r0,4(r1)
addi r0,r11,0b@l
bl _mcount
+
+ The real guts of the _mcount are in gmon/mcount.c, who's entry point
+ we have renamed to __mcount_internal. This code is just a stub that
+ saves volatiles and marshalls parameters for __mcount_internal.
*/
-ENTRY(_mcount)
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+
+/* Build a versioned object for libc. */
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_4)
+symbol_version (_old_mcount,_mcount,GLIBC_2.0)
+
+ENTRY(_old_mcount)
stwu r1,-48(r1)
/* We need to save the parameter-passing registers. */
stw r3, 12(r1)
@@ -82,4 +94,6 @@
/* ...unwind the stack frame, and return to your usual programming. */
addi r1,r1,48
bctr
-END(_mcount)
+END(_old_mcount)
+# endif
+
diff -urN libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/ppc2-mcount.S libc24/sysdeps/powerpc/powerpc32/ppc2-mcount.S
--- libc24-cvstip-20050603/sysdeps/powerpc/powerpc32/ppc2-mcount.S Wed Dec 31 16:00:00 1969
+++ libc24/sysdeps/powerpc/powerpc32/ppc2-mcount.S Thu Jun 09 14:16:49 2005
@@ -0,0 +1,130 @@
+/* Startup code for programs linked with GNU libc.
+ Copyright (C) 2005 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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 <sysdep.h>
+#include "bp-sym.h"
+
+/* The new profiling simply passes the return address (frompc) and
+ function prologue address (selfpc) to _mcount. The frompc address is
+ in the link register on entry and must be saved in the LR save
+ word (old-sp+4) before calling the _mcount stub. The selfpc is in
+ LR after the branch and link from the prologue to the _mcount stub.
+ The data word is nolonger used.
+
+ .text
+ mflr r0
+ stw r0,4(r1)
+ bl _mcount
+
+ The real guts of the _mcount are in gmon/mcount.c, who's entry point
+ we have renamed to __mcount_internal. This code is just a stub that
+ saves volatiles and marshalls parameters for __mcount_internal.
+
+ To support the new -msecure-plt we need to insure that the got
+ pointer is set before we call any mcount functions in libc.so. This
+ is an issues because gcc will generate the _mcount call be it
+ generates code to set up the got pointer.
+
+ So we make this _mcount stub always @local by by moving it to
+ libc_nonshared.a and exporting __mcount_internal@@GLIBC_PRIVATE
+ (gmon/mcount.c) from libc.so. Then _mcount stub can set up the
+ got pointer and call __mcount_internal using the PLT.
+*/
+
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+
+/* Build a versioned object for libc. */
+default_symbol_version (_new_mcount,_mcount,GLIBC_2.4)
+
+ .section ".text"
+ENTRY(_new_mcount)
+ stwu r1,-64(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, 68(r1)
+ mfcr r5
+ stw r7, 28(r1)
+ stw r8, 32(r1)
+ stw r9, 36(r1)
+#ifdef SHARED
+# ifdef HAVE_ASM_PPC_REL16
+ stw 31,60(r1)
+ stw 30,56(r1)
+ bcl 20,31,1f
+1: mflr r30
+ stw r10,40(r1)
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha
+ stw r4, 44(r1)
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l
+ stw r5, 8(r1)
+# endif
+ bl JUMPTARGET(__mcount_internal)
+#else
+ stw r10,40(r1)
+ stw r4, 44(r1)
+ stw r5, 8(r1)
+ bl __mcount_internal@local
+#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, 68(r1)
+ lwz r7, 28(r1)
+ lwz r8, 32(r1)
+ mtlr r0
+ lwz r9, 36(r1)
+ lwz r10,40(r1)
+# ifdef HAVE_ASM_PPC_REL16
+ lwz 30,56(r1)
+ lwz 31,60(r1)
+# endif
+ /* ...unwind the stack frame, and return to your usual programming. */
+ addi r1,r1,64
+ bctr
+END(_new_mcount)
+