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