// This file is C source for SWAP.
//
// SEE ALSO: storage.h
-// AUTHOR: L.Komkov, S.Dianov, A.Gerenkov
+// AUTHOR: L.Komkov, S.Dianov, A.Gerenkov, S.Andreev
// COMPANY NAME: Samsung Research Center in Moscow
-// DEPT NAME: Advanced Software Group
+// DEPT NAME: Advanced Software Group
// CREATED: 2008.02.15
// VERSION: 1.0
// REVISION DATE: 2008.12.03
#include <linux/hash.h>
#include <linux/list.h>
#include <linux/unistd.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
#include "module.h"
#include "storage.h"
+#include "handlers_core.h"
#include "CProfile.h"
#define after_buffer ec_info.buffer_size
-
char *p_buffer = NULL;
inst_us_proc_t us_proc_info;
+inst_dex_proc_t dex_proc_info;
char *deps;
char *bundle;
unsigned int inst_pid = 0;
struct hlist_head kernel_probes;
+struct hlist_head otg_kernel_probes;
int event_mask = 0L;
struct cond cond_list;
int paused = 0; /* a state after a stop condition (events are not collected) */
struct timeval last_attach_time = {0, 0};
+struct dbi_modules_handlers dbi_mh;
+
+struct dbi_modules_handlers *get_dbi_modules_handlers(void)
+{
+ return &dbi_mh;
+}
+EXPORT_SYMBOL_GPL(get_dbi_modules_handlers);
+
+inline unsigned long find_dbi_jp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
+{
+ int i;
+
+ /* Possibly we can find less expensive way */
+ for (i = 0; i < mhi->dbi_nr_handlers; i++) {
+ if (mhi->dbi_handlers[i].func_addr == p_addr) {
+ printk("Found jp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
+ return mhi->dbi_handlers[i].jp_handler_addr;
+ }
+ }
+ return 0;
+}
+
+inline unsigned long find_dbi_rp_handler(unsigned long p_addr, struct dbi_modules_handlers_info *mhi)
+{
+ int i;
+
+ /* Possibly we can find less expensive way */
+ for (i = 0; i < mhi->dbi_nr_handlers; i++) {
+ if (mhi->dbi_handlers[i].func_addr == p_addr) {
+ printk("Found rp_handler for %0lX address of %s module\n", p_addr, mhi->dbi_module->name);
+ return mhi->dbi_handlers[i].rp_handler_addr;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Search of handler in global list of modules for defined probe
+ */
+void dbi_find_and_set_handler_for_probe(kernel_probe_t *p)
+{
+ unsigned long jp_handler_addr, rp_handler_addr;
+ struct dbi_modules_handlers_info *local_mhi;
+ unsigned long dbi_flags;
+ unsigned int local_module_refcount = 0;
+
+ spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
+ list_for_each_entry_rcu(local_mhi, &dbi_mh.modules_handlers, dbi_list_head) {
+ printk("Searching handlers in %s module for %0lX address\n",
+ (local_mhi->dbi_module)->name, p->addr);
+ // XXX: absent code for pre_handlers because we suppose that they are not used
+ if ((jp_handler_addr = find_dbi_jp_handler(p->addr, local_mhi)) != 0) {
+ if (p->jprobe.entry != 0) {
+ printk("Skipping jp_handler for %s module (address %0lX)\n",
+ (local_mhi->dbi_module)->name, p->addr);
+ }
+ else {
+ local_module_refcount = module_refcount(local_mhi->dbi_module);
+ if (local_module_refcount == 0) {
+ if (!try_module_get(local_mhi->dbi_module))
+ printk("Error of try_module_get() for module %s\n",
+ (local_mhi->dbi_module)->name);
+ else
+ printk("Module %s in use now\n",
+ (local_mhi->dbi_module)->name);
+ }
+ p->jprobe.entry = (kprobe_opcode_t *)jp_handler_addr;
+ printk("Set jp_handler for %s module (address %0lX)\n",
+ (local_mhi->dbi_module)->name, p->addr);
+ }
+ }
+ if ((rp_handler_addr = find_dbi_rp_handler(p->addr, local_mhi)) != 0) {
+ if (p->retprobe.handler != 0) {
+ printk("Skipping kretprobe_handler for %s module (address %0lX)\n",
+ (local_mhi->dbi_module)->name, p->addr);
+ }
+ else {
+ local_module_refcount = module_refcount(local_mhi->dbi_module);
+ if (local_module_refcount == 0) {
+ if (!try_module_get(local_mhi->dbi_module))
+ printk("Error of try_module_get() for module %s\n",
+ (local_mhi->dbi_module)->name);
+ else
+ printk("Module %s in use now\n",
+ (local_mhi->dbi_module)->name);
+ }
+ p->retprobe.handler = (kretprobe_handler_t)rp_handler_addr;
+ printk("Set rp_handler for %s module (address %0lX)\n",
+ (local_mhi->dbi_module)->name, p->addr);
+ }
+ }
+ }
+ // not found pre_handler - set default (always true for now since pre_handlers not used)
+ if (p->jprobe.pre_entry == 0) {
+ p->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
+ printk("Set default pre_handler (address %0lX)\n", p->addr);
+ }
+ // not found jp_handler - set default
+ if (p->jprobe.entry == 0) {
+ p->jprobe.entry = (kprobe_opcode_t *) def_jprobe_event_handler;
+ printk("Set default jp_handler (address %0lX)\n", p->addr);
+ }
+ // not found kretprobe_handler - set default
+ if (p->retprobe.handler == 0) {
+ p->retprobe.handler = (kretprobe_handler_t) def_retprobe_event_handler;
+ printk("Set default rp_handler (address %0lX)\n", p->addr);
+ }
+ spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
+}
+
+// XXX TODO: possible mess when start-register/unregister-stop operation
+// so we should refuse register/unregister operation while we are in unsafe state
+int dbi_register_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
+{
+ unsigned long dbi_flags;
+// struct dbi_modules_handlers_info *local_mhi;
+ int i=0;
+ int nr_handlers=dbi_mhi->dbi_nr_handlers;
+ printk ("lookup_name=0x%08x\n", lookup_name);
+
+ if ( lookup_name != NULL){
+ for (i=0;i<nr_handlers;i++){
+ //handlers[i].func_addr = (void (*)(pte_t) ) lookup_name (handlers[i].func_name);
+ dbi_mhi->dbi_handlers[i].func_addr = (void (*)(pte_t) ) lookup_name (dbi_mhi->dbi_handlers[i].func_name);
+ printk("[0x%08x]-%s\n",dbi_mhi->dbi_handlers[i].func_addr,dbi_mhi->dbi_handlers[i].func_name);
+ }
+ }
+ else
+ {
+ printk("[ERROR] lookup_name is NULL\n");
+ }
+
+ spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
+// local_mhi = container_of(&dbi_mhi->dbi_list_head, struct dbi_modules_handlers_info, dbi_list_head);
+ list_add_rcu(&dbi_mhi->dbi_list_head, &dbi_mh.modules_handlers);
+ printk("Added module %s (head is %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
+ spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dbi_register_handlers_module);
+
+// XXX TODO: possible mess when start-register/unregister-stop operation
+// so we should refuse register/unregister operation while we are in unsafe state
+int dbi_unregister_handlers_module(struct dbi_modules_handlers_info *dbi_mhi)
+{
+ unsigned long dbi_flags;
+ // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
+ // (i.e. between attach and stop)
+ /*kernel_probe_t *p;
+ struct hlist_node *node;
+ unsigned long jp_handler_addr, rp_handler_addr, pre_handler_addr;*/
+
+ spin_lock_irqsave(&dbi_mh.lock, dbi_flags);
+ list_del_rcu(&dbi_mhi->dbi_list_head);
+ // Next code block is for far future possible usage in case when removing will be implemented for unsafe state
+ // (i.e. between attach and stop)
+ /*hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist) {
+ // XXX: absent code for pre_handlers because we suppose that they are not used
+ if ((p->jprobe.entry != ((kprobe_pre_entry_handler_t )def_jprobe_event_pre_handler)) ||
+ (p->retprobe.handler != ((kretprobe_handler_t )def_retprobe_event_handler))) {
+ printk("Searching handlers for %p address for removing in %s registered module...\n",
+ p->addr, (dbi_mhi->dbi_module)->name);
+ jp_handler_addr = find_dbi_jp_handler(p->addr, dbi_mhi);
+ rp_handler_addr = find_dbi_rp_handler(p->addr, dbi_mhi);
+ if ((jp_handler_addr != 0) || (rp_handler_addr != 0)) {
+ // search and set to another handlers or default
+ dbi_find_and_set_handler_for_probe(p);
+ printk("Removed handler(s) for %s module (address %p)\n",
+ (dbi_mhi->dbi_module)->name, p->addr);
+ }
+ }
+ }*/
+ printk("Removed module %s (head was %p)\n", (dbi_mhi->dbi_module)->name, &dbi_mhi->dbi_list_head);
+ spin_unlock_irqrestore(&dbi_mh.lock, dbi_flags);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dbi_unregister_handlers_module);
+
EXPORT_SYMBOL_GPL(us_proc_info);
+EXPORT_SYMBOL_GPL(dex_proc_info);
+typedef void *(*get_my_uprobes_info_t)(void);
int (*mec_post_event)(char *data, unsigned long len) = NULL;
unsigned copy_into_cyclic_buffer (char *buffer, unsigned dst_offset, char *src, unsigned size)
{
unsigned long spinlock_flags = 0L;
- unsigned int nSubbufferSize = ec_info.m_nSubbufSize;
- unsigned int nNumOfSubbufers = GetNumOfSubbuffers(nSize);
- unsigned long nAllocatedSize = nSubbufferSize * nNumOfSubbufers;
-
- p_buffer = vmalloc_user(nAllocatedSize);
+ p_buffer = vmalloc_user(nSize);
if(!p_buffer) {
- EPRINTF("Memory allocation error! [Size=%lu KB]", nAllocatedSize / 1024);
+ EPRINTF("Memory allocation error! [Size=%lu KB]", nSize / 1024);
return -1;
}
spin_lock_irqsave (&ec_spinlock, spinlock_flags);
- ec_info.m_nNumOfSubbuffers = nNumOfSubbufers;
- ec_info.buffer_effect = ec_info.buffer_size = nAllocatedSize;
+ ec_info.buffer_effect = ec_info.buffer_size = nSize;
spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
return 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
-#ifndef __DISABLE_RELAYFS
-
-struct rchan* gl_pRelayChannel = NULL;
-struct rchan* GetRelayChannel(void) { return gl_pRelayChannel; };
-
-struct dentry* gl_pdirRelay = NULL;
-struct dentry* GetRelayDir(void) { return gl_pdirRelay; };
-
-#ifdef __USE_PROCFS
-
-struct proc_dir_entry* alt_pde = NULL;
-
-static inline struct dentry *_dir_create (const char *dirname, struct dentry *parent, struct proc_dir_entry **p2pde)
-{
- struct dentry *dir;
- struct proc_dir_entry *pde;
-
- pde = proc_mkdir (dirname, PDE (parent->d_inode));
- if (pde == NULL)
- {
- dir = NULL;
- }
- else
- {
- mutex_lock (&parent->d_inode->i_mutex);
- dir = lookup_one_len (dirname, parent, strlen (dirname));
- mutex_unlock (&parent->d_inode->i_mutex);
-
- if (IS_ERR (dir))
- {
- dir = NULL;
- remove_proc_entry (dirname, PDE (parent->d_inode));
- }
-
- *p2pde = pde;
- }
-
- return dir;
-}
-
-static inline struct dentry *_get_proc_root (void)
-{
- struct file_system_type *procfs_type;
- struct super_block *procfs_sb;
-
- procfs_type = get_fs_type ("proc");
-
- if (!procfs_type || list_empty (&procfs_type->fs_supers))
- return NULL;
-
- procfs_sb = list_entry (procfs_type->fs_supers.next, \
- struct super_block, s_instances);
-
- return procfs_sb->s_root;
-
-}
-
-static struct dentry *create_buf (const char *filename, struct dentry *parent, int mode, struct rchan_buf *buf, int *is_global)
-{
- struct proc_dir_entry *pde;
- struct proc_dir_entry *parent_pde = NULL;
- struct dentry *dentry;
-
- if (parent)
- parent_pde = PDE (parent->d_inode);
- else
- parent = _get_proc_root ();
-
- pde = create_proc_entry (filename, S_IFREG|S_IRUSR, parent_pde);
-
- if(unlikely(!pde))
- return NULL;
-
- pde->proc_fops = &relay_file_operations;
-
- mutex_lock (&parent->d_inode->i_mutex);
- dentry = lookup_one_len (filename, parent, strlen (filename));
- mutex_unlock (&parent->d_inode->i_mutex);
-
- if (IS_ERR(dentry)) {
- remove_proc_entry (filename, parent_pde);
- }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
- dentry->d_inode->i_private = buf;
-#else
- dentry->d_inode->u.generic_ip = buf;
-#endif
-
- return dentry;
-
-}
-
-static int remove_buf (struct dentry *dentry)
-{
- if (dentry != NULL)
- {
- struct proc_dir_entry *pde = PDE (dentry->d_inode);
- dput (dentry);
- remove_proc_entry (pde->name, pde->parent);
- }
-
- return 0;
-}
-
-#endif // __USE_PROCFS
- /*
- * subbuf_start - called on buffer-switch to a new sub-buffer
- * @buf: the channel buffer containing the new sub-buffer
- * @subbuf: the start of the new sub-buffer
- * @prev_subbuf: the start of the previous sub-buffer
- * @prev_padding: unused space at the end of previous sub-buffer
- *
- * The client should return 1 to continue logging, 0 to stop
- * logging.
- *
- * NOTE: subbuf_start will also be invoked when the buffer is
- * created, so that the first sub-buffer can be initialized
- * if necessary. In this case, prev_subbuf will be NULL.
- *
- * NOTE: the client can reserve bytes at the beginning of the new
- * sub-buffer by calling subbuf_start_reserve() in this callback.
- */
-int RelayCallbackSubbufStart(struct rchan_buf *buf,
- void *subbuf,
- void *prev_subbuf,
- size_t prev_padding)
-{
- struct rchan* pRelayChannel = NULL;
- unsigned int nNumOfSubbufs = 0;
-
- unsigned long spinlock_flags = 0L;
- spin_lock_irqsave (&ec_spinlock, spinlock_flags);
-
- subbuf_start_reserve(buf, RELAY_SUBBUF_HEADER_SIZE);
- ec_info.buffer_effect += RELAY_SUBBUF_HEADER_SIZE;
- ec_info.m_nEndOffset = RELAY_SUBBUF_HEADER_SIZE;
-
- if(prev_subbuf == NULL) {
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
- return 1;
- }
- memcpy(prev_subbuf, &prev_padding, sizeof(unsigned int));
- memcpy(prev_subbuf + sizeof(unsigned int), &ec_info.m_nSubbufSavedEvents, sizeof(unsigned int));
- ec_info.m_nSubbufSavedEvents = 0;
- pRelayChannel = GetRelayChannel();
- if(pRelayChannel == NULL) {
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
- EPRINTF("Null pointer to relay channel!");
- return 0;
- }
- nNumOfSubbufs = pRelayChannel->n_subbufs;
- ec_info.m_nBeginSubbufNum = buf->subbufs_consumed % nNumOfSubbufs;
- ec_info.m_nEndSubbufNum = buf->subbufs_produced % nNumOfSubbufs;
- if(relay_buf_full(buf)) {
- void* pConsume = NULL;
- unsigned int nPaddingLength = 0;
- unsigned int nSubbufSize = 0;
- unsigned int nDataSize = 0;
- unsigned int nEffectSize = 0;
- unsigned int nSubbufDiscardedCount = 0;
- nSubbufSize = pRelayChannel->subbuf_size;
- pConsume = buf->start + buf->subbufs_consumed % nNumOfSubbufs * nSubbufSize;
- memcpy(&nPaddingLength, pConsume, sizeof(unsigned int));
- memcpy(&nSubbufDiscardedCount, pConsume + sizeof(unsigned int), sizeof(unsigned int));
- nEffectSize = nSubbufSize - nPaddingLength;
- nDataSize = nEffectSize - RELAY_SUBBUF_HEADER_SIZE;
- ec_info.discarded_events_count += nSubbufDiscardedCount;
- relay_subbufs_consumed(pRelayChannel, 0, 1);
- ec_info.m_nBeginSubbufNum = buf->subbufs_consumed % nNumOfSubbufs;
- ec_info.m_nEndSubbufNum = buf->subbufs_produced % nNumOfSubbufs;
- ec_info.buffer_effect -= nEffectSize;
- ec_info.trace_size -= nDataSize;
- buf->dentry->d_inode->i_size = ec_info.trace_size;
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
- return 1; // Overwrite mode
- }
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
- return 1;
-}
-
- /*
- * buf_mapped - relay buffer mmap notification
- * @buf: the channel buffer
- * @filp: relay file pointer
- *
- * Called when a relay file is successfully mmapped
- */
-void RelayCallbackBufMapped(struct rchan_buf *buf,
- struct file *filp)
-{
-}
-
- /*
- * buf_unmapped - relay buffer unmap notification
- * @buf: the channel buffer
- * @filp: relay file pointer
- *
- * Called when a relay file is successfully unmapped
- */
-void RelayCallbackBufUnmapped(struct rchan_buf *buf,
- struct file *filp)
-{
-}
- /*
- * create_buf_file - create file to represent a relay channel buffer
- * @filename: the name of the file to create
- * @parent: the parent of the file to create
- * @mode: the mode of the file to create
- * @buf: the channel buffer
- * @is_global: outparam - set non-zero if the buffer should be global
- *
- * Called during relay_open(), once for each per-cpu buffer,
- * to allow the client to create a file to be used to
- * represent the corresponding channel buffer. If the file is
- * created outside of relay, the parent must also exist in
- * that filesystem.
- *
- * The callback should return the dentry of the file created
- * to represent the relay buffer.
- *
- * Setting the is_global outparam to a non-zero value will
- * cause relay_open() to create a single global buffer rather
- * than the default set of per-cpu buffers.
- *
- * See Documentation/filesystems/relayfs.txt for more info.
- */
-struct dentry * RelayCallbackCreateBufFile(const char *filename,
- struct dentry *parent,
- int mode,
- struct rchan_buf *buf,
- int *is_global)
-{
- *is_global = 1;
-#ifdef __USE_PROCFS
- DPRINTF("\"%s\" is creating in procfs...!", filename);
- return create_buf(filename, parent, mode, buf, is_global);
-#else
- DPRINTF("\"%s\" is creating in debugfs...!", filename);
- return debugfs_create_file(filename, (mode_t)mode, parent, buf, &relay_file_operations);
-#endif // __USE_PROCFS
-}
-
- /*
- * remove_buf_file - remove file representing a relay channel buffer
- * @dentry: the dentry of the file to remove
- *
- * Called during relay_close(), once for each per-cpu buffer,
- * to allow the client to remove a file used to represent a
- * channel buffer.
- *
- * The callback should return 0 if successful, negative if not.
- */
-int RelayCallbackRemoveBufFile(struct dentry *dentry)
-{
-#ifdef __USE_PROCFS
- remove_buf(dentry);
-#else
- debugfs_remove(dentry);
-#endif // __USE_PROCFS
- return 0;
-}
-
-struct rchan_callbacks gl_RelayCallbacks = {
- .subbuf_start = RelayCallbackSubbufStart,
- .buf_mapped = RelayCallbackBufMapped,
- .buf_unmapped = RelayCallbackBufUnmapped,
- .create_buf_file = RelayCallbackCreateBufFile,
- .remove_buf_file = RelayCallbackRemoveBufFile
-};
-#endif //__DISABLE_RELAYFS
-
-int AllocateMultipleBuffer(unsigned int nSize) {
-#ifndef __DISABLE_RELAYFS
- unsigned long spinlock_flags = 0L;
-
- unsigned int nSubbufferSize = ec_info.m_nSubbufSize;
- unsigned int nNumOfSubbufers = GetNumOfSubbuffers(nSize);
-
- gl_pRelayChannel = relay_open(DEFAULT_RELAY_BASE_FILENAME,
- GetRelayDir(),
- nSubbufferSize,
- nNumOfSubbufers,
- &gl_RelayCallbacks
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
- ,NULL
-#endif
- );
- if(gl_pRelayChannel == NULL) {
- EPRINTF("Cannot create relay buffer channel! [%d subbufers by %u Kb = %u Kb]",
- nNumOfSubbufers, nSubbufferSize / 1024, nSize / 1024);
- return -1;
- }
-
- spin_lock_irqsave (&ec_spinlock, spinlock_flags);
- ec_info.m_nNumOfSubbuffers = nNumOfSubbufers;
- ec_info.buffer_effect = ec_info.buffer_size = nSubbufferSize * nNumOfSubbufers;
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
-
- return 0;
-#else
- EPRINTF("RelayFS not supported!");
- return -1;
-#endif //__DISABLE_RELAYFS
-}
-
-void FreeMultipleBuffer(void) {
-#ifndef __DISABLE_RELAYFS
- relay_close(gl_pRelayChannel);
- CleanECInfo();
-#else
- EPRINTF("RelayFS not supported!");
-#endif //__DISABLE_RELAYFS
-}
-
int InitializeBuffer(unsigned int nSize) {
- if(IsMultipleBuffer())
- return AllocateMultipleBuffer(nSize);
return AllocateSingleBuffer(nSize);
}
int UninitializeBuffer(void) {
- if(IsMultipleBuffer())
- FreeMultipleBuffer();
FreeSingleBuffer();
return 0;
}
-int EnableMultipleBuffer() {
- unsigned long spinlock_flags = 0L;
-
- if(IsMultipleBuffer())
- return 0;
-
- if(UninitializeBuffer() == -1)
- EPRINTF("Cannot uninitialize buffer!");
-
- spin_lock_irqsave (&ec_spinlock, spinlock_flags);
- ec_info.m_nMode |= MODEMASK_MULTIPLE_BUFFER;
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
-
- if(InitializeBuffer(GetBufferSize()) == -1) {
- EPRINTF("Cannot initialize buffer!");
- return -1;
- }
- return 0;
-}
-
-int DisableMultipleBuffer() {
- unsigned long spinlock_flags = 0L;
-
- if(!IsMultipleBuffer())
- return 0;
-
- if(UninitializeBuffer() == -1)
- EPRINTF("Cannot uninitialize buffer!");
-
- spin_lock_irqsave (&ec_spinlock, spinlock_flags);
- ec_info.m_nMode &= ~MODEMASK_MULTIPLE_BUFFER;
- spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
-
- if(InitializeBuffer(GetBufferSize()) == -1) {
- EPRINTF("Cannot initialize buffer!");
- return -1;
- }
- return 0;
-}
-
unsigned int GetBufferSize(void) { return ec_info.buffer_size; };
int SetBufferSize(unsigned int nSize) {
void ResetSingleBuffer(void) {
}
-void ResetMultipleBuffer(void) {
-#ifndef __DISABLE_RELAYFS
- relay_reset(gl_pRelayChannel);
-#else
- EPRINTF("RelayFS not supported!");
-#endif //__DISABLE_RELAYFS
-}
-
int ResetBuffer(void) {
unsigned long spinlock_flags = 0L;
return -1;
}
- if(IsMultipleBuffer())
- ResetMultipleBuffer();
- else
- ResetSingleBuffer();
+ ResetSingleBuffer();
detach_selected_probes ();
}
int WriteEventIntoSingleBuffer(char* pEvent, unsigned long nEventSize) {
- unsigned long spinlock_flags = 0L;
- int bCopied = 0;
+ unsigned int unused_space;
if(!p_buffer) {
EPRINTF("Invalid pointer to buffer!");
++ec_info.lost_events_count;
return -1;
}
- unsigned int unused_space;
if (ec_info.trace_size == 0 || ec_info.after_last > ec_info.first) {
unused_space = ec_info.buffer_size - ec_info.after_last;
if (unused_space > nEventSize) {
return 0;
}
-int WriteEventIntoMultipleBuffer(char* pEvent, unsigned long nEventSize) {
-#ifndef __DISABLE_RELAYFS
- unsigned long spinlock_flags = 0L;
- __relay_write(GetRelayChannel(), pEvent, nEventSize);
- ec_info.buffer_effect += nEventSize;
- ec_info.trace_size += nEventSize;
- ec_info.saved_events_count++;
- ec_info.m_nEndOffset += nEventSize;
- ec_info.m_nSubbufSavedEvents++;
- return 0;
-#else
- EPRINTF("RelayFS not supported!");
- return -1;
-#endif //__DISABLE_RELAYFS
-}
-
int WriteEventIntoBuffer(char* pEvent, unsigned long nEventSize) {
/*unsigned long i;
printk("%02X ", pEvent[i]);
printk("\n");*/
- if(IsMultipleBuffer())
- return WriteEventIntoMultipleBuffer(pEvent, nEventSize);
return WriteEventIntoSingleBuffer(pEvent, nEventSize);
}
match = strstr(p, lib_name);
p += len;
len = strlen(p) + 1; /* we are at path now */
- if (!match) {
+ if (!match) {
p += len;
} else {
DPRINTF("Found match: %s", match);
}
}
- return p;
+ return NULL;
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
for (k = 0; k < count2; k++)
{
//list_for_each_safe_rcu(pos, tmp, &d_lib->p_vtps[k].list) {
- list_for_each_rcu (pos, &d_lib->p_vtps[k].list)
+ list_for_each (pos, &d_lib->p_vtps[k].list)
{
us_proc_vtp_data_t *vtp = list_entry (pos, us_proc_vtp_data_t, list);
list_del_rcu (pos);
}
kfree ((void *) d_lib->p_vtps);
}
+ d_lib->plt_count = 0;
+ kfree((void*) d_lib->p_plt);
+ us_proc_info.is_plt = 0;
}
kfree ((void *) us_proc_info.p_libs);
us_proc_info.p_libs = 0;
us_proc_info.tgid = 0;
}
+struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info);
+void print_inst_us_proc(const inst_us_proc_t *task_inst_info);
+
+extern struct dentry *dentry_by_path(const char *path);
+
int link_bundle()
{
- inst_us_proc_t *my_uprobes_info;
+ get_my_uprobes_info_t get_uprobes = NULL;
+ inst_us_proc_t *my_uprobes_info = 0;
inst_us_proc_t empty_uprobes_info =
{
.libs_count = 0,
int i, j, l, k;
int len;
us_proc_lib_t *d_lib, *pd_lib;
+ dex_proc_ip_t *dex_proc;
ioctl_usr_space_lib_t s_lib;
ioctl_usr_space_vtp_t *s_vtp;
us_proc_vtp_t *mvtp;
- struct nameidata nd;
int is_app = 0;
char *ptr;
us_proc_ip_t *d_ip;
int lib_name_len;
int handler_index;
+
/* Get user-defined us handlers (if they are provided) */
- my_uprobes_info = (inst_us_proc_t *)lookup_name("my_uprobes_info");
+ get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
+ if (get_uprobes)
+ my_uprobes_info = (inst_us_proc_t *)get_uprobes();
+
if (my_uprobes_info == 0)
my_uprobes_info = &empty_uprobes_info;
len = *(u_int32_t *)p; /* App path len */
p += sizeof(u_int32_t);
+ us_proc_info.is_plt = 0;
if ( len == 0 )
{
us_proc_info.path = NULL;
}
else
{
+ int lib_path_len;
+ char *lib_path;
+
us_proc_info.path = (char *)p;
DPRINTF("app path = %s", us_proc_info.path);
p += len;
- if (strcmp(us_proc_info.path, "*"))
- {
- if (path_lookup(us_proc_info.path, LOOKUP_FOLLOW, &nd) != 0)
- {
- EPRINTF("failed to lookup dentry for path %s!", us_proc_info.path);
+ if (strcmp(us_proc_info.path, "*")) {
+ us_proc_info.m_f_dentry = dentry_by_path(us_proc_info.path);
+ if (us_proc_info.m_f_dentry == NULL) {
return -1;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
- us_proc_info.m_f_dentry = nd.dentry;
- path_release(&nd);
-#else
- us_proc_info.m_f_dentry = nd.path.dentry;
- path_put(&nd.path);
-#endif
}
else
{
for (i = 0; i < us_proc_info.libs_count; i++)
{
+ int abs_handler_idx = 0;
+
d_lib = &us_proc_info.p_libs[i];
+
lib_name_len = *(u_int32_t *)p;
p += sizeof(u_int32_t);
d_lib->path = (char *)p;
DPRINTF("d_lib->path = %s", d_lib->path);
-
p += lib_name_len;
+
+ if ( i != 0 ) {
+ lib_name_len = *(u_int32_t *)p;
+ p += sizeof(u_int32_t);
+ d_lib->path_dyn = (char *)p;
+ DPRINTF("d_lib->path_dyn = %s", d_lib->path_dyn);
+ p += lib_name_len;
+ }
+
d_lib->ips_count = *(u_int32_t *)p;
DPRINTF("d_lib->ips_count = %d", d_lib->ips_count);
p += sizeof(u_int32_t);
{
p += d_lib->ips_count * 3 * sizeof(u_int32_t);
d_lib->ips_count = 0;
+ d_lib->plt_count = *(u_int32_t*)p;
+ p += sizeof(u_int32_t);
+ p += d_lib->plt_count * 2 * sizeof(u_int32_t);
+ d_lib->plt_count = 0;
continue;
}
d_lib->path = find_lib_path(d_lib->path);
if (!d_lib->path)
{
- EPRINTF("Cannot find path!");
- return -1;
+ if (strcmp(d_lib->path_dyn, "") == 0) {
+ EPRINTF("Cannot find path for lib %s!", d_lib->path);
+ /* Just skip all the IPs and go to next lib */
+ p += d_lib->ips_count * 3 * sizeof(u_int32_t);
+ d_lib->ips_count = 0;
+ d_lib->plt_count = *(u_int32_t*)p;
+ p += sizeof(u_int32_t);
+ p += d_lib->plt_count * 2 * sizeof(u_int32_t);
+ d_lib->plt_count = 0;
+ continue;
+ }
+ else {
+ d_lib->path = d_lib->path_dyn;
+ DPRINTF("Assign path for lib as %s (in suggestion of dyn lib)", d_lib->path);
+ }
}
}
- if (path_lookup(d_lib->path, LOOKUP_FOLLOW, &nd) != 0)
- {
+ d_lib->m_f_dentry = dentry_by_path(d_lib->path);
+ if (d_lib->m_f_dentry == NULL) {
EPRINTF ("failed to lookup dentry for path %s!", d_lib->path);
- p += lib_name_len;
+ /* Just skip all the IPs and go to next lib */
+ p += d_lib->ips_count * 3 * sizeof(u_int32_t);
+ d_lib->ips_count = 0;
+ d_lib->plt_count = *(u_int32_t*)p;
p += sizeof(u_int32_t);
+ p += d_lib->plt_count * 2 * sizeof(u_int32_t);
+ d_lib->plt_count = 0;
continue;
}
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
- d_lib->m_f_dentry = nd.dentry;
- path_release(&nd);
- #else
- d_lib->m_f_dentry = nd.path.dentry;
- d_lib->m_vfs_mount = nd.path.mnt;
- path_put(&nd.path);
- #endif
pd_lib = NULL;
ptr = strrchr(d_lib->path, '/');
ptr++;
else
ptr = d_lib->path;
+
for (l = 0; l < my_uprobes_info->libs_count; l++)
{
if ((strcmp(ptr, my_uprobes_info->p_libs[l].path) == 0) ||
pd_lib = &my_uprobes_info->p_libs[l];
break;
}
+ abs_handler_idx += my_uprobes_info->p_libs[l].ips_count;
}
if (d_lib->ips_count > 0)
handler_index = *(u_int32_t *)p;
p += sizeof(u_int32_t);
- DPRINTF("pd_lib = 0x%x", pd_lib);
if (pd_lib)
{
DPRINTF("pd_lib->ips_count = 0x%x", pd_lib->ips_count);
{
DPRINTF("found handler for 0x%x", d_ip->offset);
d_ip->jprobe.pre_entry =
- pd_lib->p_ips[handler_index].jprobe.pre_entry;
+ pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.pre_entry;
d_ip->jprobe.entry =
- pd_lib->p_ips[handler_index].jprobe.entry;
+ pd_lib->p_ips[handler_index - abs_handler_idx].jprobe.entry;
d_ip->retprobe.handler =
- pd_lib->p_ips[handler_index].retprobe.handler;
+ pd_lib->p_ips[handler_index - abs_handler_idx].retprobe.handler;
}
}
}
}
+
+ d_lib->plt_count = *(u_int32_t*)p;
+ p += sizeof(u_int32_t);
+ if (d_lib->plt_count > 0)
+ {
+ int j;
+ us_proc_info.is_plt = 1;
+ d_lib->p_plt = kmalloc(d_lib->plt_count * sizeof(us_proc_plt_t), GFP_KERNEL);
+ if (!d_lib->p_plt)
+ {
+ EPRINTF("Cannot alloc p_plt!");
+ return -1;
+ }
+ memset(d_lib->p_plt, 0, d_lib->plt_count * sizeof(us_proc_plt_t));
+ for (j = 0; j < d_lib->plt_count; j++)
+ {
+ d_lib->p_plt[j].func_addr = *(u_int32_t*)p;
+ p += sizeof(u_int32_t);
+ d_lib->p_plt[j].got_addr = *(u_int32_t*)p;
+ p += sizeof(u_int32_t);
+ d_lib->p_plt[j].real_func_addr = 0;
+ }
+ }
}
/* Lib path */
- int lib_path_len = *(u_int32_t *)p;
+ lib_path_len = *(u_int32_t *)p;
DPRINTF("lib_path_len = %d", lib_path_len);
p += sizeof(u_int32_t);
- char *lib_path = p;
+ lib_path = p;
DPRINTF("lib_path = %s", lib_path);
p += lib_path_len;
p += sizeof(u_int32_t);
if (s_lib.vtps_count > 0)
{
+ unsigned long ucount = 1, pre_addr;
+ unsigned long *addrs;
+
s_lib.p_vtps = kmalloc(s_lib.vtps_count
* sizeof(ioctl_usr_space_vtp_t), GFP_KERNEL);
if (!s_lib.p_vtps)
p += sizeof(u_int32_t);
}
- unsigned long ucount = 1, pre_addr;
// array containing elements like (addr, index)
- unsigned long *addrs = kmalloc (s_lib.vtps_count * 2 * sizeof (unsigned long), GFP_KERNEL);
+ addrs = kmalloc (s_lib.vtps_count * 2 * sizeof (unsigned long), GFP_KERNEL);
// DPRINTF ("addrs=%p/%u", addrs, s_lib.vtps_count);
if (!addrs)
{
return -EFAULT;
}
//vtp_data->name[len] = 0;*/
+ vtp_data->name = s_vtp->name;
vtp_data->type = s_vtp->type;
vtp_data->size = s_vtp->size;
vtp_data->reg = s_vtp->reg;
p += sizeof(u_int32_t);
+ // print
+// print_inst_us_proc(&us_proc_info);
+
+ us_proc_info.pp = get_file_probes(&us_proc_info);
+
return 0;
}
spin_lock_irqsave (&ec_spinlock, spinlock_flags);
ec_info.m_nMode = 0; // MASK IS CLEAR (SINGLE NON_CONTINUOUS BUFFER)
-// ec_info.m_nMode |= ECMODEMASK_MULTIPLE_BUFFER;
spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
-#ifndef __DISABLE_RELAYFS
-
-#ifdef __USE_PROCFS
- gl_pdirRelay = _dir_create (DEFAULT_RELAY_BASE_DIR, _get_proc_root(), &alt_pde);
- if(gl_pdirRelay == NULL) {
- EPRINTF("Cannot create procfs directory for relay buffer!");
- return -1;
- }
-#else
- gl_pdirRelay = debugfs_create_dir(DEFAULT_RELAY_BASE_DIR, NULL);
- if(gl_pdirRelay == NULL) {
- EPRINTF("Cannot create directory for relay buffer!");
- return -1;
- }
-
-#endif // __USE_PROCFS
-
-#endif //__DISABLE_RELAYFS
-
if(InitializeBuffer(EC_BUFFER_SIZE_DEFAULT) == -1) {
EPRINTF("Cannot initialize buffer! [Size=%u KB]", EC_BUFFER_SIZE_DEFAULT / 1024 );
return -1;
}
- INIT_HLIST_HEAD (&kernel_probes);
+ INIT_HLIST_HEAD(&kernel_probes);
+ INIT_HLIST_HEAD(&otg_kernel_probes);
+ spin_lock_init(&dbi_mh.lock);
+ INIT_LIST_HEAD(&dbi_mh.modules_handlers);
return 0;
}
if(UninitializeBuffer() == -1)
EPRINTF("Cannot uninitialize buffer!");
-#ifndef __DISABLE_RELAYFS
-
-#ifdef __USE_PROCFS
-// remove_buf(gl_pdirRelay);
-#else
- debugfs_remove(gl_pdirRelay);
-#endif // __USE_PROCFS
-
-#endif //__DISABLE_RELAYFS
-
if (ec_info.collision_count)
EPRINTF ("ec_info.collision_count=%d", ec_info.collision_count);
if (ec_info.lost_events_count)
unsigned long spinlock_flags = 0L;
static char buf[EVENT_MAX_SIZE] = "";
TYPEOF_EVENT_LENGTH event_len = 0L;
- TYPEOF_TIME tv = { 0, 0 };
+ struct timeval tv = { 0, 0 };
TYPEOF_THREAD_ID current_pid = current->pid;
TYPEOF_PROCESS_ID current_tgid = current->tgid;
unsigned current_cpu = task_cpu(current);
va_start(args, fmt);
addr = get_probe_func_addr(fmt, args);
va_end(args);
- if (!find_probe(addr))
- return;
- if (((addr == pf_addr) && !(probes_flags & PROBE_FLAG_PF_INSTLD)) ||
- ((addr == exit_addr) && !(probes_flags & PROBE_FLAG_EXIT_INSTLD)))
+ if( ((addr == pf_addr) && !(probes_flags & PROBE_FLAG_PF_INSTLD)) ||
+ ((addr == cp_addr) && !(probes_flags & PROBE_FLAG_CP_INSTLD)) ||
+ ((addr == mr_addr) && !(probes_flags & PROBE_FLAG_MR_INSTLD)) ||
+ ((addr == unmap_addr) && !(probes_flags & PROBE_FLAG_UNMAP_INSTLD)) ||
+ ((addr == exit_addr) && !(probes_flags & PROBE_FLAG_EXIT_INSTLD)) ) {
return;
+ }
}
if (probe_id == US_PROBE_ID) {
va_start(args, fmt);
}
va_start (args, fmt);
- event_len = VPackEvent(buf, sizeof(buf), event_mask, probe_id, record_type, &tv,
+ event_len = VPackEvent(buf, sizeof(buf), event_mask, probe_id, record_type, (TYPEOF_TIME *)&tv,
current_tgid, current_pid, current_cpu, fmt, args);
va_end (args);
return node ? p : NULL;
}
+
int add_probe_to_list (unsigned long addr, kernel_probe_t ** pprobe)
{
kernel_probe_t *new_probe;
- unsigned long jp_handler_addr, rp_handler_addr, pre_handler_addr;
- unsigned long (*find_jp_handler)(unsigned long) =
- (unsigned long (*)(unsigned long))lookup_name("find_jp_handler");
- unsigned long (*find_rp_handler)(unsigned long) =
- (unsigned long (*)(unsigned long))lookup_name("find_rp_handler");
- unsigned long (*find_pre_handler)(unsigned long) =
- (unsigned long (*)(unsigned long))lookup_name("find_pre_handler");
-
kernel_probe_t *probe;
if (pprobe)
this probe before */
return 0;
}
-
new_probe = kmalloc (sizeof (kernel_probe_t), GFP_KERNEL);
if (!new_probe)
{
return -ENOMEM;
}
memset (new_probe, 0, sizeof (kernel_probe_t));
-
new_probe->addr = addr;
new_probe->jprobe.kp.addr = new_probe->retprobe.kp.addr = (kprobe_opcode_t *)addr;
new_probe->jprobe.priv_arg = new_probe->retprobe.priv_arg = new_probe;
-
//new_probe->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
- if (find_pre_handler == 0 ||
- (pre_handler_addr = find_pre_handler(new_probe->addr)) == 0)
- new_probe->jprobe.pre_entry = (kprobe_pre_entry_handler_t) def_jprobe_event_pre_handler;
- else
- new_probe->jprobe.pre_entry = (kprobe_pre_entry_handler_t)pre_handler_addr;
-
- if (find_jp_handler == 0 ||
- (jp_handler_addr = find_jp_handler(new_probe->addr)) == 0)
- new_probe->jprobe.entry = (kprobe_opcode_t *) def_jprobe_event_handler;
- else
- new_probe->jprobe.entry = (kprobe_opcode_t *)jp_handler_addr;
-
- if (find_rp_handler == 0 ||
- (rp_handler_addr = find_rp_handler(new_probe->addr)) == 0)
- new_probe->retprobe.handler =
- (kretprobe_handler_t) def_retprobe_event_handler;
- else
- new_probe->retprobe.handler = (kretprobe_handler_t)rp_handler_addr;
-
+ dbi_find_and_set_handler_for_probe(new_probe);
INIT_HLIST_NODE (&new_probe->hlist);
hlist_add_head_rcu (&new_probe->hlist, &kernel_probes);
-
if (pprobe)
*pprobe = new_probe;
-
return 0;
}
{
unsigned long spinlock_flags = 0L;
- SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;
- char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE)
+ SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;
+ char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE)
+ sizeof(TYPEOF_PROBE_ID);
TYPEOF_NUMBER_OF_ARGS nArgs = pEventHeader->m_nNumberOfArgs;
TYPEOF_PROBE_ID probe_id = pEventHeader->m_nProbeID;
//int i;
-
+
/*if(probe_id == US_PROBE_ID){
printk("esrc %p/%d[", data, len);
for(i = 0; i < len; i++)
printk("%02x ", data[i]);
printk("]\n");
}*/
-
+
// set pid/tid/cpu/time i
//pEventHeader->m_time.tv_sec = tv.tv_sec;
//pEventHeader->m_time.tv_usec = tv.tv_usec;
#endif
if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TIME)){
- TYPEOF_TIME tv = { 0, 0 };
+ struct timeval tv = { 0, 0 };
do_gettimeofday (&tv);
memcpy(cur, &tv, sizeof(TYPEOF_TIME));
cur += sizeof(TYPEOF_TIME);
}
//pEventHeader->m_nProcessID = current_tgid;
- if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){
+ if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){
//TYPEOF_PROCESS_ID current_tgid = current->tgid;
(*(TYPEOF_PROCESS_ID *)cur) = current->tgid;
cur += sizeof(TYPEOF_PROCESS_ID);
}
//pEventHeader->m_nThreadID = current_pid;
- if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){
+ if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){
//TYPEOF_THREAD_ID current_pid = current->pid;
(*(TYPEOF_THREAD_ID *)cur) = current->pid;
cur += sizeof(TYPEOF_THREAD_ID);
}
//pEventHeader->m_nCPU = current_cpu;
- if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){
+ if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){
//TYPEOF_CPU_NUMBER current_cpu = task_cpu(current);
(*(TYPEOF_CPU_NUMBER *)cur) = task_cpu(current);
cur += sizeof(TYPEOF_CPU_NUMBER);
//printk("%d %x", probe_id, event_mask);
// dyn lib event should have all args, it is for internal use and not visible to user
if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(event_mask & IOCTL_EMASK_ARGS)){
- // move only if any of prev fields has been skipped
+ // move only if any of prev fields has been skipped
if(event_mask & (IOCTL_EMASK_TIME|IOCTL_EMASK_PID|IOCTL_EMASK_TID|IOCTL_EMASK_CPU)){
- memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS),
+ memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS),
len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
-sizeof(TYPEOF_EVENT_LENGTH));
}
-sizeof(TYPEOF_EVENT_LENGTH);
}
else{
- // user space probes should have at least one argument to identify them
+ // user space probes should have at least one argument to identify them
if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID)){
char *pArg1;
(*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
(*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
}
- }
+ }
pEventHeader->m_nLength = cur - data + sizeof(TYPEOF_EVENT_LENGTH);
*((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
len = pEventHeader->m_nLength;
-
+
if(WriteEventIntoBuffer(data, len) == -1) {
EPRINTF("Cannot write event into buffer!");
{
int i, k, size = 0, probe_size, result, j;
char *buf, *sep1, *sep2;
+ get_my_uprobes_info_t get_uprobes = NULL;
+ inst_us_proc_t *my_uprobes_info = NULL;
+
+ inst_us_proc_t empty_uprobes_info =
+ {
+ .libs_count = 0,
+ .p_libs = NULL,
+ };
+
+ get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
+ if (get_uprobes)
+ my_uprobes_info = (inst_us_proc_t *)get_uprobes();
- inst_us_proc_t *my_uprobes_info = (inst_us_proc_t *)lookup_name("my_uprobes_info");
DPRINTF("my_uprobes_info lookup result: 0x%p", my_uprobes_info);
- inst_us_proc_t empty_uprobes_info =
- {
- .libs_count = 0,
- .p_libs = NULL,
- };
if (my_uprobes_info == 0)
my_uprobes_info = &empty_uprobes_info;
kfree(buf);
size += probe_size;
continue;
- }
+ }
sep2 = strchr(sep1+1, ':');
if(!sep2 || (sep2 == sep1) || (sep2+2 == buf+probe_size))
{
kfree(buf);
size += probe_size;
continue;
- }
+ }
for(i = 0; i < my_uprobes_info->libs_count; i++)
{
if(strncmp(buf, my_uprobes_info->p_libs[i].path, sep1-buf) != 0)
for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
{
if(strncmp(sep1+1, my_uprobes_info->p_libs[i].p_ips[k].name, sep2-sep1-1) != 0)
- continue;
+ continue;
my_uprobes_info->p_libs[i].p_ips[k].offset = simple_strtoul(sep2+1, NULL, 16);
}
}
int get_predef_uprobes_size(int *size)
{
int i, k;
+ get_my_uprobes_info_t get_uprobes = NULL;
+ inst_us_proc_t *my_uprobes_info = NULL;
- inst_us_proc_t *my_uprobes_info = (inst_us_proc_t *)lookup_name("my_uprobes_info");
- inst_us_proc_t empty_uprobes_info =
- {
- .libs_count = 0,
- .p_libs = NULL,
- };
+ inst_us_proc_t empty_uprobes_info =
+ {
+ .libs_count = 0,
+ .p_libs = NULL,
+ };
+
+ get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
+ if (get_uprobes)
+ my_uprobes_info = (inst_us_proc_t *)get_uprobes();
if (my_uprobes_info == 0)
my_uprobes_info = &empty_uprobes_info;
unsigned count = 0;
char sep[] = ":";
- inst_us_proc_t *my_uprobes_info = (inst_us_proc_t *)lookup_name("my_uprobes_info");
- inst_us_proc_t empty_uprobes_info =
- {
- .libs_count = 0,
- .p_libs = NULL,
- };
+ inst_us_proc_t empty_uprobes_info =
+ {
+ .libs_count = 0,
+ .p_libs = NULL,
+ };
+
+ get_my_uprobes_info_t get_uprobes = NULL;
+ inst_us_proc_t *my_uprobes_info = NULL;
+
+ get_uprobes = (get_my_uprobes_info_t)lookup_name("get_my_uprobes_info");
+ if (get_uprobes)
+ my_uprobes_info = (inst_us_proc_t *)get_uprobes();
+
if (my_uprobes_info == 0)
my_uprobes_info = &empty_uprobes_info;
EPRINTF("failed to copy from user!");
return -EFAULT;
}
-
+
size = 0;
for(i = 0; i < my_uprobes_info->libs_count; i++)
{
return 0;
}
-
-