Implement multiprobe 67/155267/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 12 Oct 2017 09:36:15 +0000 (12:36 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 12 Oct 2017 14:31:19 +0000 (17:31 +0300)
Change-Id: Ib2a0ef8a5961941686d1dbbc2c44ab46d2f62d1b
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
Makefile
helper/features_list.h
helper/got_patching.c
helper/multiprobe.cpp [new file with mode: 0644]
helper/multiprobe_helper.cpp [new file with mode: 0644]
helper/multiprobe_helper.h [new file with mode: 0644]
helper/multiprobe_impl.cpp [new file with mode: 0644]
helper/multiprobe_impl.h [new file with mode: 0644]
include/multiprobe.h [new file with mode: 0644]

index f93eb6e1aff0e37db3dc1b4e0357ba15b5382155..da2f033e346addcf700ca68fcedcad172c13f26c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+CPP := g++
+
 TIZEN_TARGET = da_probe_tizen.so
 PROBE_EVENT_TARGET = swap_probe_event.so
 PROBE_GRAPHICS_TARGET = swap_probe_graphics.so
@@ -97,8 +99,7 @@ CFLAGS+= -DPROBELIB_GRAPHICS=\"$(PROBELIB_GRAPHICS)\"
 CFLAGS+= -DPROBELIB_SCREENSHOT=\"$(PROBELIB_SCREENSHOT)\"
 CFLAGS+= -DPROBELIB_LSAN=\"$(PROBELIB_LSAN)\"
 CFLAGS+= -DPROBELIB_UIHV=\"$(PROBELIB_UIHV)\"
-CXXFLAGS = $(WARN_CFLAGS) -fPIC
-CPPFLAGS = $(INCLUDE_CPPFLAGS) -D_GNU_SOURCE
+CPPFLAGS = $(INCLUDE_CPPFLAGS) -D_GNU_SOURCE -fPIC
 
 TIZEN_LDFLAGS = -lstdc++
 
@@ -183,6 +184,11 @@ endif # TIZEN_FEATURE_WAYLAND
 
 TIZEN_SRCS =   $(COMMON_SRCS) \
                ./helper/common_probe_init.c
+TIZEN_SRCS_CPP = \
+       ./helper/multiprobe.cpp \
+       ./helper/multiprobe_impl.cpp \
+       ./helper/multiprobe_helper.cpp
+
 ## FIXME: new,delete and etc. operators not configured properly for SWAP-Preload
 #              ./probe_memory/libdanew.cpp
 
@@ -201,6 +207,10 @@ PROBE_UI_OBJS = $(patsubst %.cpp,%.o, $(patsubst %.c,%.o, $(PROBE_UI_SRCS)))
 PROBE_CAPI_OBJS = $(patsubst %.cpp,%.o, $(patsubst %.c,%.o, $(PROBE_CAPI_SRCS)))
 PROBE_SCREENSHOT_OBJS = $(patsubst %.cpp,%.o, $(patsubst %.c,%.o, $(PROBE_SCREENSHOT_SRCS)))
 
+TIZEN_OBJS_CPP := $(TIZEN_SRCS_CPP:.cpp=.o)
+.cpp.o:
+       $(CPP) $(CPPFLAGS) -std=c++0x -c -o $@ $<
+
 
 all:           tizen event graphics ui capi screenshot elfparser
 tizen:         headers $(TIZEN_TARGET)
@@ -255,7 +265,7 @@ $(GENERATED_HEADERS):
 
 $(TIZEN_TARGET): LDFLAGS+=$(TIZEN_LDFLAGS)
 $(TIZEN_TARGET): CPPFLAGS+=$(DEBUG_FLAGS)
-$(TIZEN_TARGET): $(TIZEN_OBJS)
+$(TIZEN_TARGET): $(TIZEN_OBJS) $(TIZEN_OBJS_CPP)
        $(CC) $(LDFLAGS) $^ -o $@
 
 PROBE_EVENT_LDFLAGS =   \
index 70def0f6a1a4a15812c8394b06a7e91671b3a83d..8e6d3423d4e2697249581e8f206c6f0cf16c0c53 100644 (file)
@@ -42,6 +42,7 @@ static const char probelib_uihv[] = PROBELIB_UIHV;
        X(FL_MEMORY_ALLOC_PROBING,         0,  memory_feature,           probelib_main) \
        X(FL_MEMORY_ALLOC_ALWAYS_PROBING,  0,  memory_feature_always,    probelib_main) \
        X(FL_ALWAYS_ON,                    0,  helper_feature,           probelib_main) \
+       X(FL_ALWAYS_ON,                    0,  multiprobe_helper_feature, probelib_main) \
        X(FL_ALWAYS_ON,                    0,  capi_feature,             probelib_capi) \
        X(FL_USER_EVENT,                   0,  event_feature,            probelib_event) \
        X(FL_FILE_API_PROBING,             0,  file_feature,             probelib_main) \
index c21e963824ea0227363796ffc4823bb6f21cde03..07003e56fb0b1610206e0a9fb5470f2229cb3e54 100644 (file)
@@ -18,6 +18,7 @@
 #include "probe_socket.h"
 #include "probe_thread.h"
 #include "probe_ui.h"
+#include "multiprobe_helper.h"
 
 #include "dahelper.h"
 #include "got_patching.h"
diff --git a/helper/multiprobe.cpp b/helper/multiprobe.cpp
new file mode 100644 (file)
index 0000000..f55ccd2
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 "multiprobe.h"
+#include "multiprobe_impl.h"
+
+
+static void *get_def_handler(const char *name)
+{
+    // dummy address
+    return reinterpret_cast<void *>(0xdead0000);
+}
+
+static MultiprobeImpl &get_impl()
+{
+    static MultiprobeImpl impl(get_def_handler);
+
+    return impl;
+}
+
+static void __attribute__((constructor)) ctor()
+{
+    // create 'impl' if one have not been created yet
+    get_impl();
+}
+
+
+void *multiprobe_pre_handler(void *handle)
+{
+    Probe *p = reinterpret_cast<Probe *>(handle);
+
+    for (Probe *next = Probe::get_next(p); next; next = Probe::get_next(next)) {
+        if (next->enable)
+            return next->handler;
+    }
+
+    // BUG!!!
+    return reinterpret_cast<void *>(0xdeadc0de);
+}
+
+void *multiprobe_reg(const char *name, void *handler, bool enable)
+{
+    Probe *p = get_impl().reg(name, handler, enable);
+
+    return reinterpret_cast<void *>(p);
+}
+
+void multiprobe_enable(void *handle)
+{
+    Probe *p = reinterpret_cast<Probe *>(handle);
+
+    p->enable = true;
+}
+
+void multiprobe_disable(void *handle)
+{
+    Probe *p = reinterpret_cast<Probe *>(handle);
+
+    p->enable = false;
+}
+
+void multiprobe_set_default_handler(const char *name, void *handler)
+{
+    get_impl().set_default_handler(name, handler);
+}
diff --git a/helper/multiprobe_helper.cpp b/helper/multiprobe_helper.cpp
new file mode 100644 (file)
index 0000000..df04336
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 "multiprobe_helper.h"
+#include <probeinfo.h>
+
+
+static struct probe_desc_t probes[] = {
+    // add probes describe
+};
+
+struct feature_desc_t multiprobe_helper_feature = {
+    .feature = (enum feature_code_0)0xffffffff,  /* Always feature */
+    .cnt = sizeof(probes) / sizeof(probes[0]),
+    .probes = probes,
+};
diff --git a/helper/multiprobe_helper.h b/helper/multiprobe_helper.h
new file mode 100644 (file)
index 0000000..18a6ddb
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 MULTIPROBE_HELPER_H
+#define MULTIPROBE_HELPER_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct feature_desc_t multiprobe_helper_feature;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MULTIPROBE_HELPER_H */
diff --git a/helper/multiprobe_impl.cpp b/helper/multiprobe_impl.cpp
new file mode 100644 (file)
index 0000000..ca7e358
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 "multiprobe_impl.h"
+
+
+MultiprobeImpl::MultiprobeImpl(get_default_handler_t handler) :
+    get_default_handler_(handler)
+{
+}
+
+MultiprobeImpl::~MultiprobeImpl()
+{
+    for (auto &it: map_) {
+        Probe *p = it.second;
+
+        // remobe list
+        for (Probe *next = Probe::get_next(p); next; next = Probe::get_next(p)) {
+            Probe::remove(next);
+            delete next;
+        }
+
+        Probe::remove(p);
+        delete p;
+    }
+}
+
+Probe *MultiprobeImpl::reg(const std::string &name, void *handler, bool enable)
+{
+    Probe *new_probe = new Probe(name, handler, enable);
+    auto it = map_.find(name);
+
+    if (it == map_.end()) {
+        void *orig_handler = get_default_handler_(name.c_str());
+        if (!orig_handler) {
+            delete new_probe;
+            return nullptr;
+        }
+
+        Probe *orig_probe = new Probe(name, orig_handler, true);
+        it = map_.insert(Map::value_type(name, orig_probe)).first;
+    }
+
+    Probe *old_probe = it->second;
+    Probe::insert(old_probe, new_probe);
+    it->second = new_probe;
+
+    return new_probe;
+}
+
+void MultiprobeImpl::unreg(Probe *probe)
+{
+    auto it = map_.find(probe->name);
+    assert(it != map_.end());
+
+    Probe::remove(probe);
+    delete probe;
+
+    Probe *first_probe = it->second;
+
+    // remove 'it' if 'probe' is last one
+    if (Probe::get_next(first_probe)) {
+        delete first_probe;
+        map_.erase(it);
+    }
+}
+
+void MultiprobeImpl::set_default_handler(const std::string &name, void *handler)
+{
+    auto it = map_.find(name);
+
+    if (it == map_.end()) {
+        // set new default handler
+        Probe *orig_probe = new Probe(name, handler, true);
+        it = map_.insert(Map::value_type(name, orig_probe)).first;
+    } else {
+        // change default handler
+        Probe *last = Probe::get_last(it->second);
+        last->handler = handler;
+    }
+}
diff --git a/helper/multiprobe_impl.h b/helper/multiprobe_impl.h
new file mode 100644 (file)
index 0000000..46f69d9
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 MULTIPROBE_IMPL_H
+#define MULTIPROBE_IMPL_H
+
+
+#include <map>
+#include <list>
+#include <string>
+#include <cassert>
+
+
+struct Probe
+{
+    Probe(const std::string &n, void *h, bool e) :
+        enable(e),
+        name(n),
+        handler(h),
+        prev_(nullptr),
+        next_(nullptr)
+    {
+    }
+
+    ~Probe()
+    {
+        assert(!(prev_ || next_));
+    }
+
+    static void insert(Probe *prev, Probe *next)
+    {
+        prev->prev_ = next;
+        next->next_ = prev;
+    }
+
+    static void remove(Probe *p)
+    {
+        if (p->next_) {
+            p->next_->prev_ = p->prev_;
+            p->next_ = nullptr;
+        }
+
+        if (p->prev_) {
+            p->prev_->next_ = p->next_;
+            p->prev_ = nullptr;
+        }
+    }
+
+    static Probe *get_next(Probe *p)
+    {
+        return p->next_;
+    }
+
+    static Probe *get_last(Probe *p)
+    {
+        Probe *last = p;
+        for (; last->next_; last = last->next_)
+            ;/* skip probe */
+
+        return last;
+    }
+
+    bool enable;
+    std::string name;
+    void *handler;
+
+private:
+    Probe *prev_;
+    Probe *next_;
+};
+
+
+class MultiprobeImpl
+{
+public:
+    typedef void *(*get_default_handler_t)(const char *name);
+
+    MultiprobeImpl(get_default_handler_t handler);
+    ~MultiprobeImpl();
+
+    Probe *reg(const std::string &name, void *handler, bool enable);
+    void unreg(Probe *probe);
+
+    void set_default_handler(const std::string &name, void *handler);
+
+private:
+    get_default_handler_t get_default_handler_;
+
+    using Map = std::map<std::string, Probe *>;
+    Map map_;
+};
+
+
+#endif // MULTIPROBE_IMPL_H
diff --git a/include/multiprobe.h b/include/multiprobe.h
new file mode 100644 (file)
index 0000000..f0288e0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@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 MULTIPROBE_H
+#define MULTIPROBE_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MULTIPROBE_CALL(handle, func_t, ...) \
+    ((func_t)multiprobe_pre_handler(handle))(__VA_ARGS__)
+
+void *multiprobe_pre_handler(void *handle);
+
+
+void *multiprobe_reg(const char *name, void *handler, bool enable);
+void multiprobe_enable(void *handle);
+void multiprobe_disable(void *handle);
+void multiprobe_set_default_handler(const char *name, void *handler);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MULTIPROBE_H */