Browse Source

break & continue working

Nicolas Cannasse 8 năm trước cách đây
mục cha
commit
c35d265870
1 tập tin đã thay đổi với 70 bổ sung15 xóa
  1. 70 15
      src/std/debug.c

+ 70 - 15
src/std/debug.c

@@ -22,8 +22,9 @@
 #include <hl.h>
 
 #ifdef HL_WIN
-static HANDLE last_process = NULL;
+static HANDLE last_process = NULL, last_thread = NULL;
 static int last_pid = -1;
+static int last_tid = -1;
 static HANDLE OpenPID( int pid ) {
 	if( pid == last_pid )
 		return last_process;
@@ -32,17 +33,23 @@ static HANDLE OpenPID( int pid ) {
 	last_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
 	return last_process;
 }
-#endif
-
-HL_API void *hl_debug_address( int low, int high ) {
-#	ifdef HL_64
-	return (void*)((int_val)low | (((int_val)high)<<32));
-#	else
-	if( high != 0 )
-		return NULL;
-	return (void*)low;
-#	endif
+static HANDLE OpenTID( int tid ) {
+	if( tid == last_tid )
+		return last_thread;
+	CloseHandle(last_thread);
+	last_tid = tid;
+	last_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
+	return last_thread;
+}
+static void CleanHandles() {
+	last_pid = -1;
+	last_tid = -1;
+	CloseHandle(last_process);
+	CloseHandle(last_thread);
+	last_process = NULL;
+	last_thread = NULL;
 }
+#endif
 
 HL_API bool hl_debug_start( int pid ) {
 #	ifdef HL_WIN
@@ -56,9 +63,7 @@ HL_API bool hl_debug_start( int pid ) {
 HL_API bool hl_debug_stop( int pid ) {
 #	ifdef HL_WIN
 	BOOL b = DebugActiveProcessStop(pid);
-	last_pid = -1;
-	CloseHandle(last_process);
-	last_process = NULL;
+	CleanHandles();
 	return (bool)b;
 #	else
 	return false;
@@ -132,12 +137,62 @@ HL_API bool hl_debug_resume( int pid, int thread ) {
 #	endif
 }
 
+#ifdef HL_WIN
+#	ifdef HL_64
+#		define GET_REG(x)	&c->R##x
+#		define REGDATA		DWORD64
+#	else
+#		define GET_REG(x)	&c->E##x
+#		define REGDATA		DWORD
+#	endif
+REGDATA *GetContextReg( CONTEXT *c, int reg ) {
+	switch( reg ) {
+	case 0: return GET_REG(sp);
+	case 1: return GET_REG(ip);
+	default: return GET_REG(ax);
+	}
+}
+#endif
+
+HL_API void *hl_debug_read_register( int pit, int thread, int reg ) {
+#	ifdef HL_WIN
+	CONTEXT c;
+	memset(&c,0xFF,sizeof(c));
+	c.ContextFlags = CONTEXT_FULL;
+	if( !GetThreadContext(OpenTID(thread),&c) )
+		return NULL;
+	if( reg == 2 )
+		return (void*)(int_val)c.EFlags;
+	return (void*)*GetContextReg(&c,reg);
+#	else
+	return NULL;
+#	endif
+}
+
+HL_API bool hl_debug_write_register( int pit, int thread, int reg, void *value ) {
+#	ifdef HL_WIN
+	CONTEXT c;
+	c.ContextFlags = CONTEXT_FULL;
+	if( !GetThreadContext(OpenTID(thread),&c) )
+		return false;
+	if( reg == 2 )
+		c.EFlags = (int)(int_val)value;
+	else
+		*GetContextReg(&c,reg) = (REGDATA)value;
+	return (bool)SetThreadContext(OpenTID(thread),&c);
+#	else
+	return false;
+#	endif
+}
+
 DEFINE_PRIM(_BOOL, debug_start, _I32);
 DEFINE_PRIM(_VOID, debug_stop, _I32);
 DEFINE_PRIM(_BOOL, debug_breakpoint, _I32);
-DEFINE_PRIM(_BYTES, debug_address, _I32 _I32);
 DEFINE_PRIM(_BOOL, debug_read, _I32 _BYTES _BYTES _I32);
 DEFINE_PRIM(_BOOL, debug_write, _I32 _BYTES _BYTES _I32);
 DEFINE_PRIM(_BOOL, debug_flush, _I32 _BYTES _I32);
 DEFINE_PRIM(_I32, debug_wait, _I32 _REF(_I32) _I32);
 DEFINE_PRIM(_BOOL, debug_resume, _I32 _I32);
+DEFINE_PRIM(_BYTES, debug_read_register, _I32 _I32 _I32);
+DEFINE_PRIM(_BOOL, debug_write_register, _I32 _I32 _I32 _BYTES);
+