summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorluoqi <luoqi@FreeBSD.org>2008-07-23 11:37:20 +0000
committerluoqi <luoqi@FreeBSD.org>2008-07-23 11:37:20 +0000
commitc9306f6f143425d8831c53d4318cf1555e10e16d (patch)
treee3cf8ad6e42c03fada42efbcde0fe17cba008265 /sys/i386
parent183560b8225c55637893ede141cefe00ac4d9020 (diff)
downloadFreeBSD-src-c9306f6f143425d8831c53d4318cf1555e10e16d.zip
FreeBSD-src-c9306f6f143425d8831c53d4318cf1555e10e16d.tar.gz
Unbreak cc -pg support on i386. In gcc 4.2, %ecx is used as the arg pointer
when stack realignment is turned on (it is ALWAYS on for main), however in a profiling build %ecx would be clobbered by mcount(), this would lead to a segmentation fault when the code tries to reference any argument. This fix changes mcount() to preserve %ecx. PR: bin/119709 Reviewed by: bde MFC after: 1 week
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/include/profile.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/i386/include/profile.h b/sys/i386/include/profile.h
index fe036d8..fb3320b 100644
--- a/sys/i386/include/profile.h
+++ b/sys/i386/include/profile.h
@@ -115,7 +115,15 @@ void user(void);
void \
mcount() \
{ \
- uintfptr_t selfpc, frompc; \
+ uintfptr_t selfpc, frompc, ecx; \
+ /* \
+ * In gcc 4.2, ecx might be used in the caller as the arg \
+ * pointer if the stack realignment option is set (-mstackrealign) \
+ * or if the caller has the force_align_arg_pointer attribute \
+ * (stack realignment is ALWAYS on for main). Preserve ecx \
+ * here. \
+ */ \
+ __asm("" : "=c" (ecx)); \
/* \
* Find the return address for mcount, \
* and the return address for mcount's caller. \
@@ -132,6 +140,7 @@ mcount() \
__asm("movl (%%ebp),%0" : "=r" (frompc)); \
frompc = ((uintfptr_t *)frompc)[1]; \
_mcount(frompc, selfpc); \
+ __asm("" : : "c" (ecx)); \
}
#else /* !__GNUCLIKE_ASM */
#define MCOUNT
OpenPOWER on IntegriCloud