Merge branch 'dev' into new_dpf
[kernel/swap-modules.git] / driver / storage.c
1 ////////////////////////////////////////////////////////////////////////////////////
2 //
3 //      FILE:           storage.c
4 //
5 //      DESCRIPTION:
6 //      This file is C source for SWAP.
7 //
8 //      SEE ALSO:       storage.h
9 //      AUTHOR:         L.Komkov, S.Dianov, A.Gerenkov, S.Andreev
10 //      COMPANY NAME:   Samsung Research Center in Moscow
11 //      DEPT NAME:      Advanced Software Group
12 //      CREATED:        2008.02.15
13 //      VERSION:        1.0
14 //      REVISION DATE:  2008.12.03
15 //
16 ////////////////////////////////////////////////////////////////////////////////////
17
18 #include <linux/types.h>
19 #include <linux/hash.h>
20 #include <linux/list.h>
21 #include <linux/unistd.h>
22 #include <linux/spinlock.h>
23 #include <linux/kernel.h>
24 #include <linux/time.h>
25 #include "module.h"
26 #include "storage.h"
27 #include "handlers_core.h"
28 #include "CProfile.h"
29
30 #define after_buffer ec_info.buffer_size
31
32 char *p_buffer = NULL;
33 inst_us_proc_t us_proc_info;
34 struct list_head otg_us_proc_info;
35 inst_dex_proc_t dex_proc_info;
36 char *deps;
37 char *bundle;
38 unsigned int inst_pid = 0;
39 struct hlist_head kernel_probes;
40 struct hlist_head otg_kernel_probes;
41 int event_mask = 0L;
42 struct cond cond_list;
43 int paused = 0; /* a state after a stop condition (events are not collected) */
44 struct timeval last_attach_time = {0, 0};
45
46 struct dbi_modules_handlers dbi_mh;
47
48 //
49 // Mr_Nobody: should we use centralized definition of this structure??
50 //
51 struct handler_map {
52         unsigned long func_addr;
53         unsigned long jp_handler_addr;
54         unsigned long rp_handler_addr;
55 };
56
57 struct dbi_modules_handlers *get_dbi_modules_handlers(void)
58 {
59         return &dbi_mh;
60 }
61 EXPORT_SYMBOL_GPL(get_dbi_modules_handlers);
62
63 inline unsigned long find_dbi_jp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
64 {
65         int i;
66
67         /* Possibly we can find less expensive way */
68         for (i = 0; i < mhi->dbi_nr_handlers; i++) {
69                 if (mhi->dbi_handlers[i].func_addr == p_addr) {
70                         printk("Found jp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
71                         return mhi->dbi_handlers[i].jp_handler_addr;
72                 }
73         }
74         return 0;
75 }
76
77 inline unsigned long find_dbi_rp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
78 {
79         int i;
80
81         /* Possibly we can find less expensive way */
82         for (i = 0; i < mhi->dbi_nr_handlers; i++) {
83                 if (mhi->dbi_handlers[i].func_addr == p_addr) {
84                         printk("Found rp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
85                         return mhi->dbi_handlers[i].rp_handler_addr;
86                 }
87         }
88         return 0;
89 }
90
91 /**
92  * Search of handler in global list of modules for defined probe
93  */
94 void dbi_find_and_set_handler_for_probe(kernel_probe_t *p)
95 {
96         unsigned long jp_handler_addr, rp_handler_addr;
97         struct dbi_modules_handlers_info *local_mhi;
98         unsigned long dbi_flags;
99         unsigned int local_module_refcount = 0;
100
101         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
102         list_for_each_entry_rcu(local_mhi, &dbi_mh.modules_handlers, dbi_list_head) {
103                 printk("Searching handlers in %s module for %0lX address\n",
104                         (local_mhi->dbi_module)->name, p->addr);
105                 // XXX: absent code for pre_handlers because we suppose that they are not used
106                 if ((jp_handler_addr = find_dbi_jp_handler(p->addr, local_mhi)) != 0) {
107                         if (p->jprobe.entry != 0) {
108                                 printk("Skipping jp_handler for %s module (address %0lX)\n",
109                                                 (local_mhi->dbi_module)->name, p->addr);
110                         }
111                         else {
112                                 local_module_refcount = module_refcount(local_mhi->dbi_module);
113                                 if (local_module_refcount == 0) {
114                                         if (!try_module_get(local_mhi->dbi_module))
115                                                 printk("Error of try_module_get() for module %s\n",
116                                                                 (local_mhi->dbi_module)->name);
117                                         else
118                                                 printk("Module %s in use now\n",
119                                                                 (local_mhi->dbi_module)->name);
120                                 }
121                                 p->jprobe.entry = (kprobe_opcode_t *)jp_handler_addr;
122                                 printk("Set jp_handler for %s module (address %0lX)\n",
123                                                 (local_mhi->dbi_module)->name, p->addr);
124                         }
125                 }
126                 if ((rp_handler_addr = find_dbi_rp_handler(p->addr, local_mhi)) != 0) {
127                         if (p->retprobe.handler != 0) {
128                                 printk("Skipping kretprobe_handler for %s module (address %0lX)\n",
129                                                 (local_mhi->dbi_module)->name, p->addr);
130                         }
131                         else {
132                                 local_module_refcount = module_refcount(local_mhi->dbi_module);
133                                 if (local_module_refcount == 0) {
134                                         if (!try_module_get(local_mhi->dbi_module))
135                                                 printk("Error of try_module_get() for module %s\n",
136                                                                 (local_mhi->dbi_module)->name);
137                                         else
138                                                 printk("Module %s in use now\n",
139                                                                 (local_mhi->dbi_module)->name);
140                                 }
141                                 p->retprobe.handler = (kretprobe_handler_t)rp_handler_addr;
142                                 printk("Set rp_handler for %s module (address %0lX)\n",
143                                                 (local_mhi->dbi_module)->name, p->addr);
144                         }
145                 }
146         }
147         // not found pre_handler - set default (always true for now since pre_handlers not used)
148         if (p->jprobe.pre_entry == 0) {
149                 p->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
150                 printk("Set default pre_handler (address %0lX)\n", p->addr);
151         }
152         // not found jp_handler - set default
153         if (p->jprobe.entry == 0) {
154                 p->jprobe.entry = (kprobe_opcode_t *) def_jprobe_event_handler;
155                 printk("Set default jp_handler (address %0lX)\n", p->addr);
156         }
157         // not found kretprobe_handler - set default
158         if (p->retprobe.handler == 0) {
159                 p->retprobe.handler = (kretprobe_handler_t) def_retprobe_event_handler;
160                 printk("Set default rp_handler (address %0lX)\n", p->addr);
161         }
162         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
163 }
164
165 // XXX TODO: possible mess when start-register/unregister-stop operation
166 // so we should refuse register/unregister operation while we are in unsafe state
167 int dbi_register_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
168 {
169         unsigned long dbi_flags;
170 //      struct dbi_modules_handlers_info *local_mhi;
171
172         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
173 //      local_mhi = container_of(&dbi_mhi->dbi_list_head, struct dbi_modules_handlers_info, dbi_list_head);
174         list_add_rcu(&dbi_mhi->dbi_list_head, &dbi_mh.modules_handlers);
175         printk("Added module %s (head is %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
176         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
177         return 0;
178 }
179 EXPORT_SYMBOL_GPL(dbi_register_handlers_module);
180
181 // XXX TODO: possible mess when start-register/unregister-stop operation
182 // so we should refuse register/unregister operation while we are in unsafe state
183 int dbi_unregister_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
184 {
185         unsigned long dbi_flags;
186         // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
187         // (i.e. between attach and stop)
188         /*kernel_probe_t *p;
189         struct hlist_node *node;
190         unsigned long jp_handler_addr, rp_handler_addr, pre_handler_addr;*/
191
192         spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
193         list_del_rcu(&dbi_mhi->dbi_list_head);
194         // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
195         // (i.e. between attach and stop)
196         /*hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist) {
197                 // XXX: absent code for pre_handlers because we suppose that they are not used
198                 if ((p->jprobe.entry != ((kprobe_pre_entry_handler_t )def_jprobe_event_pre_handler)) ||
199                                 (p->retprobe.handler != ((kretprobe_handler_t )def_retprobe_event_handler))) {
200                         printk("Searching handlers for %p address for removing in %s registered module...\n",
201                                         p->addr, (dbi_mhi->dbi_module)->name);
202                         jp_handler_addr = find_dbi_jp_handler(p->addr, dbi_mhi);
203                         rp_handler_addr = find_dbi_rp_handler(p->addr, dbi_mhi);
204                         if ((jp_handler_addr != 0) || (rp_handler_addr != 0)) {
205                                 // search and set to another handlers or default
206                                 dbi_find_and_set_handler_for_probe(p);
207                                 printk("Removed handler(s) for %s module (address %p)\n",
208                                                 (dbi_mhi->dbi_module)->name, p->addr);
209                         }
210                 }
211         }*/
212         printk("Removed module %s (head was %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
213         spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
214         return 0;
215 }
216 EXPORT_SYMBOL_GPL(dbi_unregister_handlers_module);
217
218 EXPORT_SYMBOL_GPL(us_proc_info);
219 EXPORT_SYMBOL_GPL(dex_proc_info);
220 typedef void *(*get_my_uprobes_info_t)(void);
221 int (*mec_post_event)(char *data, unsigned long len) = NULL;
222
223 unsigned copy_into_cyclic_buffer (char *buffer, unsigned dst_offset, char *src, unsigned size)
224 {
225         unsigned nOffset = dst_offset;
226         char* pSource = src;
227         while (size--)
228                 buffer[nOffset++] = *pSource++;
229         return nOffset;
230 }
231
232 unsigned copy_from_cyclic_buffer (char *dst, char *buffer, unsigned src_offset, unsigned size)
233 {
234         unsigned nOffset = src_offset;
235         char* pDestination = dst;
236         while (size--)
237                 *pDestination++ = buffer[nOffset++];
238         return nOffset;
239 }
240
241 int CheckBufferSize (unsigned int nSize)
242 {
243         if (nSize < EC_BUFFER_SIZE_MIN) {
244                 EPRINTF("Too small buffer size! [Size=%u KB]", nSize / 1024);
245                 return -1;
246         }
247         if (nSize > EC_BUFFER_SIZE_MAX) {
248                 EPRINTF("Too big buffer size! [Size=%u KB]", nSize / 1024);
249                 return -1;
250         }
251         return 0;
252 }
253
254 int AllocateSingleBuffer(unsigned int nSize)
255 {
256         unsigned long spinlock_flags = 0L;
257
258         unsigned int nSubbufferSize = ec_info.m_nSubbufSize;
259         unsigned int nNumOfSubbufers = GetNumOfSubbuffers(nSize);
260         unsigned long nAllocatedSize = nSubbufferSize * nNumOfSubbufers;
261
262         p_buffer = vmalloc_user(nAllocatedSize);
263         if(!p_buffer) {
264                 EPRINTF("Memory allocation error! [Size=%lu KB]", nAllocatedSize / 1024);
265                 return -1;
266         }
267
268         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
269         ec_info.m_nNumOfSubbuffers = nNumOfSubbufers;
270         ec_info.buffer_effect = ec_info.buffer_size = nAllocatedSize;
271         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
272
273         return 0;
274 }
275
276 void FreeSingleBuffer (void)
277 {
278         VFREE_USER(p_buffer, ec_info.buffer_size);
279         CleanECInfo();
280 }
281
282 //////////////////////////////////////////////////////////////////////////////////////////////////
283
284 int EnableContinuousRetrieval() {
285         unsigned long spinlock_flags = 0L;
286
287         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
288         ec_info.m_nMode |= MODEMASK_CONTINUOUS_RETRIEVAL;
289         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
290
291         return 0;
292 }
293
294 int DisableContinuousRetrieval() {
295         unsigned long spinlock_flags = 0L;
296
297         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
298         ec_info.m_nMode &= ~MODEMASK_CONTINUOUS_RETRIEVAL;
299         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
300
301         return 0;
302 }
303
304 //////////////////////////////////////////////////////////////////////////////////////////////////
305
306 #ifndef __DISABLE_RELAYFS
307
308 struct rchan* gl_pRelayChannel = NULL;
309 struct rchan* GetRelayChannel(void) { return gl_pRelayChannel; };
310
311 struct dentry* gl_pdirRelay = NULL;
312 struct dentry* GetRelayDir(void) { return gl_pdirRelay; };
313
314 #ifdef __USE_PROCFS
315
316 struct proc_dir_entry* alt_pde = NULL;
317
318 static inline struct dentry *_dir_create (const char *dirname, struct dentry *parent, struct proc_dir_entry **p2pde)
319 {
320     struct dentry *dir;
321     struct proc_dir_entry *pde;
322
323     pde = proc_mkdir (dirname, PDE (parent->d_inode));
324     if (pde == NULL)
325     {
326         dir = NULL;
327     }
328     else
329     {
330         mutex_lock (&parent->d_inode->i_mutex);
331         dir = lookup_one_len (dirname, parent, strlen (dirname));
332         mutex_unlock (&parent->d_inode->i_mutex);
333
334         if (IS_ERR (dir))
335         {
336             dir = NULL;
337             remove_proc_entry (dirname, PDE (parent->d_inode));
338         }
339
340         *p2pde = pde;
341     }
342
343     return dir;
344 }
345
346 static inline struct dentry *_get_proc_root (void)
347 {
348     struct file_system_type *procfs_type;
349     struct super_block *procfs_sb;
350
351     procfs_type = get_fs_type ("proc");
352
353     if (!procfs_type || list_empty (&procfs_type->fs_supers))
354         return NULL;
355
356     procfs_sb = list_entry (procfs_type->fs_supers.next, \
357         struct super_block, s_instances);
358
359     return procfs_sb->s_root;
360
361 }
362
363 static struct dentry *create_buf (const char *filename, struct dentry *parent, int mode, struct rchan_buf *buf, int *is_global)
364 {
365     struct proc_dir_entry *pde;
366     struct proc_dir_entry *parent_pde = NULL;
367     struct dentry *dentry;
368
369     if (parent)
370         parent_pde = PDE (parent->d_inode);
371     else
372         parent = _get_proc_root ();
373
374     pde = create_proc_entry (filename, S_IFREG|S_IRUSR, parent_pde);
375
376     if(unlikely(!pde))
377         return NULL;
378
379     pde->proc_fops = &relay_file_operations;
380
381     mutex_lock (&parent->d_inode->i_mutex);
382     dentry = lookup_one_len (filename, parent, strlen (filename));
383     mutex_unlock (&parent->d_inode->i_mutex);
384
385     if (IS_ERR(dentry)) {
386         remove_proc_entry (filename, parent_pde);
387         }
388
389 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
390         dentry->d_inode->i_private = buf;
391 #else
392         dentry->d_inode->u.generic_ip = buf;
393 #endif
394
395     return dentry;
396
397 }
398
399 static int remove_buf (struct dentry *dentry)
400 {
401     if (dentry != NULL)
402     {
403         struct proc_dir_entry *pde = PDE (dentry->d_inode);
404         dput (dentry);
405         remove_proc_entry (pde->name, pde->parent);
406     }
407
408     return 0;
409 }
410
411 #endif // __USE_PROCFS
412         /*
413           * subbuf_start - called on buffer-switch to a new sub-buffer
414           * @buf: the channel buffer containing the new sub-buffer
415           * @subbuf: the start of the new sub-buffer
416           * @prev_subbuf: the start of the previous sub-buffer
417           * @prev_padding: unused space at the end of previous sub-buffer
418           *
419           * The client should return 1 to continue logging, 0 to stop
420           * logging.
421           *
422           * NOTE: subbuf_start will also be invoked when the buffer is
423           *       created, so that the first sub-buffer can be initialized
424           *       if necessary.  In this case, prev_subbuf will be NULL.
425           *
426           * NOTE: the client can reserve bytes at the beginning of the new
427           *       sub-buffer by calling subbuf_start_reserve() in this callback.
428           */
429 int RelayCallbackSubbufStart(struct rchan_buf *buf,
430                               void *subbuf,
431                               void *prev_subbuf,
432                               size_t prev_padding)
433 {
434         struct rchan* pRelayChannel = NULL;
435         unsigned int nNumOfSubbufs = 0;
436
437         unsigned long spinlock_flags = 0L;
438         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
439
440         subbuf_start_reserve(buf, RELAY_SUBBUF_HEADER_SIZE);
441         ec_info.buffer_effect += RELAY_SUBBUF_HEADER_SIZE;
442         ec_info.m_nEndOffset = RELAY_SUBBUF_HEADER_SIZE;
443
444         if(prev_subbuf == NULL) {
445                 spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
446                 return 1;
447         }
448         memcpy(prev_subbuf, &prev_padding, sizeof(unsigned int));
449         memcpy(prev_subbuf + sizeof(unsigned int), &ec_info.m_nSubbufSavedEvents, sizeof(unsigned int));
450         ec_info.m_nSubbufSavedEvents = 0;
451         pRelayChannel = GetRelayChannel();
452         if(pRelayChannel == NULL) {
453                 spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
454                 EPRINTF("Null pointer to relay channel!");
455                 return 0;
456         }
457         nNumOfSubbufs = pRelayChannel->n_subbufs;
458         ec_info.m_nBeginSubbufNum = buf->subbufs_consumed % nNumOfSubbufs;
459         ec_info.m_nEndSubbufNum = buf->subbufs_produced % nNumOfSubbufs;
460         if(relay_buf_full(buf)) {
461                 void* pConsume = NULL;
462                 unsigned int nPaddingLength = 0;
463                 unsigned int nSubbufSize = 0;
464                 unsigned int nDataSize = 0;
465                 unsigned int nEffectSize = 0;
466                 unsigned int nSubbufDiscardedCount = 0;
467                 nSubbufSize = pRelayChannel->subbuf_size;
468                 pConsume = buf->start + buf->subbufs_consumed % nNumOfSubbufs * nSubbufSize;
469                 memcpy(&nPaddingLength, pConsume, sizeof(unsigned int));
470                 memcpy(&nSubbufDiscardedCount, pConsume + sizeof(unsigned int), sizeof(unsigned int));
471                 nEffectSize = nSubbufSize - nPaddingLength;
472                 nDataSize = nEffectSize - RELAY_SUBBUF_HEADER_SIZE;
473                 ec_info.discarded_events_count += nSubbufDiscardedCount;
474                 relay_subbufs_consumed(pRelayChannel, 0, 1);
475                 ec_info.m_nBeginSubbufNum = buf->subbufs_consumed % nNumOfSubbufs;
476                 ec_info.m_nEndSubbufNum = buf->subbufs_produced % nNumOfSubbufs;
477                 ec_info.buffer_effect -= nEffectSize;
478                 ec_info.trace_size -= nDataSize;
479                 buf->dentry->d_inode->i_size = ec_info.trace_size;
480                 spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
481                 return 1; // Overwrite mode
482         }
483         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
484         return 1;
485 }
486
487         /*
488           * buf_mapped - relay buffer mmap notification
489           * @buf: the channel buffer
490           * @filp: relay file pointer
491           *
492           * Called when a relay file is successfully mmapped
493           */
494 void RelayCallbackBufMapped(struct rchan_buf *buf,
495                             struct file *filp)
496 {
497 }
498
499         /*
500           * buf_unmapped - relay buffer unmap notification
501           * @buf: the channel buffer
502           * @filp: relay file pointer
503           *
504           * Called when a relay file is successfully unmapped
505           */
506 void RelayCallbackBufUnmapped(struct rchan_buf *buf,
507                              struct file *filp)
508 {
509 }
510         /*
511           * create_buf_file - create file to represent a relay channel buffer
512           * @filename: the name of the file to create
513           * @parent: the parent of the file to create
514           * @mode: the mode of the file to create
515           * @buf: the channel buffer
516           * @is_global: outparam - set non-zero if the buffer should be global
517           *
518           * Called during relay_open(), once for each per-cpu buffer,
519           * to allow the client to create a file to be used to
520           * represent the corresponding channel buffer.  If the file is
521           * created outside of relay, the parent must also exist in
522           * that filesystem.
523           *
524           * The callback should return the dentry of the file created
525           * to represent the relay buffer.
526           *
527           * Setting the is_global outparam to a non-zero value will
528           * cause relay_open() to create a single global buffer rather
529           * than the default set of per-cpu buffers.
530           *
531           * See Documentation/filesystems/relayfs.txt for more info.
532           */
533 struct dentry * RelayCallbackCreateBufFile(const char *filename,
534                                            struct dentry *parent,
535                                            int mode,
536                                            struct rchan_buf *buf,
537                                            int *is_global)
538 {
539         *is_global = 1;
540 #ifdef __USE_PROCFS
541         DPRINTF("\"%s\" is creating in procfs...!", filename);
542         return create_buf(filename, parent, mode, buf, is_global);
543 #else
544         DPRINTF("\"%s\" is creating in debugfs...!", filename);
545         return debugfs_create_file(filename, (mode_t)mode, parent, buf, &relay_file_operations);
546 #endif // __USE_PROCFS
547 }
548
549         /*
550           * remove_buf_file - remove file representing a relay channel buffer
551           * @dentry: the dentry of the file to remove
552           *
553           * Called during relay_close(), once for each per-cpu buffer,
554           * to allow the client to remove a file used to represent a
555           * channel buffer.
556           *
557           * The callback should return 0 if successful, negative if not.
558           */
559 int RelayCallbackRemoveBufFile(struct dentry *dentry)
560 {
561 #ifdef __USE_PROCFS
562         remove_buf(dentry);
563 #else
564         debugfs_remove(dentry);
565 #endif // __USE_PROCFS
566         return 0;
567 }
568
569 struct rchan_callbacks gl_RelayCallbacks = {
570         .subbuf_start = RelayCallbackSubbufStart,
571         .buf_mapped = RelayCallbackBufMapped,
572         .buf_unmapped = RelayCallbackBufUnmapped,
573         .create_buf_file = RelayCallbackCreateBufFile,
574         .remove_buf_file = RelayCallbackRemoveBufFile
575 };
576 #endif //__DISABLE_RELAYFS
577
578 int AllocateMultipleBuffer(unsigned int nSize) {
579 #ifndef __DISABLE_RELAYFS
580         unsigned long spinlock_flags = 0L;
581
582         unsigned int nSubbufferSize = ec_info.m_nSubbufSize;
583         unsigned int nNumOfSubbufers = GetNumOfSubbuffers(nSize);
584
585         gl_pRelayChannel = relay_open(DEFAULT_RELAY_BASE_FILENAME,
586                                         GetRelayDir(),
587                                         nSubbufferSize,
588                                         nNumOfSubbufers,
589                                         &gl_RelayCallbacks
590 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
591                                         ,NULL
592 #endif
593                                         );
594         if(gl_pRelayChannel == NULL) {
595                 EPRINTF("Cannot create relay buffer channel! [%d subbufers by %u Kb = %u Kb]",
596                         nNumOfSubbufers, nSubbufferSize / 1024, nSize / 1024);
597                 return -1;
598         }
599
600         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
601         ec_info.m_nNumOfSubbuffers = nNumOfSubbufers;
602         ec_info.buffer_effect = ec_info.buffer_size = nSubbufferSize * nNumOfSubbufers;
603         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
604
605         return 0;
606 #else
607         EPRINTF("RelayFS not supported!");
608         return -1;
609 #endif //__DISABLE_RELAYFS
610 }
611
612 void FreeMultipleBuffer(void) {
613 #ifndef __DISABLE_RELAYFS
614         relay_close(gl_pRelayChannel);
615         CleanECInfo();
616 #else
617         EPRINTF("RelayFS not supported!");
618 #endif //__DISABLE_RELAYFS
619 }
620
621 int InitializeBuffer(unsigned int nSize) {
622         if(IsMultipleBuffer())
623                 return AllocateMultipleBuffer(nSize);
624         return AllocateSingleBuffer(nSize);
625 }
626
627 int UninitializeBuffer(void) {
628         if(IsMultipleBuffer())
629                 FreeMultipleBuffer();
630         FreeSingleBuffer();
631         return 0;
632 }
633
634 int EnableMultipleBuffer() {
635         unsigned long spinlock_flags = 0L;
636
637         if(IsMultipleBuffer())
638                 return 0;
639
640         if(UninitializeBuffer() == -1)
641                 EPRINTF("Cannot uninitialize buffer!");
642
643         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
644         ec_info.m_nMode |= MODEMASK_MULTIPLE_BUFFER;
645         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
646
647         if(InitializeBuffer(GetBufferSize()) == -1) {
648                 EPRINTF("Cannot initialize buffer!");
649                 return -1;
650         }
651         return 0;
652 }
653
654 int DisableMultipleBuffer() {
655         unsigned long spinlock_flags = 0L;
656
657         if(!IsMultipleBuffer())
658                 return 0;
659
660         if(UninitializeBuffer() == -1)
661                 EPRINTF("Cannot uninitialize buffer!");
662
663         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
664         ec_info.m_nMode &= ~MODEMASK_MULTIPLE_BUFFER;
665         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
666
667         if(InitializeBuffer(GetBufferSize()) == -1) {
668                 EPRINTF("Cannot initialize buffer!");
669                 return -1;
670         }
671         return 0;
672 }
673
674 unsigned int GetBufferSize(void) { return ec_info.buffer_size; };
675
676 int SetBufferSize(unsigned int nSize) {
677         if (GetECState() != EC_STATE_IDLE) {
678                 EPRINTF("Buffer changes are allowed in IDLE state only (%d)!", GetECState());
679                 return -1;
680         }
681         if(GetBufferSize() == nSize)
682                 return 0;
683         if(CheckBufferSize(nSize) == -1) {
684                 EPRINTF("Invalid buffer size!");
685                 return -1;
686         }
687         detach_selected_probes ();
688         if(UninitializeBuffer() == -1)
689                 EPRINTF("Cannot uninitialize buffer!");
690         if(InitializeBuffer(nSize) == -1) {
691                 EPRINTF("Cannot initialize buffer! [Size=%u KB]", nSize / 1024);
692                 return -1;
693         }
694         return 0;
695 }
696
697 int SetPid(unsigned int pid)
698 {
699         if (GetECState() != EC_STATE_IDLE)
700         {
701                 EPRINTF("PID changes are allowed in IDLE state only (%d)!", GetECState());
702                 return -1;
703         }
704
705         inst_pid = pid;
706         DPRINTF("SetPid pid:%d\n", pid);
707         return 0;
708 }
709
710 void ResetSingleBuffer(void) {
711 }
712
713 void ResetMultipleBuffer(void) {
714 #ifndef __DISABLE_RELAYFS
715         relay_reset(gl_pRelayChannel);
716 #else
717         EPRINTF("RelayFS not supported!");
718 #endif //__DISABLE_RELAYFS
719 }
720
721 int ResetBuffer(void) {
722         unsigned long spinlock_flags = 0L;
723
724         if (GetECState() != EC_STATE_IDLE) {
725                 EPRINTF("Buffer changes are allowed in IDLE state only!");
726                 return -1;
727         }
728
729         if(IsMultipleBuffer())
730                 ResetMultipleBuffer();
731         else
732                 ResetSingleBuffer();
733
734         detach_selected_probes ();
735
736         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
737         ec_info.buffer_effect = ec_info.buffer_size;
738         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
739
740         ResetECInfo();
741
742         return 0;
743 }
744
745 int WriteEventIntoSingleBuffer(char* pEvent, unsigned long nEventSize) {
746         unsigned int unused_space;
747
748         if(!p_buffer) {
749                 EPRINTF("Invalid pointer to buffer!");
750                 ++ec_info.lost_events_count;
751                 return -1;
752         }
753         if (ec_info.trace_size == 0 || ec_info.after_last > ec_info.first) {
754                 unused_space = ec_info.buffer_size - ec_info.after_last;
755                 if (unused_space > nEventSize) {
756                         ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
757                                                                                                                  ec_info.after_last,
758                                                                                                                  pEvent,
759                                                                                                                  nEventSize);
760                         ec_info.saved_events_count++;
761                         ec_info.buffer_effect = ec_info.buffer_size;
762                         ec_info.trace_size = ec_info.after_last - ec_info.first;
763                 } else {
764                         if (ec_info.first > nEventSize) {
765                                 ec_info.buffer_effect = ec_info.after_last;
766                                 ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
767                                                                                                                          0,
768                                                                                                                          pEvent,
769                                                                                                                          nEventSize);
770                                 ec_info.saved_events_count++;
771                                 ec_info.trace_size = ec_info.buffer_effect
772                                         - ec_info.first
773                                         + ec_info.after_last;
774                         } else {
775                                 // TODO: consider two variants!
776                                 // Do nothing
777                                 ec_info.discarded_events_count++;
778                         }
779                 }
780         } else {
781                 unused_space = ec_info.first - ec_info.after_last;
782                 if (unused_space > nEventSize) {
783                         ec_info.after_last = copy_into_cyclic_buffer(p_buffer,
784                                                                                                                  ec_info.after_last,
785                                                                                                                  pEvent,
786                                                                                                                  nEventSize);
787                         ec_info.saved_events_count++;
788                         ec_info.trace_size = ec_info.buffer_effect
789                                 - ec_info.first
790                                 + ec_info.after_last;
791                 } else {
792                         // Do nothing
793                         ec_info.discarded_events_count++;
794                 }
795         }
796         return 0;
797 }
798
799 int WriteEventIntoMultipleBuffer(char* pEvent, unsigned long nEventSize) {
800 #ifndef __DISABLE_RELAYFS
801         unsigned long spinlock_flags = 0L;
802         __relay_write(GetRelayChannel(), pEvent, nEventSize);
803         ec_info.buffer_effect += nEventSize;
804         ec_info.trace_size += nEventSize;
805         ec_info.saved_events_count++;
806         ec_info.m_nEndOffset += nEventSize;
807         ec_info.m_nSubbufSavedEvents++;
808         return 0;
809 #else
810         EPRINTF("RelayFS not supported!");
811         return -1;
812 #endif //__DISABLE_RELAYFS
813 }
814
815 int WriteEventIntoBuffer(char* pEvent, unsigned long nEventSize) {
816
817         /*unsigned long i;
818         for(i = 0; i < nEventSize; i++)
819                 printk("%02X ", pEvent[i]);
820         printk("\n");*/
821
822         if(IsMultipleBuffer())
823                 return WriteEventIntoMultipleBuffer(pEvent, nEventSize);
824         return WriteEventIntoSingleBuffer(pEvent, nEventSize);
825 }
826
827 //////////////////////////////////////////////////////////////////////////////////////////////////
828
829 int set_event_mask (int new_mask)
830 {
831         unsigned long spinlock_flags = 0L;
832         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
833         event_mask = new_mask;
834         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
835         return 0;
836 }
837
838 int
839 get_event_mask (int *mask)
840 {
841         *mask = event_mask;
842         return 0;
843 }
844
845 static void
846 generic_swap (void *a, void *b, int size)
847 {
848         char t;
849         do {
850                 t = *(char *) a;
851                 *(char *) a++ = *(char *) b;
852                 *(char *) b++ = t;
853         } while (--size > 0);
854 }
855
856 static void sort (void *base, size_t num, size_t size, int (*cmp) (const void *, const void *), void (*fswap) (void *, void *, int size))
857 {
858         /* pre-scale counters for performance */
859         int i = (num / 2) * size, n = num * size, c, r;
860
861         /* heapify */
862         for (; i >= 0; i -= size)
863         {
864                 for (r = i; r * 2 < n; r = c)
865                 {
866                         c = r * 2;
867                         if (c < n - size && cmp (base + c, base + c + size) < 0)
868                                 c += size;
869                         if (cmp (base + r, base + c) >= 0)
870                                 break;
871                         fswap (base + r, base + c, size);
872                 }
873         }
874
875         /* sort */
876         for (i = n - size; i >= 0; i -= size)
877         {
878                 fswap (base, base + i, size);
879                 for (r = 0; r * 2 < i; r = c)
880                 {
881                         c = r * 2;
882                         if (c < i - size && cmp (base + c, base + c + size) < 0)
883                                 c += size;
884                         if (cmp (base + r, base + c) >= 0)
885                                 break;
886                         fswap (base + r, base + c, size);
887                 }
888         }
889 }
890
891 static int addr_cmp (const void *a, const void *b)
892 {
893         return *(unsigned long *) a > *(unsigned long *) b ? -1 : 1;
894 }
895
896 char *find_lib_path(const char *lib_name)
897 {
898         char *p = deps + sizeof(size_t);
899         char *match;
900         size_t len;
901
902         while (*p != '\0') {
903                 DPRINTF("p is at %s", p);
904                 len = strlen(p) + 1;
905                 match = strstr(p, lib_name);
906                 p += len;
907                 len = strlen(p) + 1; /* we are at path now */
908             if (!match) {
909                         p += len;
910                 } else {
911                         DPRINTF("Found match: %s", match);
912                         return p;
913                 }
914         }
915
916         return NULL;
917 }
918
919 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
920 #define list_for_each_rcu(pos, head) __list_for_each_rcu(pos, head)
921 #endif
922
923 void unlink_bundle(void)
924 {
925         int i, k;
926         us_proc_lib_t *d_lib;
927         char *path;
928         struct list_head *pos;  //, *tmp;
929         us_proc_otg_ip_t *p;
930
931         path = us_proc_info.path;
932         us_proc_info.path = 0;
933
934         // first make sure "d_lib" is not used any more and only
935         // then release storage
936         if (us_proc_info.p_libs)
937         {
938                 int count1 = us_proc_info.libs_count;
939                 us_proc_info.libs_count = 0;
940                 for (i = 0; i < count1; i++)
941                 {
942                         d_lib = &us_proc_info.p_libs[i];
943                         if (d_lib->p_ips)
944                         {
945                                 // first make sure "d_lib->p_ips" is not used any more and only
946                                 // then release storage
947                                 //int count2 = d_lib->ips_count;
948                                 d_lib->ips_count = 0;
949                                 /*for (k = 0; k < count2; k++)
950                                         kfree ((void *) d_lib->p_ips[k].name);*/
951                                 vfree ((void *) d_lib->p_ips);
952                         }
953                         if (d_lib->p_vtps)
954                         {
955                                 // first make sure "d_lib->p_vtps" is not used any more and only
956                                 // then release storage
957                                 int count2 = d_lib->vtps_count;
958                                 d_lib->vtps_count = 0;
959                                 for (k = 0; k < count2; k++)
960                                 {
961                                         //list_for_each_safe_rcu(pos, tmp, &d_lib->p_vtps[k].list) {
962                                         list_for_each (pos, &d_lib->p_vtps[k].list)
963                                         {
964                                                 us_proc_vtp_data_t *vtp = list_entry (pos, us_proc_vtp_data_t, list);
965                                                 list_del_rcu (pos);
966                                                 //kfree (vtp->name);
967                                                 kfree (vtp);
968                                         }
969                                 }
970                                 kfree ((void *) d_lib->p_vtps);
971                         }
972                         d_lib->plt_count = 0;
973                         kfree((void*) d_lib->p_plt);
974                         us_proc_info.is_plt = 0;
975                 }
976                 kfree ((void *) us_proc_info.p_libs);
977                 us_proc_info.p_libs = 0;
978         }
979         /* if (path) */
980         /* { */
981         /*      kfree ((void *) path); */
982         /*      //putname(path); */
983         /* } */
984
985         us_proc_info.tgid = 0;
986
987         /* OTG probes list cleaning */
988         list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
989                 list_del_rcu(&p->list);
990         }
991 }
992
993 struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info);
994 void print_inst_us_proc(const inst_us_proc_t *task_inst_info);
995
996 extern struct dentry *dentry_by_path(const char *path);
997
998 int link_bundle()
999 {
1000         get_my_uprobes_info_t get_uprobes = NULL;
1001         inst_us_proc_t *my_uprobes_info = 0;
1002         inst_us_proc_t empty_uprobes_info =
1003         {
1004                 .libs_count = 0,
1005                 .p_libs = NULL,
1006         };
1007         char *p = bundle; /* read pointer for bundle */
1008         int nr_kern_probes;
1009         int i, j, l, k;
1010         int len;
1011         us_proc_lib_t *d_lib, *pd_lib;
1012         dex_proc_ip_t *dex_proc;
1013         ioctl_usr_space_lib_t s_lib;
1014         ioctl_usr_space_vtp_t *s_vtp;
1015         us_proc_vtp_t *mvtp;
1016         int is_app = 0;
1017         char *ptr;
1018         us_proc_ip_t *d_ip;
1019         struct cond *c, *c_tmp, *p_cond;
1020         size_t nr_conds;
1021         int lib_name_len;
1022         int handler_index;
1023
1024
1025         /* Get user-defined us handlers (if they are provided) */
1026         get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
1027         if (get_uprobes)
1028                 my_uprobes_info = (inst_us_proc_t *)get_uprobes();
1029
1030         if (my_uprobes_info == 0)
1031                 my_uprobes_info = &empty_uprobes_info;
1032
1033         DPRINTF("Going to release us_proc_info");
1034         if (us_proc_info.path)
1035                 unlink_bundle();
1036
1037         /* Skip size - it has been used before */
1038         p += sizeof(u_int32_t);
1039
1040         /* Set mode */
1041         if (SetECMode(*(u_int32_t *)p) == -1)
1042         {
1043                 EPRINTF("Cannot set mode!\n");
1044                 return -1;
1045         }
1046
1047         p += sizeof(u_int32_t);
1048
1049         /* Buffer size */
1050         if (SetBufferSize(*(u_int32_t *)p) == -1)
1051         {
1052                 EPRINTF("Cannot set buffer size!\n");
1053                 return -1;
1054         }
1055
1056         p += sizeof(u_int32_t);
1057
1058         /* Pid */
1059         if (SetPid(*(u_int32_t *)p) == -1)
1060         {
1061                 EPRINTF("Cannot set pid!\n");
1062                 return -1;
1063         }
1064
1065         p += sizeof(u_int32_t);
1066
1067         /* Kernel probes */
1068         nr_kern_probes = *(u_int32_t *)p;
1069         p += sizeof(u_int32_t);
1070         for (i = 0; i < nr_kern_probes; i++)
1071         {
1072                 if (add_probe(*(u_int32_t *)p))
1073                 {
1074                         EPRINTF("Cannot add kernel probe at 0x%x!\n", *(u_int32_t *)p);
1075                         return -1;
1076                 }
1077                 p += sizeof(u_int32_t);
1078         }
1079
1080         /* Us probes */
1081         len = *(u_int32_t *)p; /* App path len */
1082         p += sizeof(u_int32_t);
1083
1084         us_proc_info.is_plt = 0;
1085         if ( len == 0 )
1086         {
1087             us_proc_info.path = NULL;
1088         }
1089         else
1090         {
1091                 int lib_path_len;
1092                 char *lib_path;
1093
1094                 us_proc_info.path = (char *)p;
1095                 DPRINTF("app path = %s", us_proc_info.path);
1096                 p += len;
1097
1098                 if (strcmp(us_proc_info.path, "*")) {
1099                         us_proc_info.m_f_dentry = dentry_by_path(us_proc_info.path);
1100                         if (us_proc_info.m_f_dentry == NULL) {
1101                                 return -1;
1102                         }
1103                 }
1104                 else
1105                 {
1106                         us_proc_info.m_f_dentry = NULL;
1107                 }
1108
1109                 us_proc_info.libs_count = *(u_int32_t *)p;
1110                 DPRINTF("nr of libs = %d", us_proc_info.libs_count);
1111                 p += sizeof(u_int32_t);
1112                 us_proc_info.p_libs =
1113                         kmalloc(us_proc_info.libs_count * sizeof(us_proc_lib_t), GFP_KERNEL);
1114
1115                 if (!us_proc_info.p_libs)
1116                 {
1117                         EPRINTF("Cannot alloc p_libs!");
1118                         return -1;
1119                 }
1120                 memset(us_proc_info.p_libs, 0,
1121                            us_proc_info.libs_count * sizeof(us_proc_lib_t));
1122
1123                 for (i = 0; i < us_proc_info.libs_count; i++)
1124                 {
1125                         int abs_handler_idx = 0;
1126
1127                         d_lib = &us_proc_info.p_libs[i];
1128
1129                         lib_name_len = *(u_int32_t *)p;
1130                         p += sizeof(u_int32_t);
1131                         d_lib->path = (char *)p;
1132                         DPRINTF("d_lib->path = %s", d_lib->path);
1133                         p += lib_name_len;
1134
1135                         if ( i != 0 ) {
1136                                 lib_name_len = *(u_int32_t *)p;
1137                                 p += sizeof(u_int32_t);
1138                                 d_lib->path_dyn = (char *)p;
1139                                 DPRINTF("d_lib->path_dyn = %s", d_lib->path_dyn);
1140                                 p += lib_name_len;
1141                         }
1142
1143                         d_lib->ips_count = *(u_int32_t *)p;
1144                         DPRINTF("d_lib->ips_count = %d", d_lib->ips_count);
1145                         p += sizeof(u_int32_t);
1146
1147                         /* If there are any probes for "*" app we have to drop them */
1148                         if (strcmp(d_lib->path, "*") == 0)
1149                         {
1150                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
1151                                 d_lib->ips_count = 0;
1152                                 d_lib->plt_count = *(u_int32_t*)p;
1153                                 p += sizeof(u_int32_t);
1154                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
1155                                 d_lib->plt_count = 0;
1156                                 continue;
1157                         }
1158
1159                         if (strcmp(us_proc_info.path, d_lib->path) == 0)
1160                                 is_app = 1;
1161                         else
1162                         {
1163                                 is_app = 0;
1164                                 DPRINTF("Searching path for lib %s", d_lib->path);
1165                                 d_lib->path = find_lib_path(d_lib->path);
1166                                 if (!d_lib->path)
1167                                 {
1168                                         if (strcmp(d_lib->path_dyn, "") == 0) {
1169                                                 EPRINTF("Cannot find path for lib %s!", d_lib->path);
1170                                                 /* Just skip all the IPs and go to next lib */
1171                                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
1172                                                 d_lib->ips_count = 0;
1173                                                 d_lib->plt_count = *(u_int32_t*)p;
1174                                                 p += sizeof(u_int32_t);
1175                                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
1176                                                 d_lib->plt_count = 0;
1177                                                 continue;
1178                                         }
1179                                         else {
1180                                                 d_lib->path = d_lib->path_dyn;
1181                                                 DPRINTF("Assign path for lib as %s (in suggestion of dyn lib)", d_lib->path);
1182                                         }
1183                                 }
1184                         }
1185
1186                         d_lib->m_f_dentry = dentry_by_path(d_lib->path);
1187                         if (d_lib->m_f_dentry == NULL) {
1188                                 EPRINTF ("failed to lookup dentry for path %s!", d_lib->path);
1189                                 /* Just skip all the IPs and go to next lib */
1190                                 p += d_lib->ips_count * 3 * sizeof(u_int32_t);
1191                                 d_lib->ips_count = 0;
1192                                 d_lib->plt_count = *(u_int32_t*)p;
1193                                 p += sizeof(u_int32_t);
1194                                 p += d_lib->plt_count * 2 * sizeof(u_int32_t);
1195                                 d_lib->plt_count = 0;
1196                                 continue;
1197                         }
1198
1199                         pd_lib = NULL;
1200                         ptr = strrchr(d_lib->path, '/');
1201                         if (ptr)
1202                                 ptr++;
1203                         else
1204                                 ptr = d_lib->path;
1205
1206                         for (l = 0; l < my_uprobes_info->libs_count; l++)
1207                         {
1208                                 if ((strcmp(ptr, my_uprobes_info->p_libs[l].path) == 0) ||
1209                                         (is_app && *(my_uprobes_info->p_libs[l].path) == '\0'))
1210                                 {
1211                                         pd_lib = &my_uprobes_info->p_libs[l];
1212                                         break;
1213                                 }
1214                                 abs_handler_idx += my_uprobes_info->p_libs[l].ips_count;
1215                         }
1216
1217                         if (d_lib->ips_count > 0)
1218                         {
1219                                 us_proc_info.unres_ips_count += d_lib->ips_count;
1220                                 d_lib->p_ips = vmalloc(d_lib->ips_count * sizeof(us_proc_ip_t));
1221                                 DPRINTF("d_lib[%i]->p_ips=%p/%u [%s]", i, d_lib->p_ips,
1222                                                 us_proc_info.unres_ips_count, d_lib->path);
1223
1224                                 if (!d_lib->p_ips)
1225                                 {
1226                                         EPRINTF("Cannot alloc p_ips!\n");
1227                                         return -1;
1228                                 }
1229
1230                                 memset (d_lib->p_ips, 0, d_lib->ips_count * sizeof(us_proc_ip_t));
1231                                 for (k = 0; k < d_lib->ips_count; k++)
1232                                 {
1233                                         d_ip = &d_lib->p_ips[k];
1234                                         d_ip->offset = *(u_int32_t *)p;
1235                                         p += sizeof(u_int32_t);
1236                                         p += sizeof(u_int32_t); /* Skip inst type */
1237                                         handler_index = *(u_int32_t *)p;
1238                                         p += sizeof(u_int32_t);
1239
1240                                         if (pd_lib)
1241                                         {
1242                                                 DPRINTF("pd_lib->ips_count = 0x%x", pd_lib->ips_count);
1243                                                 if (handler_index != -1)
1244                                                 {
1245                                                         DPRINTF("found handler for 0x%x", d_ip->offset);
1246                                                         d_ip->jprobe.pre_entry =
1247                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.pre_entry;
1248                                                         d_ip->jprobe.entry =
1249                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.entry;
1250                                                         d_ip->retprobe.handler =
1251                                                                 pd_lib->p_ips[handler_index - abs_handler_idx].retprobe.handler;
1252                                                 }
1253                                         }
1254                                 }
1255                         }
1256
1257                         d_lib->plt_count = *(u_int32_t*)p;
1258                         p += sizeof(u_int32_t);
1259                         if (d_lib->plt_count > 0)
1260                         {
1261                                 int j;
1262                                 us_proc_info.is_plt = 1;
1263                                 d_lib->p_plt = kmalloc(d_lib->plt_count * sizeof(us_proc_plt_t), GFP_KERNEL);
1264                                 if (!d_lib->p_plt)
1265                                 {
1266                                         EPRINTF("Cannot alloc p_plt!");
1267                                         return -1;
1268                                 }
1269                                 memset(d_lib->p_plt, 0, d_lib->plt_count * sizeof(us_proc_plt_t));
1270                                 for (j = 0; j < d_lib->plt_count; j++)
1271                                 {
1272                                         d_lib->p_plt[j].func_addr = *(u_int32_t*)p;
1273                                         p += sizeof(u_int32_t);
1274                                         d_lib->p_plt[j].got_addr = *(u_int32_t*)p;
1275                                         p += sizeof(u_int32_t);
1276                                         d_lib->p_plt[j].real_func_addr = 0;
1277                                 }
1278                         }
1279                 }
1280
1281                 /* Lib path */
1282                 lib_path_len = *(u_int32_t *)p;
1283                 DPRINTF("lib_path_len = %d", lib_path_len);
1284                 p += sizeof(u_int32_t);
1285                 lib_path = p;
1286                 DPRINTF("lib_path = %s", lib_path);
1287                 p += lib_path_len;
1288
1289                 /* Link FBI info */
1290                 d_lib = &us_proc_info.p_libs[0];
1291                 s_lib.vtps_count = *(u_int32_t *)p;
1292                 DPRINTF("s_lib.vtps_count = %d", s_lib.vtps_count);
1293                 p += sizeof(u_int32_t);
1294                 if (s_lib.vtps_count > 0)
1295                 {
1296                         unsigned long ucount = 1, pre_addr;
1297                         unsigned long *addrs;
1298
1299                         s_lib.p_vtps = kmalloc(s_lib.vtps_count
1300                                                                    * sizeof(ioctl_usr_space_vtp_t), GFP_KERNEL);
1301                         if (!s_lib.p_vtps)
1302                         {
1303                                 //kfree (addrs);
1304                                 return -1;
1305                         }
1306
1307                         for (i = 0; i < s_lib.vtps_count; i++)
1308                         {
1309                                 int var_name_len = *(u_int32_t *)p;
1310                                 p += sizeof(u_int32_t);
1311                                 s_lib.p_vtps[i].name = p;
1312                                 p += var_name_len;
1313                                 s_lib.p_vtps[i].addr = *(u_int32_t *)p;
1314                                 p += sizeof(u_int32_t);
1315                                 s_lib.p_vtps[i].type = *(u_int32_t *)p;
1316                                 p += sizeof(u_int32_t);
1317                                 s_lib.p_vtps[i].size = *(u_int32_t *)p;
1318                                 p += sizeof(u_int32_t);
1319                                 s_lib.p_vtps[i].reg = *(u_int32_t *)p;
1320                                 p += sizeof(u_int32_t);
1321                                 s_lib.p_vtps[i].off = *(u_int32_t *)p;
1322                                 p += sizeof(u_int32_t);
1323                         }
1324
1325                         // array containing elements like (addr, index)
1326                         addrs = kmalloc (s_lib.vtps_count * 2 * sizeof (unsigned long), GFP_KERNEL);
1327         //                      DPRINTF ("addrs=%p/%u", addrs, s_lib.vtps_count);
1328                         if (!addrs)
1329                         {
1330                                 //note: storage will released next time or at clean-up moment
1331                                 return -ENOMEM;
1332                         }
1333                         memset (addrs, 0, s_lib.vtps_count * 2 * sizeof (unsigned long));
1334                         // fill the array in
1335                         for (k = 0; k < s_lib.vtps_count; k++)
1336                         {
1337                                 s_vtp = &s_lib.p_vtps[k];
1338                                 addrs[2 * k] = s_vtp->addr;
1339                                 addrs[2 * k + 1] = k;
1340                         }
1341                         // sort by VTP addresses, i.e. make VTPs with the same addresses adjacent;
1342                         // organize them into bundles
1343                         sort (addrs, s_lib.vtps_count, 2 * sizeof (unsigned long), addr_cmp, generic_swap);
1344
1345                         // calc number of VTPs with unique addresses
1346                         for (k = 1, pre_addr = addrs[0]; k < s_lib.vtps_count; k++)
1347                         {
1348                                 if (addrs[2 * k] != pre_addr)
1349                                         ucount++;       // count different only
1350                                 pre_addr = addrs[2 * k];
1351                         }
1352                         us_proc_info.unres_vtps_count += ucount;
1353                         d_lib->vtps_count = ucount;
1354                         d_lib->p_vtps = kmalloc (ucount * sizeof (us_proc_vtp_t), GFP_KERNEL);
1355                         DPRINTF ("d_lib[%i]->p_vtps=%p/%lu", i, d_lib->p_vtps, ucount); //, d_lib->path);
1356                         if (!d_lib->p_vtps)
1357                         {
1358                                 //note: storage will released next time or at clean-up moment
1359                                 kfree (addrs);
1360                                 return -ENOMEM;
1361                         }
1362                         memset (d_lib->p_vtps, 0, d_lib->vtps_count * sizeof (us_proc_vtp_t));
1363                         // go through sorted VTPS.
1364                         for (k = 0, j = 0, pre_addr = 0, mvtp = NULL; k < s_lib.vtps_count; k++)
1365                         {
1366                                 us_proc_vtp_data_t *vtp_data;
1367                                 // copy VTP data
1368                                 s_vtp = &s_lib.p_vtps[addrs[2 * k + 1]];
1369                                 // if this is the first VTP in bundle (master VTP)
1370                                 if (addrs[2 * k] != pre_addr)
1371                                 {
1372                                         // data are in the array of master VTPs
1373                                         mvtp = &d_lib->p_vtps[j++];
1374                                         mvtp->addr = s_vtp->addr;
1375                                         INIT_LIST_HEAD (&mvtp->list);
1376                                 }
1377                                 // data are in the list of slave VTPs
1378                                 vtp_data = kmalloc (sizeof (us_proc_vtp_data_t), GFP_KERNEL);
1379                                 if (!vtp_data)
1380                                 {
1381                                         //note: storage will released next time or at clean-up moment
1382                                         kfree (addrs);
1383                                         return -ENOMEM;
1384                                 }
1385
1386                                 /*len = strlen_user (s_vtp->name);
1387                                   vtp_data->name = kmalloc (len, GFP_KERNEL);
1388                                   if (!vtp_data->name)
1389                                   {
1390                                   //note: storage will released next time or at clean-up moment
1391                                   kfree (vtp_data);
1392                                   kfree (addrs);
1393                                   return -ENOMEM;
1394                                   }
1395                                   if (strncpy_from_user (vtp_data->name, s_vtp->name, len) != (len-1))
1396                                   {
1397                                   //note: storage will released next time or at clean-up moment
1398                                   EPRINTF ("strncpy_from_user VTP name failed %p (%ld)", vtp_data->name, len);
1399                                   kfree (vtp_data->name);
1400                                   kfree (vtp_data);
1401                                   kfree (addrs);
1402                                   return -EFAULT;
1403                                   }
1404                                   //vtp_data->name[len] = 0;*/
1405                                 vtp_data->name = s_vtp->name;
1406                                 vtp_data->type = s_vtp->type;
1407                                 vtp_data->size = s_vtp->size;
1408                                 vtp_data->reg = s_vtp->reg;
1409                                 vtp_data->off = s_vtp->off;
1410                                 list_add_tail_rcu (&vtp_data->list, &mvtp->list);
1411                                 pre_addr = addrs[2 * k];
1412                         }
1413                         kfree (addrs);
1414                         kfree(s_lib.p_vtps);
1415                 }
1416         }
1417
1418         // ================================================================================
1419         // DEX Probes
1420         // ================================================================================
1421         len = *(u_int32_t *)p; /* App path len */
1422         p += sizeof(u_int32_t);
1423
1424         if ( len == 0 )
1425         {
1426             dex_proc_info.path = NULL;
1427         }
1428         else
1429         {
1430                 dex_proc_info.path = p;
1431                 DPRINTF("dex path = %s", dex_proc_info.path);
1432                 p += len;
1433
1434                 dex_proc_info.ips_count = *(u_int32_t *)p;
1435                 DPRINTF("nr of dex probes = %d", dex_proc_info.ips_count);
1436                 p += sizeof(u_int32_t);
1437
1438                 dex_proc_info.p_ips =
1439                         kmalloc(dex_proc_info.ips_count * sizeof(dex_proc_ip_t), GFP_KERNEL);
1440
1441                 if (!dex_proc_info.p_ips)
1442                 {
1443                         EPRINTF("Cannot alloc dex probes!");
1444                         return -1;
1445                 }
1446
1447                 memset(dex_proc_info.p_ips, 0,
1448                            dex_proc_info.ips_count * sizeof(dex_proc_ip_t));
1449
1450                 for (i = 0; i < dex_proc_info.ips_count; i++)
1451                 {
1452                         dex_proc = &dex_proc_info.p_ips[i];
1453
1454                         // fill up dex proc
1455
1456                         dex_proc->addr = *(u_int32_t *)p;
1457                         p += sizeof(u_int32_t);
1458
1459                         dex_proc->inst_type = *(u_int32_t *)p;
1460                         p += sizeof(u_int32_t);
1461
1462                         // name
1463                         lib_name_len = *(u_int32_t *)p;
1464                         p += sizeof(u_int32_t);
1465                         dex_proc->name = (char *)p;
1466                         p += lib_name_len;
1467
1468                         // class name
1469                         lib_name_len = *(u_int32_t *)p;
1470                         p += sizeof(u_int32_t);
1471                         dex_proc->class_name = (char *)p;
1472                         p += lib_name_len;
1473
1474                         // method name
1475                         lib_name_len = *(u_int32_t *)p;
1476                         p += sizeof(u_int32_t);
1477                         dex_proc->method_name = (char *)p;
1478                         p += lib_name_len;
1479
1480                         // prototype
1481                         lib_name_len = *(u_int32_t *)p;
1482                         p += sizeof(u_int32_t);
1483                         dex_proc->prototype = (char *)p;
1484                         p += lib_name_len;
1485                 }
1486
1487         }
1488         // ================================================================================
1489         // END OF DEX Probes
1490         // ================================================================================
1491
1492
1493         /* Conds */
1494         /* first, delete all the conds */
1495         list_for_each_entry_safe(c, c_tmp, &cond_list.list, list) {
1496                 list_del(&c->list);
1497                 kfree(c);
1498         }
1499         /* second, add new conds */
1500         /* This can be improved (by placing conds into array) */
1501         nr_conds = *(u_int32_t *)p;
1502         DPRINTF("nr_conds = %d", nr_conds);
1503         p += sizeof(u_int32_t);
1504         for (i = 0; i < nr_conds; i++) {
1505                 p_cond = kmalloc(sizeof(struct cond), GFP_KERNEL);
1506                 if (!p_cond) {
1507                         EPRINTF("Cannot alloc cond!\n");
1508                         return -1;
1509                         break;
1510                 }
1511                 memcpy(&p_cond->tmpl, p, sizeof(struct event_tmpl));
1512                 p_cond->applied = 0;
1513                 list_add(&(p_cond->list), &(cond_list.list));
1514                 p += sizeof(struct event_tmpl);
1515         }
1516
1517         /* Event mask */
1518         if (set_event_mask(*(u_int32_t *)p)) {
1519                 EPRINTF("Cannot set event mask!");
1520                 return -1;
1521         }
1522
1523         p += sizeof(u_int32_t);
1524
1525         // print
1526 //      print_inst_us_proc(&us_proc_info);
1527
1528         us_proc_info.pp = get_file_probes(&us_proc_info);
1529
1530         return 0;
1531 }
1532
1533 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1534 int storage_init (void)
1535 {
1536         unsigned long spinlock_flags = 0L;
1537
1538         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1539         ec_info.m_nMode = 0; // MASK IS CLEAR (SINGLE NON_CONTINUOUS BUFFER)
1540 //      ec_info.m_nMode |= ECMODEMASK_MULTIPLE_BUFFER;
1541         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
1542
1543 #ifndef __DISABLE_RELAYFS
1544
1545 #ifdef __USE_PROCFS
1546         gl_pdirRelay = _dir_create (DEFAULT_RELAY_BASE_DIR, _get_proc_root(), &alt_pde);
1547         if(gl_pdirRelay == NULL) {
1548                 EPRINTF("Cannot create procfs directory for relay buffer!");
1549                 return -1;
1550         }
1551 #else
1552         gl_pdirRelay = debugfs_create_dir(DEFAULT_RELAY_BASE_DIR, NULL);
1553         if(gl_pdirRelay == NULL) {
1554                 EPRINTF("Cannot create directory for relay buffer!");
1555                 return -1;
1556         }
1557
1558 #endif // __USE_PROCFS
1559
1560 #endif //__DISABLE_RELAYFS
1561
1562         if(InitializeBuffer(EC_BUFFER_SIZE_DEFAULT) == -1) {
1563                 EPRINTF("Cannot initialize buffer! [Size=%u KB]", EC_BUFFER_SIZE_DEFAULT / 1024 );
1564                 return -1;
1565         }
1566
1567         INIT_HLIST_HEAD(&kernel_probes);
1568         INIT_HLIST_HEAD(&otg_kernel_probes);
1569         INIT_LIST_HEAD(&otg_us_proc_info);
1570         spin_lock_init(&dbi_mh.lock);
1571         INIT_LIST_HEAD(&dbi_mh.modules_handlers);
1572         return 0;
1573 }
1574
1575 /*
1576     Shuts down "storage".
1577     Assumes that all probes are already deactivated.
1578 */
1579 void storage_down (void)
1580 {
1581         if(UninitializeBuffer() == -1)
1582                 EPRINTF("Cannot uninitialize buffer!");
1583
1584 #ifndef __DISABLE_RELAYFS
1585
1586 #ifdef __USE_PROCFS
1587 //      remove_buf(gl_pdirRelay);
1588 #else
1589         debugfs_remove(gl_pdirRelay);
1590 #endif // __USE_PROCFS
1591
1592 #endif //__DISABLE_RELAYFS
1593
1594         if (ec_info.collision_count)
1595                 EPRINTF ("ec_info.collision_count=%d", ec_info.collision_count);
1596         if (ec_info.lost_events_count)
1597                 EPRINTF ("ec_info.lost_events_count=%d", ec_info.lost_events_count);
1598 }
1599
1600 u_int32_t get_probe_func_addr(const char *fmt, va_list args)
1601 {
1602         if (fmt[0] != 'p')
1603                 return 0;
1604
1605         return va_arg(args, u_int32_t);
1606 }
1607
1608 void pack_event_info (probe_id_t probe_id, record_type_t record_type, const char *fmt, ...)
1609 {
1610         unsigned long spinlock_flags = 0L;
1611         static char buf[EVENT_MAX_SIZE] = "";
1612         TYPEOF_EVENT_LENGTH event_len = 0L;
1613         struct timeval tv = { 0, 0 };
1614         TYPEOF_THREAD_ID current_pid = current->pid;
1615         TYPEOF_PROCESS_ID current_tgid = current->tgid;
1616         unsigned current_cpu = task_cpu(current);
1617         va_list args;
1618         unsigned long addr = 0;
1619         struct cond *p_cond;
1620         struct event_tmpl *p_tmpl;
1621
1622         spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1623         memset(buf, 0, EVENT_MAX_SIZE);
1624         spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1625
1626         do_gettimeofday (&tv);
1627
1628         if (probe_id == KS_PROBE_ID) {
1629                 va_start(args, fmt);
1630                 addr = get_probe_func_addr(fmt, args);
1631                 va_end(args);
1632                 if( ((addr == pf_addr) && !(probes_flags & PROBE_FLAG_PF_INSTLD)) ||
1633                     ((addr == cp_addr) && !(probes_flags & PROBE_FLAG_CP_INSTLD)) ||
1634                     ((addr == mr_addr) && !(probes_flags & PROBE_FLAG_MR_INSTLD)) ||
1635                     ((addr == unmap_addr) && !(probes_flags & PROBE_FLAG_UNMAP_INSTLD)) ||
1636                     ((addr == exit_addr) && !(probes_flags & PROBE_FLAG_EXIT_INSTLD)) ) {
1637                         return;
1638                 }
1639         }
1640         if (probe_id == US_PROBE_ID) {
1641                 va_start(args, fmt);
1642                 addr = get_probe_func_addr(fmt, args);
1643                 va_end(args);
1644         }
1645
1646         /* Checking for all the conditions
1647          * except stop condition that we process after saving the event */
1648         list_for_each_entry(p_cond, &cond_list.list, list) {
1649                 p_tmpl = &p_cond->tmpl;
1650                 switch (p_tmpl->type) {
1651                 case ET_TYPE_START_COND:
1652                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1653                                  (addr == p_tmpl->addr)) &&
1654                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1655                                  (current_tgid == p_tmpl->pid)) &&
1656                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1657                                  (current_pid == p_tmpl->tid)) &&
1658                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1659                                  (current_cpu == p_tmpl->cpu_num)) &&
1660                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1661                                  (strcmp(current->comm, p_tmpl->bin_name) == 0)) &&
1662                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TIME) ||
1663                                  (tv.tv_sec > last_attach_time.tv_sec + p_tmpl->sec) ||
1664                                  (tv.tv_sec == last_attach_time.tv_sec + p_tmpl->sec &&
1665                                   tv.tv_usec >= last_attach_time.tv_usec + p_tmpl->usec)) &&
1666                                 !p_cond->applied) {
1667                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1668                                 paused = 0;
1669                                 p_cond->applied = 1;
1670                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1671                         }
1672                         break;
1673                 case ET_TYPE_IGNORE_COND:
1674                         /* if (probe_id == PROBE_SCHEDULE) */
1675                         /*      break; */
1676                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1677                                  (addr == p_tmpl->addr)) &&
1678                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1679                                  (current_tgid == p_tmpl->pid)) &&
1680                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1681                                  (current_pid == p_tmpl->tid)) &&
1682                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1683                                  (current_cpu == p_tmpl->cpu_num)) &&
1684                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1685                                  (strcmp(current->comm, p_tmpl->bin_name) == 0))) {
1686                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1687                                 ec_info.ignored_events_count++;
1688                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1689                                 return;
1690                         }
1691                         break;
1692                 }
1693         }
1694
1695         /* Save only not masked entry or return kernel and user space events */
1696         if (likely(!((probe_id == KS_PROBE_ID || probe_id == US_PROBE_ID)
1697                   && ((record_type == RECORD_ENTRY && (event_mask & IOCTL_EMASK_ENTRY))
1698                           || (record_type == RECORD_RET && (event_mask & IOCTL_EMASK_EXIT)))))) {
1699
1700                 spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1701
1702                 if (paused && (!(probe_id == EVENT_FMT_PROBE_ID || probe_id == DYN_LIB_PROBE_ID))) {
1703                         ec_info.ignored_events_count++;
1704                         spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1705                         return;
1706                 }
1707
1708                 va_start (args, fmt);
1709                 event_len = VPackEvent(buf, sizeof(buf), event_mask, probe_id, record_type, (TYPEOF_TIME *)&tv,
1710                                                            current_tgid, current_pid, current_cpu, fmt, args);
1711                 va_end (args);
1712
1713                 if(event_len == 0) {
1714                         EPRINTF ("ERROR: failed to pack event!");
1715                         ++ec_info.lost_events_count;
1716
1717                 } else if(WriteEventIntoBuffer(buf, event_len) == -1) {
1718                         EPRINTF("Cannot write event into buffer!");
1719                         ++ec_info.lost_events_count;
1720                 }
1721                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1722
1723         }
1724
1725         /* Check for stop condition.  We pause collecting the trace right after
1726          * storing this event */
1727         list_for_each_entry(p_cond, &cond_list.list, list) {
1728                 p_tmpl = &p_cond->tmpl;
1729                 switch (p_tmpl->type) {
1730                 case ET_TYPE_STOP_COND:
1731                         if ((!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_ADDR) ||
1732                                  (addr == p_tmpl->addr)) &&
1733                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_PID) ||
1734                                  (current_tgid == p_tmpl->pid)) &&
1735                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TID) ||
1736                                  (current_pid == p_tmpl->tid)) &&
1737                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_CPU_NUM) ||
1738                                  (current_cpu == p_tmpl->cpu_num)) &&
1739                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_BIN_NAME) ||
1740                                 (strcmp(current->comm, p_tmpl->bin_name) == 0)) &&
1741                                 (!ET_FIELD_ISSET(p_tmpl->flags, ET_MATCH_TIME) ||
1742                                  (tv.tv_sec > last_attach_time.tv_sec + p_tmpl->sec) ||
1743                                  (tv.tv_sec == last_attach_time.tv_sec + p_tmpl->sec &&
1744                                   tv.tv_usec >= last_attach_time.tv_usec + p_tmpl->usec)) &&
1745                                 !p_cond->applied) {
1746                                 spin_lock_irqsave(&ec_spinlock, spinlock_flags);
1747                                 paused = 1;
1748                                 p_cond->applied = 1;
1749                                 spin_unlock_irqrestore(&ec_spinlock, spinlock_flags);
1750                         }
1751                         break;
1752                 }
1753         }
1754 }
1755 EXPORT_SYMBOL_GPL(pack_event_info);
1756
1757 kernel_probe_t* find_probe (unsigned long addr)
1758 {
1759         kernel_probe_t *p;
1760         struct hlist_node *node;
1761
1762         //check if such probe does exist
1763         hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist)
1764                 if (p->addr == addr)
1765                         break;
1766
1767         return node ? p : NULL;
1768 }
1769
1770
1771 int add_probe_to_list (unsigned long addr, kernel_probe_t ** pprobe)
1772 {
1773         kernel_probe_t *new_probe;
1774         kernel_probe_t *probe;
1775
1776         if (pprobe)
1777                 *pprobe = NULL;
1778         //check if such probe does already exist
1779         probe = find_probe(addr);
1780         if (probe) {
1781                 /* It is not a problem if we have already registered
1782                    this probe before */
1783                 return 0;
1784         }
1785         new_probe = kmalloc (sizeof (kernel_probe_t), GFP_KERNEL);
1786         if (!new_probe)
1787         {
1788                 EPRINTF ("no memory for new probe!");
1789                 return -ENOMEM;
1790         }
1791         memset (new_probe, 0, sizeof (kernel_probe_t));
1792         new_probe->addr = addr;
1793         new_probe->jprobe.kp.addr = new_probe->retprobe.kp.addr = (kprobe_opcode_t *)addr;
1794         new_probe->jprobe.priv_arg = new_probe->retprobe.priv_arg = new_probe;
1795         //new_probe->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
1796         dbi_find_and_set_handler_for_probe(new_probe);
1797         INIT_HLIST_NODE (&new_probe->hlist);
1798         hlist_add_head_rcu (&new_probe->hlist, &kernel_probes);
1799         if (pprobe)
1800                 *pprobe = new_probe;
1801         return 0;
1802 }
1803
1804 int remove_probe_from_list (unsigned long addr)
1805 {
1806         kernel_probe_t *p;
1807
1808         //check if such probe does exist
1809         p = find_probe (addr);
1810         if (!p) {
1811                 /* We do not care about it. Nothing bad. */
1812                 return 0;
1813         }
1814
1815         hlist_del_rcu (&p->hlist);
1816
1817         kfree (p);
1818
1819         return 0;
1820 }
1821
1822
1823 int put_us_event (char *data, unsigned long len)
1824 {
1825         unsigned long spinlock_flags = 0L;
1826
1827         SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;
1828         char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE)
1829                                 + sizeof(TYPEOF_PROBE_ID);
1830         TYPEOF_NUMBER_OF_ARGS nArgs = pEventHeader->m_nNumberOfArgs;
1831         TYPEOF_PROBE_ID probe_id = pEventHeader->m_nProbeID;
1832         //int i;
1833
1834         /*if(probe_id == US_PROBE_ID){
1835                 printk("esrc %p/%d[", data, len);
1836                 for(i = 0; i < len; i++)
1837                         printk("%02x ", data[i]);
1838                 printk("]\n");
1839         }*/
1840
1841         // set pid/tid/cpu/time i
1842         //pEventHeader->m_time.tv_sec = tv.tv_sec;
1843         //pEventHeader->m_time.tv_usec = tv.tv_usec;
1844
1845 #ifdef MEMORY_CHECKER
1846         //TODO: move this part to special MEC event posting routine, new IOCTL is needed
1847         if((probe_id >= MEC_PROBE_ID_MIN) && (probe_id <= MEC_PROBE_ID_MAX))
1848         {
1849                 if(mec_post_event != NULL)
1850                 {
1851                         int res = mec_post_event(data, len);
1852                         if(res == -1)
1853                         {
1854                                 return -1;
1855                         }
1856                 }
1857                 else
1858                 {
1859                         mec_post_event = lookup_name("mec_post_event");
1860                         if(mec_post_event == NULL)
1861                         {
1862                                 EPRINTF ("Failed to find function 'mec_post_event' from mec_handlers.ko. Memory Error Checker will work incorrectly.");
1863                         }
1864                         else
1865                         {
1866                                 int res = mec_post_event(data, len);
1867                                 if(res == -1)
1868                                 {
1869                                         return -1;
1870                                 }
1871                         }
1872                 }
1873         }
1874 #endif
1875
1876         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TIME)){
1877                 struct timeval tv = { 0, 0 };
1878                 do_gettimeofday (&tv);
1879                 memcpy(cur, &tv, sizeof(TYPEOF_TIME));
1880                 cur += sizeof(TYPEOF_TIME);
1881         }
1882         //pEventHeader->m_nProcessID = current_tgid;
1883         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){
1884                 //TYPEOF_PROCESS_ID current_tgid = current->tgid;
1885                 (*(TYPEOF_PROCESS_ID *)cur) = current->tgid;
1886                 cur += sizeof(TYPEOF_PROCESS_ID);
1887         }
1888         //pEventHeader->m_nThreadID = current_pid;
1889         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){
1890                 //TYPEOF_THREAD_ID current_pid = current->pid;
1891                 (*(TYPEOF_THREAD_ID *)cur) = current->pid;
1892                 cur += sizeof(TYPEOF_THREAD_ID);
1893         }
1894         //pEventHeader->m_nCPU = current_cpu;
1895         if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){
1896                 //TYPEOF_CPU_NUMBER current_cpu = task_cpu(current);
1897                 (*(TYPEOF_CPU_NUMBER *)cur) = task_cpu(current);
1898                 cur += sizeof(TYPEOF_CPU_NUMBER);
1899         }
1900         //printk("%d %x", probe_id, event_mask);
1901         // dyn lib event should have all args, it is for internal use and not visible to user
1902         if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(event_mask & IOCTL_EMASK_ARGS)){
1903                 // move only if any of prev fields has been skipped
1904                 if(event_mask & (IOCTL_EMASK_TIME|IOCTL_EMASK_PID|IOCTL_EMASK_TID|IOCTL_EMASK_CPU)){
1905                         memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS),
1906                                         len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
1907                                         -sizeof(TYPEOF_EVENT_LENGTH));
1908                 }
1909                 cur += len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
1910                                 -sizeof(TYPEOF_EVENT_LENGTH);
1911         }
1912         else{
1913                 // user space probes should have at least one argument to identify them
1914                 if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID)){
1915                         char *pArg1;
1916                         (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
1917                         cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
1918                         // pack args using format string for the 1st arg only
1919                         memset(cur, 0, ALIGN_VALUE(2));
1920                         cur[0] = 'p'; cur[1] = '\0';
1921                         cur += ALIGN_VALUE(2);
1922                         pArg1 = data + sizeof(SWAP_TYPE_EVENT_HEADER)+ALIGN_VALUE(nArgs+1);
1923                         memmove(cur, pArg1, sizeof(unsigned long));
1924                         cur += sizeof(unsigned long);
1925                 }
1926                 else {
1927                         (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
1928                         cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
1929                 }
1930         }
1931         pEventHeader->m_nLength = cur - data + sizeof(TYPEOF_EVENT_LENGTH);
1932         *((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
1933         len = pEventHeader->m_nLength;
1934
1935         if(WriteEventIntoBuffer(data, len) == -1) {
1936                 EPRINTF("Cannot write event into buffer!");
1937
1938                 spin_lock_irqsave (&ec_spinlock, spinlock_flags);
1939                 ++ec_info.lost_events_count;
1940                 spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
1941         }
1942
1943         return 0;
1944 }
1945
1946 int set_predef_uprobes (ioctl_predef_uprobes_info_t *data)
1947 {
1948         int i, k, size = 0, probe_size, result, j;
1949         char *buf, *sep1, *sep2;
1950         get_my_uprobes_info_t get_uprobes = NULL;
1951         inst_us_proc_t *my_uprobes_info = NULL;
1952
1953         inst_us_proc_t empty_uprobes_info =
1954         {
1955                 .libs_count = 0,
1956                 .p_libs = NULL,
1957         };
1958
1959         get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
1960         if (get_uprobes)
1961                 my_uprobes_info = (inst_us_proc_t *)get_uprobes();
1962
1963         DPRINTF("my_uprobes_info lookup result: 0x%p", my_uprobes_info);
1964         if (my_uprobes_info == 0)
1965                 my_uprobes_info = &empty_uprobes_info;
1966
1967         for(j = 0; j < data->probes_count; j++)
1968         {
1969                 probe_size = strlen_user(data->p_probes+size);
1970                 buf = kmalloc(probe_size, GFP_KERNEL);
1971
1972                 if(!buf)
1973                 {
1974                         EPRINTF("failed to alloc mem!");
1975                         return -EFAULT;
1976                 }
1977
1978                 result = strncpy_from_user(buf, data->p_probes+size, probe_size);
1979                 if (result != (probe_size-1))
1980                 {
1981                         EPRINTF("failed to copy from user!");
1982                         kfree(buf);
1983                         return -EFAULT;
1984                 }
1985                 //DPRINTF("%s", buf);
1986                 sep1 = strchr(buf, ':');
1987                 if(!sep1)
1988                 {
1989                         EPRINTF("skipping invalid predefined uprobe string '%s'!", buf);
1990                         kfree(buf);
1991                         size += probe_size;
1992                         continue;
1993                 }
1994                 sep2 = strchr(sep1+1, ':');
1995                 if(!sep2 || (sep2 == sep1) || (sep2+2 == buf+probe_size))
1996                 {
1997                         EPRINTF("skipping invalid predefined uprobe string '%s'!", buf);
1998                         kfree(buf);
1999                         size += probe_size;
2000                         continue;
2001                 }
2002                 for(i = 0; i < my_uprobes_info->libs_count; i++)
2003                 {
2004                         if(strncmp(buf, my_uprobes_info->p_libs[i].path, sep1-buf) != 0)
2005                                 continue;
2006                         for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
2007                         {
2008                                 if(strncmp(sep1+1, my_uprobes_info->p_libs[i].p_ips[k].name, sep2-sep1-1) != 0)
2009                                         continue;
2010                                 my_uprobes_info->p_libs[i].p_ips[k].offset = simple_strtoul(sep2+1, NULL, 16);
2011                         }
2012                 }
2013
2014                 kfree(buf);
2015                 size += probe_size;
2016         }
2017         return 0;
2018 }
2019
2020 int get_predef_uprobes_size(int *size)
2021 {
2022         int i, k;
2023         get_my_uprobes_info_t get_uprobes = NULL;
2024         inst_us_proc_t *my_uprobes_info = NULL;
2025
2026         inst_us_proc_t empty_uprobes_info =
2027         {
2028                 .libs_count = 0,
2029                 .p_libs = NULL,
2030         };
2031
2032         get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
2033         if (get_uprobes)
2034                 my_uprobes_info = (inst_us_proc_t *)get_uprobes();
2035
2036         if (my_uprobes_info == 0)
2037                 my_uprobes_info = &empty_uprobes_info;
2038
2039         *size = 0;
2040         for(i = 0; i < my_uprobes_info->libs_count; i++)
2041         {
2042                 int lib_size = strlen(my_uprobes_info->p_libs[i].path);
2043                 for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
2044                 {
2045                         // libc.so.6:printf:
2046                         *size += lib_size + 1 + strlen(my_uprobes_info->p_libs[i].p_ips[k].name) + 2;
2047                 }
2048         }
2049
2050         return 0;
2051 }
2052
2053 int get_predef_uprobes(ioctl_predef_uprobes_info_t *udata)
2054 {
2055         ioctl_predef_uprobes_info_t data;
2056         int i, k, size, lib_size, func_size, result;
2057         unsigned count = 0;
2058         char sep[] = ":";
2059
2060         inst_us_proc_t empty_uprobes_info =
2061         {
2062                 .libs_count = 0,
2063                 .p_libs = NULL,
2064         };
2065
2066         get_my_uprobes_info_t get_uprobes = NULL;
2067         inst_us_proc_t *my_uprobes_info = NULL;
2068
2069         get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
2070         if (get_uprobes)
2071                 my_uprobes_info = (inst_us_proc_t *)get_uprobes();
2072
2073         if (my_uprobes_info == 0)
2074                 my_uprobes_info = &empty_uprobes_info;
2075
2076         // get addr of array
2077         if (copy_from_user ((void *)&data, udata, sizeof (data)))
2078         {
2079                 EPRINTF("failed to copy from user!");
2080                 return -EFAULT;
2081         }
2082
2083         size = 0;
2084         for(i = 0; i < my_uprobes_info->libs_count; i++)
2085         {
2086                 lib_size = strlen(my_uprobes_info->p_libs[i].path);
2087                 for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
2088                 {
2089                         // libname
2090                         result = copy_to_user ((void *)(data.p_probes+size), my_uprobes_info->p_libs[i].path, lib_size);
2091                         if (result)
2092                         {
2093                                 EPRINTF("failed to copy to user!");
2094                                 return -EFAULT;
2095                         }
2096                         size += lib_size;
2097                         // ":"
2098                         result = copy_to_user ((void *)(data.p_probes+size), sep, 1);
2099                         if (result)
2100                         {
2101                                 EPRINTF("failed to copy to user!");
2102                                 return -EFAULT;
2103                         }
2104                         size++;
2105                         // probename
2106                         //DPRINTF("'%s'", my_uprobes_info->p_libs[i].p_ips[k].name);
2107                         func_size = strlen(my_uprobes_info->p_libs[i].p_ips[k].name);
2108                         result = copy_to_user ((void *)(data.p_probes+size), my_uprobes_info->p_libs[i].p_ips[k].name, func_size);
2109                         if (result)
2110                         {
2111                                 EPRINTF("failed to copy to user!");
2112                                 return -EFAULT;
2113                         }
2114                         size += func_size;
2115                         // ":\0"
2116                         result = copy_to_user ((void *)(data.p_probes+size), sep, 2);
2117                         if (result)
2118                         {
2119                                 EPRINTF("failed to copy to user!");
2120                                 return -EFAULT;
2121                         }
2122                         size += 2;
2123                         count++;
2124                 }
2125         }
2126
2127         // set probes_count
2128         result = copy_to_user ((void *)&(udata->probes_count), &count, sizeof(count));
2129         if (result)
2130         {
2131                 EPRINTF("failed to copy to user!");
2132                 return -EFAULT;
2133         }
2134
2135         return 0;
2136 }