add 'swap_ksyms' module
[kernel/swap-modules.git] / driver / storage.c
1 ////////////////////////////////////////////////////////////////////////////////////
2 //
3 //      FILE:           storage.c
4 //
5 //      DESCRIPTION:
6 //      This file is C source for SWAP.
7 //
8 //      SEE ALSO:       storage.h
9 //      AUTHOR:         L.Komkov, S.Dianov, A.Gerenkov, S.Andreev
10 //      COMPANY NAME:   Samsung Research Center in Moscow
11 //      DEPT NAME:      Advanced Software Group
12 //      CREATED:        2008.02.15
13 //      VERSION:        1.0
14 //      REVISION DATE:  2008.12.03
15 //
16 ////////////////////////////////////////////////////////////////////////////////////
17
18 #include <linux/types.h>
19 #include <linux/hash.h>
20 #include <linux/list.h>
21 #include <linux/unistd.h>
22 #include <linux/spinlock.h>
23 #include <linux/kernel.h>
24 #include <linux/time.h>
25 #include "module.h"
26 #include "storage.h"
27 #include "handlers_core.h"
28 #include "CProfile.h"
29
30 #define after_buffer ec_info.buffer_size
31
32 char *p_buffer = NULL;
33 inst_us_proc_t us_proc_info;
34 struct list_head otg_us_proc_info;
35 inst_dex_proc_t dex_proc_info;
36 char *deps;
37 char *bundle;
38 unsigned int inst_pid = 0;
39 struct hlist_head kernel_probes;
40 struct hlist_head otg_kernel_probes;
41 int event_mask = 0L;
42 struct cond cond_list;
43 int paused = 0; /* a state after a stop condition (events are not collected) */
44 struct timeval last_attach_time = {0, 0};
45
46 struct dbi_modules_handlers dbi_mh;
47
48 struct dbi_modules_handlers *get_dbi_modules_handlers(void)
49 {
50         return &dbi_mh;
51 }
52 EXPORT_SYMBOL_GPL(get_dbi_modules_handlers);
53
54 inline unsigned long find_dbi_jp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
55 {
56         int i;
57
58         /* Possibly we can find less expensive way */
59         for (i = 0; i < mhi->dbi_nr_handlers; i++) {
60                 if (mhi->dbi_handlers[i].func_addr == p_addr) {
61                         printk("Found jp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
62                         return mhi->dbi_handlers[i].jp_handler_addr;
63                 }
64         }
65         return 0;
66 }
67
68 inline unsigned long find_dbi_rp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
69 {
70         int i;
71
72         /* Possibly we can find less expensive way */
73         for (i = 0; i < mhi->dbi_nr_handlers; i++) {
74                 if (mhi->dbi_handlers[i].func_addr == p_addr) {
75                         printk("Found rp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
76                         return mhi->dbi_handlers[i].rp_handler_addr;
77                 }
78         }
79         return 0;
80 }
81
82 /**
83  * Search of handler in global list of modules for defined probe
84  */
85 void dbi_find_and_set_handler_for_probe(kernel_probe_t *p)
86 {
87         unsigned long jp_handler_addr, rp_handler_addr;
88         struct dbi_modules_handlers_info *local_mhi;
89         unsigned long dbi_flags;
90         unsigned int local_module_refcount = 0;
91
92         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
93         list_for_each_entry_rcu(local_mhi, &dbi_mh.modules_handlers, dbi_list_head) {
94                 printk("Searching handlers in %s module for %0lX address\n",
95                         (local_mhi->dbi_module)->name, p->addr);
96                 // XXX: absent code for pre_handlers because we suppose that they are not used
97                 if ((jp_handler_addr = find_dbi_jp_handler(p->addr, local_mhi)) != 0) {
98                         if (p->jprobe.entry != 0) {
99                                 printk("Skipping jp_handler for %s module (address %0lX)\n",
100                                                 (local_mhi->dbi_module)->name, p->addr);
101                         }
102                         else {
103                                 local_module_refcount = module_refcount(local_mhi->dbi_module);
104                                 if (local_module_refcount == 0) {
105                                         if (!try_module_get(local_mhi->dbi_module))
106                                                 printk("Error of try_module_get() for module %s\n",
107                                                                 (local_mhi->dbi_module)->name);
108                                         else
109                                                 printk("Module %s in use now\n",
110                                                                 (local_mhi->dbi_module)->name);
111                                 }
112                                 p->jprobe.entry = (kprobe_opcode_t *)jp_handler_addr;
113                                 printk("Set jp_handler for %s module (address %0lX)\n",
114                                                 (local_mhi->dbi_module)->name, p->addr);
115                         }
116                 }
117                 if ((rp_handler_addr = find_dbi_rp_handler(p->addr, local_mhi)) != 0) {
118                         if (p->retprobe.handler != 0) {
119                                 printk("Skipping kretprobe_handler for %s module (address %0lX)\n",
120                                                 (local_mhi->dbi_module)->name, p->addr);
121                         }
122                         else {
123                                 local_module_refcount = module_refcount(local_mhi->dbi_module);
124                                 if (local_module_refcount == 0) {
125                                         if (!try_module_get(local_mhi->dbi_module))
126                                                 printk("Error of try_module_get() for module %s\n",
127                                                                 (local_mhi->dbi_module)->name);
128                                         else
129                                                 printk("Module %s in use now\n",
130                                                                 (local_mhi->dbi_module)->name);
131                                 }
132                                 p->retprobe.handler = (kretprobe_handler_t)rp_handler_addr;
133                                 printk("Set rp_handler for %s module (address %0lX)\n",
134                                                 (local_mhi->dbi_module)->name, p->addr);
135                         }
136                 }
137         }
138         // not found pre_handler - set default (always true for now since pre_handlers not used)
139         if (p->jprobe.pre_entry == 0) {
140                 p->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
141                 printk("Set default pre_handler (address %0lX)\n", p->addr);
142         }
143         // not found jp_handler - set default
144         if (p->jprobe.entry == 0) {
145                 p->jprobe.entry = (kprobe_opcode_t *) def_jprobe_event_handler;
146                 printk("Set default jp_handler (address %0lX)\n", p->addr);
147         }
148         // not found kretprobe_handler - set default
149         if (p->retprobe.handler == 0) {
150                 p->retprobe.handler = (kretprobe_handler_t) def_retprobe_event_handler;
151                 printk("Set default rp_handler (address %0lX)\n", p->addr);
152         }
153         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
154 }
155
156 // XXX TODO: possible mess when start-register/unregister-stop operation
157 // so we should refuse register/unregister operation while we are in unsafe state
158 int dbi_register_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
159 {
160         unsigned long dbi_flags;
161 //      struct dbi_modules_handlers_info *local_mhi;
162         int i=0;
163         int nr_handlers=dbi_mhi->dbi_nr_handlers;
164
165         for (i = 0; i < nr_handlers; ++i) {
166                 dbi_mhi->dbi_handlers[i].func_addr = swap_ksyms(dbi_mhi->dbi_handlers[i].func_name);
167                 printk("[0x%08x]-%s\n", dbi_mhi->dbi_handlers[i].func_addr, dbi_mhi->dbi_handlers[i].func_name);
168         }
169
170         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
171 //      local_mhi = container_of(&dbi_mhi->dbi_list_head, struct dbi_modules_handlers_info, dbi_list_head);
172         list_add_rcu(&dbi_mhi->dbi_list_head, &dbi_mh.modules_handlers);
173         printk("Added module %s (head is %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
174         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
175         return 0;
176 }
177 EXPORT_SYMBOL_GPL(dbi_register_handlers_module);
178
179 // XXX TODO: possible mess when start-register/unregister-stop operation
180 // so we should refuse register/unregister operation while we are in unsafe state
181 int dbi_unregister_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
182 {
183         unsigned long dbi_flags;
184         // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
185         // (i.e. between attach and stop)
186         /*kernel_probe_t *p;
187         struct hlist_node *node;
188         unsigned long jp_handler_addr, rp_handler_addr, pre_handler_addr;*/
189
190         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
191         list_del_rcu(&dbi_mhi->dbi_list_head);
192         // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
193         // (i.e. between attach and stop)
194         /*hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist) {
195                 // XXX: absent code for pre_handlers because we suppose that they are not used
196                 if ((p->jprobe.entry != ((kprobe_pre_entry_handler_t )def_jprobe_event_pre_handler)) ||
197                                 (p->retprobe.handler != ((kretprobe_handler_t )def_retprobe_event_handler))) {
198                         printk("Searching handlers for %p address for removing in %s registered module...\n",
199                                         p->addr, (dbi_mhi->dbi_module)->name);
200                         jp_handler_addr = find_dbi_jp_handler(p->addr, dbi_mhi);
201                         rp_handler_addr = find_dbi_rp_handler(p->addr, dbi_mhi);
202                         if ((jp_handler_addr != 0) || (rp_handler_addr != 0)) {
203                                 // search and set to another handlers or default
204                                 dbi_find_and_set_handler_for_probe(p);
205                                 printk("Removed handler(s) for %s module (address %p)\n",
206                                                 (dbi_mhi->dbi_module)->name, p->addr);
207                         }
208                 }
209         }*/
210         printk("Removed module %s (head was %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
211         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
212         return 0;
213 }
214 EXPORT_SYMBOL_GPL(dbi_unregister_handlers_module);
215
216 static inst_us_proc_t empty_uprobes_info =
217 {
218         .libs_count = 0,
219         .p_libs = NULL,
220 };
221
222 static inst_us_proc_t *get_uprobes(void)
223 {
224         unsigned long dbi_flags;
225         inst_us_proc_t *ret = &empty_uprobes_info;
226         struct dbi_modules_handlers_info *mhi;
227         struct list_head *head = &dbi_mh.modules_handlers;
228
229         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
230         list_for_each_entry_rcu(mhi, head, dbi_list_head) {
231                 if (mhi->get_uprobes) {
232                         ret = mhi->get_uprobes();
233                         break;
234                 }
235         }
236         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
237
238         return ret;
239 }
240
241 EXPORT_SYMBOL_GPL(us_proc_info);
242 EXPORT_SYMBOL_GPL(dex_proc_info);
243 typedef void *(*get_my_uprobes_info_t)(void);
244 int (*mec_post_event)(char *data, unsigned long len) = NULL;
245
246 unsigned copy_into_cyclic_buffer (char *buffer, unsigned dst_offset, char *src, unsigned size)
247 {
248         unsigned nOffset = dst_offset;
249         char* pSource = src;
250         while (size--)
251                 buffer[nOffset++] = *pSource++;
252         return nOffset;
253 }
254
255 unsigned copy_from_cyclic_buffer (char *dst, char *buffer, unsigned src_offset, unsigned size)
256 {
257         unsigned nOffset = src_offset;
258         char* pDestination = dst;
259         while (size--)
260                 *pDestination++ = buffer[nOffset++];
261         return nOffset;
262 }
263
264 int CheckBufferSize (unsigned int nSize)
265 {
266         if (nSize < EC_BUFFER_SIZE_MIN) {
267                 EPRINTF("Too small buffer size! [Size=%u KB]", nSize / 1024);
268                 return -1;
269         }
270         if (nSize > EC_BUFFER_SIZE_MAX) {
271                 EPRINTF("Too big buffer size! [Size=%u KB]", nSize / 1024);
272                 return -1;
273         }
274         return 0;
275 }
276
277 int AllocateSingleBuffer(unsigned int nSize)
278 {
279         unsigned long spinlock_flags = 0L;
280
281         p_buffer = vmalloc_user(nSize);
282         if(!p_buffer) {
283                 EPRINTF("Memory allocation error! [Size=%lu KB]", nSize / 1024);
284                 return -1;
285         }
286
287         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
288         ec_info.buffer_effect = ec_info.buffer_size = nSize;
289         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
290
291         return 0;
292 }
293
294 void FreeSingleBuffer (void)
295 {
296         VFREE_USER(p_buffer, ec_info.buffer_size);
297         CleanECInfo();
298 }
299
300 //////////////////////////////////////////////////////////////////////////////////////////////////
301
302 int EnableContinuousRetrieval() {
303         unsigned long spinlock_flags = 0L;
304
305         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
306         ec_info.m_nMode |= MODEMASK_CONTINUOUS_RETRIEVAL;
307         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
308
309         return 0;
310 }
311
312 int DisableContinuousRetrieval() {
313         unsigned long spinlock_flags = 0L;
314
315         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
316         ec_info.m_nMode &= ~MODEMASK_CONTINUOUS_RETRIEVAL;
317         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
318
319         return 0;
320 }
321
322 //////////////////////////////////////////////////////////////////////////////////////////////////
323
324 int InitializeBuffer(unsigned int nSize) {
325         return AllocateSingleBuffer(nSize);
326 }
327
328 int UninitializeBuffer(void) {
329         FreeSingleBuffer();
330         return 0;
331 }
332
333 unsigned int GetBufferSize(void) { return ec_info.buffer_size; };
334
335 int SetBufferSize(unsigned int nSize) {
336         if (GetECState() != EC_STATE_IDLE) {
337                 EPRINTF("Buffer changes are allowed in IDLE state only (%d)!", GetECState());
338                 return -1;
339         }
340         if(GetBufferSize() == nSize)
341                 return 0;
342         if(CheckBufferSize(nSize) == -1) {
343                 EPRINTF("Invalid buffer size!");
344                 return -1;
345         }
346         detach_selected_probes ();
347         if(UninitializeBuffer() == -1)
348                 EPRINTF("Cannot uninitialize buffer!");
349         if(InitializeBuffer(nSize) == -1) {
350                 EPRINTF("Cannot initialize buffer! [Size=%u KB]", nSize / 1024);
351                 return -1;
352         }
353         return 0;
354 }
355
356 int SetPid(unsigned int pid)
357 {
358         if (GetECState() != EC_STATE_IDLE)
359         {
360                 EPRINTF("PID changes are allowed in IDLE state only (%d)!", GetECState());
361                 return -1;
362         }
363
364         inst_pid = pid;
365         DPRINTF("SetPid pid:%d\n", pid);
366         return 0;
367 }
368
369 void ResetSingleBuffer(void) {
370 }
371
372 int ResetBuffer(void) {
373         unsigned long spinlock_flags = 0L;
374
375         if (GetECState() != EC_STATE_IDLE) {
376                 EPRINTF("Buffer changes are allowed in IDLE state only!");
377                 return -1;
378         }
379
380         ResetSingleBuffer();
381
382         detach_selected_probes ();
383
384         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
385         ec_info.buffer_effect = ec_info.buffer_size;
386         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
387
388         ResetECInfo();
389
390         return 0;
391 }
392
393 int WriteEventIntoSingleBuffer(char* pEvent, unsigned long nEventSize) {
394         unsigned int unused_space;
395
396         if(!p_buffer) {
397                 EPRINTF("Invalid pointer to buffer!");
398                 ++ec_info.lost_events_count;
399                 return -1;
400         }
401         if (ec_info.trace_size == 0 || ec_info.after_last > ec_info.first) {
402                 unused_space = ec_info.buffer_size - ec_info.after_last;
403                 if (unused_space > nEventSize) {
404                         ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
405                                                                                                                  ec_info.after_last,
406                                                                                                                  pEvent,
407                                                                                                                  nEventSize);
408                         ec_info.saved_events_count++;
409                         ec_info.buffer_effect = ec_info.buffer_size;
410                         ec_info.trace_size = ec_info.after_last - ec_info.first;
411                 } else {
412                         if (ec_info.first > nEventSize) {
413                                 ec_info.buffer_effect = ec_info.after_last;
414                                 ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
415                                                                                                                          0,
416                                                                                                                          pEvent,
417                                                                                                                          nEventSize);
418                                 ec_info.saved_events_count++;
419                                 ec_info.trace_size = ec_info.buffer_effect
420                                         - ec_info.first
421                                         + ec_info.after_last;
422                         } else {
423                                 // TODO: consider two variants!
424                                 // Do nothing
425                                 ec_info.discarded_events_count++;
426                         }
427                 }
428         } else {
429                 unused_space = ec_info.first - ec_info.after_last;
430                 if (unused_space > nEventSize) {
431                         ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
432                                                                                                                  ec_info.after_last,
433                                                                                                                  pEvent,
434                                                                                                                  nEventSize);
435                         ec_info.saved_events_count++;
436                         ec_info.trace_size = ec_info.buffer_effect
437                                 - ec_info.first
438                                 + ec_info.after_last;
439                 } else {
440                         // Do nothing
441                         ec_info.discarded_events_count++;
442                 }
443         }
444         return 0;
445 }
446
447 int WriteEventIntoBuffer(char* pEvent, unsigned long nEventSize) {
448
449         /*unsigned long i;
450         for(i = 0; i < nEventSize; i++)
451                 printk("%02X ", pEvent[i]);
452         printk("\n");*/
453
454         return WriteEventIntoSingleBuffer(pEvent, nEventSize);
455 }
456
457 //////////////////////////////////////////////////////////////////////////////////////////////////
458
459 int set_event_mask (int new_mask)
460 {
461         unsigned long spinlock_flags = 0L;
462         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
463         event_mask = new_mask;
464         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
465         return 0;
466 }
467
468 int
469 get_event_mask (int *mask)
470 {
471         *mask = event_mask;
472         return 0;
473 }
474
475 static void
476 generic_swap (void *a, void *b, int size)
477 {
478         char t;
479         do {
480                 t = *(char *) a;
481                 *(char *) a++ = *(char *) b;
482                 *(char *) b++ = t;
483         } while (--size > 0);
484 }
485
486 static void sort (void *base, size_t num, size_t size, int (*cmp) (const void *, const void *), void (*fswap) (void *, void *, int size))
487 {
488         /* pre-scale counters for performance */
489         int i = (num / 2) * size, n = num * size, c, r;
490
491         /* heapify */
492         for (; i >= 0; i -= size)
493         {
494                 for (r = i; r * 2 < n; r = c)
495                 {
496                         c = r * 2;
497                         if (c < n - size && cmp (base + c, base + c + size) < 0)
498                                 c += size;
499                         if (cmp (base + r, base + c) >= 0)
500                                 break;
501                         fswap (base + r, base + c, size);
502                 }
503         }
504
505         /* sort */
506         for (i = n - size; i >= 0; i -= size)
507         {
508                 fswap (base, base + i, size);
509                 for (r = 0; r * 2 < i; r = c)
510                 {
511                         c = r * 2;
512                         if (c < i - size && cmp (base + c, base + c + size) < 0)
513                                 c += size;
514                         if (cmp (base + r, base + c) >= 0)
515                                 break;
516                         fswap (base + r, base + c, size);
517                 }
518         }
519 }
520
521 static int addr_cmp (const void *a, const void *b)
522 {
523         return *(unsigned long *) a > *(unsigned long *) b ? -1 : 1;
524 }
525
526 char *find_lib_path(const char *lib_name)
527 {
528         char *p = deps + sizeof(size_t);
529         char *match;
530         size_t len;
531
532         while (*p != '\0') {
533                 DPRINTF("p is at %s", p);
534                 len = strlen(p) + 1;
535                 match = strstr(p, lib_name);
536                 p += len;
537                 len = strlen(p) + 1; /* we are at path now */
538             if (!match) {
539                         p += len;
540                 } else {
541                         DPRINTF("Found match: %s", match);
542                         return p;
543                 }
544         }
545
546         return NULL;
547 }
548
549 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
550 #define list_for_each_rcu(pos, head) __list_for_each_rcu(pos, head)
551 #endif
552
553 void unlink_bundle(void)
554 {
555         int i, k;
556         us_proc_lib_t *d_lib;
557         char *path;
558         struct list_head *pos;  //, *tmp;
559         us_proc_otg_ip_t *p;
560
561         path = us_proc_info.path;
562         us_proc_info.path = 0;
563
564         // first make sure "d_lib" is not used any more and only
565         // then release storage
566         if (us_proc_info.p_libs)
567         {
568                 int count1 = us_proc_info.libs_count;
569                 us_proc_info.libs_count = 0;
570                 for (i = 0; i < count1; i++)
571                 {
572                         d_lib = &us_proc_info.p_libs[i];
573                         if (d_lib->p_ips)
574                         {
575                                 // first make sure "d_lib->p_ips" is not used any more and only
576                                 // then release storage
577                                 //int count2 = d_lib->ips_count;
578                                 d_lib->ips_count = 0;
579                                 /*for (k = 0; k < count2; k++)
580                                         kfree ((void *) d_lib->p_ips[k].name);*/
581                                 vfree ((void *) d_lib->p_ips);
582                         }
583                         if (d_lib->p_vtps)
584                         {
585                                 // first make sure "d_lib->p_vtps" is not used any more and only
586                                 // then release storage
587                                 int count2 = d_lib->vtps_count;
588                                 d_lib->vtps_count = 0;
589                                 for (k = 0; k < count2; k++)
590                                 {
591                                         //list_for_each_safe_rcu(pos, tmp, &d_lib->p_vtps[k].list) {
592                                         list_for_each (pos, &d_lib->p_vtps[k].list)
593                                         {
594                                                 us_proc_vtp_data_t *vtp = list_entry (pos, us_proc_vtp_data_t, list);
595                                                 list_del_rcu (pos);
596                                                 //kfree (vtp->name);
597                                                 kfree (vtp);
598                                         }
599                                 }
600                                 kfree ((void *) d_lib->p_vtps);
601                         }
602                         d_lib->plt_count = 0;
603                         kfree((void*) d_lib->p_plt);
604                         us_proc_info.is_plt = 0;
605                 }
606                 kfree ((void *) us_proc_info.p_libs);
607                 us_proc_info.p_libs = 0;
608         }
609         /* if (path) */
610         /* { */
611         /*      kfree ((void *) path); */
612         /*      //putname(path); */
613         /* } */
614
615         us_proc_info.tgid = 0;
616
617         /* OTG probes list cleaning */
618         list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
619                 list_del_rcu(&p->list);
620         }
621 }
622
623 extern struct dentry *dentry_by_path(const char *path);
624
625 int link_bundle()
626 {
627         inst_us_proc_t *my_uprobes_info = get_uprobes();
628         char *p = bundle; /* read pointer for bundle */
629         int nr_kern_probes;
630         int i, j, l, k;
631         int len;
632         us_proc_lib_t *d_lib, *pd_lib;
633         dex_proc_ip_t *dex_proc;
634         ioctl_usr_space_lib_t s_lib;
635         ioctl_usr_space_vtp_t *s_vtp;
636         us_proc_vtp_t *mvtp;
637         int is_app = 0;
638         char *ptr;
639         us_proc_ip_t *d_ip;
640         struct cond *c, *c_tmp, *p_cond;
641         size_t nr_conds;
642         int lib_name_len;
643         int handler_index;
644
645         DPRINTF("Going to release us_proc_info");
646         if (us_proc_info.path)
647                 unlink_bundle();
648
649         /* Skip size - it has been used before */
650         p += sizeof(u_int32_t);
651
652         /* Set mode */
653         if (SetECMode(*(u_int32_t *)p) == -1)
654         {
655                 EPRINTF("Cannot set mode!\n");
656                 return -1;
657         }
658
659         p += sizeof(u_int32_t);
660
661         /* Buffer size */
662         if (SetBufferSize(*(u_int32_t *)p) == -1)
663         {
664                 EPRINTF("Cannot set buffer size!\n");
665                 return -1;
666         }
667
668         p += sizeof(u_int32_t);
669
670         /* Pid */
671         if (SetPid(*(u_int32_t *)p) == -1)
672         {
673                 EPRINTF("Cannot set pid!\n");
674                 return -1;
675         }
676
677         p += sizeof(u_int32_t);
678
679         /* Kernel probes */
680         nr_kern_probes = *(u_int32_t *)p;
681         p += sizeof(u_int32_t);
682         for (i = 0; i < nr_kern_probes; i++)
683         {
684                 if (add_probe(*(u_int32_t *)p))
685                 {
686                         EPRINTF("Cannot add kernel probe at 0x%x!\n", *(u_int32_t *)p);
687                         return -1;
688                 }
689                 p += sizeof(u_int32_t);
690         }
691
692         /* Us probes */
693         len = *(u_int32_t *)p; /* App path len */
694         p += sizeof(u_int32_t);
695
696         us_proc_info.is_plt = 0;
697         if ( len == 0 )
698         {
699             us_proc_info.path = NULL;
700         }
701         else
702         {
703                 int lib_path_len;
704                 char *lib_path;
705
706                 us_proc_info.path = (char *)p;
707                 DPRINTF("app path = %s", us_proc_info.path);
708                 p += len;
709
710                 if (strcmp(us_proc_info.path, "*")) {
711                         us_proc_info.m_f_dentry = dentry_by_path(us_proc_info.path);
712                         if (us_proc_info.m_f_dentry == NULL) {
713                                 return -1;
714                         }
715                 }
716                 else
717                 {
718                         us_proc_info.m_f_dentry = NULL;
719                 }
720
721                 us_proc_info.libs_count = *(u_int32_t *)p;
722                 DPRINTF("nr of libs = %d", us_proc_info.libs_count);
723                 p += sizeof(u_int32_t);
724                 us_proc_info.p_libs =
725                         kmalloc(us_proc_info.libs_count * sizeof(us_proc_lib_t), GFP_KERNEL);
726
727                 if (!us_proc_info.p_libs)
728                 {
729                         EPRINTF("Cannot alloc p_libs!");
730                         return -1;
731                 }
732                 memset(us_proc_info.p_libs, 0,
733                            us_proc_info.libs_count * sizeof(us_proc_lib_t));
734
735                 for (i = 0; i < us_proc_info.libs_count; i++)
736                 {
737                         int abs_handler_idx = 0;
738
739                         d_lib = &us_proc_info.p_libs[i];
740
741                         lib_name_len = *(u_int32_t *)p;
742                         p += sizeof(u_int32_t);
743                         d_lib->path = (char *)p;
744                         DPRINTF("d_lib->path = %s", d_lib->path);
745                         p += lib_name_len;
746
747                         if ( i != 0 ) {
748                                 lib_name_len = *(u_int32_t *)p;
749                                 p += sizeof(u_int32_t);
750                                 d_lib->path_dyn = (char *)p;
751                                 DPRINTF("d_lib->path_dyn = %s", d_lib->path_dyn);
752                                 p += lib_name_len;
753                         }
754
755                         d_lib->ips_count = *(u_int32_t *)p;
756                         DPRINTF("d_lib->ips_count = %d", d_lib->ips_count);
757                         p += sizeof(u_int32_t);
758
759                         /* If there are any probes for "*" app we have to drop them */
760                         if (strcmp(d_lib->path, "*") == 0)
761                         {
762                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
763                                 d_lib->ips_count = 0;
764                                 d_lib->plt_count = *(u_int32_t*)p;
765                                 p += sizeof(u_int32_t);
766                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
767                                 d_lib->plt_count = 0;
768                                 continue;
769                         }
770
771                         if (strcmp(us_proc_info.path, d_lib->path) == 0)
772                                 is_app = 1;
773                         else
774                         {
775                                 is_app = 0;
776                                 DPRINTF("Searching path for lib %s", d_lib->path);
777                                 d_lib->path = find_lib_path(d_lib->path);
778                                 if (!d_lib->path)
779                                 {
780                                         if (strcmp(d_lib->path_dyn, "") == 0) {
781                                                 EPRINTF("Cannot find path for lib %s!", d_lib->path);
782                                                 /* Just skip all the IPs and go to next lib */
783                                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
784                                                 d_lib->ips_count = 0;
785                                                 d_lib->plt_count = *(u_int32_t*)p;
786                                                 p += sizeof(u_int32_t);
787                                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
788                                                 d_lib->plt_count = 0;
789                                                 continue;
790                                         }
791                                         else {
792                                                 d_lib->path = d_lib->path_dyn;
793                                                 DPRINTF("Assign path for lib as %s (in suggestion of dyn lib)", d_lib->path);
794                                         }
795                                 }
796                         }
797
798                         d_lib->m_f_dentry = dentry_by_path(d_lib->path);
799                         if (d_lib->m_f_dentry == NULL) {
800                                 EPRINTF ("failed to lookup dentry for path %s!", d_lib->path);
801                                 /* Just skip all the IPs and go to next lib */
802                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
803                                 d_lib->ips_count = 0;
804                                 d_lib->plt_count = *(u_int32_t*)p;
805                                 p += sizeof(u_int32_t);
806                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
807                                 d_lib->plt_count = 0;
808                                 continue;
809                         }
810
811                         pd_lib = NULL;
812                         ptr = strrchr(d_lib->path, '/');
813                         if (ptr)
814                                 ptr++;
815                         else
816                                 ptr = d_lib->path;
817
818                         for (l = 0; l < my_uprobes_info->libs_count; l++)
819                         {
820                                 if ((strcmp(ptr, my_uprobes_info->p_libs[l].path) == 0) ||
821                                         (is_app && *(my_uprobes_info->p_libs[l].path) == '\0'))
822                                 {
823                                         pd_lib = &my_uprobes_info->p_libs[l];
824                                         break;
825                                 }
826                                 abs_handler_idx += my_uprobes_info->p_libs[l].ips_count;
827                         }
828
829                         if (d_lib->ips_count > 0)
830                         {
831                                 us_proc_info.unres_ips_count += d_lib->ips_count;
832                                 d_lib->p_ips = vmalloc(d_lib->ips_count * sizeof(us_proc_ip_t));
833                                 DPRINTF("d_lib[%i]->p_ips=%p/%u [%s]", i, d_lib->p_ips,
834                                                 us_proc_info.unres_ips_count, d_lib->path);
835
836                                 if (!d_lib->p_ips)
837                                 {
838                                         EPRINTF("Cannot alloc p_ips!\n");
839                                         return -1;
840                                 }
841
842                                 memset (d_lib->p_ips, 0, d_lib->ips_count * sizeof(us_proc_ip_t));
843                                 for (k = 0; k < d_lib->ips_count; k++)
844                                 {
845                                         d_ip = &d_lib->p_ips[k];
846                                         d_ip->offset = *(u_int32_t *)p;
847                                         p += sizeof(u_int32_t);
848                                         p += sizeof(u_int32_t); /* Skip inst type */
849                                         handler_index = *(u_int32_t *)p;
850                                         p += sizeof(u_int32_t);
851
852                                         if (pd_lib)
853                                         {
854                                                 DPRINTF("pd_lib->ips_count = 0x%x", pd_lib->ips_count);
855                                                 if (handler_index != -1)
856                                                 {
857                                                         DPRINTF("found handler for 0x%x", d_ip->offset);
858                                                         d_ip->jprobe.pre_entry =
859                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.pre_entry;
860                                                         d_ip->jprobe.entry =
861                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.entry;
862                                                         d_ip->retprobe.handler =
863                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].retprobe.handler;
864                                                 }
865                                         }
866                                 }
867                         }
868
869                         d_lib->plt_count = *(u_int32_t*)p;
870                         p += sizeof(u_int32_t);
871                         if (d_lib->plt_count > 0)
872                         {
873                                 int j;
874                                 us_proc_info.is_plt = 1;
875                                 d_lib->p_plt = kmalloc(d_lib->plt_count * sizeof(us_proc_plt_t), GFP_KERNEL);
876                                 if (!d_lib->p_plt)
877                                 {
878                                         EPRINTF("Cannot alloc p_plt!");
879                                         return -1;
880                                 }
881                                 memset(d_lib->p_plt, 0, d_lib->plt_count * sizeof(us_proc_plt_t));
882                                 for (j = 0; j < d_lib->plt_count; j++)
883                                 {
884                                         d_lib->p_plt[j].func_addr = *(u_int32_t*)p;
885                                         p += sizeof(u_int32_t);
886                                         d_lib->p_plt[j].got_addr = *(u_int32_t*)p;
887                                         p += sizeof(u_int32_t);
888                                         d_lib->p_plt[j].real_func_addr = 0;
889                                 }
890                         }
891                 }
892
893                 /* Lib path */
894                 lib_path_len = *(u_int32_t *)p;
895                 DPRINTF("lib_path_len = %d", lib_path_len);
896                 p += sizeof(u_int32_t);
897                 lib_path = p;
898                 DPRINTF("lib_path = %s", lib_path);
899                 p += lib_path_len;
900
901                 /* Link FBI info */
902                 d_lib = &us_proc_info.p_libs[0];
903                 s_lib.vtps_count = *(u_int32_t *)p;
904                 DPRINTF("s_lib.vtps_count = %d", s_lib.vtps_count);
905                 p += sizeof(u_int32_t);
906                 if (s_lib.vtps_count > 0)
907                 {
908                         unsigned long ucount = 1, pre_addr;
909                         unsigned long *addrs;
910
911                         s_lib.p_vtps = kmalloc(s_lib.vtps_count
912                                                                    * sizeof(ioctl_usr_space_vtp_t), GFP_KERNEL);
913                         if (!s_lib.p_vtps)
914                         {
915                                 //kfree (addrs);
916                                 return -1;
917                         }
918
919                         for (i = 0; i < s_lib.vtps_count; i++)
920                         {
921                                 int var_name_len = *(u_int32_t *)p;
922                                 p += sizeof(u_int32_t);
923                                 s_lib.p_vtps[i].name = p;
924                                 p += var_name_len;
925                                 s_lib.p_vtps[i].addr = *(u_int32_t *)p;
926                                 p += sizeof(u_int32_t);
927                                 s_lib.p_vtps[i].type = *(u_int32_t *)p;
928                                 p += sizeof(u_int32_t);
929                                 s_lib.p_vtps[i].size = *(u_int32_t *)p;
930                                 p += sizeof(u_int32_t);
931                                 s_lib.p_vtps[i].reg = *(u_int32_t *)p;
932                                 p += sizeof(u_int32_t);
933                                 s_lib.p_vtps[i].off = *(u_int32_t *)p;
934                                 p += sizeof(u_int32_t);
935                         }
936
937                         // array containing elements like (addr, index)
938                         addrs = kmalloc (s_lib.vtps_count * 2 * sizeof (unsigned long), GFP_KERNEL);
939         //                      DPRINTF ("addrs=%p/%u", addrs, s_lib.vtps_count);
940                         if (!addrs)
941                         {
942                                 //note: storage will released next time or at clean-up moment
943                                 return -ENOMEM;
944                         }
945                         memset (addrs, 0, s_lib.vtps_count * 2 * sizeof (unsigned long));
946                         // fill the array in
947                         for (k = 0; k < s_lib.vtps_count; k++)
948                         {
949                                 s_vtp = &s_lib.p_vtps[k];
950                                 addrs[2 * k] = s_vtp->addr;
951                                 addrs[2 * k + 1] = k;
952                         }
953                         // sort by VTP addresses, i.e. make VTPs with the same addresses adjacent;
954                         // organize them into bundles
955                         sort (addrs, s_lib.vtps_count, 2 * sizeof (unsigned long), addr_cmp, generic_swap);
956
957                         // calc number of VTPs with unique addresses
958                         for (k = 1, pre_addr = addrs[0]; k < s_lib.vtps_count; k++)
959                         {
960                                 if (addrs[2 * k] != pre_addr)
961                                         ucount++;       // count different only
962                                 pre_addr = addrs[2 * k];
963                         }
964                         us_proc_info.unres_vtps_count += ucount;
965                         d_lib->vtps_count = ucount;
966                         d_lib->p_vtps = kmalloc (ucount * sizeof (us_proc_vtp_t), GFP_KERNEL);
967                         DPRINTF ("d_lib[%i]->p_vtps=%p/%lu", i, d_lib->p_vtps, ucount); //, d_lib->path);
968                         if (!d_lib->p_vtps)
969                         {
970                                 //note: storage will released next time or at clean-up moment
971                                 kfree (addrs);
972                                 return -ENOMEM;
973                         }
974                         memset (d_lib->p_vtps, 0, d_lib->vtps_count * sizeof (us_proc_vtp_t));
975                         // go through sorted VTPS.
976                         for (k = 0, j = 0, pre_addr = 0, mvtp = NULL; k < s_lib.vtps_count; k++)
977                         {
978                                 us_proc_vtp_data_t *vtp_data;
979                                 // copy VTP data
980                                 s_vtp = &s_lib.p_vtps[addrs[2 * k + 1]];
981                                 // if this is the first VTP in bundle (master VTP)
982                                 if (addrs[2 * k] != pre_addr)
983                                 {
984                                         // data are in the array of master VTPs
985                                         mvtp = &d_lib->p_vtps[j++];
986                                         mvtp->addr = s_vtp->addr;
987                                         INIT_LIST_HEAD (&mvtp->list);
988                                 }
989                                 // data are in the list of slave VTPs
990                                 vtp_data = kmalloc (sizeof (us_proc_vtp_data_t), GFP_KERNEL);
991                                 if (!vtp_data)
992                                 {
993                                         //note: storage will released next time or at clean-up moment
994                                         kfree (addrs);
995                                         return -ENOMEM;
996                                 }
997
998                                 /*len = strlen_user (s_vtp->name);
999                                   vtp_data->name = kmalloc (len, GFP_KERNEL);
1000                                   if (!vtp_data->name)
1001                                   {
1002                                   //note: storage will released next time or at clean-up moment
1003                                   kfree (vtp_data);
1004                                   kfree (addrs);
1005                                   return -ENOMEM;
1006                                   }
1007                                   if (strncpy_from_user (vtp_data->name, s_vtp->name, len) != (len-1))
1008                                   {
1009                                   //note: storage will released next time or at clean-up moment
1010                                   EPRINTF ("strncpy_from_user VTP name failed %p (%ld)", vtp_data->name, len);
1011                                   kfree (vtp_data->name);
1012                                   kfree (vtp_data);
1013                                   kfree (addrs);
1014                                   return -EFAULT;
1015                                   }
1016                                   //vtp_data->name[len] = 0;*/
1017                                 vtp_data->name = s_vtp->name;
1018                                 vtp_data->type = s_vtp->type;
1019                                 vtp_data->size = s_vtp->size;
1020                                 vtp_data->reg = s_vtp->reg;
1021                                 vtp_data->off = s_vtp->off;
1022                                 list_add_tail_rcu (&vtp_data->list, &mvtp->list);
1023                                 pre_addr = addrs[2 * k];
1024                         }
1025                         kfree (addrs);
1026                         kfree(s_lib.p_vtps);
1027                 }
1028         }
1029
1030         /* Conds */
1031         /* first, delete all the conds */
1032         list_for_each_entry_safe(c, c_tmp, &cond_list.list, list) {
1033                 list_del(&c->list);
1034                 kfree(c);
1035         }
1036         /* second, add new conds */
1037         /* This can be improved (by placing conds into array) */
1038         nr_conds = *(u_int32_t *)p;
1039         DPRINTF("nr_conds = %d", nr_conds);
1040         p += sizeof(u_int32_t);
1041         for (i = 0; i < nr_conds; i++) {
1042                 p_cond = kmalloc(sizeof(struct cond), GFP_KERNEL);
1043                 if (!p_cond) {
1044                         EPRINTF("Cannot alloc cond!\n");
1045                         return -1;
1046                         break;
1047                 }
1048                 memcpy(&p_cond->tmpl, p, sizeof(struct event_tmpl));
1049                 p_cond->applied = 0;
1050                 list_add(&(p_cond->list), &(cond_list.list));
1051                 p += sizeof(struct event_tmpl);
1052         }
1053
1054         /* Event mask */
1055         if (set_event_mask(*(u_int32_t *)p)) {
1056                 EPRINTF("Cannot set event mask!");
1057                 return -1;
1058         }
1059
1060         p += sizeof(u_int32_t);
1061
1062         return 0;
1063 }
1064
1065 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1066 int storage_init (void)
1067 {
1068         unsigned long spinlock_flags = 0L;
1069
1070         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1071         ec_info.m_nMode = 0; // MASK IS CLEAR (SINGLE NON_CONTINUOUS BUFFER)
1072         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
1073
1074         if(InitializeBuffer(EC_BUFFER_SIZE_DEFAULT) == -1) {
1075                 EPRINTF("Cannot initialize buffer! [Size=%u KB]", EC_BUFFER_SIZE_DEFAULT / 1024 );
1076                 return -1;
1077         }
1078
1079         INIT_HLIST_HEAD(&kernel_probes);
1080         INIT_HLIST_HEAD(&otg_kernel_probes);
1081         INIT_LIST_HEAD(&otg_us_proc_info);
1082         spin_lock_init(&dbi_mh.lock);
1083         INIT_LIST_HEAD(&dbi_mh.modules_handlers);
1084         return 0;
1085 }
1086
1087 /*
1088     Shuts down "storage".
1089     Assumes that all probes are already deactivated.
1090 */
1091 void storage_down (void)
1092 {
1093         if(UninitializeBuffer() == -1)
1094                 EPRINTF("Cannot uninitialize buffer!");
1095
1096         if (ec_info.collision_count)
1097                 EPRINTF ("ec_info.collision_count=%d", ec_info.collision_count);
1098         if (ec_info.lost_events_count)
1099                 EPRINTF ("ec_info.lost_events_count=%d", ec_info.lost_events_count);
1100 }
1101
1102 u_int32_t get_probe_func_addr(const char *fmt, va_list args)
1103 {
1104         if (fmt[0] != 'p')
1105                 return 0;
1106
1107         return va_arg(args, u_int32_t);
1108 }
1109
1110 void pack_task_event_info(struct task_struct *task, probe_id_t probe_id,
1111                 record_type_t record_type, const char *fmt, ...)
1112 {
1113         unsigned long spinlock_flags = 0L;
1114         static char buf[EVENT_MAX_SIZE] = "";
1115         TYPEOF_EVENT_LENGTH event_len = 0L;
1116         struct timeval tv = { 0, 0 };
1117         TYPEOF_THREAD_ID current_pid = task->pid;
1118         TYPEOF_PROCESS_ID current_tgid = task->tgid;
1119         unsigned current_cpu = task_cpu(task);
1120         va_list args;
1121         unsigned long addr = 0;
1122         struct cond *p_cond;
1123         struct event_tmpl *p_tmpl;
1124
1125         spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1126         memset(buf, 0, EVENT_MAX_SIZE);
1127         spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1128
1129         do_gettimeofday (&tv);
1130
1131         if (probe_id == KS_PROBE_ID) {
1132                 va_start(args, fmt);
1133                 addr = get_probe_func_addr(fmt, args);
1134                 va_end(args);
1135                 if( ((addr == pf_addr) && !(probes_flags & PROBE_FLAG_PF_INSTLD)) ||
1136                     ((addr == cp_addr) && !(probes_flags & PROBE_FLAG_CP_INSTLD)) ||
1137                     ((addr == mr_addr) && !(probes_flags & PROBE_FLAG_MR_INSTLD)) ||
1138                     ((addr == unmap_addr) && !(probes_flags & PROBE_FLAG_UNMAP_INSTLD)) ||
1139                     ((addr == exit_addr) && !(probes_flags & PROBE_FLAG_EXIT_INSTLD)) ) {
1140                         return;
1141                 }
1142         }
1143         if (probe_id == US_PROBE_ID) {
1144                 va_start(args, fmt);
1145                 addr = get_probe_func_addr(fmt, args);
1146                 va_end(args);
1147         }
1148
1149         /* Checking for all the conditions
1150          * except stop condition that we process after saving the event */
1151         list_for_each_entry(p_cond, &cond_list.list, list) {
1152                 p_tmpl = &p_cond->tmpl;
1153                 switch (p_tmpl->type) {
1154                 case ET_TYPE_START_COND:
1155                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1156                                  (addr == p_tmpl->addr)) &&
1157                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1158                                  (current_tgid == p_tmpl->pid)) &&
1159                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1160                                  (current_pid == p_tmpl->tid)) &&
1161                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1162                                  (current_cpu == p_tmpl->cpu_num)) &&
1163                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1164                                  (strcmp(task->comm, p_tmpl->bin_name) == 0)) &&
1165                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TIME) ||
1166                                  (tv.tv_sec > last_attach_time.tv_sec + p_tmpl->sec) ||
1167                                  (tv.tv_sec == last_attach_time.tv_sec + p_tmpl->sec &&
1168                                   tv.tv_usec >= last_attach_time.tv_usec + p_tmpl->usec)) &&
1169                                 !p_cond->applied) {
1170                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1171                                 paused = 0;
1172                                 p_cond->applied = 1;
1173                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1174                         }
1175                         break;
1176                 case ET_TYPE_IGNORE_COND:
1177                         /* if (probe_id == PROBE_SCHEDULE) */
1178                         /*      break; */
1179                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1180                                  (addr == p_tmpl->addr)) &&
1181                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1182                                  (current_tgid == p_tmpl->pid)) &&
1183                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1184                                  (current_pid == p_tmpl->tid)) &&
1185                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1186                                  (current_cpu == p_tmpl->cpu_num)) &&
1187                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1188                                  (strcmp(task->comm, p_tmpl->bin_name) == 0))) {
1189                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1190                                 ec_info.ignored_events_count++;
1191                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1192                                 return;
1193                         }
1194                         break;
1195                 }
1196         }
1197
1198         /* Save only not masked entry or return kernel and user space events */
1199         if (likely(!((probe_id == KS_PROBE_ID || probe_id == US_PROBE_ID)
1200                   && ((record_type == RECORD_ENTRY && (event_mask & IOCTL_EMASK_ENTRY))
1201                           || (record_type == RECORD_RET && (event_mask & IOCTL_EMASK_EXIT)))))) {
1202
1203                 spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1204
1205                 if (paused && (!(probe_id == EVENT_FMT_PROBE_ID || probe_id == DYN_LIB_PROBE_ID))) {
1206                         ec_info.ignored_events_count++;
1207                         spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1208                         return;
1209                 }
1210
1211                 va_start (args, fmt);
1212                 event_len = VPackEvent(buf, sizeof(buf), event_mask, probe_id, record_type, (TYPEOF_TIME *)&tv,
1213                                                            current_tgid, current_pid, current_cpu, fmt, args);
1214                 va_end (args);
1215
1216                 if(event_len == 0) {
1217                         EPRINTF ("ERROR: failed to pack event!");
1218                         ++ec_info.lost_events_count;
1219
1220                 } else if(WriteEventIntoBuffer(buf, event_len) == -1) {
1221                         EPRINTF("Cannot write event into buffer!");
1222                         ++ec_info.lost_events_count;
1223                 }
1224                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1225
1226         }
1227
1228         /* Check for stop condition.  We pause collecting the trace right after
1229          * storing this event */
1230         list_for_each_entry(p_cond, &cond_list.list, list) {
1231                 p_tmpl = &p_cond->tmpl;
1232                 switch (p_tmpl->type) {
1233                 case ET_TYPE_STOP_COND:
1234                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1235                                  (addr == p_tmpl->addr)) &&
1236                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1237                                  (current_tgid == p_tmpl->pid)) &&
1238                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1239                                  (current_pid == p_tmpl->tid)) &&
1240                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1241                                  (current_cpu == p_tmpl->cpu_num)) &&
1242                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1243                                 (strcmp(task->comm, p_tmpl->bin_name) == 0)) &&
1244                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TIME) ||
1245                                  (tv.tv_sec > last_attach_time.tv_sec + p_tmpl->sec) ||
1246                                  (tv.tv_sec == last_attach_time.tv_sec + p_tmpl->sec &&
1247                                   tv.tv_usec >= last_attach_time.tv_usec + p_tmpl->usec)) &&
1248                                 !p_cond->applied) {
1249                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1250                                 paused = 1;
1251                                 p_cond->applied = 1;
1252                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1253                         }
1254                         break;
1255                 }
1256         }
1257 }
1258 EXPORT_SYMBOL_GPL(pack_task_event_info);
1259
1260 kernel_probe_t* find_probe (unsigned long addr)
1261 {
1262         kernel_probe_t *p;
1263         struct hlist_node *node;
1264
1265         //check if such probe does exist
1266         hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist)
1267                 if (p->addr == addr)
1268                         break;
1269
1270         return node ? p : NULL;
1271 }
1272
1273
1274 int add_probe_to_list (unsigned long addr, kernel_probe_t ** pprobe)
1275 {
1276         kernel_probe_t *new_probe;
1277         kernel_probe_t *probe;
1278
1279         if (pprobe)
1280                 *pprobe = NULL;
1281         //check if such probe does already exist
1282         probe = find_probe(addr);
1283         if (probe) {
1284                 /* It is not a problem if we have already registered
1285                    this probe before */
1286                 return 0;
1287         }
1288         new_probe = kmalloc (sizeof (kernel_probe_t), GFP_KERNEL);
1289         if (!new_probe)
1290         {
1291                 EPRINTF ("no memory for new probe!");
1292                 return -ENOMEM;
1293         }
1294         memset (new_probe, 0, sizeof (kernel_probe_t));
1295         new_probe->addr = addr;
1296         new_probe->jprobe.kp.addr = new_probe->retprobe.kp.addr = (kprobe_opcode_t *)addr;
1297         new_probe->jprobe.priv_arg = new_probe->retprobe.priv_arg = new_probe;
1298         //new_probe->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
1299         dbi_find_and_set_handler_for_probe(new_probe);
1300         INIT_HLIST_NODE (&new_probe->hlist);
1301         hlist_add_head_rcu (&new_probe->hlist, &kernel_probes);
1302         if (pprobe)
1303                 *pprobe = new_probe;
1304         return 0;
1305 }
1306
1307 int remove_probe_from_list (unsigned long addr)
1308 {
1309         kernel_probe_t *p;
1310
1311         //check if such probe does exist
1312         p = find_probe (addr);
1313         if (!p) {
1314                 /* We do not care about it. Nothing bad. */
1315                 return 0;
1316         }
1317
1318         hlist_del_rcu (&p->hlist);
1319
1320         kfree (p);
1321
1322         return 0;
1323 }
1324
1325
1326 int put_us_event (char *data, unsigned long len)
1327 {
1328         unsigned long spinlock_flags = 0L;
1329
1330         SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;
1331         char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE)
1332                                 + sizeof(TYPEOF_PROBE_ID);
1333         TYPEOF_NUMBER_OF_ARGS nArgs = pEventHeader->m_nNumberOfArgs;
1334         TYPEOF_PROBE_ID probe_id = pEventHeader->m_nProbeID;
1335         //int i;
1336
1337         /*if(probe_id == US_PROBE_ID){
1338                 printk("esrc %p/%d[", data, len);
1339                 for(i = 0; i < len; i++)
1340                         printk("%02x ", data[i]);
1341                 printk("]\n");
1342         }*/
1343
1344         // set pid/tid/cpu/time i
1345         //pEventHeader->m_time.tv_sec = tv.tv_sec;
1346         //pEventHeader->m_time.tv_usec = tv.tv_usec;
1347
1348 #ifdef MEMORY_CHECKER
1349         //TODO: move this part to special MEC event posting routine, new IOCTL is needed
1350         if((probe_id >= MEC_PROBE_ID_MIN) && (probe_id <= MEC_PROBE_ID_MAX))
1351         {
1352                 if(mec_post_event != NULL)
1353                 {
1354                         int res = mec_post_event(data, len);
1355                         if(res == -1)
1356                         {
1357                                 return -1;
1358                         }
1359                 }
1360                 else
1361                 {
1362                         // FIXME: 'mec_post_event' - not found
1363                         mec_post_event = swap_ksyms("mec_post_event");
1364                         if(mec_post_event == NULL)
1365                         {
1366                                 EPRINTF ("Failed to find function 'mec_post_event' from mec_handlers.ko. Memory Error Checker will work incorrectly.");
1367                         }
1368                         else
1369                         {
1370                                 int res = mec_post_event(data, len);
1371                                 if(res == -1)
1372                                 {
1373                                         return -1;
1374                                 }
1375                         }
1376                 }
1377         }
1378 #endif
1379
1380         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TIME)){
1381                 struct timeval tv = { 0, 0 };
1382                 do_gettimeofday (&tv);
1383                 memcpy(cur, &tv, sizeof(TYPEOF_TIME));
1384                 cur += sizeof(TYPEOF_TIME);
1385         }
1386         //pEventHeader->m_nProcessID = current_tgid;
1387         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){
1388                 //TYPEOF_PROCESS_ID current_tgid = current->tgid;
1389                 (*(TYPEOF_PROCESS_ID *)cur) = current->tgid;
1390                 cur += sizeof(TYPEOF_PROCESS_ID);
1391         }
1392         //pEventHeader->m_nThreadID = current_pid;
1393         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){
1394                 //TYPEOF_THREAD_ID current_pid = current->pid;
1395                 (*(TYPEOF_THREAD_ID *)cur) = current->pid;
1396                 cur += sizeof(TYPEOF_THREAD_ID);
1397         }
1398         //pEventHeader->m_nCPU = current_cpu;
1399         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){
1400                 //TYPEOF_CPU_NUMBER current_cpu = task_cpu(current);
1401                 (*(TYPEOF_CPU_NUMBER *)cur) = task_cpu(current);
1402                 cur += sizeof(TYPEOF_CPU_NUMBER);
1403         }
1404         //printk("%d %x", probe_id, event_mask);
1405         // dyn lib event should have all args, it is for internal use and not visible to user
1406         if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(event_mask & IOCTL_EMASK_ARGS)){
1407                 // move only if any of prev fields has been skipped
1408                 if(event_mask & (IOCTL_EMASK_TIME|IOCTL_EMASK_PID|IOCTL_EMASK_TID|IOCTL_EMASK_CPU)){
1409                         memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS),
1410                                         len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
1411                                         -sizeof(TYPEOF_EVENT_LENGTH));
1412                 }
1413                 cur += len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
1414                                 -sizeof(TYPEOF_EVENT_LENGTH);
1415         }
1416         else{
1417                 // user space probes should have at least one argument to identify them
1418                 if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID)){
1419                         char *pArg1;
1420                         (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
1421                         cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
1422                         // pack args using format string for the 1st arg only
1423                         memset(cur, 0, ALIGN_VALUE(2));
1424                         cur[0] = 'p'; cur[1] = '\0';
1425                         cur += ALIGN_VALUE(2);
1426                         pArg1 = data + sizeof(SWAP_TYPE_EVENT_HEADER)+ALIGN_VALUE(nArgs+1);
1427                         memmove(cur, pArg1, sizeof(unsigned long));
1428                         cur += sizeof(unsigned long);
1429                 }
1430                 else {
1431                         (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
1432                         cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
1433                 }
1434         }
1435         pEventHeader->m_nLength = cur - data + sizeof(TYPEOF_EVENT_LENGTH);
1436         *((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
1437         len = pEventHeader->m_nLength;
1438
1439         if(WriteEventIntoBuffer(data, len) == -1) {
1440                 EPRINTF("Cannot write event into buffer!");
1441
1442                 spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1443                 ++ec_info.lost_events_count;
1444                 spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
1445         }
1446
1447         return 0;
1448 }
1449
1450 int set_predef_uprobes (ioctl_predef_uprobes_info_t *data)
1451 {
1452         int i, k, size = 0, probe_size, result, j;
1453         char *buf, *sep1, *sep2;
1454         inst_us_proc_t *my_uprobes_info = get_uprobes();
1455
1456         for(j = 0; j < data->probes_count; j++)
1457         {
1458                 probe_size = strlen_user(data->p_probes+size);
1459                 buf = kmalloc(probe_size, GFP_KERNEL);
1460
1461                 if(!buf)
1462                 {
1463                         EPRINTF("failed to alloc mem!");
1464                         return -EFAULT;
1465                 }
1466
1467                 result = strncpy_from_user(buf, data->p_probes+size, probe_size);
1468                 if (result != (probe_size-1))
1469                 {
1470                         EPRINTF("failed to copy from user!");
1471                         kfree(buf);
1472                         return -EFAULT;
1473                 }
1474                 //DPRINTF("%s", buf);
1475                 sep1 = strchr(buf, ':');
1476                 if(!sep1)
1477                 {
1478                         EPRINTF("skipping invalid predefined uprobe string '%s'!", buf);
1479                         kfree(buf);
1480                         size += probe_size;
1481                         continue;
1482                 }
1483                 sep2 = strchr(sep1+1, ':');
1484                 if(!sep2 || (sep2 == sep1) || (sep2+2 == buf+probe_size))
1485                 {
1486                         EPRINTF("skipping invalid predefined uprobe string '%s'!", buf);
1487                         kfree(buf);
1488                         size += probe_size;
1489                         continue;
1490                 }
1491                 for(i = 0; i < my_uprobes_info->libs_count; i++)
1492                 {
1493                         if(strncmp(buf, my_uprobes_info->p_libs[i].path, sep1-buf) != 0)
1494                                 continue;
1495                         for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
1496                         {
1497                                 if(strncmp(sep1+1, my_uprobes_info->p_libs[i].p_ips[k].name, sep2-sep1-1) != 0)
1498                                         continue;
1499                                 my_uprobes_info->p_libs[i].p_ips[k].offset = simple_strtoul(sep2+1, NULL, 16);
1500                         }
1501                 }
1502
1503                 kfree(buf);
1504                 size += probe_size;
1505         }
1506         return 0;
1507 }
1508
1509 int get_predef_uprobes_size(int *size)
1510 {
1511         int i, k;
1512         inst_us_proc_t *my_uprobes_info = get_uprobes();
1513
1514         *size = 0;
1515         for(i = 0; i < my_uprobes_info->libs_count; i++)
1516         {
1517                 int lib_size = strlen(my_uprobes_info->p_libs[i].path);
1518                 for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
1519                 {
1520                         // libc.so.6:printf:
1521                         *size += lib_size + 1 + strlen(my_uprobes_info->p_libs[i].p_ips[k].name) + 2;
1522                 }
1523         }
1524
1525         return 0;
1526 }
1527
1528 int get_predef_uprobes(ioctl_predef_uprobes_info_t *udata)
1529 {
1530         ioctl_predef_uprobes_info_t data;
1531         int i, k, size, lib_size, func_size, result;
1532         unsigned count = 0;
1533         char sep[] = ":";
1534         inst_us_proc_t *my_uprobes_info = get_uprobes();
1535
1536         // get addr of array
1537         if (copy_from_user ((void *)&data, udata, sizeof (data)))
1538         {
1539                 EPRINTF("failed to copy from user!");
1540                 return -EFAULT;
1541         }
1542
1543         size = 0;
1544         for(i = 0; i < my_uprobes_info->libs_count; i++)
1545         {
1546                 lib_size = strlen(my_uprobes_info->p_libs[i].path);
1547                 for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
1548                 {
1549                         // libname
1550                         result = copy_to_user ((void *)(data.p_probes+size), my_uprobes_info->p_libs[i].path, lib_size);
1551                         if (result)
1552                         {
1553                                 EPRINTF("failed to copy to user!");
1554                                 return -EFAULT;
1555                         }
1556                         size += lib_size;
1557                         // ":"
1558                         result = copy_to_user ((void *)(data.p_probes+size), sep, 1);
1559                         if (result)
1560                         {
1561                                 EPRINTF("failed to copy to user!");
1562                                 return -EFAULT;
1563                         }
1564                         size++;
1565                         // probename
1566                         //DPRINTF("'%s'", my_uprobes_info->p_libs[i].p_ips[k].name);
1567                         func_size = strlen(my_uprobes_info->p_libs[i].p_ips[k].name);
1568                         result = copy_to_user ((void *)(data.p_probes+size), my_uprobes_info->p_libs[i].p_ips[k].name, func_size);
1569                         if (result)
1570                         {
1571                                 EPRINTF("failed to copy to user!");
1572                                 return -EFAULT;
1573                         }
1574                         size += func_size;
1575                         // ":\0"
1576                         result = copy_to_user ((void *)(data.p_probes+size), sep, 2);
1577                         if (result)
1578                         {
1579                                 EPRINTF("failed to copy to user!");
1580                                 return -EFAULT;
1581                         }
1582                         size += 2;
1583                         count++;
1584                 }
1585         }
1586
1587         // set probes_count
1588         result = copy_to_user ((void *)&(udata->probes_count), &count, sizeof(count));
1589         if (result)
1590         {
1591                 EPRINTF("failed to copy to user!");
1592                 return -EFAULT;
1593         }
1594
1595         return 0;
1596 }