aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-debug.c')
-rw-r--r--camel/camel-debug.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/camel/camel-debug.c b/camel/camel-debug.c
index 7c16c9a614..77a5d1cf8b 100644
--- a/camel/camel-debug.c
+++ b/camel/camel-debug.c
@@ -21,6 +21,9 @@
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+#include <pthread.h>
#include "camel-debug.h"
@@ -113,3 +116,143 @@ gboolean camel_debug(const char *mode)
return FALSE;
}
+
+static pthread_mutex_t debug_lock = PTHREAD_MUTEX_INITIALIZER;
+/**
+ * camel_debug_start:
+ * @mode:
+ *
+ * Start debug output for a given mode, used to make sure debug output
+ * is output atomically and not interspersed with unrelated stuff.
+ *
+ * Return value: Returns true if mode is set, and in which case, you must
+ * call debug_end when finished any screen output.
+ **/
+gboolean
+camel_debug_start(const char *mode)
+{
+ if (camel_debug(mode)) {
+ pthread_mutex_lock(&debug_lock);
+ printf("Thread %lx >\n", pthread_self());
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * camel_debug_end:
+ *
+ * Call this when you're done with your debug output. If and only if
+ * you called camel_debug_start, and if it returns TRUE.
+ **/
+void
+camel_debug_end(void)
+{
+ printf("< %lx >\n", pthread_self());
+ pthread_mutex_unlock(&debug_lock);
+}
+
+#include <sys/debugreg.h>
+
+#if 0
+static unsigned
+i386_length_and_rw_bits (int len, enum target_hw_bp_type type)
+{
+ unsigned rw;
+
+ switch (type)
+ {
+ case hw_execute:
+ rw = DR_RW_EXECUTE;
+ break;
+ case hw_write:
+ rw = DR_RW_WRITE;
+ break;
+ case hw_read: /* x86 doesn't support data-read watchpoints */
+ case hw_access:
+ rw = DR_RW_READ;
+ break;
+#if 0
+ case hw_io_access: /* not yet supported */
+ rw = DR_RW_IORW;
+ break;
+#endif
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type);
+ }
+
+ switch (len)
+ {
+ case 1:
+ return (DR_LEN_1 | rw);
+ case 2:
+ return (DR_LEN_2 | rw);
+ case 4:
+ return (DR_LEN_4 | rw);
+ case 8:
+ if (TARGET_HAS_DR_LEN_8)
+ return (DR_LEN_8 | rw);
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len);
+ }
+}
+
+#define I386_DR_SET_RW_LEN(i,rwlen) \
+ do { \
+ dr_control_mirror &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ dr_control_mirror |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ } while (0)
+
+#define I386_DR_LOCAL_ENABLE(i) \
+ dr_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
+
+
+#define set_dr(regnum, val) \
+ __asm__("movl %0,%%db" #regnum \
+ : /* no output */ \
+ :"r" (val))
+
+#define get_dr(regnum, val) \
+ __asm__("movl %%db" #regnum ", %0" \
+ :"=r" (val))
+
+/* fine idea, but it doesn't work, crashes in get_dr :-/ */
+void
+camel_debug_hwatch(int wp, void *addr)
+{
+ guint32 control, rw;
+
+ g_assert(wp <= DR_LASTADDR);
+ g_assert(sizeof(addr) == 4);
+
+ get_dr(7, control);
+ /* set watch mode + size */
+ rw = DR_RW_WRITE | DR_LEN_4;
+ control &= ~(((1<<DR_CONTROL_SIZE)-1) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE * wp));
+ control |= rw << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*wp);
+ /* set watch enable */
+ control |= ( 1<< (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * wp));
+ control |= DR_LOCAL_SLOWDOWN;
+ control &= ~DR_CONTROL_RESERVED;
+
+ switch (wp) {
+ case 0:
+ set_dr(0, addr);
+ break;
+ case 1:
+ set_dr(1, addr);
+ break;
+ case 2:
+ set_dr(2, addr);
+ break;
+ case 3:
+ set_dr(3, addr);
+ break;
+ }
+ set_dr(7, control);
+}
+
+#endif