Index: cacao-0.99.3/src/vm/jit/arm/linux/md-os.c
===================================================================
--- cacao-0.99.3.orig/src/vm/jit/arm/linux/md-os.c	2008-07-07 13:36:19.000000000 +0200
+++ cacao-0.99.3/src/vm/jit/arm/linux/md-os.c	2008-09-24 17:15:23.191805889 +0200
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -60,7 +61,7 @@
 #include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
-
+#include "vm/jit/patcher-common.h"
 
 /* md_signal_handler_sigsegv ***************************************************
 
@@ -126,56 +127,52 @@
 
 void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
 {
-	ucontext_t     *_uc;
-	scontext_t     *_sc;
-	u1             *pv;
-	u1             *sp;
-	u1             *ra;
-	u1             *xpc;
-	u4              mcode;
-	int             type;
-	intptr_t        val;
-	void           *p;
-
-	_uc = (ucontext_t*) _p;
-	_sc = &_uc->uc_mcontext;
-
-	/* ATTENTION: glibc included messed up kernel headers we needed a
-	   workaround for the ucontext structure. */
-
-	pv  = (u1 *) _sc->arm_ip;
-	sp  = (u1 *) _sc->arm_sp;
-	ra  = (u1 *) _sc->arm_lr;                    /* this is correct for leafs */
-	xpc = (u1 *) _sc->arm_pc;
-
-	/* get exception-throwing instruction */
-
-	mcode = *((u4 *) xpc);
-
-	/* check for undefined instruction we use */
-
-	if ((mcode & 0x0ff000f0) != 0x07f000f0) {
-		log_println("md_signal_handler_sigill: unknown illegal instruction: inst=%x", mcode);
-#if defined(ENABLE_DISASSEMBLER)
-		DISASSINSTR(xpc);
-#endif
-		vm_abort("Aborting...");
-	}
-
-	type = (mcode >> 8) & 0x0fff;
-	val  = *((s4 *) _sc + OFFSET(scontext_t, arm_r0)/4 + (mcode & 0x0f));
-
-	/* Handle the trap. */
-
-	p = trap_handle(type, val, pv, sp, ra, xpc, _p);
-
-	/* set registers if we have an exception, continue execution
-	   otherwise (this is needed for patchers to work) */
-
-	if (p != NULL) {
-		_sc->arm_r10 = (uintptr_t) p;
-		_sc->arm_fp  = (uintptr_t) xpc;
-		_sc->arm_pc  = (uintptr_t) asm_handle_exception;
+	int type;
+	intptr_t val;
+	void *p;
+ 	ucontext_t* _uc = (ucontext_t*) _p;
+ 	scontext_t* _sc = &_uc->uc_mcontext;
+  
+  	/* ATTENTION: glibc included messed up kernel headers we needed a
+  	   workaround for the ucontext structure. */
+  
+ 	void* pv  = (void*) _sc->arm_ip;
+ 	void* sp  = (void*) _sc->arm_sp;
+ 	void* ra  = (void*) _sc->arm_lr; // The RA is correct for leaf methods.
+ 	void* xpc = (void*) _sc->arm_pc;
+  
+ 	// Get the exception-throwing instruction.
+ 	uint32_t mcode = *((uint32_t*) xpc);
+  
+ 	// Check if the trap instruction is valid.
+ 	// TODO Move this into patcher_handler.
+ 	if (patcher_is_valid_trap_instruction_at(xpc) == false) {
+ 		// Check if the PC has been patched during our way to this
+ 		// signal handler (see PR85).
+ 		// NOTE: ARM uses SIGILL for other traps too, but it's OK to
+ 		// do this check anyway because it will fail.
+ 		if (patcher_is_patched_at(xpc) == true)
+ 			return;
+  
+ 		// We have a problem...
+  		log_println("md_signal_handler_sigill: Unknown illegal instruction 0x%x at 0x%x", mcode, xpc);
+  #if defined(ENABLE_DISASSEMBLER)
+ 		(void) disassinstr(xpc);
+  #endif
+  		vm_abort("Aborting...");
+  	}
+  
+ 	type = (mcode >> 8) & 0x0fff;
+ 	val  = *((int32_t*) _sc + OFFSET(scontext_t, arm_r0)/4 + (mcode & 0x0f));
+  
+ 	// Handle the trap.
+ 	p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+  
+ 	// Set registers if we have an exception, continue execution
+ 	// otherwise.
+  	if (p != NULL) {
+  		_sc->arm_r10 = (uintptr_t) p;
+  		_sc->arm_fp  = (uintptr_t) xpc;
 	}
 }
 
Index: cacao-0.99.3/src/vm/jit/arm/patcher.c
===================================================================
--- cacao-0.99.3.orig/src/vm/jit/arm/patcher.c	2008-04-27 23:44:08.000000000 +0200
+++ cacao-0.99.3/src/vm/jit/arm/patcher.c	2008-09-24 17:05:17.003795314 +0200
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -76,6 +77,25 @@
 	PATCH_BACK_ORIGINAL_MCODE;
 }
 
+ 
+/**
+ * Check if the trap instruction at the given PC is valid.
+ *
+ * @param pc Program counter.
+ *
+ * @return true if valid, false otherwise.
+ */
+bool patcher_is_valid_trap_instruction_at(void* pc)
+{
+	uint32_t mcode = *((uint32_t*) pc);
+ 
+ 	// Check for the undefined instruction we use.
+ 	if ((mcode & 0x0ff000f0) != 0x07f000f0) {
+ 		return false;
+ 	}
+ 
+ 	return true;
+}
 
 /* patcher_get_putstatic *******************************************************
 
Index: cacao-0.99.3/src/vm/jit/patcher-common.c
===================================================================
--- cacao-0.99.3.orig/src/vm/jit/patcher-common.c	2008-04-28 21:52:41.000000000 +0200
+++ cacao-0.99.3/src/vm/jit/patcher-common.c	2008-09-24 17:05:17.047796037 +0200
@@ -2,6 +2,7 @@
 
    Copyright (C) 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -254,6 +255,49 @@
 }
 
 
+/**
+ * Check if the patcher is already patched.  This is done by comparing
+ * the machine instruction.
+ *
+ * @param pr Patcher structure.
+ *
+ * @return true if patched, false otherwise.
+ */
+bool patcher_is_patched(patchref_t* pr)
+{
+	// Validate the instruction at the patching position is the same
+	// instruction as the patcher structure contains.
+	uint32_t mcode = *((uint32_t*) pr->mpc);
+
+	if (mcode != pr->mcode) {
+		// The code differs.
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+ *
+ */
+bool patcher_is_patched_at(void* pc)
+{
+	codeinfo* code = code_find_codeinfo_for_pc(pc);
+
+	// Get the patcher for the given PC.
+	patchref_t* pr = patcher_list_find(code, pc);
+
+	if (pr == NULL) {
+		// The given PC is not a patcher position.
+		return false;
+	}
+
+	// Validate the instruction.
+	return patcher_is_patched(pr);
+}
+
+
 /* patcher_handler *************************************************************
 
    Handles the request to patch JIT code at the given patching
Index: cacao-0.99.3/src/vm/jit/patcher-common.h
===================================================================
--- cacao-0.99.3.orig/src/vm/jit/patcher-common.h	2008-04-27 23:44:08.000000000 +0200
+++ cacao-0.99.3/src/vm/jit/patcher-common.h	2008-09-24 17:05:17.115800331 +0200
@@ -73,6 +73,12 @@
 
 void patcher_resolve(jitdata* jd);
 
+bool patcher_is_patched(patchref_t* pr);
+bool patcher_is_patched_at(void* pc);
+
+// MD function.
+bool patcher_is_valid_trap_instruction_at(void* pc);
+
 java_handle_t *patcher_handler(u1 *pc);