about summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-07-21 20:32:17 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-07-21 20:32:17 +0200
commit2e6acc86e15927cbfa416b94a226494aae84662d (patch)
tree0a4b0bc27de9c11cde547f15fa844267ff550d5b /tests
parentc6e981a36369b560012f22f29b69e8e8843c072b (diff)
downloadbox64-2e6acc86e15927cbfa416b94a226494aae84662d.tar.gz
box64-2e6acc86e15927cbfa416b94a226494aae84662d.zip
Improved exception/int 3 handling
Diffstat (limited to 'tests')
-rw-r--r--tests/ref21.txt4
-rwxr-xr-xtests/test21bin19088 -> 23696 bytes
-rw-r--r--tests/test21.c72
3 files changed, 73 insertions, 3 deletions
diff --git a/tests/ref21.txt b/tests/ref21.txt
index 38e983ce..8fc221a0 100644
--- a/tests/ref21.txt
+++ b/tests/ref21.txt
@@ -1,2 +1,6 @@
 sig = 11
 got bad_ptr
+sig = 5
+si_addr: 0, si_code: 128, si_errno: 0, RIP offset: 1, TRAPERR=0 TRAPNO=3
+sig = 5
+si_addr: 0, si_code: 128, si_errno: 0, RIP offset: 2, TRAPERR=0 TRAPNO=3
diff --git a/tests/test21 b/tests/test21
index 71760a7d..934ebcb7 100755
--- a/tests/test21
+++ b/tests/test21
Binary files differdiff --git a/tests/test21.c b/tests/test21.c
index 803f0142..09bae72a 100644
--- a/tests/test21.c
+++ b/tests/test21.c
@@ -1,13 +1,19 @@
+#define __USE_GNU
 #include <signal.h>
 #include <setjmp.h>
 #include <stdio.h>
+#include <sys/mman.h>
+#include <sys/ucontext.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
 
 static jmp_buf context_buf;
 
 static void segv_handler(int sig)
 {
 	printf("sig = %d\n", sig);
-	longjmp(context_buf, 1);
+	siglongjmp(context_buf, 1);
 }
 
 void test()
@@ -20,11 +26,71 @@ void test()
 	}
 }
 
+void* exec_p = NULL;
+typedef void(*vFv_t)(void);
+#define X_IP		16
+#define X_TRAPNO 	20
+#define X_ERR		19
+static void segv_action(int sig, siginfo_t* info, ucontext_t* ucntx)
+{
+	printf("sig = %d\n", sig);
+	printf("si_addr: %zx, si_code: %d, si_errno: %d, RIP offset: %zd, TRAPERR=%d TRAPNO=%d\n", 
+		info->si_addr,
+		info->si_code,
+		info->si_errno,
+		((intptr_t)ucntx->uc_mcontext.gregs[X_IP])-((intptr_t)exec_p),
+		ucntx->uc_mcontext.gregs[X_ERR],
+		ucntx->uc_mcontext.gregs[X_TRAPNO]
+	);
+	siglongjmp(context_buf, 1);
+}
+
+static unsigned char buff_cc[] = { 0xcc, 0xc3 };
+static unsigned char buff_cd03[] = { 0xcd, 0x03, 0xc3 };
+static unsigned char buff_cd2d[] = { 0xcd, 0x2d, 0xc3 };
+void test_cc()
+{
+	memcpy(exec_p, buff_cc, sizeof(buff_cc));
+	if(!setjmp(context_buf)) {
+		vFv_t f = (vFv_t)exec_p;
+		f();
+	}
+	memcpy(exec_p, buff_cd03, sizeof(buff_cd03));
+	if(!setjmp(context_buf)) {
+		vFv_t f = (vFv_t)exec_p;
+		f();
+	}
+	/*memcpy(exec_p, buff_cd2d, sizeof(buff_cd2d));
+	if(!setjmp(context_buf)) {
+		vFv_t f = (vFv_t)exec_p;
+		f();
+	}*/
+}
+
 int main()
 {
-	if(signal(SIGSEGV, segv_handler) == SIG_ERR)
-		printf("Err = %m\n");
+	if(signal(SIGSEGV, segv_handler) == SIG_ERR) {
+		printf("signal: Err = %d\n", errno);
+		return -1;
+	}
 	//printf("handler = %p\n", segv_handler);
 	test();
+    struct sigaction action = {0};
+    action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
+    action.sa_sigaction = segv_action;
+    if(sigaction(SIGSEGV, &action, NULL)) {
+		printf("sigaction: Err = %d\n", errno);
+		return -2;
+	}
+    if(sigaction(SIGTRAP, &action, NULL)) {
+		printf("sigaction 2: Err = %d\n", errno);
+		return -2;
+	}
+	exec_p = mmap(NULL, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+	if(exec_p==MAP_FAILED) {
+		printf("mmap: Err = %d\n", errno);
+		return -3;
+	}
+	test_cc();
 	return 0;
 }