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