This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] x86: Add support for frame pointer less mcount
- From: Andi Kleen <andi at firstfloor dot org>
- To: libc-alpha at sourceware dot org
- Date: Sat, 31 Jul 2010 10:19:28 +0200
- Subject: [PATCH] x86: Add support for frame pointer less mcount
Traditionally -pg profiling required enabling the frame pointer in the compiler,
because the mcount entry point is defined using the frame pointer.
Recent gcc has new -mfentry option that uses an alternative entry point and
does not require frame pointer. The new entry point is called __fentry__
This has advantages on systems where frame pointer is relatively expensive,
like Atom CPUs.
This patch adds __fentry__ support to x86 glibc. It just copies the existing
mcount entry points and adapts them to be frame pointer less.
I added a new GLIBC 2.13 namespace for this, because it's a new symbol.
-Andi
* 2010-07-17 Andi Kleen <ak@linux.intel.com>
* sysdeps/i386/i386-mcount.S (__fentry__): Add.
* sysdeps/x86_64/_mcount.S (__fentry__): Add.
* stdlib/Versions (__fentry__): Add for GLIBC 2.13
* Versions.def (GLIBC_2.13): Add.
diff --git a/Versions.def b/Versions.def
index eab006b..0ccda50 100644
--- a/Versions.def
+++ b/Versions.def
@@ -29,6 +29,7 @@ libc {
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
+ GLIBC_2.13
%ifdef USE_IN_LIBIO
HURD_CTHREADS_0.3
%endif
diff --git a/stdlib/Versions b/stdlib/Versions
index 3e7b892..2aa396e 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -100,6 +100,9 @@ libc {
GLIBC_2.10 {
quick_exit; __cxa_at_quick_exit;
}
+ GLIBC_2.13 {
+ __fentry__;
+ }
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.
diff --git a/sysdeps/i386/i386-mcount.S b/sysdeps/i386/i386-mcount.S
index 8b11adb..ebb659f 100644
--- a/sysdeps/i386/i386-mcount.S
+++ b/sysdeps/i386/i386-mcount.S
@@ -53,3 +53,28 @@ C_LABEL(_mcount)
#undef mcount
weak_alias (_mcount, mcount)
+
+ /* Same as above, but doesn't require a frame pointer */
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(__fentry__)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(__fentry__), @function)
+ .align ALIGNARG(4)
+C_LABEL(__fentry__)
+ /* Save the caller-clobbered registers. */
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+
+ movl 12(%esp), %edx
+ movl 16(%esp), %eax
+
+ /* No need to access the PLT or GOT, __mcount_internal is an
+ internal function and we can make a relative call. */
+ call C_SYMBOL_NAME(__mcount_internal)
+
+ /* Pop the saved registers. Please note that `mcount_nofp' has no
+ return value. */
+ popl %edx
+ popl %ecx
+ popl %eax
+ ret
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(__fentry__))
diff --git a/sysdeps/x86_64/_mcount.S b/sysdeps/x86_64/_mcount.S
index c005932..1571a4d 100644
--- a/sysdeps/x86_64/_mcount.S
+++ b/sysdeps/x86_64/_mcount.S
@@ -65,3 +65,41 @@ C_LABEL(_mcount)
#undef mcount
weak_alias (_mcount, mcount)
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(__fentry__)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(__fentry__), @function)
+ .align ALIGNARG(4)
+C_LABEL(__fentry__)
+ /* Allocate space for 7 registers. */
+ subq $56,%rsp
+ movq %rax,(%rsp)
+ movq %rcx,8(%rsp)
+ movq %rdx,16(%rsp)
+ movq %rsi,24(%rsp)
+ movq %rdi,32(%rsp)
+ movq %r8,40(%rsp)
+ movq %r9,48(%rsp)
+
+ /* Setup parameter for __mcount_internal. */
+ /* selfpc is the return address on the stack. */
+ movq 56(%rsp),%rsi
+ /* caller is the return address above it */
+ movq 64(%rsp),%rdi
+#ifdef PIC
+ call C_SYMBOL_NAME(__mcount_internal)@PLT
+#else
+ call C_SYMBOL_NAME(__mcount_internal)
+#endif
+ /* Pop the saved registers. Please note that `__fentry__' has no
+ return value. */
+ movq 48(%rsp),%r9
+ movq 40(%rsp),%r8
+ movq 32(%rsp),%rdi
+ movq 24(%rsp),%rsi
+ movq 16(%rsp),%rdx
+ movq 8(%rsp),%rcx
+ movq (%rsp),%rax
+ addq $56,%rsp
+ ret
+
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(__fentry__))
--
ak@linux.intel.com -- Speaking for myself only.