fix 32-bits lttv for kprobes
[lttv.git] / trunk / lttv / lttv / lttv / state.c
index e6278ac8070bccba3d3a504326fda047c8ec0978..52c8ea6b963bec3e0a983b23173849a14db1b89f 100644 (file)
@@ -59,6 +59,7 @@ GQuark
     LTT_CHANNEL_SYSCALL_STATE,
     LTT_CHANNEL_TASK_STATE,
     LTT_CHANNEL_VM_STATE,
+    LTT_CHANNEL_KPROBE_STATE,
     LTT_CHANNEL_FS,
     LTT_CHANNEL_KERNEL,
     LTT_CHANNEL_MM,
@@ -70,6 +71,10 @@ GQuark
 GQuark 
     LTT_EVENT_SYSCALL_ENTRY,
     LTT_EVENT_SYSCALL_EXIT,
+    LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY,
+    LTT_EVENT_PAGE_FAULT_NOSEM_EXIT,
+    LTT_EVENT_PAGE_FAULT_ENTRY,
+    LTT_EVENT_PAGE_FAULT_EXIT,
     LTT_EVENT_TRAP_ENTRY,
     LTT_EVENT_TRAP_EXIT,
     LTT_EVENT_IRQ_ENTRY,
@@ -92,7 +97,9 @@ GQuark
     LTT_EVENT_REQUEST_COMPLETE,
     LTT_EVENT_LIST_INTERRUPT,
     LTT_EVENT_SYS_CALL_TABLE,
-    LTT_EVENT_SOFTIRQ_VEC;
+    LTT_EVENT_SOFTIRQ_VEC,
+    LTT_EVENT_KPROBE_TABLE,
+    LTT_EVENT_KPROBE;
 
 /* Fields Quarks */
 
@@ -123,7 +130,8 @@ GQuark
     LTT_FIELD_ACTION,
     LTT_FIELD_ID,
     LTT_FIELD_ADDRESS,
-    LTT_FIELD_SYMBOL;
+    LTT_FIELD_SYMBOL,
+    LTT_FIELD_IP;
 
 LttvExecutionMode
   LTTV_STATE_MODE_UNKNOWN,
@@ -219,6 +227,23 @@ static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data);
 static LttvBdevState *bdevstate_copy(LttvBdevState *bds);
 
 
+#if (__SIZEOF_LONG__ == 4)
+guint guint64_hash(gconstpointer key)
+{
+       guint64 ukey = *(const guint64 *)key;
+
+       return (guint)ukey ^ (guint)(ukey >> 32);
+}
+
+gboolean guint64_equal(gconstpointer a, gconstpointer b)
+{
+       guint64 ua = *(const guint64 *)a;
+       guint64 ub = *(const guint64 *)b;
+
+       return ua == ub;
+}
+#endif
+
 void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
 {
   LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
@@ -318,6 +343,18 @@ static void expand_syscall_table(LttvTraceState *ts, int id)
   ts->nb_syscalls = new_nb;
 }
 
+static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol)
+{
+#if (__SIZEOF_LONG__ == 4)
+  guint64 *ip_ptr = g_new(guint64, 1);
+  g_hash_table_insert(ts->kprobe_hash, ip_ptr,
+    (gpointer)(glong)g_quark_from_string(symbol));
+#else
+  g_hash_table_insert(ts->kprobe_hash, (gpointer)ip,
+    (gpointer)(glong)g_quark_from_string(symbol));
+#endif
+}
+
 static void expand_trap_table(LttvTraceState *ts, int id)
 {
   guint new_nb = check_expand(ts->nb_traps, id);
@@ -1861,6 +1898,7 @@ typedef struct _LttvNameTables {
   guint nb_irqs;
   GQuark *soft_irq_names;
   guint nb_softirqs;
+  GHashTable *kprobe_hash;
 } LttvNameTables;
 
 
@@ -1990,6 +2028,13 @@ create_name_tables(LttvTraceState *tcs)
   g_array_free(hooks, TRUE);
 
   g_string_free(fe_name, TRUE);
+
+#if (__SIZEOF_LONG__ == 4)
+  name_tables->kprobe_hash = g_hash_table_new_full(guint64_hash, guint64_equal,
+    g_free, NULL);
+#else
+  name_tables->kprobe_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
+#endif
 }
 
 
@@ -2013,6 +2058,7 @@ get_name_tables(LttvTraceState *tcs)
   tcs->soft_irq_names = name_tables->soft_irq_names;
   tcs->nb_irqs = name_tables->nb_irqs;
   tcs->nb_soft_irqs = name_tables->nb_softirqs;
+  tcs->kprobe_hash = name_tables->kprobe_hash;
 }
 
 
@@ -2034,6 +2080,7 @@ free_name_tables(LttvTraceState *tcs)
   if(name_tables->irq_names) g_free(name_tables->irq_names);
   if(name_tables->soft_irq_names) g_free(name_tables->soft_irq_names);
   if(name_tables) g_free(name_tables);
+  if(name_tables) g_hash_table_destroy(name_tables->kprobe_hash);
 } 
 
 #ifdef HASH_TABLE_DEBUG
@@ -2781,6 +2828,23 @@ static gboolean dump_syscall(void *hook_data, void *call_data)
   return FALSE;
 }
 
+static gboolean dump_kprobe(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHook *th = (LttvTraceHook *)hook_data;
+  guint64 ip;
+  char *symbol;
+
+  ip = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 0));
+  symbol = ltt_event_get_string(e, lttv_trace_get_hook_field(th, 1));
+
+  expand_kprobe_table(ts, ip, symbol);
+
+  return FALSE;
+}
+
 static gboolean dump_softirq(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
@@ -3393,7 +3457,7 @@ void lttv_state_add_event_hooks(LttvTracesetState *self)
     /* Find the eventtype id for the following events and register the
        associated by id hooks. */
 
-    hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 19);
+    hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 20);
     //hooks = g_array_set_size(hooks, 19); // Max possible number of hooks.
     //hn = 0;
 
@@ -3421,6 +3485,30 @@ void lttv_state_add_event_hooks(LttvTracesetState *self)
         NULL,
         trap_exit, NULL, &hooks);
 
+    lttv_trace_find_hook(ts->parent.t,
+        LTT_CHANNEL_KERNEL,
+        LTT_EVENT_PAGE_FAULT_ENTRY,
+        FIELD_ARRAY(LTT_FIELD_TRAP_ID),
+        trap_entry, NULL, &hooks);
+
+    lttv_trace_find_hook(ts->parent.t,
+        LTT_CHANNEL_KERNEL,
+        LTT_EVENT_PAGE_FAULT_EXIT,
+        NULL,
+        trap_exit, NULL, &hooks);
+
+    lttv_trace_find_hook(ts->parent.t,
+        LTT_CHANNEL_KERNEL,
+        LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY,
+        FIELD_ARRAY(LTT_FIELD_TRAP_ID),
+        trap_entry, NULL, &hooks);
+
+    lttv_trace_find_hook(ts->parent.t,
+        LTT_CHANNEL_KERNEL,
+        LTT_EVENT_PAGE_FAULT_NOSEM_EXIT,
+        NULL,
+        trap_exit, NULL, &hooks);
+
     lttv_trace_find_hook(ts->parent.t,
         LTT_CHANNEL_KERNEL,
         LTT_EVENT_IRQ_ENTRY,
@@ -3546,6 +3634,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self)
         FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL),
         dump_syscall, NULL, &hooks);
 
+    lttv_trace_find_hook(ts->parent.t,
+        LTT_CHANNEL_KPROBE_STATE,
+        LTT_EVENT_KPROBE_TABLE,
+        FIELD_ARRAY(LTT_FIELD_IP, LTT_FIELD_SYMBOL),
+        dump_kprobe, NULL, &hooks);
+
     lttv_trace_find_hook(ts->parent.t,
         LTT_CHANNEL_SOFTIRQ_STATE,
         LTT_EVENT_SOFTIRQ_VEC,
@@ -4220,6 +4314,7 @@ static void module_init()
   LTT_CHANNEL_SYSCALL_STATE     = g_quark_from_string("syscall_state");
   LTT_CHANNEL_TASK_STATE     = g_quark_from_string("task_state");
   LTT_CHANNEL_VM_STATE     = g_quark_from_string("vm_state");
+  LTT_CHANNEL_KPROBE_STATE     = g_quark_from_string("kprobe_state");
   LTT_CHANNEL_FS     = g_quark_from_string("fs");
   LTT_CHANNEL_KERNEL     = g_quark_from_string("kernel");
   LTT_CHANNEL_MM     = g_quark_from_string("mm");
@@ -4230,6 +4325,10 @@ static void module_init()
   LTT_EVENT_SYSCALL_EXIT  = g_quark_from_string("syscall_exit");
   LTT_EVENT_TRAP_ENTRY    = g_quark_from_string("trap_entry");
   LTT_EVENT_TRAP_EXIT     = g_quark_from_string("trap_exit");
+  LTT_EVENT_PAGE_FAULT_ENTRY    = g_quark_from_string("page_fault_entry");
+  LTT_EVENT_PAGE_FAULT_EXIT     = g_quark_from_string("page_fault_exit");
+  LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY = g_quark_from_string("page_fault_nosem_entry");
+  LTT_EVENT_PAGE_FAULT_NOSEM_EXIT = g_quark_from_string("page_fault_nosem_exit");
   LTT_EVENT_IRQ_ENTRY     = g_quark_from_string("irq_entry");
   LTT_EVENT_IRQ_EXIT      = g_quark_from_string("irq_exit");
   LTT_EVENT_SOFT_IRQ_RAISE     = g_quark_from_string("softirq_raise");
@@ -4251,6 +4350,8 @@ static void module_init()
   LTT_EVENT_LIST_INTERRUPT = g_quark_from_string("interrupt");
   LTT_EVENT_SYS_CALL_TABLE = g_quark_from_string("sys_call_table");
   LTT_EVENT_SOFTIRQ_VEC = g_quark_from_string("softirq_vec");
+  LTT_EVENT_KPROBE_TABLE = g_quark_from_string("kprobe_table");
+  LTT_EVENT_KPROBE = g_quark_from_string("kprobe");
 
   LTT_FIELD_SYSCALL_ID    = g_quark_from_string("syscall_id");
   LTT_FIELD_TRAP_ID       = g_quark_from_string("trap_id");
@@ -4279,6 +4380,7 @@ static void module_init()
   LTT_FIELD_ID            = g_quark_from_string("id");
   LTT_FIELD_ADDRESS       = g_quark_from_string("address");
   LTT_FIELD_SYMBOL        = g_quark_from_string("symbol");
+  LTT_FIELD_IP            = g_quark_from_string("ip");
   
   LTTV_CPU_UNKNOWN = g_quark_from_string("unknown");
   LTTV_CPU_IDLE = g_quark_from_string("idle");
This page took 0.025659 seconds and 4 git commands to generate.