Add checking if code is executed in handler 04/154604/3
authorAlexander Aksenov <a.aksenov@samsung.com>
Tue, 10 Oct 2017 12:07:36 +0000 (15:07 +0300)
committerAlexander Aksenov <a.aksenov@samsung.com>
Fri, 13 Oct 2017 11:24:11 +0000 (14:24 +0300)
This is useful for preventing proifiling debug libraries when
target functions are called indirectrly. For some features that
are sensitive for events consistence, like LSan, this issue is
critical.

Change-Id: I8be26c8bd4889d81b247085cf35e8a820487402b
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
Makefile
helper/in_handler.c [new file with mode: 0644]
helper/libdaprobe.c
helper/thread_data.c [new file with mode: 0644]
helper/thread_data.h [new file with mode: 0644]
include/binproto.h
include/in_handler.h [new file with mode: 0644]

index 9b6495888bd43e8312cda4042d5c0d1e1e851582..f4b1152a3ccc3542f2b04fa4aff5573e323adc77 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -120,7 +120,9 @@ UTILITY_SRCS =                              \
        ./helper/got_patching.c         \
        ./helper/get_got.c              \
        ./helper/file_buffer.c          \
-       ./helper/screenshot_iface.c
+       ./helper/screenshot_iface.c     \
+       ./helper/thread_data.c          \
+       ./helper/in_handler.c
 
 PROBE_SRCS =                                   \
        ./probe_memory/libdamemalloc.c          \
diff --git a/helper/in_handler.c b/helper/in_handler.c
new file mode 100644 (file)
index 0000000..f858d14
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  SWAP probe library
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Alexander Aksenov <a.aksenov@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <malloc.h>
+#include "daprobe.h"
+#include "thread_data.h"
+#include "in_handler.h"
+
+
+struct in_handler_data_t {
+       bool is_in_handler;
+};
+
+
+static void *key;
+
+static void _thread_destructor(void *data)
+{
+       struct in_handler_data_t *ihd = (struct in_handler_data_t *)data;
+
+       free(ihd);
+}
+
+static struct in_handler_data_t *_get_in_handler_data(void)
+{
+       struct in_handler_data_t *ihd;
+
+       ihd = thread_data_get(key);
+       if (!ihd) {
+               ihd = malloc(sizeof(*ihd));
+               if (!ihd) {
+                       PRINTERR("Cannot allocate thread data for in hander!");
+                       return NULL;
+               }
+               thread_data_set(key, ihd);
+       }
+
+       return ihd;
+}
+
+
+void init_in_handler(void)
+{
+       key = thread_handle_get_new(_thread_destructor);
+}
+
+void set_in_handler(void)
+{
+       struct in_handler_data_t *ihd;
+
+       ihd = _get_in_handler_data();
+       if (!ihd)
+               return;
+
+       ihd->is_in_handler = true;
+}
+
+void unset_in_handler(void)
+{
+       struct in_handler_data_t *ihd;
+
+       ihd = _get_in_handler_data();
+       if (!ihd)
+               return;
+
+       ihd->is_in_handler = false;
+}
+
+bool is_in_handler(void)
+{
+       struct in_handler_data_t *ihd;
+
+       ihd = thread_data_get(key);
+       /* ihd is NULL if it was not set. If if was not set then we're not in
+        * handler! */
+       if (!ihd)
+               return false;
+
+       return ihd->is_in_handler;
+}
index c99cdf941728a981e0189296df2c44992ef444d5..a7abfaa32390545e00bd18096e5ad1e062160305 100755 (executable)
@@ -66,6 +66,8 @@
 #include "lsan_open.h"
 #include "got_patching.h"
 #include "arch_probe_dummies.h"
+#include "in_handler.h"
+#include "thread_data.h"
 
 #define UDS_NAME "/run/swap/lib.socket"
 #define TIMERFD_INTERVAL 100000000      /* 0.1 sec */
@@ -368,6 +370,9 @@ static void *recv_thread(void __unused * data)
        log_t log;
        sigset_t profsigmask;
 
+       /* This thread is a handling thread, so it is a "handler" itself */
+       set_in_handler();
+
        if (gTraceInfo.socket.daemonSock == -1)
                return NULL;
 
@@ -519,6 +524,7 @@ void _init_(void)
 
        init_exec_fork();
        initialize_hash_table();
+       init_in_handler();
 
        /* create socket for communication with da_daemon */
        if (create_socket() == 0) {
@@ -565,6 +571,8 @@ void _uninit_(void)
        }
 
        finalize_hash_table();
+       cleanup_binaries();
+       thread_handle_del_all();
 
        for (i = 0; i < NUM_ORIGINAL_LIBRARY; i++)
                if(lib_handle[i] != NULL)
diff --git a/helper/thread_data.c b/helper/thread_data.c
new file mode 100644 (file)
index 0000000..2500ad7
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  SWAP probe library
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Alexander Aksenov <a.aksenov@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <pthread.h>
+#include <malloc.h>
+#include <sys/queue.h>
+#include "daprobe.h"
+#include "thread_data.h"
+
+
+
+struct pkey_list_el {
+       SLIST_ENTRY(pkey_list_el) entries;
+       pthread_key_t key;
+};
+
+
+static SLIST_HEAD(listhead, pkey_list_el) head = SLIST_HEAD_INITIALIZER(head);
+static pthread_mutex_t pkey_list_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+
+void *thread_handle_get_new(destructor_t d)
+{
+       struct pkey_list_el *ple;
+
+       ple = malloc(sizeof(*ple));
+       if (!ple) {
+               PRINTERR("Not enough memory to alloc struct!");
+               return NULL;
+       }
+
+       pthread_mutex_lock(&pkey_list_mutex);
+
+       pthread_key_create(&ple->key, d);
+       SLIST_INSERT_HEAD(&head, ple, entries);
+
+       pthread_mutex_unlock(&pkey_list_mutex);
+
+       return ple;
+}
+
+void thread_handle_del(void *handle)
+{
+       struct pkey_list_el *ple = (struct pkey_list_el *)handle;
+
+       if (!ple) {
+               PRINTERR("Passed NULL handle to <%s>!", __func__);
+               return;
+       }
+
+       pthread_mutex_lock(&pkey_list_mutex);
+
+       SLIST_REMOVE(&head, ple, pkey_list_el, entries);
+       pthread_key_delete(ple->key);
+
+       pthread_mutex_unlock(&pkey_list_mutex);
+
+       free(ple);
+}
+
+void thread_handle_del_all(void)
+{
+       struct pkey_list_el *ple;
+
+       pthread_mutex_lock(&pkey_list_mutex);
+
+       while (!SLIST_EMPTY(&head)) {
+               ple = SLIST_FIRST(&head);
+               SLIST_REMOVE_HEAD(&head, entries);
+               pthread_key_delete(ple->key);
+               free(ple);
+       }
+
+       pthread_mutex_unlock(&pkey_list_mutex);
+}
+
+void *thread_data_get(void *handle)
+{
+       struct pkey_list_el *ple = (struct pkey_list_el *)handle;
+
+       if (!ple) {
+               PRINTERR("Passed NULL handle to <%s>!", __func__);
+               return NULL;
+       }
+
+       return pthread_getspecific(ple->key);
+}
+
+void thread_data_set(void *handle, void *data)
+{
+       struct pkey_list_el *ple = (struct pkey_list_el *)handle;
+
+       if (!ple) {
+               PRINTERR("Passed NULL handle to <%s>!", __func__);
+               return;
+       }
+
+       pthread_setspecific(ple->key, data);
+}
diff --git a/helper/thread_data.h b/helper/thread_data.h
new file mode 100644 (file)
index 0000000..461391d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  SWAP probe library
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Alexander Aksenov <a.aksenov@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __THREAD_DATA_H__
+#define __THREAD_DATA_H__
+
+
+typedef void (*destructor_t)(void *);
+
+/* Called only once for one handle, like pthread_key_create() */
+void *thread_handle_get_new(destructor_t d);
+void thread_handle_del(void *handle);
+void thread_handle_del_all(void);
+
+/* Returns NULL when uninited */
+void *thread_data_get(void *handle);
+void thread_data_set(void *handle, void *data);
+
+#endif /* __THREAD_DATA_H__ */
index d9a4313fde97c7d69605c8e2880f24b038728cfb..73aa6c7b410706f5cbec7be6ccc7c5de27ebde49 100644 (file)
@@ -47,6 +47,7 @@
 #include <sys/socket.h>
 #include "dahelper.h"
 #include "api_id_mapping.h"
+#include "in_handler.h"
 
 #define MSG_PROBE_MEMORY 0x0101
 #define MSG_PROBE_UICONTROL 0x0102
@@ -365,6 +366,8 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
 #define PROBE_GET_ORIG(pd_p)            (pd_p)->orig
 #define PROBE_GET_FUNC(pd_p)            (pd_p)->func
 
+#define PASS_PTR(pd)                    gen_type_t, &pd
+
 #define PACK_INT32(val)                                \
        BUF_PTR = pack_int32(BUF_PTR, val);
 #define PACK_INT64(val)                                \
@@ -384,6 +387,8 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
 #define FUNC_TA8(t1, n1, ...)     t1 n1, FUNC_TA7(__VA_ARGS__)
 #define FUNC_TA9(t1, n1, ...)     t1 n1, FUNC_TA8(__VA_ARGS__)
 #define FUNC_TA10(t1, n1, ...)     t1 n1, FUNC_TA9(__VA_ARGS__)
+#define FUNC_TA11(t1, n1, ...)     t1 n1, FUNC_TA10(__VA_ARGS__)
+#define FUNC_TA12(t1, n1, ...)     t1 n1, FUNC_TA11(__VA_ARGS__)
 
 #define FUNC_TA_V0(...)            void
 #define FUNC_TA_V1(n1)             n1
@@ -396,6 +401,8 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
 #define FUNC_TA_V8(t1, n1, ...)    t1 n1, FUNC_TA_V7(__VA_ARGS__)
 #define FUNC_TA_V9(t1, n1, ...)    t1 n1, FUNC_TA_V8(__VA_ARGS__)
 #define FUNC_TA_V10(t1, n1, ...)    t1 n1, FUNC_TA_V9(__VA_ARGS__)
+#define FUNC_TA_V11(t1, n1, ...)    t1 n1, FUNC_TA_V10(__VA_ARGS__)
+#define FUNC_TA_V12(t1, n1, ...)    t1 n1, FUNC_TA_V11(__VA_ARGS__)
 
 #define FUNC_TA_H0(...)
 #define FUNC_TA_H1(t1, n1, ...)     ,t1 n1
@@ -408,6 +415,8 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
 #define FUNC_TA_H8(t1, n1, ...)     ,t1 n1 FUNC_TA_H7(__VA_ARGS__)
 #define FUNC_TA_H9(t1, n1, ...)     ,t1 n1 FUNC_TA_H8(__VA_ARGS__)
 #define FUNC_TA_H10(t1, n1, ...)     ,t1 n1 FUNC_TA_H9(__VA_ARGS__)
+#define FUNC_TA_H11(t1, n1, ...)     ,t1 n1 FUNC_TA_H10(__VA_ARGS__)
+#define FUNC_TA_H12(t1, n1, ...)     ,t1 n1 FUNC_TA_H11(__VA_ARGS__)
 
 #define FUNC_TA_VAR0(...)
 #define FUNC_TA_VAR1(n1)              ,va_list args
@@ -420,30 +429,36 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
 #define FUNC_TA_VAR8(t1, n1, ...)     ,t1 n1 FUNC_TA_VAR7(__VA_ARGS__)
 #define FUNC_TA_VAR9(t1, n1, ...)     ,t1 n1 FUNC_TA_VAR8(__VA_ARGS__)
 #define FUNC_TA_VAR10(t1, n1, ...)    ,t1 n1 FUNC_TA_VAR9(__VA_ARGS__)
+#define FUNC_TA_VAR11(t1, n1, ...)    ,t1 n1 FUNC_TA_VAR10(__VA_ARGS__)
+#define FUNC_TA_VAR12(t1, n1, ...)    ,t1 n1 FUNC_TA_VAR11(__VA_ARGS__)
 
 #define FUNC_ARGS0(...)
-#define FUNC_ARGS1(t1, n1, ...)     ,n1
-#define FUNC_ARGS2(t1, n1, ...)     ,n1 FUNC_ARGS1(__VA_ARGS__)
-#define FUNC_ARGS3(t1, n1, ...)     ,n1 FUNC_ARGS2(__VA_ARGS__)
-#define FUNC_ARGS4(t1, n1, ...)     ,n1 FUNC_ARGS3(__VA_ARGS__)
-#define FUNC_ARGS5(t1, n1, ...)     ,n1 FUNC_ARGS4(__VA_ARGS__)
-#define FUNC_ARGS6(t1, n1, ...)     ,n1 FUNC_ARGS5(__VA_ARGS__)
-#define FUNC_ARGS7(t1, n1, ...)     ,n1 FUNC_ARGS6(__VA_ARGS__)
-#define FUNC_ARGS8(t1, n1, ...)     ,n1 FUNC_ARGS7(__VA_ARGS__)
-#define FUNC_ARGS9(t1, n1, ...)     ,n1 FUNC_ARGS8(__VA_ARGS__)
-#define FUNC_ARGS10(t1, n1, ...)     ,n1 FUNC_ARGS9(__VA_ARGS__)
+#define FUNC_ARGS1(t1, n1, ...)         n1
+#define FUNC_ARGS2(t1, n1, ...)         n1, FUNC_ARGS1(__VA_ARGS__)
+#define FUNC_ARGS3(t1, n1, ...)         n1, FUNC_ARGS2(__VA_ARGS__)
+#define FUNC_ARGS4(t1, n1, ...)         n1, FUNC_ARGS3(__VA_ARGS__)
+#define FUNC_ARGS5(t1, n1, ...)         n1, FUNC_ARGS4(__VA_ARGS__)
+#define FUNC_ARGS6(t1, n1, ...)         n1, FUNC_ARGS5(__VA_ARGS__)
+#define FUNC_ARGS7(t1, n1, ...)         n1, FUNC_ARGS6(__VA_ARGS__)
+#define FUNC_ARGS8(t1, n1, ...)         n1, FUNC_ARGS7(__VA_ARGS__)
+#define FUNC_ARGS9(t1, n1, ...)         n1, FUNC_ARGS8(__VA_ARGS__)
+#define FUNC_ARGS10(t1, n1, ...)        n1, FUNC_ARGS9(__VA_ARGS__)
+#define FUNC_ARGS11(t1, n1, ...)        n1, FUNC_ARGS10(__VA_ARGS__)
+#define FUNC_ARGS12(t1, n1, ...)        n1, FUNC_ARGS11(__VA_ARGS__)
 
 #define FUNC_ARGS_VA0(...)              args
-#define FUNC_ARGS_VA1(t1, n1, ...)     ,n1, FUNC_ARGS_VA0(__VA_ARGS__)
-#define FUNC_ARGS_VA2(t1, n1, ...)     ,n1 FUNC_ARGS_VA1(__VA_ARGS__)
-#define FUNC_ARGS_VA3(t1, n1, ...)     ,n1 FUNC_ARGS_VA2(__VA_ARGS__)
-#define FUNC_ARGS_VA4(t1, n1, ...)     ,n1 FUNC_ARGS_VA3(__VA_ARGS__)
-#define FUNC_ARGS_VA5(t1, n1, ...)     ,n1 FUNC_ARGS_VA4(__VA_ARGS__)
-#define FUNC_ARGS_VA6(t1, n1, ...)     ,n1 FUNC_ARGS_VA5(__VA_ARGS__)
-#define FUNC_ARGS_VA7(t1, n1, ...)     ,n1 FUNC_ARGS_VA6(__VA_ARGS__)
-#define FUNC_ARGS_VA8(t1, n1, ...)     ,n1 FUNC_ARGS_VA7(__VA_ARGS__)
-#define FUNC_ARGS_VA9(t1, n1, ...)     ,n1 FUNC_ARGS_VA8(__VA_ARGS__)
-#define FUNC_ARGS_VA10(t1, n1, ...)     ,n1 FUNC_ARGS_VA9(__VA_ARGS__)
+#define FUNC_ARGS_VA1(t1, n1, ...)      n1, FUNC_ARGS_VA0(__VA_ARGS__)
+#define FUNC_ARGS_VA2(t1, n1, ...)      n1, FUNC_ARGS_VA1(__VA_ARGS__)
+#define FUNC_ARGS_VA3(t1, n1, ...)      n1, FUNC_ARGS_VA2(__VA_ARGS__)
+#define FUNC_ARGS_VA4(t1, n1, ...)      n1, FUNC_ARGS_VA3(__VA_ARGS__)
+#define FUNC_ARGS_VA5(t1, n1, ...)      n1, FUNC_ARGS_VA4(__VA_ARGS__)
+#define FUNC_ARGS_VA6(t1, n1, ...)      n1, FUNC_ARGS_VA5(__VA_ARGS__)
+#define FUNC_ARGS_VA7(t1, n1, ...)      n1, FUNC_ARGS_VA6(__VA_ARGS__)
+#define FUNC_ARGS_VA8(t1, n1, ...)      n1, FUNC_ARGS_VA7(__VA_ARGS__)
+#define FUNC_ARGS_VA9(t1, n1, ...)      n1, FUNC_ARGS_VA8(__VA_ARGS__)
+#define FUNC_ARGS_VA10(t1, n1, ...)     n1, FUNC_ARGS_VA9(__VA_ARGS__)
+#define FUNC_ARGS_VA11(t1, n1, ...)     n1, FUNC_ARGS_VA10(__VA_ARGS__)
+#define FUNC_ARGS_VA12(t1, n1, ...)     n1, FUNC_ARGS_VA11(__VA_ARGS__)
 
 #define FUNC_TA(...)          \
        CONCAT(FUNC_TA, N_ARG(__VA_ARGS__, C_SEQ_N())(__VA_ARGS__))
@@ -459,9 +474,9 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
        CONCAT(FUNC_ARGS_VA, N_ARG(__VA_ARGS__, C_SEQ_N())(__VA_ARGS__))
 #define N_ARG(...)                  ARG_N(__VA_ARGS__)
 #define ARG_N(_1n, _1t, _2n, _2t, _3n, _3t, _4n, _4t, _5n, _5t, _6n, _6t, _7n, \
-             _7t, _8n, _8t, _9n, _9t, _10n, _10t, N, ...) N
-#define C_SEQ_N() 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0
-#define C_SEQ_NV() 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 0
+             _7t, _8n, _8t, _9n, _9t, _10n, _10t, _11n, _11t, _12n, _12t, N, ...) N
+#define C_SEQ_N() 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0
+#define C_SEQ_NV() 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 0
 
 
 #define DEF_H(_ret_type, _func_name, ...)                                     \
@@ -502,13 +517,40 @@ do {                                                                             \
        __pd.call_type = _call_type;                                           \
        __pd.orig = __orig;                                                    \
        __pd.func = (void *)__orig;                                            \
+       __orig_func_p = (orig_t)__orig;                                        \
 } while (0)
 
-#define GOT_DECLARE_VARS                                                      \
+#define GOT_DECLARE(_ret_type, ...)                                           \
+       typedef _ret_type (*orig_t)(FUNC_TA(__VA_ARGS__));                     \
        unsigned long __caller;                                                \
        ElfW(Addr) __orig;                                                     \
+       orig_t __orig_func_p;                                                  \
        struct probe_data_t __pd
 
+#define GOT_RUN_RETURN(_func_name, ...)                                               \
+       if (is_in_handler())                                                   \
+               return __orig_func_p(FUNC_ARGS(__VA_ARGS__));                  \
+       else                                                                   \
+               return CONCAT(_func_name, _handler)(FUNC_ARGS(PASS_PTR(__pd),  \
+                                                               __VA_ARGS__))
+
+#define GOT_RUN_RETURN_VA(_ret_name, _varg_param, _func_name, ...)            \
+       va_start(args, _varg_param);                                           \
+       if (is_in_handler())                                                   \
+               _ret_name = __orig_func_p(FUNC_ARGS(__VA_ARGS__));             \
+       else                                                                   \
+               _ret_name = CONCAT(_func_name, _handler)(FUNC_ARGS_VA(         \
+                                                               PASS_PTR(__pd),\
+                                                               __VA_ARGS__)); \
+       va_end(args)
+
+#define GOT_RUN_VOID(_func_name, ...)                                         \
+       if (is_in_handler())                                                   \
+               __orig_func_p(FUNC_ARGS(__VA_ARGS__));                         \
+       else                                                                   \
+               CONCAT(_func_name, _handler)(FUNC_ARGS(PASS_PTR(__pd),         \
+                                                      __VA_ARGS__))
+
 #define PRELOAD_PREPARE_TO_EXEC(_func_name)                                   \
 do {                                                                          \
        __func = dlsym(RTLD_DEFAULT, #_func_name);                             \
@@ -533,20 +575,18 @@ DEF_H(_ret_type, _func_name, __VA_ARGS__);                                       \
                                                                               \
 DEF_W(_ret_type, _func_name, __VA_ARGS__)                                     \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature, _func_name, INTERNAL_CALL);              \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       GOT_RUN_RETURN(_func_name, __VA_ARGS__);                               \
 }                                                                             \
                                                                               \
 DEF_WA(_ret_type, _func_name, __VA_ARGS__)                                    \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature ## _always, _func_name, EXTERNAL_CALL);   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       GOT_RUN_RETURN(_func_name, __VA_ARGS__);                               \
 }                                                                             \
                                                                               \
 /* Wrapper to be called from kernel. Takes ret type, func name and args */     \
@@ -555,8 +595,8 @@ DEF_WKC(_ret_type, _func_name, __VA_ARGS__)                                \
        PRELOAD_DECLARE_VARS;                                                  \
        PRELOAD_PREPARE_TO_EXEC(_func_name);                                   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       return CONCAT(_func_name, _handler)(FUNC_ARGS(PASS_PTR(__pd),          \
+                                                     __VA_ARGS__));           \
 }                                                                             \
                                                                               \
 DEF_H(_ret_type, _func_name, __VA_ARGS__)
@@ -566,20 +606,18 @@ DEF_H(_ret_type, _func_name, __VA_ARGS__);                                       \
                                                                               \
 DEF_W(_ret_type, _func_name, __VA_ARGS__)                                     \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature, _func_name, INTERNAL_CALL);              \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));           \
+       GOT_RUN_VOID(_func_name, __VA_ARGS__);                                 \
 }                                                                             \
                                                                               \
 DEF_WA(_ret_type, _func_name, __VA_ARGS__)                                    \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature ## _always, _func_name, EXTERNAL_CALL);   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));           \
+       GOT_RUN_VOID(_func_name, __VA_ARGS__);                                 \
 }                                                                             \
                                                                               \
 /* Wrapper to be called from kernel. Takes ret type, func name and args */     \
@@ -588,8 +626,7 @@ DEF_WKC(_ret_type, _func_name, __VA_ARGS__)                                \
        PRELOAD_DECLARE_VARS;                                                  \
        PRELOAD_PREPARE_TO_EXEC(_func_name);                                   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));           \
+       CONCAT(_func_name, _handler)(FUNC_ARGS(PASS_PTR(__pd), __VA_ARGS__));  \
 }                                                                             \
                                                                               \
 DEF_H(_ret_type, _func_name, __VA_ARGS__)
@@ -599,32 +636,24 @@ DEF_HVAR(_ret_type, _func_name, __VA_ARGS__);                                    \
                                                                               \
 DEF_WV(_ret_type, _func_name, __VA_ARGS__)                                    \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        va_list args;                                                          \
        _ret_type ret;                                                         \
                                                                               \
        GOT_PREPARE_TO_EXEC(_feature, _func_name, INTERNAL_CALL);              \
-                                                                              \
-       va_start(args, _varg_param);                                           \
-       /* It is important not to have comma before FUNC_ARGS_VA macro */      \
-       ret = CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS_VA(__VA_ARGS__));  \
-       va_end(args);                                                          \
+       GOT_RUN_RETURN_VA(ret, _varg_param, _func_name, __VA_ARGS__);          \
                                                                               \
        return ret;                                                            \
 }                                                                             \
                                                                               \
 DEF_WAV(_ret_type, _func_name, __VA_ARGS__)                                   \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        va_list args;                                                          \
        _ret_type ret;                                                         \
                                                                               \
        GOT_PREPARE_TO_EXEC(_feature ## _always, _func_name, EXTERNAL_CALL);   \
-                                                                              \
-       va_start(args, _varg_param);                                           \
-       /* It is important not to have comma before FUNC_ARGS_VA macro */      \
-       ret = CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS_VA(__VA_ARGS__));  \
-       va_end(args);                                                          \
+       GOT_RUN_RETURN_VA(ret, _varg_param, _func_name, __VA_ARGS__);          \
                                                                               \
        return ret;                                                            \
 }                                                                             \
@@ -638,8 +667,8 @@ DEF_WKCV(_ret_type, _func_name, __VA_ARGS__)                                       \
        PRELOAD_PREPARE_TO_EXEC(_func_name);                                   \
                                                                               \
        va_start(args, _varg_param);                                           \
-       /* It is important not to have comma before FUNC_ARGS_VA macro */      \
-       ret = CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS_VA(__VA_ARGS__));  \
+       ret = CONCAT(_func_name, _handler)(FUNC_ARGS_VA(PASS_PTR(__pd),        \
+                                                       __VA_ARGS__));         \
        va_end(args);                                                          \
                                                                               \
        return ret;                                                            \
@@ -652,20 +681,18 @@ DEF_H(_ret_type, _func_name, __VA_ARGS__) throw _throw;                          \
                                                                               \
 DEF_W(_ret_type, _func_name, __VA_ARGS__) throw _throw                        \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature, _func_name, INTERNAL_CALL);              \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       GOT_RUN_RETURN(_func_name, __VA_ARGS__);                               \
 }                                                                             \
                                                                               \
 DEF_WA(_ret_type, _func_name, __VA_ARGS__) throw _throw                               \
 {                                                                             \
-       GOT_DECLARE_VARS;                                                      \
+       GOT_DECLARE(_ret_type, __VA_ARGS__);                                   \
        GOT_PREPARE_TO_EXEC(_feature ## _always, _func_name, EXTERNAL_CALL);   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       GOT_RUN_RETURN(_func_name, __VA_ARGS__);                               \
 }                                                                             \
                                                                               \
 /* Wrapper to be called from kernel. Takes ret type, func name and args */     \
@@ -674,8 +701,8 @@ DEF_WKC(_ret_type, _func_name, __VA_ARGS__) throw _throw                   \
        PRELOAD_DECLARE_VARS;                                                  \
        PRELOAD_PREPARE_TO_EXEC(_func_name);                                   \
                                                                               \
-       /* It is important not to have comma before FUNC_ARGS macro */         \
-       return CONCAT(_func_name, _handler)(&__pd  FUNC_ARGS(__VA_ARGS__));    \
+       return CONCAT(_func_name, _handler)(FUNC_ARGS(PASS_PTR(__pd),          \
+                                                     __VA_ARGS__));           \
 }                                                                             \
                                                                               \
 DEF_H(_ret_type, _func_name, __VA_ARGS__) throw _throw
diff --git a/include/in_handler.h b/include/in_handler.h
new file mode 100644 (file)
index 0000000..b187c82
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  SWAP probe library
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Alexander Aksenov <a.aksenov@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __IN_HANDLER_H__
+#define __IN_HANDLER_H__
+
+void init_in_handler(void);
+void set_in_handler(void);
+void unset_in_handler(void);
+bool is_in_handler(void);
+
+#endif /* __IN_HANDLER_H__ */