[kaffe] CVS kaffe (guilhem): Implementing possibilities to use other heuristics to detect stack boundaries.
Kaffe CVS
cvs-commits at kaffe.org
Sun May 9 07:50:02 PDT 2004
PatchSet 4722
Date: 2004/05/09 14:20:10
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
Implementing possibilities to use other heuristics to detect stack boundaries.
* config/i386/linux/md.c, config/i386/linux/md.h:
New machine dependent function mdGetStackBase(). KAFFEMD_STACKBASE
is defined on ix86/linux now. If the user is running a GLIBC, then use
__libc_stack_end.
* kaffe/kaffevm/systems/unix-jthreads/signal.c:
(detectStackBoundaries) Updated heuristics on detecting
stack boundaries. The code now accepts either KAFFEMD_STACKBASE,
KAFFEMD_STACKEND, stack limit finder or the old heuristic.
* FAQ/FAQ.kaffemd: Missing file from a previous check in.
Members:
ChangeLog:1.2296->1.2297
FAQ/FAQ.kaffemd:INITIAL->1.1
config/i386/linux/md.c:1.1->1.2
config/i386/linux/md.h:1.11->1.12
kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4->1.5
kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16->1.17
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2296 kaffe/ChangeLog:1.2297
--- kaffe/ChangeLog:1.2296 Thu May 6 10:20:31 2004
+++ kaffe/ChangeLog Sun May 9 14:20:10 2004
@@ -1,3 +1,17 @@
+2004-05-07 Guilhem Lavaux <guilhem at kaffe.org>
+
+ * config/i386/linux/md.c, config/i386/linux/md.h:
+ New machine dependent function mdGetStackBase(). KAFFEMD_STACKBASE
+ is defined on ix86/linux now. If the user is running a GLIBC, then use
+ __libc_stack_end.
+
+ * kaffe/kaffevm/systems/unix-jthreads/signal.c:
+ (detectStackBoundaries) Updated heuristics on detecting
+ stack boundaries. The code now accepts either KAFFEMD_STACKBASE,
+ KAFFEMD_STACKEND, stack limit finder or the old heuristic.
+
+ * FAQ/FAQ.kaffemd: Missing file from a previous check in.
+
2004-05-06 Dalibor Topic <robilad at kaffe.org>
* libraries/javalib/java/text/Format.java:
===================================================================
Checking out kaffe/FAQ/FAQ.kaffemd
RCS: /home/cvs/kaffe/kaffe/FAQ/FAQ.kaffemd,v
VERS: 1.1
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/FAQ/FAQ.kaffemd Sun May 9 14:23:57 2004
@@ -0,0 +1,32 @@
+FAQ for defines
+===============
+
+Here are the defines to put in config/*/*/md.h to enable features
+in kaffe.
+
+KAFFEMD_PAGESIZE
+----------------
+
+This macro is to be defined if the OS supports mdGetPageSize().
+mdGetPageSize() returns the current page size for the operating system.
+
+KAFFEMD_STACKOVERFLOW
+---------------------
+
+This macro is to be defined if the operating system supports stack overflow
+reporting. This macro should require that at least SA_ONSTACK, STACK_POINTER
+and HAVE_SIGALTSTACK are defined. But if the operating system is badly supported
+on the architecture this can be left undefined and kaffe will keep the old
+behaviour.
+
+KAFFEMD_STACKBASE
+-----------------
+
+This macro is to be defined is the platform supports mdGetStackBase(). This
+function returns a pointer to the bottom of the stack.
+
+KAFFEMD_STACKEND
+-----------------
+
+This macro is to be defined is the platform supports mdGetStackEnd(). This
+function returns a pointer to the end of the stack.
Index: kaffe/config/i386/linux/md.c
diff -u kaffe/config/i386/linux/md.c:1.1 kaffe/config/i386/linux/md.c:1.2
--- kaffe/config/i386/linux/md.c:1.1 Tue Mar 31 19:10:53 1998
+++ kaffe/config/i386/linux/md.c Sun May 9 14:20:12 2004
@@ -11,6 +11,9 @@
#include "config.h"
#include <malloc.h>
+#if defined(HAVE_FEATURES_H)
+#include <features.h>
+#endif
void
init_md(void)
@@ -19,3 +22,12 @@
mallopt(M_MMAP_MAX, 0);
#endif
}
+
+#if defined(__GLIBC__)
+extern void * __libc_stack_end;
+
+void *mdGetStackBase(void)
+{
+ return __libc_stack_end;
+}
+#endif
Index: kaffe/config/i386/linux/md.h
diff -u kaffe/config/i386/linux/md.h:1.11 kaffe/config/i386/linux/md.h:1.12
--- kaffe/config/i386/linux/md.h:1.11 Wed Apr 28 12:01:47 2004
+++ kaffe/config/i386/linux/md.h Sun May 9 14:20:12 2004
@@ -90,6 +90,11 @@
}
#endif
+#if defined(__GLIBC__)
+#define KAFFEMD_STACKBASE
+extern void *mdGetStackBase(void);
+#endif
+
#if defined(TRANSLATOR)
#include "jit-md.h"
#endif
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4 kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.5
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4 Thu Apr 22 16:28:16 2004
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h Sun May 9 14:20:12 2004
@@ -45,6 +45,6 @@
void unblockAsyncSignals(void);
void blockAsyncSignals(void);
-void detectStackBoudaries(jthread jtid, int mainThreadStackSize);
+void detectStackBoundaries(jthread_t jtid, int mainThreadStackSize);
#endif /* UNIXJTHREAD_SIGNAL_H */
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16 kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.17
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16 Sat Apr 24 19:48:10 2004
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c Sun May 9 14:20:12 2004
@@ -345,62 +345,143 @@
}
-#if defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK)
+#if defined(HAVE_SIGALTSTACK) && defined(SA_ONSTACK)
+static void
+setupSigAltStack(void)
+{
+ STACK_STRUCT newstack;
-static JTHREAD_JMPBUF outOfLoop;
-static void *stackPointer;
+ /*
+ * Signals has to have their own stack so we can solve
+ * stack problems.
+ */
+ newstack.ss_size = THREADSTACKSIZE;
+ newstack.ss_flags = 0;
+ newstack.ss_sp = KMALLOC(newstack.ss_size);
+ if (sigaltstack(&newstack, NULL) < 0)
+ {
+ dprintf("Unexpected error calling sigaltstack: %s\n",
+ SYS_ERROR(errno));
+ EXIT(1);
+ }
+}
+#else
+static void
+setupSigAltStack(void)
+{
+}
+#endif
+
+/* ----------------------------------------------------------------------
+ * STACK BOUNDARY DETECTORS
+ * ----------------------------------------------------------------------
+ */
+
+#if defined(KAFFEMD_STACKBASE) // STACK_POINTER
/*
- * This function intends to create a stack overflow error so we can evaluate
- * the stack boundaries. Unfortunately, gcc optimizes it here. This is the
- * purpose of the dummy variable a.
- */
-static void
-infiniteLoop()
-{
- int a;
- infiniteLoop();
- a = 0;
+ * The OS gives us the stack base. Get it and adjust the pointers.
+ */
+
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
+ void *stackPointer;
+
+ stackPointer = mdGetStackBase();
+
+ setupSigAltStack();
+
+#if defined(STACK_GROWS_UP)
+ jtid->stackBase = stackPointer;
+ jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
+ jtid->restorePoint = jtid->stackEnd;
+#else
+ jtid->stackEnd = stackPointer;
+ jtid->stackBase = (char *) jtid->stackEnd - mainThreadStackSize;
+ jtid->restorePoint = jtid->stackBase;
+#endif
+
}
+#elif defined(KAFFEMD_STACKEND) // KAFFEMD_STACKBASE
+
+/*
+ * Here the OS gives us the position of the end of stack. Get it
+ * and adjust our internal pointers.
+ */
+
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
+ void *stackPointer;
+
+ setupSigAltStack();
+
+ stackPointer = mdGetStackEnd();
+ fprintf(stderr,"stackPointer=%p\n", stackPointer);
+
+#if defined(STACK_GROWS_UP)
+ jtid->stackEnd = stackPointer;
+ jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
+ jtid->restorePoint = jtid->stackEnd;
+#else
+ jtid->stackBase = stackPointer;
+ jtid->stackEnd = (char *) jtid->stackBase + mainThreadStackSize;
+ jtid->restorePoint = jtid->stackBase;
+#endif
+}
+
+#elif defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK) && !defined(KAFFEMD_BUGGY_STACK_OVERFLOW)
+
+static JTHREAD_JMPBUF outOfLoop;
+
/*
* This function is called by the system when we go beyond stack boundaries
* in infiniteLoop. We get the stack address using the stack pointer register
* and then go back in detectStackBoundaries() using the old stack.
*/
-static void
-stackOverflowDetector(SIGNAL_ARGS(sig, sc))
+static void NONRETURNING
+stackOverflowDetector(SIGNAL_ARGS(sig UNUSED, sc))
{
- stackPointer = (void *)STACK_POINTER(GET_SIGNAL_CONTEXT_POINTER(sc));
unblockSignal(SIGSEGV);
JTHREAD_LONGJMP(outOfLoop, 1);
}
-#endif
+void kaffeNoopFunc(char c UNUSED)
+{
+}
+
+/*
+ * This is the first type of heuristic we can use to guess the boundaries.
+ * Here we are provoking a SIGSEGV by overflowing the stack. Then we get
+ * the faulty adress directly.
+ */
void
detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
{
-#if defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK)
- STACK_STRUCT newstack;
+ char *guessPointer;
+
+ setupSigAltStack();
- /*
- * Signals has to have their own stack so we can solve
- * stack problems.
- */
- newstack.ss_size = THREADSTACKSIZE;
- newstack.ss_flags = 0;
- newstack.ss_sp = KMALLOC(newstack.ss_size);
- if (sigaltstack(&newstack, NULL) < 0)
- {
- dprintf("Unexpected error calling sigaltstack: %s\n",
- SYS_ERROR(errno));
- EXIT(1);
- }
-
registerSignalHandler(SIGSEGV, stackOverflowDetector, false);
if (JTHREAD_SETJMP(outOfLoop) == 0)
- infiniteLoop();
+ {
+ unsigned int pageSize = getpagesize();
+
+ guessPointer = (char *)((uintp)(&jtid) & ~(pageSize-1));
+
+ while (1)
+ {
+#if defined(STACK_GROWS_UP)
+ guessPointer -= pageSize;
+#else
+ guessPointer += pageSize;
+#endif
+ kaffeNoopFunc(*guessPointer);
+ }
+ }
/* Here we have detected one the boundary of the stack.
* If stack grows up then it is the upper boundary. In the other
@@ -408,26 +489,35 @@
* may guess the other boundary.
*/
#if defined(STACK_GROWS_UP)
- jtid->stackEnd = stackPointer;
- jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
+ jtid->stackBase = guessPointer;
+ jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
jtid->restorePoint = jtid->stackEnd;
#else
- jtid->stackBase = stackPointer;
- jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
+ jtid->stackEnd = guessPointer;
+ jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
jtid->restorePoint = jtid->stackBase;
#endif
+}
-#else // STACK_POINTER
+#else
+
+/*
+ * This is the worse heuristic in terms of precision. But
+ * this may be the only one working on this platform.
+ */
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
#if defined(STACK_GROWS_UP)
jtid->stackBase = (void*)(uintp)(&jtid - 0x100);
- jtid->stackEnd = jtid->stackBase + mainThreadStackSize;
+ jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
jtid->restorePoint = jtid->stackEnd;
#else
jtid->stackEnd = (void*)(uintp)(&jtid + 0x100);
jtid->stackBase = (char *) jtid->stackEnd - mainThreadStackSize;
jtid->restorePoint = jtid->stackBase;
#endif
+}
#endif
-}
More information about the kaffe
mailing list