tizen 2.3 release tizen_2.3 submit/tizen_2.3/20150202.063934 tizen_2.3_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 31 Jan 2015 07:42:52 +0000 (16:42 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 31 Jan 2015 07:42:52 +0000 (16:42 +0900)
79 files changed:
AUTHOR [new file with mode: 0644]
COPYING [new file with mode: 0644]
LICENSE [new file with mode: 0644]
LICENSE.MIT [new file with mode: 0644]
Makefile [new file with mode: 0644]
NOTICE [new file with mode: 0644]
custom_chart/da_chart.c [new file with mode: 0755]
custom_chart/da_chart.h [new file with mode: 0755]
custom_chart/da_chart_dummy.c [new file with mode: 0755]
feature_tests/new_capi_appfw.cpp [new file with mode: 0644]
helper/addr-tizen.c [new file with mode: 0644]
helper/btsym.c [new file with mode: 0755]
helper/common_probe_init.c [new file with mode: 0644]
helper/da_call_original.S [new file with mode: 0644]
helper/dacapture.c [new file with mode: 0755]
helper/dacollection.c [new file with mode: 0755]
helper/daforkexec.c [new file with mode: 0644]
helper/daforkexec.h [new file with mode: 0644]
helper/dahelper.c [new file with mode: 0755]
helper/damaps.c [new file with mode: 0755]
helper/dastdout.c [new file with mode: 0644]
helper/dastdout.h [new file with mode: 0644]
helper/libdaprobe.c [new file with mode: 0755]
helper/private_link.h [new file with mode: 0644]
helper/real_functions.c [new file with mode: 0644]
include/binproto.h [new file with mode: 0644]
include/common_probe_init.h [new file with mode: 0644]
include/da_gl_api_func_list.h [new file with mode: 0644]
include/da_gles20.h [new file with mode: 0644]
include/dacollection.h [new file with mode: 0755]
include/daerror.h [new file with mode: 0755]
include/dahelper.h [new file with mode: 0755]
include/damaps.h [new file with mode: 0644]
include/daprobe.h [new file with mode: 0644]
include/dautil.h [new file with mode: 0644]
include/khash.h [new file with mode: 0755]
include/probeinfo.h [new file with mode: 0755]
include/real_functions.h [new file with mode: 0644]
include/tizen_probe.h [new file with mode: 0755]
packaging/dynamic-analysis-probe.changes [new file with mode: 0644]
packaging/swap-probe.spec [new file with mode: 0644]
probe_capi/capi_appfw.c [new file with mode: 0644]
probe_event/da_event.c [new file with mode: 0755]
probe_event/da_event.h [new file with mode: 0755]
probe_event/gesture.cpp [new file with mode: 0755]
probe_event/gesture.h [new file with mode: 0644]
probe_event/keytouch.c [new file with mode: 0755]
probe_event/orientation.c [new file with mode: 0644]
probe_file/da_io.h [new file with mode: 0755]
probe_file/da_io_posix.c [new file with mode: 0755]
probe_file/da_io_stdc.c [new file with mode: 0644]
probe_graphics/da_egl_native.cpp [new file with mode: 0644]
probe_graphics/da_egl_tizen.cpp [new file with mode: 0644]
probe_graphics/da_evas_gl.c [new file with mode: 0644]
probe_graphics/da_gl_api_init.c [new file with mode: 0644]
probe_graphics/da_gles20_native.cpp [new file with mode: 0644]
probe_graphics/da_gles20_tizen.cpp [new file with mode: 0644]
probe_memory/da_memory.h [new file with mode: 0644]
probe_memory/libdamemalloc.c [new file with mode: 0755]
probe_memory/libdamemmanage.c [new file with mode: 0644]
probe_memory/libdanew.cpp [new file with mode: 0644]
probe_socket/da_socket.h [new file with mode: 0644]
probe_socket/libdasocket.c [new file with mode: 0644]
probe_third/libdaemon.c [new file with mode: 0644]
probe_thread/da_sync.h [new file with mode: 0644]
probe_thread/da_thread.h [new file with mode: 0644]
probe_thread/libdasync.c [new file with mode: 0644]
probe_thread/libdathread.c [new file with mode: 0644]
probe_ui/capi_capture.c [new file with mode: 0755]
probe_ui/da_ui.h [new file with mode: 0755]
probe_ui/tizen_frameani.h [new file with mode: 0644]
probe_userfunc/libdauserfunc.c [new file with mode: 0755]
scripts/api_names.txt [new file with mode: 0644]
scripts/gen_api_config.sh [new file with mode: 0755]
scripts/gen_api_id_mapping_header.awk [new file with mode: 0644]
scripts/gen_api_id_mapping_header_list.awk [new file with mode: 0644]
scripts/gen_api_id_mapping_list.awk [new file with mode: 0644]
swap-probe.manifest [new file with mode: 0644]
test_preload.sh [new file with mode: 0644]

diff --git a/AUTHOR b/AUTHOR
new file mode 100644 (file)
index 0000000..c1560be
--- /dev/null
+++ b/AUTHOR
@@ -0,0 +1,9 @@
+Jaewon Lim <jaewon81.lim@samsung.com>
+Woojin Jung <woojin2.jung@samsung.com>
+Yeongtaik Byeon <yeongtaik.byeon@samsung.com>
+Jooyoul Lee <jy.exe.lee@samsung.com>
+Sanghyun Lee <sanghyunnim.lee@samsung.com>
+Juyoung Kim <j0.kim@samsung.com>
+HyunGoo Kang <hyungoo1.kang@samsung.com>
+Nikita Kalyazin <n.kalyazin@samsung.com>
+Anastasia Lyupa <a.lyupa@samsung.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..f961d73
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,2 @@
+include/khash.h LICENSE.MIT
+All other       LICENSE.LGPLv2.1
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..f7c046b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,503 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
diff --git a/LICENSE.MIT b/LICENSE.MIT
new file mode 100644 (file)
index 0000000..fb122a0
--- /dev/null
@@ -0,0 +1,19 @@
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..2b0cb5f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,174 @@
+INSTALLDIR = usr/lib
+
+## Since include directives do not impose additional dependencies, we can make
+## Makefile more clear, simply putting all includes we ever need in single
+## variable. Keep it alphabetic, please.
+DEBUG_FLAGS=                                   \
+#              -DSTDTOFILE                             \#
+
+INCLUDE_CPPFLAGS =                             \
+               -I./include                     \
+               -I./probe_thread                \
+               -I/usr/include/appfw            \
+               -I/usr/include/dbus-1.0         \
+               -I/usr/include/e_dbus-1         \
+               -I/usr/include/ecore-1          \
+               -I/usr/include/edje-1           \
+               -I/usr/include/eet-1            \
+               -I/usr/include/efreet-1         \
+               -I/usr/include/eina-1           \
+               -I/usr/include/eina-1/eina      \
+               -I/usr/include/elementary-1     \
+               -I/usr/include/ethumb-1         \
+               -I/usr/include/evas-1           \
+               -I/usr/include/pixman-1         \
+               -I/usr/include/system           \
+               -I/usr/include/capi-system-runtime-info \
+               -I/usr/include/vconf            \
+               -I/usr/lib/dbus-1.0/include     \
+
+WARN_CFLAGS =                          \
+               -Wall                   \
+               -funwind-tables         \
+               -fomit-frame-pointer    \
+               -Xlinker                \
+               --no-undefined          \
+               -Werror                 \
+               -Wextra                 \
+               -O2                     \
+               -Wwrite-strings         \
+               -Wlogical-op            \
+               -Wpacked                \
+               -Winline                \
+               -Wno-psabi              \
+
+## Since linking unneeded libraries bloats output of ldd(1), this variable
+## holds search paths and common libraries.
+
+LDFLAGS = -shared      \
+       -lX11                           \
+       -lXext                          \
+       -lcapi-appfw-application        \
+       -lcapi-system-runtime-info      \
+       -ldl                            \
+       -lecore                         \
+       -lecore_input                   \
+       -lecore_x                       \
+       -leina                          \
+       -levas                          \
+       -lpthread                       \
+       -lrt                            \
+       -Wl,-z,noexecstack
+
+ASMFLAG = -O0 -g
+
+## FIXME: Ideally, UTILITY_SRCS is sources for probe infrastructure and
+## PROBE_SRCS is sources for actual replacement functions.  Unfortunatelly,
+## it is not so easy and UTILITY_SRCS do not link alone.
+
+COMMON_SRCS = $(UTILITY_SRCS) $(PROBE_SRCS)
+UTILITY_SRCS =                         \
+       ./helper/real_functions.c       \
+       ./helper/libdaprobe.c           \
+       ./helper/dahelper.c             \
+       ./helper/btsym.c                \
+       ./helper/dacollection.c         \
+       ./helper/dacapture.c            \
+       ./helper/daforkexec.c           \
+       ./helper/damaps.c                       \
+       ./helper/dastdout.c                     \
+       ./custom_chart/da_chart.c       \
+
+PROBE_SRCS =                                   \
+       ./probe_memory/libdamemalloc.c          \
+       ./probe_memory/libdamemmanage.c         \
+       ./probe_socket/libdasocket.c            \
+       ./probe_event/da_event.c                \
+       ./probe_event/keytouch.c                \
+       ./probe_event/orientation.c             \
+       ./probe_third/libdaemon.c               \
+       ./probe_thread/libdathread.c            \
+       ./probe_thread/libdasync.c              \
+       ./probe_userfunc/libdauserfunc.c        \
+       ./probe_file/da_io_posix.c              \
+       ./probe_file/da_io_stdc.c               \
+
+DUMMY_SRCS = ./custom_chart/da_chart_dummy.c
+CAPI_SRCS =    $(COMMON_SRCS)                  \
+               ./probe_capi/capi_appfw.c               \
+               ./probe_ui/capi_capture.c
+
+TIZEN_SRCS =   $(COMMON_SRCS) $(CAPI_SRCS)\
+               ./helper/addr-tizen.c                                           \
+               ./helper/common_probe_init.c                            \
+               ./probe_memory/libdanew.cpp                                     \
+               ./probe_graphics/da_evas_gl.c                           \
+               ./probe_graphics/da_gl_api_init.c                       \
+               ./probe_graphics/da_gles20_tizen.cpp                    \
+               ./probe_graphics/da_gles20_native.cpp
+
+ASM_SRC = ./helper/da_call_original.S
+
+## Totally brain-dead.
+## FIXME: Rewrite this normally with eval.
+ASM_OBJ = $(patsubst %.S,%.o, $(ASM_SRC))
+CAPI_OBJS = $(patsubst %.c,%.o, $(CAPI_SRCS)) $(ASM_OBJ)
+TIZEN_OBJS = $(patsubst %.cpp,%.o, $(patsubst %.c,%.o, $(TIZEN_SRCS))) $(ASM_OBJ)
+DUMMY_OBJS = $(patsubst %.c,%.o, $(DUMMY_SRCS))
+
+
+TIZEN_TARGET = da_probe_tizen.so
+DUMMY_TARGET = libdaprobe.so
+
+CPPFLAGS = $(INCLUDE_CPPFLAGS) -D_GNU_SOURCE -DSELF_LIB_NAME="\"/$(INSTALLDIR)/$(TIZEN_TARGET)\""
+CFLAGS = $(WARN_CFLAGS) -fPIC
+CXXFLAGS = $(WARN_CFLAGS) -fPIC
+
+TIZEN_CPPFLAGS = -DTIZENAPP $(SWAP_PROBE_DEFS)
+TIZEN_LDFLAGS = -lstdc++
+
+all:   capi tizen dummy
+tizen: headers $(TIZEN_TARGET)
+dummy: headers $(DUMMY_TARGET)
+
+$(ASM_OBJ): $(ASM_SRC)
+       $(CC) $(ASMFLAG) -c $^ -o $@
+
+GENERATED_CONFIG = include/api_config.h
+GENERATED_HEADERS = include/api_id_mapping.h include/api_id_list.h include/id_list
+headers: $(GENERATED_CONFIG) $(GENERATED_HEADERS)
+rmheaders:
+       rm -f $(GENERATED_CONFIG) $(GENERATED_HEADERS)
+
+$(GENERATED_CONFIG): ./scripts/gen_api_config.sh
+       sh $< > $@
+
+include/api_id_mapping.h: ./scripts/gen_api_id_mapping_header.awk
+include/api_id_list.h: ./scripts/gen_api_id_mapping_header_list.awk
+include/id_list: ./scripts/gen_api_id_mapping_list.awk
+
+da_api_map: $(GENERATED_HEADERS)
+
+$(GENERATED_HEADERS): APINAMES=scripts/api_names.txt
+$(GENERATED_HEADERS): ./scripts/api_names.txt
+$(GENERATED_HEADERS):
+       awk -f $< < $(APINAMES) > $@
+
+$(TIZEN_TARGET): LDFLAGS+=$(TIZEN_LDFLAGS)
+$(TIZEN_TARGET): CPPFLAGS+=$(TIZEN_CPPFLAGS)
+$(TIZEN_TARGET): CPPFLAGS+=$(DEBUG_FLAGS)
+$(TIZEN_TARGET): $(TIZEN_OBJS)
+       $(CC) $(LDFLAGS) $^ -o $@
+
+$(DUMMY_TARGET): $(DUMMY_OBJS)
+       $(CC) $(LDFLAGS) $^ -o $@
+
+install: all
+       [ -d "$(DESTDIR)/$(INSTALLDIR)" ] || mkdir -p $(DESTDIR)/$(INSTALLDIR)
+       install $(TIZEN_TARGET) $(DUMMY_TARGET) $(DESTDIR)/$(INSTALLDIR)/
+       install -m 644 include/id_list $(DESTDIR)/$(INSTALLDIR)/da_api_map
+
+clean:
+       rm -f *.so *.o $(GENERATED_HEADERS)
+
+.PHONY: all capi tizen dummy clean install headers
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..1f57476
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,9 @@
+Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Lesser GNU Public License , Version 2.1.
+Please, see the LICENSE.LGPLv2.1 file for Lesser General Public License terms and conditions.
+
+Several source codes may have its original copyright owner and/or
+be licensed under other than Lesser GNU Public License , Version 2.1, say, MIT License.
+Please, see copyright and license comments section in the header of each file,
+and the LICENSE.MIT file for MIT License terms and conditions.
+
diff --git a/custom_chart/da_chart.c b/custom_chart/da_chart.c
new file mode 100755 (executable)
index 0000000..78f80a7
--- /dev/null
@@ -0,0 +1,598 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <pthread.h>
+#include <signal.h>                    // for signal
+#include <unistd.h>                    // for ualarm, sleep
+#include <sys/timerfd.h>       // for timerfd
+#include <stdio.h>
+#include <errno.h>                     // for errno
+#include <string.h>                    // for memset
+#include <stdint.h>                    // for uint64_t
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "probeinfo.h"
+#define _USE_DA_
+#include "da_chart.h"
+
+#include "binproto.h"
+#include "real_functions.h"
+
+#define ERR_THREAD_CREATE_FAIL -2001   // thread creation fail
+
+#define MAX_TITLE_LENGTH               16
+#define MAX_CHART_HANDLE               10              // cannot be exceeded 10
+#define MAX_SERIES_PER_CHART   4               // cannot be exceeded 10
+// chart handle is  from 1 to 9
+// series handle is from 11 to 99
+// series handle 32 means that the series is 2nd series in 3rd chart.
+// zero value handle means error
+
+// =====================================================================
+// global variable
+// =====================================================================
+
+typedef struct _chart_interval_callback
+{
+       da_handle chart_handle;
+       da_handle series_handle;
+       da_user_data_2_chart_data callback;
+       void* user_data;
+       struct _chart_interval_callback* next;
+} chart_interval_callback;
+
+typedef struct
+{
+       int                     timerfd;
+       pthread_t       thread_handle;
+       chart_interval_callback*        callback_list;
+       pthread_mutex_t         list_mutex;
+} interval_manager;
+
+typedef struct
+{
+       int                     chart_handle_index;
+       int                     series_handle_index[MAX_CHART_HANDLE];
+       int                     interval_for_series[MAX_CHART_HANDLE][MAX_SERIES_PER_CHART];
+       interval_manager        interval_10ms;
+       interval_manager        interval_100ms;
+       interval_manager        interval_1s;
+} chart_handle_maintainer;
+
+chart_handle_maintainer chm;
+
+__thread pid_t cur_thread = -1;
+
+
+// =====================================================================
+// internal macro definition
+// =====================================================================
+
+#define DECLARE_CHART_VARIABLE                                 \
+       da_handle __attribute__((unused)) ret = 0;      \
+       probeInfo_t probeInfo;
+
+// =====================================================================
+// timer thread routine for callback
+// =====================================================================
+
+void* _chart_timerThread(void* data)
+{
+       DECLARE_CHART_VARIABLE;
+
+       uint64_t exp;
+       ssize_t readsize;
+       chart_interval_callback* cur;
+       float value;
+       sigset_t profsigmask;
+       interval_manager* pmanager = (interval_manager*)data;
+
+       probeBlockStart();
+
+       sigemptyset(&profsigmask);
+       sigaddset(&profsigmask, SIGPROF);
+       pthread_sigmask(SIG_BLOCK, &profsigmask, NULL);
+
+       while((readsize = read(pmanager->timerfd, &exp, sizeof(uint64_t))) > 0)
+       {
+               pthread_mutex_lock(&pmanager->list_mutex);
+
+               cur = pmanager->callback_list;
+               while(cur != NULL)
+               {
+                       value = cur->callback(cur->user_data);
+
+                       setProbePoint(&probeInfo);
+
+                       PREPARE_LOCAL_BUF();
+                       PACK_COMMON_BEGIN(MSG_PROBE_CUSTOM,
+                                         API_ID__chart_timerThread,
+                                         "", 0);
+                       PACK_COMMON_END('p', 0, 0, 2);
+                       PACK_CUSTOM(cur->series_handle, 0, "", 0, value);
+                       FLUSH_LOCAL_BUF();
+
+                       cur = cur->next;
+               }
+
+               pthread_mutex_unlock(&pmanager->list_mutex);
+
+               sleep(0);
+       }
+
+       probeBlockEnd();
+
+       return NULL;
+}
+
+static int start_callback_thread(chart_interval interval)
+{
+       int* timerfd = NULL;
+       pthread_t* thread_handle = NULL;
+       interval_manager* pman = NULL;
+       struct itimerspec timevalue;
+
+       if(interval == CHART_INTERVAL_10MSEC)
+       {
+               timerfd = &(chm.interval_10ms.timerfd);
+               thread_handle = &(chm.interval_10ms.thread_handle);
+               pman = &(chm.interval_10ms);
+               timevalue.it_value.tv_sec = 0;
+               timevalue.it_value.tv_nsec = 10000000L;
+               timevalue.it_interval.tv_sec = 0;
+               timevalue.it_interval.tv_nsec = 10000000L;
+       }
+       else if(interval == CHART_INTERVAL_100MSEC)
+       {
+               timerfd = &(chm.interval_100ms.timerfd);
+               thread_handle = &(chm.interval_100ms.thread_handle);
+               pman = &(chm.interval_100ms);
+               timevalue.it_value.tv_sec = 0;
+               timevalue.it_value.tv_nsec = 100000000L;
+               timevalue.it_interval.tv_sec = 0;
+               timevalue.it_interval.tv_nsec = 100000000L;
+       }
+       else if(interval == CHART_INTERVAL_1SEC)
+       {
+               timerfd = &(chm.interval_1s.timerfd);
+               thread_handle = &(chm.interval_1s.thread_handle);
+               pman = &(chm.interval_1s);
+               timevalue.it_value.tv_sec = 1;
+               timevalue.it_value.tv_nsec = 0;
+               timevalue.it_interval.tv_sec = 1;
+               timevalue.it_interval.tv_nsec = 0;
+       }
+       else
+       {
+               return ERR_WRONG_PARAMETER;
+       }
+
+       /**
+        * FIXME: Type of pthread_t is undefined.
+        * Comparing it with -1 is *very* bad
+        */
+       if (*timerfd != -1 || *thread_handle != (pthread_t) -1)
+               return 0;               // already thread exist
+
+       *timerfd = timerfd_create(CLOCK_REALTIME, 0);
+       if (*timerfd == -1)
+               return errno;
+
+       if (timerfd_settime(*timerfd, 0, &timevalue, NULL) == -1)
+               return errno;
+
+       if (pthread_create(thread_handle, NULL, _chart_timerThread, pman) < 0)
+               return ERR_THREAD_CREATE_FAIL;
+
+       return 0;
+}
+
+
+// =====================================================================
+// internal utility function
+// =====================================================================
+
+static void add_to_callback_list(chart_interval interval, da_handle charthandle, da_handle series_handle,
+               da_user_data_2_chart_data callback, void* user_data)
+{
+       chart_interval_callback* newelem;
+
+       newelem = (chart_interval_callback*)real_malloc(sizeof(chart_interval_callback));
+       newelem->chart_handle = charthandle;
+       newelem->series_handle = series_handle;
+       newelem->callback = callback;
+       newelem->user_data = user_data;
+
+       chm.interval_for_series[charthandle][series_handle % 10] = interval;
+
+       switch(interval)
+       {
+       case CHART_INTERVAL_10MSEC:
+               pthread_mutex_lock(&chm.interval_10ms.list_mutex);
+               newelem->next = chm.interval_10ms.callback_list;
+               chm.interval_10ms.callback_list = newelem;
+               pthread_mutex_unlock(&chm.interval_10ms.list_mutex);
+               __sync_add_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+               break;
+       case CHART_INTERVAL_100MSEC:
+               pthread_mutex_lock(&chm.interval_100ms.list_mutex);
+               newelem->next = chm.interval_100ms.callback_list;
+               chm.interval_100ms.callback_list = newelem;
+               pthread_mutex_unlock(&chm.interval_100ms.list_mutex);
+               __sync_add_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+               break;
+       case CHART_INTERVAL_1SEC:
+               pthread_mutex_lock(&chm.interval_1s.list_mutex);
+               newelem->next = chm.interval_1s.callback_list;
+               chm.interval_1s.callback_list = newelem;
+               pthread_mutex_unlock(&chm.interval_1s.list_mutex);
+               __sync_add_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+               break;
+       default:
+               free(newelem);
+               break;
+       }
+}
+
+static void remove_all_callback_list()
+{
+       chart_interval_callback* cur;
+
+       pthread_mutex_lock(&chm.interval_10ms.list_mutex);
+       while(chm.interval_10ms.callback_list != NULL)
+       {
+               cur = chm.interval_10ms.callback_list;
+               chm.interval_10ms.callback_list = cur->next;
+               free(cur);
+       }
+       pthread_mutex_unlock(&chm.interval_10ms.list_mutex);
+
+       pthread_mutex_lock(&chm.interval_100ms.list_mutex);
+       while(chm.interval_100ms.callback_list != NULL)
+       {
+               cur = chm.interval_100ms.callback_list;
+               chm.interval_100ms.callback_list = cur->next;
+               free(cur);
+       }
+       pthread_mutex_unlock(&chm.interval_100ms.list_mutex);
+
+       pthread_mutex_lock(&chm.interval_1s.list_mutex);
+       while(chm.interval_1s.callback_list != NULL)
+       {
+               cur = chm.interval_1s.callback_list;
+               chm.interval_1s.callback_list = cur->next;
+               free(cur);
+       }
+       pthread_mutex_unlock(&chm.interval_1s.list_mutex);
+
+       memset(&chm.interval_for_series, 0, sizeof(chm.interval_for_series));
+       __sync_and_and_fetch(&(gTraceInfo.custom_chart_callback_count), 0);
+}
+
+static void remove_from_callback_list(da_handle charthandle, da_handle series_handle)
+{
+       chart_interval_callback *prev, *cur;
+       chart_interval interval;
+
+       interval = chm.interval_for_series[charthandle][series_handle % 10];
+       chm.interval_for_series[charthandle][series_handle % 10] = 0;
+
+       switch(interval)
+       {
+       case CHART_INTERVAL_10MSEC:
+               pthread_mutex_lock(&chm.interval_10ms.list_mutex);
+
+               prev = NULL;
+               cur = chm.interval_10ms.callback_list;
+               while(cur != NULL)
+               {
+                       if(cur->chart_handle == charthandle && cur->series_handle == series_handle)
+                       {
+                               if(prev)
+                                       prev->next = cur->next;
+                               else
+                                       chm.interval_10ms.callback_list = cur->next;
+
+                               __sync_sub_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+                               free(cur);
+                               break;
+                       }
+
+                       prev = cur;
+                       cur = cur->next;
+               }
+
+               pthread_mutex_unlock(&chm.interval_10ms.list_mutex);
+               break;
+       case CHART_INTERVAL_100MSEC:
+               pthread_mutex_lock(&chm.interval_100ms.list_mutex);
+
+               prev = NULL;
+               cur = chm.interval_100ms.callback_list;
+               while(cur != NULL)
+               {
+                       if(cur->chart_handle == charthandle && cur->series_handle == series_handle)
+                       {
+                               if(prev)
+                                       prev->next = cur->next;
+                               else
+                                       chm.interval_100ms.callback_list = cur->next;
+
+                               __sync_sub_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+                               free(cur);
+                               break;
+                       }
+
+                       prev = cur;
+                       cur = cur->next;
+               }
+
+               pthread_mutex_unlock(&chm.interval_100ms.list_mutex);
+               break;
+       case CHART_INTERVAL_1SEC:
+               pthread_mutex_lock(&chm.interval_1s.list_mutex);
+
+               prev = NULL;
+               cur = chm.interval_1s.callback_list;
+               while(cur != NULL)
+               {
+                       if(cur->chart_handle == charthandle && cur->series_handle == series_handle)
+                       {
+                               if(prev)
+                                       prev->next = cur->next;
+                               else
+                                       chm.interval_1s.callback_list = cur->next;
+
+                               __sync_sub_and_fetch(&(gTraceInfo.custom_chart_callback_count), 1);
+                               free(cur);
+                               break;
+                       }
+
+                       prev = cur;
+                       cur = cur->next;
+               }
+
+               pthread_mutex_unlock(&chm.interval_1s.list_mutex);
+               break;
+       default:
+               break;
+       }
+}
+
+
+// =====================================================================
+// constructor and destructor functions
+// =====================================================================
+
+void __attribute__((constructor)) _init_lib()
+{
+       probeBlockStart();
+
+       memset(&chm, 0, sizeof(chm));
+       chm.interval_10ms.timerfd = -1;
+       chm.interval_100ms.timerfd = -1;
+       chm.interval_1s.timerfd = -1;
+       chm.interval_10ms.thread_handle = -1;
+       chm.interval_100ms.thread_handle = -1;
+       chm.interval_1s.thread_handle = -1;
+       pthread_mutex_init(&chm.interval_10ms.list_mutex, NULL);
+       pthread_mutex_init(&chm.interval_100ms.list_mutex, NULL);
+       pthread_mutex_init(&chm.interval_1s.list_mutex, NULL);
+
+       probeBlockEnd();
+}
+
+void __attribute__((destructor)) _fini_lib()
+{
+       probeBlockStart();
+
+       remove_all_callback_list();
+       if (chm.interval_10ms.timerfd != -1)
+               close(chm.interval_10ms.timerfd);
+       if (chm.interval_100ms.timerfd != -1)
+               close(chm.interval_100ms.timerfd);
+       if (chm.interval_1s.timerfd != -1)
+               close(chm.interval_1s.timerfd);
+       /*! Bad. Ugly. Unportable */
+       if (chm.interval_10ms.thread_handle != (pthread_t) -1)
+               pthread_join(chm.interval_10ms.thread_handle, NULL);
+       if (chm.interval_100ms.thread_handle != (pthread_t) -1)
+               pthread_join(chm.interval_100ms.thread_handle, NULL);
+       if (chm.interval_1s.thread_handle != (pthread_t) -1)
+               pthread_join(chm.interval_1s.thread_handle, NULL);
+
+       probeBlockEnd();
+}
+
+
+// =====================================================================
+// api definition
+// =====================================================================
+
+void da_mark(chart_color color, char* mark_text)
+{
+       DECLARE_CHART_VARIABLE;
+
+       probeBlockStart();
+
+       setProbePoint(&probeInfo);
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_CUSTOM,
+                         API_ID_da_mark,
+                         "dp", color, voidp_to_uint64(mark_text));
+       PACK_COMMON_END('v', 0, 0, 2);
+       PACK_CUSTOM(0, 0, mark_text, color, 0.0f);
+       FLUSH_LOCAL_BUF();
+
+       probeBlockEnd();
+}
+
+da_handle da_create_chart(char* chart_name)
+{
+       DECLARE_CHART_VARIABLE;
+
+       // check if there is available chart handle slot
+       if(chm.chart_handle_index + 1 >= MAX_CHART_HANDLE)
+               return ERR_MAX_CHART_NUMBER;
+
+       // check if chart_name is null
+       if(chart_name == NULL)
+               return ERR_WRONG_PARAMETER;
+
+       probeBlockStart();
+       ret = ++(chm.chart_handle_index);
+
+       setProbePoint(&probeInfo);
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_CUSTOM,
+                         API_ID_da_create_chart,
+                         "p", voidp_to_uint64(chart_name));
+       PACK_COMMON_END('d', ret, 0, 2);
+       PACK_CUSTOM(0, 0, chart_name, 0, 0.0f);
+       FLUSH_LOCAL_BUF();
+
+       probeBlockEnd();
+
+       return ret;
+}
+
+da_handle da_create_series(da_handle charthandle, char* seriesname,
+               series_type type, chart_color color)
+{
+       DECLARE_CHART_VARIABLE;
+
+       // check if charthandle is valid handle or not
+       if(charthandle <= 0 || charthandle > chm.chart_handle_index)
+               return ERR_WRONG_HANDLE;
+
+       // chech if extra parameter is valid
+       if(seriesname == NULL)
+               return ERR_WRONG_PARAMETER;
+
+       // check if there is available series spot
+       if(chm.series_handle_index[(int)charthandle] + 1 >= MAX_SERIES_PER_CHART)
+               return ERR_MAX_CHART_NUMBER;
+
+       probeBlockStart();
+       ret = ++(chm.series_handle_index[charthandle]);
+       ret += (10 * charthandle);
+
+       setProbePoint(&probeInfo);
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_CUSTOM,
+                         API_ID_da_create_series,
+                         "dpdd",  charthandle, voidp_to_uint64(seriesname),
+                         type, color);
+       PACK_COMMON_END('d', ret, 0, 2);
+       PACK_CUSTOM(charthandle, type, seriesname, color, 0.0f);
+       FLUSH_LOCAL_BUF();
+
+       probeBlockEnd();
+
+       return ret;
+}
+
+da_handle da_create_default_series(da_handle charthandle, char* seriesname)
+{
+       return da_create_series(charthandle, seriesname,
+                       CHART_TYPE_AUTO, CHART_COLOR_AUTO);
+}
+
+int da_set_callback(da_handle series_handle, da_user_data_2_chart_data callback,
+               void* data_addr, chart_interval interval)
+{
+       int cindex, sindex;
+       cindex = (int)(series_handle / 10);
+       sindex = series_handle % 10;
+
+       // check series handle
+       if(cindex <= 0 || cindex > chm.chart_handle_index)
+               return ERR_WRONG_HANDLE;
+
+       if(sindex > chm.series_handle_index[(int)cindex])
+               return ERR_WRONG_HANDLE;
+
+       // check rest parameters
+       if(interval == CHART_NO_CYCLE && callback != NULL)
+               return ERR_WRONG_PARAMETER;
+
+       probeBlockStart();
+
+       // remove previously registered callback
+       remove_from_callback_list(cindex, series_handle);
+
+       // register new callback
+       if(callback != NULL)
+       {
+               int re;
+               add_to_callback_list(interval, cindex, series_handle, callback, data_addr);
+               re = start_callback_thread(interval);
+               PRINTMSG("start callback thread return %d\n", re);
+       }
+       probeBlockEnd();
+
+       return 0;
+}
+
+void da_log(da_handle series_handle, float uservalue)
+{
+       DECLARE_CHART_VARIABLE;
+
+       // chech if series handle is valid
+       int cindex, sindex;
+       cindex = (int)(series_handle / 10);
+       sindex = series_handle % 10;
+
+       if(cindex <= 0 || cindex > chm.chart_handle_index)
+               return;
+
+       if(sindex > chm.series_handle_index[(int)cindex])
+               return;
+
+       probeBlockStart();
+
+       setProbePoint(&probeInfo);
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_CUSTOM,
+                         API_ID_da_log,
+                         "df", series_handle, uservalue);
+       PACK_COMMON_END('v', 0, 0, 2);
+       PACK_CUSTOM(series_handle, 0, "", 0, uservalue);
+       FLUSH_LOCAL_BUF();
+
+       probeBlockEnd();
+}
diff --git a/custom_chart/da_chart.h b/custom_chart/da_chart.h
new file mode 100755 (executable)
index 0000000..93ff214
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __DA_CHART_H__
+#define __DA_CHART_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Error code
+#define ERR_MAX_CHART_NUMBER   -1001   // no more chart or series can be added
+#define ERR_WRONG_HANDLE               -1002   // chart or series handle is wrong handle
+#define ERR_WRONG_PARAMETER            -1003   // wrong parameter
+
+typedef enum
+{
+       CHART_TYPE_AUTO = 0,
+       CHART_TYPE_LINE = 1,
+       CHART_TYPE_BAR = 2,
+       CHART_TYPE_AREA = 3,
+       CHART_TYPE_STEP = 4
+} series_type;
+
+typedef enum
+{
+       CHART_COLOR_AUTO = 0,
+       CHART_COLOR_BLUE = 1,
+       CHART_COLOR_GREEN = 2,
+       CHART_COLOR_RED = 3,
+       CHART_COLOR_BROWN = 4,
+       CHART_COLOR_PURPLE = 5,
+       CHART_COLOR_NAVY = 6,
+       CHART_COLOR_CHOCOLATE = 7,
+       CHART_COLOR_INDIGO = 8,
+       CHART_COLOR_MAGENTA = 9,
+       CHART_COLOR_TEAL = 10
+} chart_color;
+
+typedef enum
+{
+       CHART_NO_CYCLE = 0,
+       CHART_INTERVAL_10MSEC = 1,
+       CHART_INTERVAL_100MSEC = 2,
+       CHART_INTERVAL_1SEC = 3
+} chart_interval;
+
+typedef int da_handle;
+typedef float (* da_user_data_2_chart_data) (void* data_addr);
+
+
+// api definition
+#ifdef _USE_DA_
+
+extern da_handle da_create_chart (char* chart_name);
+extern da_handle da_create_series (da_handle charthandle, char* seriesname,
+               series_type type, chart_color color);
+extern da_handle da_create_default_series (da_handle charthandle, char* seriesname);
+extern int da_set_callback (da_handle series_handle,   da_user_data_2_chart_data callback,
+               void* data_addr, chart_interval interval);
+extern void da_log (da_handle series_handle, float uservalue);
+
+
+extern void da_mark (chart_color color, char* mark_text);
+
+#else // _USE_DA_ (do not use da custom chart)
+
+#define da_create_chart(a)                                             0
+#define da_create_series(a, b, c, d)                   0
+#define da_create_default_series(a, b)                 0
+#define da_set_callback(a, b, c, d)                            0
+#define da_log(a, b)
+
+
+#define da_mark(color, text)
+
+#endif // _USE_DA_
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __DA_CHART_H__
diff --git a/custom_chart/da_chart_dummy.c b/custom_chart/da_chart_dummy.c
new file mode 100755 (executable)
index 0000000..7b709c2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#define _USE_DA_
+#include "da_chart.h"
+
+// =====================================================================
+// api definition
+// =====================================================================
+#define __unused __attribute__((unused))
+void da_mark(chart_color __unused color, char __unused * mark_text)
+{
+
+}
+
+da_handle da_create_chart(char __unused * chart_name)
+{
+       return 0;
+}
+
+da_handle da_create_series(da_handle __unused charthandle,
+                          char __unused * seriesname,
+                          series_type __unused type,
+                          chart_color __unused color)
+{
+       return 0;
+}
+
+da_handle da_create_default_series(da_handle __unused charthandle,
+                                  char __unused * seriesname)
+{
+       return 0;
+}
+
+int da_set_callback(da_handle __unused series_handle,
+                   da_user_data_2_chart_data __unused callback,
+                   void __unused * data_addr,
+                   chart_interval __unused interval)
+{
+       return 0;
+}
+
+void da_log(da_handle __unused series_handle, float __unused uservalue)
+{
+}
diff --git a/feature_tests/new_capi_appfw.cpp b/feature_tests/new_capi_appfw.cpp
new file mode 100644 (file)
index 0000000..549cc9e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vasily Ulyanov <v.ulyanov@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
+ *
+ * Description:
+ *   Test app for checking capi_appfw version. The new one has app_control_h
+ *   type defined instead of service_h
+ *
+ */
+
+#include <app.h>
+
+int main(int argc, char *argv[])
+{
+       app_control_h __attribute__((unused)) handle;
+
+       return 0;
+}
diff --git a/helper/addr-tizen.c b/helper/addr-tizen.c
new file mode 100644 (file)
index 0000000..dabe6c5
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <dlfcn.h>
+#include "daprobe.h"
+#include "dahelper.h"
+
+int get_map_address(void* sym, void** start, void** end);
+
+int getExecutableMappingAddress()
+{
+       int ret = 0, i = 0;
+       void *main_symbol;
+       static const char *funcs[] = {"OspMain", "main"};
+
+       probeBlockStart();
+       for (i = 0; i < (int)(sizeof(funcs)/sizeof(funcs[0])); i++){
+               main_symbol = dlsym(RTLD_NEXT, funcs[i]);
+               if(main_symbol != NULL) {
+                       ret = get_map_address(main_symbol, &(gTraceInfo.exec_map.map_start),
+                                                       &(gTraceInfo.exec_map.map_end));
+                       break;
+               }
+       }
+       probeBlockEnd();
+
+       return ret;
+}
diff --git a/helper/btsym.c b/helper/btsym.c
new file mode 100755 (executable)
index 0000000..95f01e7
--- /dev/null
@@ -0,0 +1,481 @@
+/* Return list with names for address in backtrace.
+   Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+/*
+2011-12-15 Jaewon Lim <jaewon81.lim@samsung.com> add hashing for symbols
+
+2011-12-08 Jaewon Lim <jaewon81.lim@samsung.com> get symbol data from binary's symtab when dladdr cannot resolve symbol
+*/
+
+#include <assert.h>            // for assert
+#include <stdio.h>             // for printf, sprintf
+#include <stdlib.h>            // for malloc
+#include <string.h>            // for strlen
+#include <stddef.h>            // for ptrdiff_t
+#include <errno.h>             // for program_invocation_name
+
+#include <sys/types.h> // for open, fstat
+#include <sys/stat.h>  // for open, fstat
+#include <fcntl.h>             // for open
+#include <unistd.h>            // for fstat
+#include <sys/mman.h>  // for mmap, munmap
+
+#include "private_link.h"              // for link_map, ElfW
+#include "dahelper.h"
+#include "dacollection.h"
+
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assyme 64bits.  */
+# define WORD_WIDTH 16
+#endif
+
+#define FILEPATH_MAX 1024
+
+/* We use this macro to refer to ELF types independent of the native wordsize.
+   'ElfW(TYPE)' is used in place of 'Elf32_TYPE' or 'Elf64_TYPE'.  */
+#define ELFW(type)  _ElfW (ELF, __ELF_NATIVE_CLASS, type)
+
+/* Result of the lookup functions and how to retrieve the base address.  */
+typedef struct link_map *lookup_t;
+#define LOOKUP_VALUE(map) map
+#define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0)
+
+/* On some architectures a pointer to a function is not just a pointer
+   to the actual code of the function but rather an architecture
+   specific descriptor. */
+#ifndef ELF_FUNCTION_PTR_IS_SPECIAL
+# define DL_SYMBOL_ADDRESS(map, ref) \
+       (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
+# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
+# define DL_DT_INIT_ADDRESS(map, start) (start)
+# define DL_DT_FINI_ADDRESS(map, start) (start)
+#endif
+
+/* On some architectures dladdr can't use st_size of all symbols this way.  */
+#define DL_ADDR_SYM_MATCH(L, SYM, ADDR) \
+       (((ADDR) >= (L)->l_addr + (SYM)->st_value)              \
+               && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0)       \
+                       && ((ADDR) == (L)->l_addr + (SYM)->st_value))         \
+                       || ((ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size)))
+
+// start of implementation by Jaewon Lim
+struct _symdata
+{
+       ElfW(Shdr)      symhdr;
+       ElfW(Shdr)      strhdr;
+       ElfW(Sym)*      symtab;
+       char*           strtab;
+};
+
+typedef struct _symdata symdata_t;
+
+// get symbol data from file binary
+static symdata_t* _get_symboldata(char* filepath)
+{
+       int fd;
+       struct stat st;
+       char *contents;
+       symdata_t* pdata;
+
+       // first find in glist
+       pdata = (symdata_t*)find_glist(filepath);
+       if(pdata != NULL)
+       {
+               return pdata;
+       }
+
+       fd = open(filepath, O_RDONLY | O_CLOEXEC);
+       if(fd == -1)
+       {
+               return pdata;
+       }
+
+       if(fstat(fd, &st) == -1)
+       {
+               close(fd);
+               return pdata;
+       }
+
+       contents = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+       if(likely(contents != NULL))
+       {
+               ElfW(Ehdr) * elf_hdr = (ElfW(Ehdr) *)(contents);
+               ElfW(Shdr) * sec_hdr = (ElfW(Shdr) *)(contents + elf_hdr->e_shoff);
+               int i, symtab_idx = -1;
+
+               for (i = 0; i < elf_hdr->e_shnum; ++i)
+               {
+                       if(unlikely(sec_hdr[i].sh_type == SHT_SYMTAB))
+                       {
+                               symtab_idx = i;
+                               break;
+                       }
+               }
+
+               if(symtab_idx != -1)    //there is symbol table
+               {
+                       int strtab_idx = sec_hdr[symtab_idx].sh_link;
+                       if(likely((strtab_idx != 0) && (sec_hdr[strtab_idx].sh_type == SHT_STRTAB)))    // associated string table is valid
+                       {
+                               pdata = (symdata_t*)malloc(sizeof(symdata_t) +
+                                               sec_hdr[symtab_idx].sh_size +
+                                               sec_hdr[strtab_idx].sh_size);
+
+                               if(likely(pdata != NULL))
+                               {
+                                       memcpy(&(pdata->symhdr), &(sec_hdr[symtab_idx]), sizeof(ElfW(Shdr)));
+                                       memcpy(&(pdata->strhdr), &(sec_hdr[strtab_idx]), sizeof(ElfW(Shdr)));
+                                       pdata->symtab = (ElfW(Sym) *)(pdata + 1);
+                                       pdata->strtab = ((char*)pdata) + sizeof(symdata_t) + sec_hdr[symtab_idx].sh_size;
+                                       memcpy((void*)(pdata->symtab), (void*)(contents + sec_hdr[symtab_idx].sh_offset), sec_hdr[symtab_idx].sh_size);
+                                       memcpy((void*)(pdata->strtab), (void*)(contents + sec_hdr[strtab_idx].sh_offset), sec_hdr[strtab_idx].sh_size);
+
+                                       if(add_to_glist(filepath, (void*)pdata) == 0)   // fail to add
+                                       {
+                                               free(pdata);
+                                               pdata = NULL;
+                                       }
+                               }
+                       }
+               }
+
+               munmap((void*)contents, st.st_size);
+       }
+
+       close(fd);
+
+       return pdata;
+}
+
+int get_map_address(void* symbol, void** map_start, void** map_end)
+{
+       Dl_info info;
+       int status, ret = 0;
+       struct link_map* map = NULL;
+
+       status = dladdr1(symbol, &info, (void**)&map, RTLD_DL_LINKMAP);
+       if(status && map != NULL)
+       {
+               *map_start = (void*)(map->l_map_start);
+               *map_end = (void*)(map->l_map_end);
+               ret = 1;
+       }
+       else
+               ret = 0;
+
+       return ret;
+}
+
+// end of implementation by Jaewon Lim
+
+char** cached_backtrace_symbols (void* const* array, int size)
+{
+       Dl_info info[MAX_STACK_DEPTH];
+       int status[MAX_STACK_DEPTH];
+       char* chararr[MAX_STACK_DEPTH];
+       int cnt;
+       size_t total = 0;
+       char **result;
+       char* foundsym;
+
+       memset(chararr, 0, MAX_STACK_DEPTH * sizeof(char*));
+
+       /* Fill in the information we can get from `dladdr'.  */
+       for (cnt = 0; cnt < size; ++cnt)
+       {
+               struct link_map* map;
+
+               if(find_symbol_hash(array[cnt], &foundsym) <= 0)        // not found or error
+               {
+                       status[cnt] = dladdr1 (array[cnt], &info[cnt], (void**)&map, RTLD_DL_LINKMAP);
+                       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+                       {
+                               /* We have some info, compute the length of the string which will be
+                               "<file-name>(<sym-name>+offset) [address].  */
+                               total += (strlen (info[cnt].dli_fname ?: "")
+                                               + strlen (info[cnt].dli_sname ?: "")
+                                               + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+                               /* The load bias is more useful to the user than the load
+                               address.  The use of these addresses is to calculate an
+                               address in the ELF file, so its prelinked bias is not
+                               something we want to subtract out.  */
+                               info[cnt].dli_fbase = (void *) map->l_addr;
+                       }
+                       else
+                               total += 5 + WORD_WIDTH;
+               }
+               else            // there is a entry for key
+               {
+                       status[cnt] = 0;
+                       chararr[cnt] = foundsym;
+                       if(chararr[cnt] != NULL)
+                               total += (strlen(chararr[cnt]) + 1);
+                       else
+                       {
+                               // this never happened
+                               total += 100;
+                       }
+               }
+       }
+
+       /* Allocate memory for the result.  */
+       result = (char **) malloc (size * sizeof (char *) + total);
+       if (result != NULL)
+       {
+               char *last = (char *) (result + size);
+
+               for (cnt = 0; cnt < size; ++cnt)
+               {
+                       result[cnt] = last;
+
+                       if(chararr[cnt] != NULL)                // there is a cache
+                       {
+                               last += (1 + sprintf(last, "%s", chararr[cnt]));
+                       }
+                       else            // there is no cache
+                       {
+                               int tstrlen;
+                               if (status[cnt] && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
+                               {
+                                       // We found no symbol name to use, so describe it as relative to the file.
+                                       if (info[cnt].dli_sname == NULL)
+                                               info[cnt].dli_saddr = info[cnt].dli_fbase;
+
+                                       if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+                                       {
+                                               tstrlen = sprintf (last, "%s(%s) [%p]", info[cnt].dli_fname ?: "", info[cnt].dli_sname ?: "", array[cnt]);
+                                       }
+                                       else
+                                       {
+                                               char sign;
+                                               ptrdiff_t offset;
+                                               if (array[cnt] >= (void *) info[cnt].dli_saddr)
+                                               {
+                                                       sign = '+';
+                                                       offset = array[cnt] - info[cnt].dli_saddr;
+                                               }
+                                               else
+                                               {
+                                                       sign = '-';
+                                                       offset = info[cnt].dli_saddr - array[cnt];
+                                               }
+
+                                               tstrlen = sprintf (last, "%s(%s%c%#tx) [%p]",
+                                                               info[cnt].dli_fname ?: "",
+                                                               info[cnt].dli_sname ?: "",
+                                                               sign, offset, array[cnt]);
+                                       }
+                               }
+                               else
+                               {
+                                       tstrlen = sprintf (last, "[%p]", array[cnt]);
+                               }
+                               tstrlen++;
+
+                               add_symbol_hash(array[cnt], last, tstrlen);
+
+                               last += tstrlen;
+                       }
+               }
+
+               assert (last <= (char *) result + size * sizeof (char *) + total);
+       }
+       else            // fail to malloc
+       {
+               // do nothing
+       }
+
+       return result;
+}
+
+char** da_backtrace_symbols (void* const* array, int size)
+{
+       Dl_info info[MAX_STACK_DEPTH];
+       int status[MAX_STACK_DEPTH];
+       char* chararr[MAX_STACK_DEPTH];
+       int cnt;
+       size_t total = 0;
+       char **result;
+       char* foundsym;
+
+       memset(chararr, 0, MAX_STACK_DEPTH * sizeof(char*));
+
+       /* Fill in the information we can get from `dladdr'.  */
+       for (cnt = 0; cnt < size; ++cnt)
+       {
+               struct link_map* map;
+
+               if(find_symbol_hash(array[cnt], &foundsym) <= 0)        // not found or error
+               {
+                       status[cnt] = dladdr1 (array[cnt], &info[cnt], (void**)&map, RTLD_DL_LINKMAP);
+                       if(info[cnt].dli_sname == NULL)
+                       {
+                               char filepath[FILEPATH_MAX];    // for file path
+
+                               /* If this is the main program the information is incomplete.  */
+                               if (map->l_name[0] == '\0' && map->l_type == lt_executable)
+                               {
+                                       strncpy(filepath, program_invocation_name, FILEPATH_MAX - 1);
+                               }
+                               else
+                               {
+                                       int len;
+                                       if(map->l_origin)
+                                       {
+                                               strcpy(filepath, map->l_origin);
+                                               len = strlen(filepath);
+                                               if(len > 0 && filepath[len-1] != '/')
+                                               {
+                                                       filepath[len] = '/';
+                                                       filepath[len+1] = '\0';
+                                               }
+                                       }
+                                       else
+                                               filepath[0] = '\0';
+                                       strcat(filepath, map->l_name);
+                               }
+
+                               symdata_t* pdata = _get_symboldata(filepath);
+                               if(pdata != NULL)
+                               {
+                                       ElfW(Sym) * sym_ent = pdata->symtab;
+                                       char* strtab = pdata->strtab;
+                                       int i, num_syms = pdata->symhdr.sh_size / pdata->symhdr.sh_entsize;
+
+                                       for(i = 0; i < num_syms; ++i)
+                                       {
+                                               if (ELFW(ST_TYPE) (sym_ent[i].st_info) != STT_TLS
+                                                               && (sym_ent[i].st_shndx != SHN_UNDEF || sym_ent[i].st_value != 0)
+                                                               && DL_ADDR_SYM_MATCH (map, &(sym_ent[i]), DL_LOOKUP_ADDRESS (array[cnt]))
+                                                               && sym_ent[i].st_name < pdata->strhdr.sh_size)
+                                               {
+                                                       // We found a symbol close by.  Fill in its name and exact address.
+                                                       info[cnt].dli_sname = strtab + ((ElfW(Sym) *)(sym_ent + i))->st_name;
+                                                       info[cnt].dli_saddr = DL_SYMBOL_ADDRESS (map, ((ElfW(Sym) *)(sym_ent + i)));
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+                       {
+                               /* We have some info, compute the length of the string which will be
+                               "<file-name>(<sym-name>+offset) [address].  */
+                               total += (strlen (info[cnt].dli_fname ?: "")
+                                               + strlen (info[cnt].dli_sname ?: "")
+                                               + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+                               /* The load bias is more useful to the user than the load
+                               address.  The use of these addresses is to calculate an
+                               address in the ELF file, so its prelinked bias is not
+                               something we want to subtract out.  */
+//                             info[cnt].dli_fbase = (void *) map->l_addr;
+                       }
+                       else
+                               total += 5 + WORD_WIDTH;
+               }
+               else            // there is a entry for key
+               {
+                       chararr[cnt] = foundsym;
+                       if(chararr[cnt] != NULL)
+                               total += (strlen(chararr[cnt]) + 1);
+                       else
+                       {
+                               assert(false);
+                               total += 100;
+                       }
+               }
+       }
+
+       /* Allocate memory for the result.  */
+       result = (char **) malloc (size * sizeof (char *) + total);
+       if (result != NULL)
+       {
+               char *last = (char *) (result + size);
+
+               for (cnt = 0; cnt < size; ++cnt)
+               {
+                       result[cnt] = last;
+
+                       if(chararr[cnt] != NULL)                // there is a cache
+                       {
+                               last += (1 + sprintf(last, "%s", chararr[cnt]));
+                       }
+                       else            // there is no cache
+                       {
+                               int tstrlen;
+                               if (status[cnt] && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
+                               {
+                                       // We found no symbol name to use, so describe it as relative to the file.
+                                       if (info[cnt].dli_sname == NULL)
+                                               info[cnt].dli_saddr = info[cnt].dli_fbase;
+
+                                       if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+                                       {
+                                               tstrlen = sprintf (last, "%s(%s) [%p]", info[cnt].dli_fname ?: "", info[cnt].dli_sname ?: "", array[cnt]);
+                                       }
+                                       else
+                                       {
+                                               char sign;
+                                               ptrdiff_t offset;
+                                               if (array[cnt] >= (void *) info[cnt].dli_saddr)
+                                               {
+                                                       sign = '+';
+                                                       offset = array[cnt] - info[cnt].dli_saddr;
+                                               }
+                                               else
+                                               {
+                                                       sign = '-';
+                                                       offset = info[cnt].dli_saddr - array[cnt];
+                                               }
+
+                                               tstrlen = sprintf (last, "%s(%s%c%#tx) [%p]",
+                                                               info[cnt].dli_fname ?: "",
+                                                               info[cnt].dli_sname ?: "",
+                                                               sign, offset, array[cnt]);
+                                       }
+                               }
+                               else
+                               {
+                                       tstrlen = sprintf (last, "[%p]", array[cnt]);
+                               }
+                               tstrlen++;
+
+                               add_symbol_hash(array[cnt], last, tstrlen);
+
+                               last += tstrlen;
+                       }
+               }
+
+               assert (last <= (char *) result + size * sizeof (char *) + total);
+       }
+       else            // fail to malloc
+       {
+               // do nothing
+       }
+
+       return result;
+}
+
diff --git a/helper/common_probe_init.c b/helper/common_probe_init.c
new file mode 100644 (file)
index 0000000..4a94789
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <unistd.h>
+#include "da_gles20.h"
+#include "binproto.h"
+#include "common_probe_init.h"
+#include "real_functions.h"
+
+//#define EGL_TEST
+Evas_GL_API *__gl_api;
+void (*real_glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params);
+void (*real_glGetIntegerv)(GLenum pname, GLint * params);
+void (*real_glGetProgramiv)(GLuint program, GLenum pname, GLint *params);
+void (*real_glGetShaderiv)(GLuint shader, GLenum pname, GLint *params);
+void (*real_glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize,
+                              GLsizei *length, GLint *size, GLenum *type,
+                              char *name);
+void (*real_glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize,
+                               GLsizei *length, GLint *size, GLenum *type,
+                               char *name);
+void (*real_glGetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length,
+                              char *source);
+void (*real_glGetBufferParameteriv)(GLenum target, GLenum value, GLint *data);
+
+void __gl_dummy_function()
+{
+       PRINTERR("call of dummy gl function!!!");
+}
+
+void set_real_func(const char *func_name, void **func_pointer,
+                  ORIGINAL_LIBRARY id)
+{
+       void *faddr;
+       void *_id;
+
+       if (lib_handle[id] == NULL)
+               lib_handle[id] = dlopen(lib_string[id], RTLD_LAZY);
+
+       _id = lib_handle[id];
+
+       if (_id == NULL)
+               probe_terminate_with_err("dlopen failed", func_name, id);
+
+       faddr = dlsym(_id, func_name);
+       if (faddr == NULL || dlerror() != NULL) {
+               PRINTWRN("[set_real_function] function <%s> not found in lib <%s>; dummy function will be seted",
+                        func_name, lib_string[id]);
+               faddr = __gl_dummy_function;
+       }
+
+       memcpy(func_pointer, &faddr, sizeof(faddr));
+}
+
+#define INIT_REAL_GL(func)\
+       do {                                                                    \
+                set_real_func(#func, (void **)&real##_##func, LIBGLES20);      \
+       } while (0)
+
+int __init_gl_functions__(void)
+{
+       /* init gl API */
+       __init_gl_api__();
+
+       /* init real call functions */
+       INIT_REAL_GL(glGetVertexAttribfv);
+       INIT_REAL_GL(glGetProgramiv);
+       INIT_REAL_GL(glGetShaderiv);
+       INIT_REAL_GL(glGetActiveAttrib);
+       INIT_REAL_GL(glGetActiveUniform);
+       INIT_REAL_GL(glGetShaderSource);
+       INIT_REAL_GL(glGetIntegerv);
+       INIT_REAL_GL(glGetBufferParameteriv);
+
+       return 0;
+}
+
+void probe_terminate_with_err(const char *msg, const char *func_name,
+                             ORIGINAL_LIBRARY id)
+{
+       char error_msg[1024];
+       const char *lib_name = "unknown";
+
+       if (id != LIB_NO && id < NUM_ORIGINAL_LIBRARY)
+               lib_name = lib_string[id];
+       snprintf(error_msg, sizeof(error_msg), "%s : [%s], %s\n", msg,
+                func_name, lib_name);
+       perror(error_msg);
+       PRINTERR(error_msg);
+       //wait for flush
+       sleep(1);
+       exit(0);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//egl init probe function
+//  params:
+//    func_name    - original function name for dlsym search
+//    func_pointer - original function pointer (return)
+//
+//  info
+//    search original function by name
+//    function have no return becouse on error it terminates main application
+#ifdef EGL_TEST
+
+void dummy()
+{
+       return;
+}
+
+void init_probe_egl(__attribute__ ((unused))const char *func_name, void **func_pointer,
+                   __attribute__ ((unused))ORIGINAL_LIBRARY id)
+{
+       PRINTMSG(func_name);
+       *func_pointer = (void *)dummy;
+}
+#else
+void init_probe_egl(const char *func_name, void **func_pointer,
+                   ORIGINAL_LIBRARY id)
+{
+       void *faddr = 0;
+
+       (gProbeBlockCount++);
+       if (lib_handle[id] == ((void *)0)) {
+               lib_handle[id] = dlopen(lib_string[id],
+                                       RTLD_LAZY | RTLD_GLOBAL);
+
+               if (lib_handle[id] == ((void *)0))
+                       probe_terminate_with_err("dlopen failed", func_name, id);
+       };
+       faddr = dlsym(lib_handle[id], func_name);
+       if (faddr == NULL || dlerror() != NULL)
+               probe_terminate_with_err("dlsym failed", func_name, id);
+       memcpy(func_pointer, &faddr, sizeof(faddr));
+       (gProbeBlockCount--);
+}
+#endif
+
+void init_probe_gl(const char *func_name, void **func_pointer,
+                  ORIGINAL_LIBRARY id, int blockresult, int32_t vAPI_ID)
+{
+       void *faddr;
+       probeInfo_t tempProbeInfo;
+
+       probeBlockStart();
+       if (lib_handle[id] == ((void *)0)) {
+               lib_handle[id] = dlopen(lib_string[id], RTLD_LAZY);
+               if (lib_handle[id] == ((void *)0))
+                       probe_terminate_with_err("dlopen failed", func_name,
+                                                id);
+
+               setProbePoint(&tempProbeInfo);
+               if (blockresult != 0) {
+                       /* get max value */
+                       char maxValString[64];
+                       GLint maxVal[2];
+                       real_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVal[0]);
+                       real_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
+                                          &maxVal[1]);
+                       snprintf(maxValString, sizeof(maxValString), "%d,%d", maxVal[0], maxVal[1]);
+                       PREPARE_LOCAL_BUF();
+                       PACK_COMMON_BEGIN(MSG_PROBE_GL, vAPI_ID, "", 0);
+                       PACK_COMMON_END('p', 1, 0, 0);
+                       PACK_GL_ADD(APITYPE_INIT, 0, maxValString);
+                       FLUSH_LOCAL_BUF();
+               }
+       }
+
+       faddr = dlsym(lib_handle[id], func_name);
+       if (faddr == NULL || dlerror() != NULL)
+               probe_terminate_with_err("function not found in lib", func_name,
+                                        id);
+
+       memcpy(func_pointer, &faddr, sizeof(faddr));
+       probeBlockEnd();
+}
diff --git a/helper/da_call_original.S b/helper/da_call_original.S
new file mode 100644 (file)
index 0000000..11119bc
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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
+ *
+ */
+
+/*
+ * function
+ *  <some ret type> _da_call_original(void *funcp, char *args[], int args_count);
+ *
+ *  arguments:
+ *     funcp       - function pointer address to call
+ *     args        - params array for function
+ *     args_count  - params count
+ *  return values:
+ *     depends on original function (funcp)
+ *
+ *  use this function to call original function with variable arguments count
+ *  in ld-preloaded probes
+ *
+ *  example:
+ *     #include <dlfcn.h>
+ *     #include <dlsym.h>
+ *
+ *     typedef int (*execl_type)(const char *path, const char *arg, ...);
+ *     static execl_type execl_real;
+ *     //....
+ *     //_da_call_original function prototype
+ *     int call_original(void *funcp, char *args[], int args_count);
+ *     //...
+ *     execl_real = (execl_type)dlsym(RTLD_NEXT , "execl");
+ *     //...
+ *     //probe execl
+ *     int execl(const char *path, const char *arg, ...)
+ *     {
+ *             int res = 0;
+ *             va_list ap;
+ *             int args_count = 0, i;
+ *
+ *             //additional argumets list terminates with NULL pointer on execl call
+ *             //calculate arguments count with terminate NULL
+ *             va_start(ap, arg);
+ *             do
+ *                     args_count++;
+ *             while (va_arg(ap, char *) != 0);
+ *             va_end(ap);
+ *
+ *             //add 2 for <path> and <arg> params
+ *             args_count += 2;
+ *
+ *             //create and fill args arras
+ *             char *all_args[args_count];
+ *
+ *             va_start(ap, arg);
+ *
+ *             all_args[0] = (char *)path;
+ *             all_args[1] = (char *)arg;
+ *             for (i = 2; i < args_count; i++)
+ *                     all_args[i] = va_arg(ap, char *);
+ *             //do something
+ *             //.....
+ *             //call original function
+ *             res = _da_call_original(&execl_real, all_args, args_count);
+ *             //do something
+ *             //......
+ *             return res;
+ *
+ *     }
+ *
+ *  this function is written in asm because there is no other way to prepare
+ *  variable count of arguments for original function call
+ */
+
+#define stack_size 0x40
+
+#if defined(__x86_64__)
+    /* x86 64-bit ----------------------------------------------- */
+
+.text
+.global _da_call_original
+.type _da_call_original, @function
+_da_call_original:
+       mov     $-1, %rax
+       ret
+#elif defined(__i386)
+
+.text
+.global _da_call_original
+.type _da_call_original, @function
+_da_call_original:
+       #save stack position
+       push %ebp
+       mov  %esp, %ebp
+
+       #create local stack
+       sub  $stack_size, %esp
+
+       #store registers
+       push %ebx
+       push %ecx
+       push %edx
+
+       #load args array pointer
+       movl 0xc(%ebp),%ecx
+       #load args_count
+       movl 0x10(%ebp), %ebx
+
+       #calculate stack size for original function call
+       #stack size = (args_count) * 4
+       shl  $2, %ebx
+       #create stack for original function call
+       sub  %ebx, %esp
+
+       #push all arguments to stack
+       #for (i = 0; i < args_count; i++) {
+       movl $0, %eax
+       jmp  for_i_cmp
+       for_i:
+               #args[i] -> stack
+               mov  (%ecx), %edx
+               mov  %edx, (%esp)
+               #stack++
+               add  $4, %esp
+               add  $4, %ecx
+               add  $4, %eax
+       for_i_cmp:
+       cmpl %ebx, %eax
+       jl   for_i
+       #}
+
+       #shift stack back
+       sub  %ebx, %esp
+
+       #call original function (funcp)
+       movl 8(%ebp), %eax
+       call *(%eax)
+       #now function result in %eax
+
+       #restore stack after call function
+       add  %ebx, %esp
+
+       #restore registers
+       pop  %edx
+       pop  %ecx
+       pop  %ebx
+
+       #restore local stack
+       add  $stack_size, %esp
+       #return
+       pop  %ebp
+       ret
+
+#elif defined(__arm__)
+.text
+.global _da_call_original
+.type _da_call_original, %function
+
+_da_call_original:
+       push {fp, lr, r5, r6, r7, r8}
+       #create local stack
+       add  fp, sp, #4
+       sub  sp, sp, #stack_size
+       #store params to stack
+       str  r0, [fp, #-12]
+       str  r1, [fp, #-16]
+       str  r2, [fp, #-20]
+
+       #load args array pointer
+       ldr  r5, [fp, #-16]
+       #load args_count
+       ldr  r6, [fp, #-20]
+
+       #calculate stack size for original function call
+       #stack size = (args_count) * 4
+       lsl  r6, r6, #2
+       #create stack for original function call
+       sub  sp, sp, r6
+       #first 4 params pass throw r0-r3
+       #so move stack to 4 words
+       sub  sp, sp, #16
+
+       #for (i = 4; i < arg; i++) {
+       mov  r7, #16
+       b    for_i_cmp
+       for_i:
+               #args[i] -> stack[i]
+               ldr  r8, [r5, r7]
+               str  r8, [sp, r7]
+               add  r7, r7, #4
+       for_i_cmp:
+       cmp  r7, r6
+       blt  for_i
+       #}
+
+       #move stack pointer back to 4 words
+       add  sp, sp, #16
+       #load first 4 args
+       ldr  r0, [r5, #0 ]
+       ldr  r1, [r5, #4 ]
+       ldr  r2, [r5, #8 ]
+       ldr  r3, [r5, #12]
+
+       #call original function (funcp)
+       ldr  r5, [fp, #-12]
+       ldr  r5, [r5]
+       blx  r5
+       #now function result in r0
+
+       #restore stack after original fincion call
+       add  sp, sp, r6
+
+       #local stack restore
+       add  sp, sp, #stack_size
+       #return
+       pop  {fp, pc, r5, r6, r7, r8}
+#endif
diff --git a/helper/dacapture.c b/helper/dacapture.c
new file mode 100755 (executable)
index 0000000..f363987
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+/*
+ * We refer to the Evas example source code with BSD
+ * (Evas/src/examples/evas-buffer-simple.c)
+ *
+ */
+
+#include <stdlib.h>            // for system
+#include <sys/types.h>         // for stat, getpid
+#include <sys/stat.h>          // fot stat, chmod
+#include <unistd.h>            // fot stat, getpid
+#include <sys/shm.h>           // for shmget, shmat
+#include <pthread.h>           // for mutex
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+#include <Ecore.h>
+#include <Evas.h>
+#include <Evas_Engine_Buffer.h>
+
+#include "real_functions.h"
+#include "daprobe.h"
+#include "dahelper.h"
+
+#include "binproto.h"
+
+#define MAX_HEIGHT     720
+#define CAPTURE_TIMEOUT                2.0
+
+typedef struct _screenshot_data
+{
+       XImage*                 ximage;
+       Display*                dpy;
+       XShmSegmentInfo x_shm_info;
+} screenshot_data;
+
+/*
+int convert_image(     void* srcbuf, void* dstbuf,
+                                       pixman_format_code_t src_format,
+                                       pixman_format_code_t dst_format,
+                                       int src_width, int src_height,
+                                       int dst_width, int dst_height,
+                                       int     rotate)
+{
+       pixman_image_t *   src_img;
+       pixman_image_t *   dst_img;
+       pixman_transform_t transform;
+
+       int                src_stride, dst_stride;
+       int                src_bpp;
+       int                dst_bpp;
+       pixman_op_t        op;
+       int                rotate_step;
+       int                ret = False;
+
+       return_val_if_fail (srcbuf != NULL, False);
+       return_val_if_fail (dstbuf != NULL, False);
+       return_val_if_fail (rotate <= 360 && rotate >= -360, False);
+
+       op = PIXMAN_OP_SRC;
+
+       src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
+       return_val_if_fail (src_bpp > 0, False);
+
+       dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
+       return_val_if_fail (dst_bpp > 0, False);
+
+       rotate_step = (rotate + 360) / 90 % 4;
+
+       src_stride = src_width * src_bpp;
+       dst_stride = dst_width * dst_bpp;
+
+       src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride);
+       dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride);
+
+       goto_if_fail (src_img != NULL, CANT_CONVERT);
+       goto_if_fail (dst_img != NULL, CANT_CONVERT);
+
+       pixman_transform_init_identity (&transform);
+
+       if (rotate_step > 0)
+       {
+               int c, s, tx = 0, ty = 0;
+               switch (rotate_step)
+               {
+               case 1:
+                       // 270 degrees
+                       c = 0;
+                       s = -pixman_fixed_1;
+                       ty = pixman_int_to_fixed (dst_width);
+                       break;
+               case 2:
+                       // 180 degrees
+                       c = -pixman_fixed_1;
+                       s = 0;
+                       tx = pixman_int_to_fixed (dst_width);
+                       ty = pixman_int_to_fixed (dst_height);
+                       break;
+               case 3:
+                       // 90 degrees
+                       c = 0;
+                       s = pixman_fixed_1;
+                       tx = pixman_int_to_fixed (dst_height);
+                       break;
+               default:
+                       // 0 degrees
+                       c = 0;
+                       s = 0;
+                       break;
+               }
+               pixman_transform_rotate (&transform, NULL, c, s);
+               pixman_transform_translate (&transform, NULL, tx, ty);
+       }
+
+       pixman_image_set_transform (src_img, &transform);
+
+       pixman_image_composite (op, src_img, NULL, dst_img,
+                               0, 0, 0, 0, 0, 0, dst_width, dst_height);
+
+       ret = True;
+
+CANT_CONVERT:
+       if (src_img)
+               pixman_image_unref (src_img);
+       if (dst_img)
+               pixman_image_unref (dst_img);
+
+       return ret;
+}
+*/
+
+static char* captureScreenShotX(int* pwidth, int* pheight, screenshot_data* sdata)
+{
+       Window                  root;
+//     Atom                    atom_rotation;
+
+       sdata->dpy = XOpenDisplay(NULL);
+       if(unlikely(sdata->dpy == NULL))
+       {
+               // XOpenDisplay failed!
+               return NULL;
+       }
+
+       *pwidth = DisplayWidth(sdata->dpy, DefaultScreen(sdata->dpy));
+       *pheight = DisplayHeight(sdata->dpy, DefaultScreen(sdata->dpy));
+
+       root = RootWindow(sdata->dpy, DefaultScreen(sdata->dpy));
+
+       sdata->ximage = XShmCreateImage(sdata->dpy, DefaultVisualOfScreen (DefaultScreenOfDisplay (sdata->dpy)), 24,
+                                       ZPixmap, NULL, &sdata->x_shm_info, (unsigned int)*pwidth, (unsigned int)*pheight);
+
+       if(sdata->ximage != NULL)
+       {
+               sdata->x_shm_info.shmid = shmget(IPC_PRIVATE, sdata->ximage->bytes_per_line * sdata->ximage->height, IPC_CREAT | 0777);
+               sdata->x_shm_info.shmaddr = sdata->ximage->data = shmat(sdata->x_shm_info.shmid, 0, 0);
+               sdata->x_shm_info.readOnly = False;
+
+               if(XShmAttach(sdata->dpy, &sdata->x_shm_info))
+               {
+                       if(XShmGetImage(sdata->dpy, root, sdata->ximage, 0, 0, AllPlanes))
+                       {
+                               XSync (sdata->dpy, False);
+                               return sdata->ximage->data;
+                       }
+                       else
+                       {
+                               ; // XShmGetImage failed !
+                       }
+
+                       XShmDetach (sdata->dpy, &sdata->x_shm_info);
+               }
+               else
+               {
+                       ; // XShmAttach failed !
+               }
+
+               shmdt (sdata->x_shm_info.shmaddr);
+               shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL);
+               XDestroyImage(sdata->ximage);
+               sdata->ximage = NULL;
+       }
+       else
+       {
+               ; // XShmCreateImage failed!
+       }
+
+       return NULL;
+}
+
+static void releaseScreenShotX(screenshot_data* sdata)
+{
+       if(sdata->ximage)
+       {
+               XShmDetach (sdata->dpy, &sdata->x_shm_info);
+               shmdt (sdata->x_shm_info.shmaddr);
+               shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL);
+               XDestroyImage(sdata->ximage);
+       }
+       else { }
+
+       if(sdata->dpy)
+       {
+               XCloseDisplay(sdata->dpy);
+       }
+}
+
+static Evas* create_canvas(int width, int height)
+{
+       Evas *canvas;
+       Evas_Engine_Info_Buffer *einfo;
+       int method;
+       void *pixels;
+
+       method = evas_render_method_lookup("buffer");
+       if (unlikely(method <= 0))
+       {
+               //fputs("ERROR: evas was not compiled with 'buffer' engine!\n", stderr);
+               return NULL;
+       }
+
+       canvas = evas_new();
+       if (unlikely(canvas == NULL))
+       {
+               //fputs("ERROR: could not instantiate new evas canvas.\n", stderr);
+               return NULL;
+       }
+
+       evas_output_method_set(canvas, method);
+       evas_output_size_set(canvas, width, height);
+       evas_output_viewport_set(canvas, 0, 0, width, height);
+
+       einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas);
+       if (unlikely(einfo == NULL))
+       {
+               //fputs("ERROR: could not get evas engine info!\n", stderr);
+               evas_free(canvas);
+               return NULL;
+       }
+
+       // ARGB32 is sizeof(int), that is 4 bytes, per pixel
+       pixels = real_malloc(width * height * sizeof(int));
+       if (unlikely(pixels == NULL)) {
+               //fputs("ERROR: could not allocate canvas pixels!\n", stderr);
+               evas_free(canvas);
+               return NULL;
+       }
+
+       einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+       einfo->info.dest_buffer = pixels;
+       einfo->info.dest_buffer_row_bytes = width * sizeof(int);
+       einfo->info.use_color_key = 0;
+       einfo->info.alpha_threshold = 0;
+       einfo->info.func.new_update_region = NULL;
+       einfo->info.func.free_update_region = NULL;
+
+       if (unlikely(evas_engine_info_set(canvas,(Evas_Engine_Info*)einfo) == EINA_FALSE)) {
+               PRINTMSG("ERROR: could not set evas engine info!\n");
+               evas_free(canvas);
+               return NULL;
+       }
+
+       return canvas;
+}
+
+static void destroy_canvas(Evas* canvas)
+{
+       Evas_Engine_Info_Buffer *einfo;
+
+       einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas);
+       if (unlikely(einfo == NULL))
+       {
+               //fputs("ERROR: could not get evas engine info!\n", stderr);
+               evas_free(canvas);
+               return;
+       }
+
+       free(einfo->info.dest_buffer);
+       evas_free(canvas);
+}
+
+int captureScreen()
+{
+       char dstpath[MAX_PATH_LENGTH];
+       char* scrimage;
+       int width, height;
+       Evas* ev = NULL;
+       Evas_Object* img;
+       screenshot_data sdata;
+       probeInfo_t     probeInfo;
+       int ret = 0;
+       static pthread_mutex_t captureScreenLock = PTHREAD_MUTEX_INITIALIZER;
+
+       pthread_mutex_lock(&captureScreenLock);
+
+       probeBlockStart();
+
+       setProbePoint(&probeInfo);
+       sdata.ximage = NULL;
+       scrimage = captureScreenShotX(&width, &height, &sdata);
+       if(scrimage != NULL)
+       {
+               ev = create_canvas(width, height);
+               if(likely(ev != NULL))
+               {
+                       snprintf(dstpath, sizeof(dstpath),
+                                SCREENSHOT_DIRECTORY "/%d_%d.png", getpid(),
+                                probeInfo.eventIndex);
+
+                       // make image buffer
+                       if((img = evas_object_image_add(ev)) != NULL)
+                       {
+                               //image buffer set
+                               evas_object_image_data_set(img, NULL);
+                               evas_object_image_size_set(img, width, height);
+                               evas_object_image_data_set(img, scrimage);
+
+                               // resize image
+                               if(height > MAX_HEIGHT)
+                               {
+                                       width = width * MAX_HEIGHT / height;
+                                       height = MAX_HEIGHT;
+                                       evas_object_resize(img, width, height);
+                                       evas_object_image_fill_set(img, 0, 0, width, height);
+                               }
+                               evas_object_image_data_update_add(img, 0, 0, width, height);
+
+                               //save file
+                               if(evas_object_image_save(img, dstpath, NULL, "compress=5") != 0)
+                               {
+                                       chmod(dstpath, 0777);
+
+                                       /* welcome to the hell */
+                                       log_t log;
+                                       PREPARE_LOCAL_BUF_THOUGH((char *)&log);
+
+                                       /* skip header */
+                                       LOCAL_BUF += offsetof(log_t, data);
+                                       /* pack screenshot name */
+                                       BUF_PTR = pack_string(LOCAL_BUF, dstpath); /* file name */
+                                       LOCAL_BUF = BUF_PTR;
+
+                                       /* pack probe */
+                                       PACK_COMMON_BEGIN(MSG_PROBE_SCREENSHOT, API_ID_captureScreen, "", 0);
+                                       PACK_COMMON_END('d', 0, 0, 0);
+                                       PACK_SCREENSHOT(dstpath, getOrientation());
+                                       SET_MSG_LEN();
+                                       log.length = GET_MSG_LEN() + MSG_LEN_OFFSET + strlen(dstpath) + 1;
+
+                                       /* send all message */
+                                       printLog(&log, MSG_IMAGE);
+                               }
+                               else
+                               {
+                                       // captureScreen : evas_object_image_save failed
+                                       ret = -1;
+                               }
+                       }
+                       else
+                       {
+                               // captureScreen : evas_object_image_add failed
+                               ret = -1;
+                       }
+               }
+               else
+               {
+                       // captureScreen : create canvas failed
+                       ret = -1;
+               }
+       }
+       else
+       {
+               // captureScreen : captureScreenShotX failed
+               ret = -1;
+       }
+
+       // release resources
+       releaseScreenShotX(&sdata);
+       if(ev)
+               destroy_canvas(ev);
+
+       probeBlockEnd();
+
+       pthread_mutex_unlock(&captureScreenLock);
+       return ret;
+}
+
+int initialize_screencapture()
+{
+       // remove all previous screenshot in dir
+//     remove_indir(SCREENSHOT_DIRECTORY);
+
+       // make screenshot directory
+//     mkdir(SCREENSHOT_DIRECTORY, 0777);
+
+       return 0;
+}
+
+int finalize_screencapture()
+{
+       return 0;
+}
+
+// =======================================================================
+// screen shot manipulation functions
+// =======================================================================
+
+static Eina_Bool _captureTimer(void __unused * data)
+{
+       probeBlockStart();
+       SCREENSHOT_TIMEOUT();
+       probeBlockEnd();
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+int activateCaptureTimer()
+{
+       ecore_timer_add(CAPTURE_TIMEOUT, _captureTimer, NULL);
+       return 0;
+}
+
+void _cb_render_post(void __unused * data, Evas __unused * e,
+                    void __unused * eventinfo)
+{
+       probeBlockStart();
+       SCREENSHOT_DONE();
+       probeBlockEnd();
+}
diff --git a/helper/dacollection.c b/helper/dacollection.c
new file mode 100755 (executable)
index 0000000..efff256
--- /dev/null
@@ -0,0 +1,838 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <assert.h>            // for assert
+#include <stdlib.h>            // for malloc, free
+#include <string.h>            // for strlen, strcpy
+#include <pthread.h>   // for pthread_mutex_t
+
+#include "dahelper.h"
+#include "daerror.h"
+#include "dacollection.h"
+
+// hash table variable
+__hashInfo _hashinfo =
+{
+       NULL,                                           // khash_t(symbol)*     symHash
+       PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t symHashMutex
+       NULL,                                           // khash_t(allocmap)*   memHash
+       PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t memHashMutex
+       NULL,                                           // khash_t(uiobject)*   uiobjHash
+       PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t      uiobjHashMutex
+       NULL,                                           // khash_t(object)*     objHash
+       PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t objHashMutex
+       NULL,                                           // khash_t(detector)*   dttHash
+       PTHREAD_MUTEX_INITIALIZER       // pthread_mutex_t dttHashMutex
+};
+
+// glist typedef and variable
+struct _element
+{
+       int             keylen;
+       char*   keystr;
+       void*   dataptr;
+       struct _element*        next;
+       struct _element*        prev;
+};
+
+typedef struct _element element_t;
+
+element_t* gsymbol_list = NULL;
+pthread_mutex_t glist_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// *********************************************************************************************
+// hash table related implemenation
+// *********************************************************************************************
+
+int initialize_hash_table()
+{
+       SYMBOLHASH_LOCK;
+       SYMBOLHASH = kh_init(symbol);
+       SYMBOLHASH_UNLOCK;
+
+       MEMORYHASH_LOCK;
+       MEMORYHASH = kh_init(allocmap);
+       MEMORYHASH_UNLOCK;
+
+       UIOBJECTHASH_LOCK;
+       UIOBJECTHASH = kh_init(uiobject);
+       UIOBJECTHASH_UNLOCK;
+
+       OBJECTHASH_LOCK;
+       OBJECTHASH = kh_init(object);
+       OBJECTHASH_UNLOCK;
+
+       DETECTORHASH_LOCK;
+       DETECTORHASH = kh_init(detector);
+       DETECTORHASH_UNLOCK;
+
+       return 0;
+}
+
+int finalize_hash_table()
+{
+       if (SYMBOLHASH)
+       {
+               khiter_t k;
+               char* val;
+
+               SYMBOLHASH_LOCK;
+               for(k = kh_begin(SYMBOLHASH); k != kh_end(SYMBOLHASH); k++)
+               {
+                       if (kh_exist(SYMBOLHASH, k))
+                       {
+                               val = kh_value(SYMBOLHASH, k);
+                               free(val);
+                       }
+               }
+               kh_destroy(symbol, SYMBOLHASH);
+               SYMBOLHASH = NULL;
+               SYMBOLHASH_UNLOCK;
+       }
+
+       if (MEMORYHASH)
+       {
+               MEMORYHASH_LOCK;
+               kh_destroy(allocmap, MEMORYHASH);
+               MEMORYHASH = NULL;
+               MEMORYHASH_UNLOCK;
+       }
+
+       if (UIOBJECTHASH)
+       {
+               khiter_t k;
+               _uiobjectinfo* val;
+
+               UIOBJECTHASH_LOCK;
+               for(k = kh_begin(UIOBJECTHASH); k != kh_end(UIOBJECTHASH); k++)
+               {
+                       if (kh_exist(UIOBJECTHASH, k))
+                       {
+                               val = kh_value(UIOBJECTHASH, k);
+                               if (likely(val->type != 0)) free(val->type);
+                               if (likely(val->name != 0)) free(val->name);
+                               free(val);
+                       }
+               }
+               kh_destroy(uiobject, UIOBJECTHASH);
+               UIOBJECTHASH = NULL;
+               UIOBJECTHASH_UNLOCK;
+       }
+
+       if (OBJECTHASH)
+       {
+               OBJECTHASH_LOCK;
+               kh_destroy(object, OBJECTHASH);
+               OBJECTHASH = NULL;
+               OBJECTHASH_UNLOCK;
+       }
+
+       if (DETECTORHASH)
+       {
+               DETECTORHASH_LOCK;
+               kh_destroy(detector, DETECTORHASH);
+               DETECTORHASH = NULL;
+               DETECTORHASH_UNLOCK;
+       }
+
+       return 0;
+}
+
+/***********************************************************
+ * symbol hash related functions
+ ***********************************************************/
+// return 0 if there is no entry in hash
+// return 1 if there is entry in hash
+// return negative value if error occurred
+int find_symbol_hash(void* ptr, char** psymbol)
+{
+       khiter_t k;
+       int ret = 0;
+
+       if (unlikely(SYMBOLHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(psymbol == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       SYMBOLHASH_LOCK;
+       k = kh_get(symbol, SYMBOLHASH, (uint32_t)ptr);
+       if (k == kh_end(SYMBOLHASH))            // there is no entry for key
+       {
+               ret = 0;
+       }
+       else
+       {
+               *psymbol = kh_value(SYMBOLHASH, k);
+               ret = 1;
+       }
+       SYMBOLHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if there is already exist in hash
+// return negative value if other error occurred
+int add_symbol_hash(void* ptr, const char* str, int strlen)
+{
+       khiter_t k;
+       int rethash, ret = 0;
+
+       if (unlikely(SYMBOLHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(str == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       SYMBOLHASH_LOCK;
+       k = kh_put(symbol, SYMBOLHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash != 0))       // succeed to add in hash table
+       {
+               char* tlast = (char*)real_malloc(strlen);
+               if (likely(tlast != NULL))
+               {
+                       memcpy(tlast, str, strlen);
+                       kh_value(SYMBOLHASH, k) = tlast;
+               }
+               else
+               {
+                       kh_del(symbol, SYMBOLHASH, k);
+                       ret = ERR_OUTOFMEMORY;
+               }
+       }
+       else
+       {
+               // TODO : error handling
+               ret = 1;
+       }
+       SYMBOLHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+/***********************************************************
+ * memory hash related functions
+ ***********************************************************/
+// return 0 if succeed
+// return 1 if key is already exist in hash table
+// return negative value if other error occurred
+int add_memory_hash(void* ptr, size_t size, unsigned short type, unsigned short caller)
+{
+       khiter_t k;
+       int rethash, ret = 0;
+       size_t memsize;
+       uint64_t meminfo;
+
+       if (unlikely(MEMORYHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+       MEMORYHASH_LOCK;
+       k = kh_put(allocmap, MEMORYHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash != 0))       // succeed to add in hash table
+       {
+               kh_value(MEMORYHASH, k) = MAKE_MEMINFO(caller, type, size);
+               update_heap_memory_size(true, size);
+       }
+       else
+       {
+               // key is already exist in hash
+               // update memory info
+               meminfo = kh_value(MEMORYHASH, k);
+               memsize = GET_MEMSIZE(meminfo);
+               if (memsize == size)
+               {
+                       kh_value(MEMORYHASH, k) = MAKE_MEMINFO(caller, type, size);
+               }
+               ret = 1;
+       }
+       MEMORYHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if key is not in hash table
+// return negative if other error occurred
+int del_memory_hash(void* ptr, unsigned short type, unsigned short* caller)
+{
+       khiter_t k;
+       int ret = 0;
+       uint32_t size;
+       uint64_t meminfo;
+
+       if (unlikely(MEMORYHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+       MEMORYHASH_LOCK;
+       k = kh_get(allocmap, MEMORYHASH, (uint32_t)ptr);
+       if (likely(k != kh_end(MEMORYHASH)))
+       {                               // there is entry in hash table
+               meminfo = kh_value(MEMORYHASH, k);
+               if (unlikely(type != GET_MEMTYPE(meminfo)))
+               {
+                       ret = -1;
+               }
+               else
+               {
+                       size = GET_MEMSIZE(meminfo);
+                       if (caller != NULL)
+                               *caller = GET_MEMCALLER(meminfo);
+                       update_heap_memory_size(false, size);
+                       kh_del(allocmap, MEMORYHASH, k);
+               }
+       }
+       else
+       {
+               ret = 1;        // there is not entry in hash table
+       }
+       MEMORYHASH_UNLOCK;
+       probeBlockEnd();
+
+       return ret;
+}
+
+/***********************************************************
+ * uiobject hash related functions
+ ***********************************************************/
+// return 0 if there is no entry in hash
+// return 1 if there is entry in hash
+// return negative value if error occurred
+int find_uiobject_hash(void* ptr, char** type, char** classname)
+{
+       khiter_t k;
+       int ret = 0;
+
+       if (unlikely(UIOBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(type == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(classname == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       UIOBJECTHASH_LOCK;
+       k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
+       if (unlikely(k == kh_end(UIOBJECTHASH)))                // there is no entry for key
+       {
+               ret = 0;
+       }
+       else
+       {
+               *classname = kh_value(UIOBJECTHASH, k)->name;
+               *type = kh_value(UIOBJECTHASH, k)->type;
+               ret = 1;
+       }
+       UIOBJECTHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if there is no entry in hash
+// return negative value if other error occurred
+int add_uiobject_hash_class(void* ptr, const char* classname)
+{
+       int str_len;
+       khiter_t k;
+       int rethash, ret = 0;
+
+       if (unlikely(UIOBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(classname == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       str_len = strlen(classname) + 1;
+
+       UIOBJECTHASH_LOCK;
+       k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash == 0))       // entry is already in hash table
+       {
+               if (likely(kh_value(UIOBJECTHASH, k) != NULL))
+               {
+                       if (kh_value(UIOBJECTHASH, k)->name == NULL)
+                       {
+                               char* tlast = (char*)real_malloc(str_len);
+                               if (likely(tlast != NULL))
+                               {
+                                       memcpy(tlast, classname, str_len);
+                                       kh_value(UIOBJECTHASH, k)->name = tlast;
+                               }
+                               else
+                               {
+                                       kh_value(UIOBJECTHASH, k)->name = NULL;
+                                       ret = ERR_OUTOFMEMORY;  // out of memory
+                               }
+                       }
+                       else
+                               ret = ERR_ALREADYEXIST;
+               }
+               else    // not possible
+                       ret = ERR_NOTEXIST;     // there is entry but there is no value
+       }
+       else    // error
+               ret = 1;        // there is no entry
+
+       UIOBJECTHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if there is already exist in hash
+// return negative value if other error occurred
+int add_uiobject_hash_type(void* ptr, const char* type)
+{
+       int str_len;
+       khiter_t k;
+       int rethash, ret = 0;
+
+       if (unlikely(UIOBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(type == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       str_len = strlen(type) + 1;
+
+       UIOBJECTHASH_LOCK;
+       k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash != 0))       // succeed to add in hash table
+       {
+               char* tlast;
+               _uiobjectinfo* newentry;
+
+               newentry = (_uiobjectinfo*)calloc(1, sizeof(_uiobjectinfo));
+               if (likely(newentry != NULL))
+               {
+                       kh_value(UIOBJECTHASH, k) = newentry;
+
+                       tlast = (char*)real_malloc(str_len);
+                       if (likely(tlast != NULL))
+                       {
+                               memcpy(tlast, type, str_len);
+                               kh_value(UIOBJECTHASH, k)->type = tlast;
+                       }
+                       else
+                       {
+                               kh_value(UIOBJECTHASH, k)->type = NULL;
+                               ret = ERR_OUTOFMEMORY;
+                       }
+               }
+               else
+               {
+                       kh_del(uiobject, UIOBJECTHASH, k);
+                       ret = ERR_OUTOFMEMORY;
+               }
+       }
+       else
+               ret = 1;
+
+       UIOBJECTHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if key is not in hash table
+// return negative value if other error occurred
+int del_uiobject_hash(void* ptr)
+{
+       khiter_t k;
+       _uiobjectinfo* val;
+       int ret = 0;
+
+       if (unlikely(UIOBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+       UIOBJECTHASH_LOCK;
+       k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
+       if (likely(k != kh_end(UIOBJECTHASH)))          // there is entry in hash table
+       {
+               val = kh_value(UIOBJECTHASH, k);
+               kh_del(uiobject, UIOBJECTHASH, k);
+               if (likely(val->type != NULL)) free(val->type);
+               if (likely(val->name != NULL)) free(val->name);
+               free(val);
+       }
+       else
+       {
+               ret = 1;
+       }
+       UIOBJECTHASH_UNLOCK;
+       probeBlockEnd();
+
+       return ret;
+}
+
+/***********************************************************
+ * object hash related functions
+ ***********************************************************/
+// return 0 if there is no entry in hash
+// return 1 if there is entry in hash
+// return negative value if error occurred
+int find_object_hash(void* ptr, unsigned short *caller)
+{
+       khiter_t k;
+       int ret = 0;
+
+       if (unlikely(OBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(caller == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       OBJECTHASH_LOCK;
+       k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
+       if (unlikely(k == kh_end(OBJECTHASH)))          // there is no entry for key
+       {
+               ret = 0;
+       }
+       else
+       {
+               *caller = kh_value(OBJECTHASH, k);
+               ret = 1;
+       }
+       OBJECTHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if there is no entry in hash
+// return negative value if other error occurred
+int add_object_hash(void* ptr, unsigned short caller)
+{
+       khiter_t k;
+       int rethash, ret = 0;
+
+       if (unlikely(OBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       OBJECTHASH_LOCK;
+       k = kh_put(object, OBJECTHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash != 0))       // entry is already in hash table
+       {
+               kh_value(OBJECTHASH, k) = caller;
+       }
+       else
+       {
+               // TODO : error handling
+               ret = 1;
+       }
+
+       OBJECTHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if key is not in hash table
+// return negative value if other error occurred
+int del_object_hash(void* ptr, unsigned short *caller)
+{
+       khiter_t k;
+       int ret = 0;
+
+       if (unlikely(OBJECTHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(caller == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       OBJECTHASH_LOCK;
+       k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
+       if (likely(k != kh_end(OBJECTHASH)))            // there is entry in hash table
+       {
+               *caller = kh_value(OBJECTHASH, k);
+               kh_del(object, OBJECTHASH, k);
+       }
+       else
+       {
+               ret = 1;
+       }
+       OBJECTHASH_UNLOCK;
+       probeBlockEnd();
+
+       return ret;
+}
+
+/***********************************************************
+ * detector hash related functions
+ ***********************************************************/
+// return 0 if succeed
+// return 1 if there is already exist in hash
+// return negative value if other error occurred
+int add_detector_hash(void* ptr, void* listener)
+{
+       khiter_t k;
+       int rethash, ret = 0;
+
+       if (unlikely(DETECTORHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       if (unlikely(listener == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+
+       DETECTORHASH_LOCK;
+       k = kh_put(detector, DETECTORHASH, (uint32_t)ptr, &rethash);
+       if (likely(rethash != 0))       // succeed to add in hash table
+       {
+               kh_value(DETECTORHASH, k) = listener;
+       }
+       else
+       {
+               // TODO : error handling
+               ret = 1;
+       }
+       DETECTORHASH_UNLOCK;
+       probeBlockEnd();
+       return ret;
+}
+
+// return 0 if succeed
+// return 1 if key is not in hash table
+// return negative value if other error occurred
+int del_detector_hash(void* ptr)
+{
+       khiter_t k;
+       int ret = 0;
+
+       if (unlikely(DETECTORHASH == 0))
+               return ERR_NOTINITIALIZED;
+
+       if (unlikely(ptr == NULL))
+               return ERR_WRONGPARAMETER;
+
+       probeBlockStart();
+       DETECTORHASH_LOCK;
+       k = kh_get(detector, DETECTORHASH, (uint32_t)ptr);
+       if (likely(k != kh_end(DETECTORHASH)))          // there is entry in hash table
+       {
+               kh_del(detector, DETECTORHASH, k);
+       }
+       else
+       {
+               ret = 1;
+       }
+       DETECTORHASH_UNLOCK;
+       probeBlockEnd();
+
+       return ret;
+}
+
+
+// *********************************************************************************************
+// glist implemenation
+// *********************************************************************************************
+
+// all function to call this function have to use mutex_lock
+static element_t* find_element(char* key)
+{
+       element_t* res;
+       int keylen;
+
+       if (unlikely(key == NULL))
+               return NULL;
+
+       keylen = strlen(key);
+
+//     pthread_mutex_lock(&glist_mutex);       // this is commented because of static function
+       res = gsymbol_list;
+       while(res != NULL)
+       {
+               if (keylen == res->keylen && (strcmp(key, res->keystr) == 0))
+                       break;
+               res = res->next;
+       }
+//     pthread_mutex_unlock(&glist_mutex);     // this is commented because of static function
+
+       return res;
+}
+
+int add_to_glist(char* key, void* data)
+{
+       element_t* elm;
+       int ret = 0;
+
+       if (unlikely(key == NULL || data == NULL))
+               return 0;
+
+       pthread_mutex_lock(&glist_mutex);
+       elm = find_element(key);
+       if (elm == NULL)
+       {
+               elm = (element_t*)real_malloc(sizeof(element_t));
+               if (likely(elm != NULL))
+               {
+                       elm->keylen = strlen(key);
+                       elm->keystr = (char*)real_malloc(elm->keylen + 1);
+                       if (likely(elm->keystr != NULL))
+                       {
+                               memcpy(elm->keystr, key, elm->keylen + 1);
+                               elm->dataptr = data;
+                               elm->next = gsymbol_list;
+                               elm->prev = NULL;
+                               if (gsymbol_list)
+                                       gsymbol_list->prev = elm;
+                               gsymbol_list = elm;
+                               ret = 1;
+                       }
+                       else
+                       {
+                               free(elm);
+                       }
+               }
+       }
+       pthread_mutex_unlock(&glist_mutex);
+
+       return ret;
+}
+
+int remove_from_glist(char* key)
+{
+       element_t* elm;
+       int ret = 0;
+
+       pthread_mutex_lock(&glist_mutex);
+       elm = find_element(key);
+       if (elm != NULL)
+       {
+               if (elm->prev)
+                       elm->prev->next = elm->next;
+               if (elm->next)
+                       elm->next->prev = elm->prev;
+               if (gsymbol_list == elm)
+                       gsymbol_list = gsymbol_list->next;
+       }
+       pthread_mutex_unlock(&glist_mutex);
+
+       if (elm != NULL)
+       {
+               free(elm->dataptr);
+               free(elm->keystr);
+               free(elm);
+               ret = 1;
+       }
+
+       return ret;
+}
+
+int remove_all_glist()
+{
+       element_t* elm;
+
+       pthread_mutex_lock(&glist_mutex);
+       while(gsymbol_list != NULL)
+       {
+               elm = gsymbol_list;
+               gsymbol_list = elm->next;
+               free(elm->dataptr);
+               free(elm->keystr);
+               free(elm);
+       }
+       pthread_mutex_unlock(&glist_mutex);
+
+       return 1;
+}
+
+void* find_glist(char* key)
+{
+       element_t* elm;
+
+       pthread_mutex_lock(&glist_mutex);
+       elm = find_element(key);
+       pthread_mutex_unlock(&glist_mutex);
+
+       if (elm)
+               return elm->dataptr;
+       else
+               return NULL;
+}
+
diff --git a/helper/daforkexec.c b/helper/daforkexec.c
new file mode 100644 (file)
index 0000000..d541def
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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 <sys/types.h>
+#include <signal.h>
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "binproto.h"
+#include "daforkexec.h"
+
+DECLARE(int, execl , const char *path, const char *arg, ...);
+DECLARE(int, execlp, const char *file, const char *arg, ...);
+DECLARE(int, execle, const char *path, const char *arg, ...);//, char * const envp[]);
+DECLARE(int, execv, const char *path, char *const argv[]);
+DECLARE(int, execve, const char *filename, char *const argv[],char *const envp[]);
+DECLARE(int, execvp, const char *file, char *const argv[]);
+DECLARE(int, execvpe, const char *file, char *const argv[],char *const envp[]);
+DECLARE(pid_t, fork, void);
+
+void init_exec_fork()
+{
+       INIT_FUNC_EXEC(fork);
+       INIT_FUNC_EXEC(execl);
+       INIT_FUNC_EXEC(execlp);
+       INIT_FUNC_EXEC(execle);
+       INIT_FUNC_EXEC(execv);
+       INIT_FUNC_EXEC(execve);
+       INIT_FUNC_EXEC(execvp);
+       INIT_FUNC_EXEC(execvpe);
+}
+
+#define prepare_params( FUNCTION , p1, p2)             \
+       va_list ap;                                     \
+       int args_count = 0;                             \
+       int i;                                          \
+                                                       \
+       INIT_FUNC_EXEC( FUNCTION );                     \
+                                                       \
+       va_start(ap, p2);                               \
+       do                                              \
+               args_count++;                           \
+       while (va_arg(ap, char *));                     \
+       va_end(ap);                                     \
+       args_count += 2 + 1;                            \
+                                                       \
+       char *arg_arr[args_count];                      \
+                                                       \
+       va_start(ap, p2);                               \
+                                                       \
+       arg_arr[0] = (char *)p1;                        \
+       arg_arr[1] = (char *)p2;                        \
+       for (i = 2; i < args_count; i++)                \
+               arg_arr[i] = va_arg(ap, char *);        \
+                                                       \
+       va_end(ap)
+
+int _da_call_original(void *funcp, char *args[], int args_count);
+
+#define print_params(buf, p1, p2)                      \
+       char *p = buf;                                  \
+       char *pp;                                       \
+       va_list par;                                    \
+       p += sprintf(p, "--> %s ", __FUNCTION__);       \
+       p += sprintf(p, "[%d]: <", getpid());           \
+       p += sprintf(p, " \"%s\",", p1);                \
+       p += sprintf(p, " \"%s\",", p2);                \
+       va_start(par, p2);                              \
+       while ( (pp = va_arg(par, char *)) != NULL)     \
+               p += sprintf(p, " \"%s\",", pp);        \
+       va_end(par);                                    \
+       p += sprintf(p, ">");
+
+int execl(const char *path, const char *arg, ...)
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       prepare_params(execl, path, arg);
+       res = _da_call_original(&execl_p, arg_arr, args_count);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, res, path);
+       return res;
+}
+
+int execlp(const char *file, const char *arg, ...)
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       prepare_params(execlp, file, arg);
+       res = _da_call_original(&execlp_p, arg_arr, args_count);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
+       return res;
+}
+
+int execle(const char *path, const char *arg, ...
+       /* original func have one more argument but
+        * i can't leave it in code by compilation reasons
+        * so it is commented:
+        *
+        *,__attribute__((unused)) char * const envp[] */
+       )
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       prepare_params(execle, path, arg);
+       res = _da_call_original(&execle_p, arg_arr, args_count);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, path, res);
+       return res;
+}
+
+int execv(const char *path, char *const argv[])
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       res = execv_p(path, argv);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, path, res);
+       return res;
+}
+
+int execvp(const char *file, char *const argv[])
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       res = execvp_p(file, argv);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
+       return res;
+}
+
+int execve(const char *filename, char *const argv[],char *const envp[])
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       res =  execve_p(filename, argv, envp);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, filename, res);
+       return res;
+}
+
+int execvpe(const char *file, char *const argv[],char *const envp[])
+{
+       int res;
+       PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
+
+       _uninit_();
+       res =  execvpe_p(file, argv, envp);
+       _init_();
+
+       PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
+       return res;
+}
+
+pid_t fork(void)
+{
+       pid_t res = fork_p();
+
+       PRINTMSG("<fork = %d>", res);
+       if (res == 0) {
+               reset_pid_tid(); /* important reset pid values */
+               if (gTraceInfo.socket.daemonSock >= 0) {
+                       close(gTraceInfo.socket.daemonSock);
+                       _init_();
+               }
+       }
+
+       return res;
+}
diff --git a/helper/daforkexec.h b/helper/daforkexec.h
new file mode 100644 (file)
index 0000000..320f6c1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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 __DAFORKEXEC_H_
+#define __DAFORKEXEC_H_
+
+#define INIT_FUNC_EXEC(FUNCNAME)                                       \
+       if(!FUNCNAME##_p) {                                             \
+               void *tmpPtr = dlsym(RTLD_NEXT , #FUNCNAME);    \
+               if (tmpPtr == NULL || dlerror() != NULL) {              \
+                       perror("dlsym failed : " #FUNCNAME);            \
+                       exit(0);                                        \
+               }                                                       \
+               memcpy(&FUNCNAME##_p, &tmpPtr, sizeof(tmpPtr));         \
+       }
+
+#define DECLARE(RET, FUNCTION, ...)                    \
+       typedef RET (* FUNCTION ## _p_t)(__VA_ARGS__);  \
+       static FUNCTION ## _p_t FUNCTION ## _p = 0
+
+void init_exec_fork();
+
+#endif /* __DAFORKEXEC_H_ */
diff --git a/helper/dahelper.c b/helper/dahelper.c
new file mode 100755 (executable)
index 0000000..6ce75e5
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <wchar.h>                     // for wcslen
+#include <unistd.h>                    // for unlink
+#include <sys/types.h>
+#include <dirent.h>                    // for opendir, readdir
+#include <assert.h>
+#include "dahelper.h"
+
+int app_efl_main_flg = 0;
+
+const char *lib_string[NUM_ORIGINAL_LIBRARY] = {
+       "libc.so.6",                            //0
+       "libpthread.so.0",                      //1
+       "libelementary.so.1",                   //2
+       "libecore_input_evas.so.1",             //3
+       "libdaemon.so.0",                       //4
+       "libcapi-appfw-application.so.0",       //5
+       "libGLESv2.so",                         //6
+       "libEGL.so",                            //7
+       SELF_LIB_NAME                           //8
+};
+void *lib_handle[NUM_ORIGINAL_LIBRARY];
+
+/* trace info global variable */
+__traceInfo gTraceInfo =
+{
+       {
+               1,                                                      // int eventIndex
+               PTHREAD_MUTEX_INITIALIZER       // pthread_mutex_t eventMutex
+       },              // __indexInfo
+       {
+               -1,                                                     // int daemonSock
+               PTHREAD_MUTEX_INITIALIZER       // ptrhread_mutex_t sockMutex
+       },              // __socketInfo
+       {
+               {0, },                                          // char appName[128]
+               0                                                       // unsigned int startTime
+       },              // __appInfo
+       {
+               0,                                                      // int state
+               PTHREAD_MUTEX_INITIALIZER       // ptrhread_mutex_t ssMutex
+       },              // __screenshotInfo
+       {
+               NULL,                                           // map_start
+               NULL                                            // map_end
+       },              // __mapInfo
+       -1,                                                             // int stateTouch
+       0,                                                              // int init_complete
+       0,                                                              // int custom_chart_callback_count
+       0                                                               // unsigned long optionflag
+};
+
+void WcharToChar(char* pstrDest, const wchar_t* pwstrSrc)
+{
+       int nLen=(int)wcslen(pwstrSrc);
+       wcstombs(pstrDest, pwstrSrc, nLen+1);
+}
+
+// return 0 if succeed
+// return -1 if error occured
+int remove_indir(const char *dirname)
+{
+       DIR *dir;
+       struct dirent *entry;
+       char path[MAX_PATH_LENGTH];
+       static char dirent_buffer[ sizeof(struct dirent) + PATH_MAX + 1 ] = {0,};
+       static struct dirent *dirent_r = (struct dirent *)dirent_buffer;
+
+
+       dir = opendir(dirname);
+       if(dir == NULL)
+       {
+               return -1;
+       }
+
+       while ((readdir_r(dir, dirent_r, &entry) == 0) && entry) {
+               if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
+               {
+                       snprintf(path, (size_t) MAX_PATH_LENGTH, "%s/%s", dirname, entry->d_name);
+                       if (entry->d_type != DT_DIR)    // file
+                       {
+                               unlink(path);
+                       }
+                       else { }        // directory
+               }
+       }
+       closedir(dir);
+
+       return 0;
+}
+
+static int absolute_filepath_p(const char *fname)
+{
+       return fname[0] == '/';
+}
+
+char *absolutize_filepath(const char *fname, char *buffer, size_t bufsiz)
+{
+       char cwd[PATH_MAX];
+
+       assert(fname && "Filename, passed to stdc function is NULL.");
+       if (absolute_filepath_p(fname) || getcwd(cwd, sizeof(cwd)) == NULL)
+               snprintf(buffer, bufsiz, "%s", fname);
+       else
+               snprintf(buffer, bufsiz, "%s/%s", cwd, fname);
+       return buffer;
+}
+
+char *real_abs_path(int fd, char *buffer, size_t bufsiz)
+{
+       static const char *PROC_FD = "/proc/self/fd/%d";
+       char proc_path[sizeof(PROC_FD) + 16]; /* PATH_MAX not needed here */
+       ssize_t ret = 0;
+
+       if (fd < 0)
+               return NULL;
+
+       snprintf(proc_path, sizeof(proc_path), PROC_FD, fd);
+
+       ret = readlink(proc_path, buffer, bufsiz);
+       if (ret < 0) /* some error occured */
+               return NULL;
+       buffer[ret] = '\0';
+
+       return buffer;
+}
diff --git a/helper/damaps.c b/helper/damaps.c
new file mode 100755 (executable)
index 0000000..ac4da2d
--- /dev/null
@@ -0,0 +1,693 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <unistd.h>
+#include "dahelper.h"
+#include "real_functions.h"
+
+struct data_list_t {
+       union {
+               void *next;
+               void *first;
+       };
+       union {
+               void *data;
+               void *tail;
+       };
+       union {
+               uint32_t hash;
+               uint32_t count;
+       };
+};
+
+struct map_t {
+       uint32_t hash;
+       int is_instrument;
+       void *addr;
+       void *endaddr;
+       char permissions[20];
+       long long offset;
+       char device[256];
+       long long inode;
+       char filename[1024]; /* TODO dynamic allocation */
+};
+
+typedef int cmp_by_hash_and_name_t(void *a, void *b);
+
+/* variables */
+
+static pthread_mutex_t maps_lock = PTHREAD_MUTEX_INITIALIZER;
+
+char **map_inst_list = NULL;
+char *map_inst_list_set = NULL;
+uint32_t map_inst_count = 0;
+
+static struct data_list_t sections_list = {
+       {NULL}, /* head element */
+       {NULL}, /* tail for head list el */
+       {0},    /* count */
+};
+
+static uint32_t addr_hash_table_el_count_total = 0;
+static uint32_t addr_hash_table_el_count_buzy = 0;
+static struct map_t **addr_hash_table = NULL;
+
+static uint32_t name_hash_table_el_count_total = 0;
+static uint32_t name_hash_table_el_count_buzy = 0;
+static struct map_t **name_hash_table = NULL;
+
+#define MAX_READERS_COUNT 8
+static sem_t readers_mutex;
+
+/*
+ *
+ * Functions
+ *
+ */
+
+static uint32_t calc_string_hash(char *str)
+{
+       uint32_t res = 0;
+       while (*str != '\0') {
+               res += *str;
+               res <<= 1;
+               str++;
+       }
+       return res;
+}
+
+static struct data_list_t *get_first_el(struct data_list_t *list)
+{
+       return (struct data_list_t *)list->first;
+}
+
+static struct data_list_t *get_next_el(struct data_list_t *el)
+{
+       return (struct data_list_t *)el->next;
+}
+
+static void print_map(struct map_t *map)
+{
+       PRINTMSG("mapp-> %p-%p %s %llx %s %llx %s",
+                 map->addr,
+                 map->endaddr,
+                 map->permissions,
+                 map->offset,
+                 map->device,
+                 map->inode,
+                 map->filename);
+}
+
+static int read_mapping_line(FILE *mapfile, struct map_t *m)
+{
+       char ch1, ch2;
+       int ret = 0;
+
+       if (m == NULL) {
+               PRINTERR("map_t param is NULL\n");
+               return 0;
+       }
+
+       ret = fscanf(mapfile, "%p-%p %s %llx %s %llx%c%c",
+                    &m->addr,
+                    &m->endaddr,
+                    (char *)m->permissions,
+                    &m->offset,
+                    (char *)m->device,
+                    &m->inode,
+                    &ch1, &ch2);
+
+       m->is_instrument = 0;
+       if (ret > 0 && ret != EOF) {
+               int len = 0;
+
+               if (ch2 != '\n') {
+                       ret = (fgets((char *)m->filename, sizeof(m->filename), mapfile) != NULL);
+                       if (ret) {
+                               /* remove leading white spaces */
+                               if (m->filename[0] == ' ') {
+                                       char *p = m->filename;
+                                       while (*p == ' ')
+                                               p++;
+                                       len = strlen(p);
+                                       memmove(m->filename, p, len);
+                               } else
+                                       len = strlen(m->filename);
+                               if (len > 0)
+                                       len--;
+                       }
+               }
+
+               m->filename[len] = '\0';
+
+               return 1;
+       } else
+               return 0;
+
+       return (ret != 0 && ret != EOF);
+}
+
+static void print_list()
+{
+       struct data_list_t *p = NULL;
+       struct map_t *m = NULL;
+       uint32_t i = 0;
+
+       PRINTMSG("=====================================");
+       for (p = get_first_el(&sections_list); p != NULL && i < sections_list.count; p = p->next) {
+               m = (struct map_t *)p->data;
+               PRINTMSG("mapp[%03d]-> %p-%p %s %llx %s %llx %s",
+                        ++i,
+                        m->addr,
+                        m->endaddr,
+                        m->permissions,
+                        m->offset,
+                        m->device,
+                        m->inode,
+                        m->filename);
+               usleep(500);
+       }
+
+}
+
+static struct data_list_t *new_data(void)
+{
+       struct data_list_t *el = (*real_malloc)(sizeof(*el));
+       el->next = NULL;
+       el->hash = 0;
+       el->data = NULL;
+       return el;
+}
+
+static int data_list_append(struct data_list_t *head, struct data_list_t *el)
+{
+       if (head->first == NULL) {
+               // empty list
+               head->first = el;
+               head->tail = el;
+       } else {
+               ((struct data_list_t *)head->tail)->next = el;
+               head->tail = el;
+       }
+       head->count++;
+       return 0;
+}
+
+static int add_to_map_list(struct map_t **m)
+{
+       struct data_list_t *el = new_data();
+       el->data = (void *)(*m);
+       el->hash = (*m)->hash;
+       data_list_append(&sections_list, el);
+       *m = NULL;
+
+       return 0;
+}
+
+static void print_list_sorted(struct map_t **list)
+{
+       struct map_t *m = NULL;
+       uint32_t i = 0;
+
+       PRINTMSG("=====================================");
+       for (i = 0; i < sections_list.count; i++) {
+               m = list[i];
+               if (m->is_instrument)
+               PRINTMSG("mapp[%03d]-> %016X %d <%s>",
+                        i + 1,
+                        m->hash,
+                        m->is_instrument,
+                        m->filename);
+               usleep(500);
+       }
+}
+
+static int realloc_array(struct map_t ***p, uint32_t *count_total,
+                        uint32_t *count_buzy, cmp_by_hash_and_name_t cmp_func)
+{
+       uint32_t i, j;
+       struct map_t **list;
+       struct data_list_t *el;
+
+       if (*p == NULL) {
+               /* first init */
+               if (sections_list.count != 0) {
+                       *p = (*real_malloc)(sizeof(**p) * sections_list.count);
+                       *count_total = sections_list.count;
+               }
+       } else {
+               /* not first init */
+               if (sections_list.count > *count_total) {
+                       /* not enaught space in hash */
+                       *p = realloc(*p, sizeof(**p) * sections_list.count);
+                       *count_total = sections_list.count;
+               }
+       }
+       *count_buzy = sections_list.count;
+
+       /* fill table */
+       list = *p;
+       el = get_first_el(&sections_list);
+
+       for (i = 0; i < sections_list.count; i++) {
+               list[i] = (struct map_t *)el->data;
+               el = get_next_el(el);
+       }
+
+       /* sort */
+       uint32_t max = *count_buzy;
+       struct map_t *tmp;
+       if (cmp_func) {
+               for (i = 0; i < max; i++)
+                       for (j = i + 1; j < *count_buzy; j++) {
+                               if (cmp_func(list[i], list[j]) > 0) {
+                                       tmp = list[i];
+                                       list[i] = list[j];
+                                       list[j] = tmp;
+                               }
+                       }
+               return 0;
+       }
+
+       return 0;
+}
+
+static int create_addr_hash_table()
+{
+       realloc_array(&addr_hash_table, &addr_hash_table_el_count_total,
+                     &addr_hash_table_el_count_buzy, NULL);
+
+       return 0;
+}
+
+static int cmp_by_hash_and_name(void *a, void *b)
+{
+       if (((struct map_t *)a)->hash != ((struct map_t *)b)->hash) {
+               /* hash value is major priority */
+               if (((struct map_t *)a)->hash > ((struct map_t *)b)->hash)
+                       return 1;
+               else /* if i(a->hash < b->hash) */
+                       return -1;
+       } else {
+               /* hash equel */
+               /* retun filename cmp */
+               return strcmp(((struct map_t *)a)->filename,
+                             ((struct map_t *)b)->filename);
+       }
+
+       /* never happens */
+       return 0;
+}
+
+static int create_name_hash_table()
+{
+       realloc_array(&name_hash_table, &name_hash_table_el_count_total,
+                     &name_hash_table_el_count_buzy, cmp_by_hash_and_name);
+
+       return 0;
+}
+
+static struct map_t **get_map_by_filename(char *filename, int *count)
+{
+       uint32_t hash = calc_string_hash(filename);
+       struct map_t **res = NULL;
+       uint32_t left, right, cur;
+
+       *count = 0;
+
+       if (name_hash_table_el_count_buzy == 0 ||
+           name_hash_table[0]->hash > hash ||
+           name_hash_table[name_hash_table_el_count_buzy - 1]->hash < hash) {
+               goto find_exit;
+       }
+
+       left = 0;
+       right = name_hash_table_el_count_buzy - 1;
+       cur = (left + right) >> 1;
+       while (left < right) {
+               if (hash < name_hash_table[cur]->hash) {
+                       right = cur - 1;
+                       cur = (left + right) >> 1;
+                       continue;
+               }
+               if (hash > name_hash_table[cur]->hash) {
+                       left = cur + 1;
+                       cur = (left + right) >> 1;
+                       continue;
+               }
+               break;
+       }
+
+       /* resolve collisions */
+       if (name_hash_table[cur]->hash == hash) {
+
+               /* get first with same hash */
+               while (1) {
+                       if (cur == 0)
+                               /* top of list */
+                               break;
+                       if (name_hash_table[cur - 1]->hash != hash)
+                               /* previous element have different hash */
+                               break;
+                       /* previous element have the same hash */
+                       cur--;
+               }
+
+               /* get first with same hash and filename */
+               while (1) {
+                       if (cur > name_hash_table_el_count_buzy - 1)
+                               /* top of list */
+                               break;
+                       if (name_hash_table[cur]->hash != hash)
+                               /* previous element have different hash */
+                               break;
+                       if (strncmp(name_hash_table[cur]->filename, filename, strlen(filename)) == 0)
+                               break;
+                       /* previous element have the same hash */
+                       cur++;
+               }
+
+               /* calculate sections count */
+               while (cur <= (name_hash_table_el_count_buzy - 1) &&
+                      name_hash_table[cur]->hash == hash &&
+                      strncmp(name_hash_table[cur]->filename, filename, strlen(filename)) == 0) {
+                       if (res == NULL)
+                               res = &name_hash_table[cur];
+                       cur++;
+                       *count = *count + 1;
+               }
+       }
+
+find_exit:
+       return res;
+}
+
+static int update_is_instrument_lib_attr_nolock()
+{
+       uint32_t i;
+       struct map_t **map;
+
+       /* clear is_instrument fields */
+       for (i = 0; i < name_hash_table_el_count_buzy; i++)
+               name_hash_table[i]->is_instrument = 0;
+
+       /* set is_instrument fields */
+       for (i = 0; i < map_inst_count; i++) {
+               int count = 0;
+               map = get_map_by_filename(map_inst_list[i], &count);
+               for (;count > 0; count--) {
+                       PRINTMSG("set 1!!! = %s [%p:%p]", (*map)->filename,
+                                 (*map)->addr, (*map)->endaddr);
+                       (*map)->is_instrument = 1;
+                       map++;
+               }
+       }
+
+       return 0;
+       print_list_sorted(name_hash_table);
+}
+
+static struct map_t *get_map_by_addr(void *addr)
+{
+       struct map_t *d = NULL;
+       struct map_t *res = NULL;
+       uint32_t left, right, cur;
+
+       if (addr_hash_table_el_count_buzy == 0)
+               goto find_exit;
+
+       if (addr < addr_hash_table[0]->addr)
+               goto find_exit;
+
+       if (addr > addr_hash_table[addr_hash_table_el_count_buzy - 1]->endaddr)
+               goto find_exit;
+
+       left = 0;
+       right = addr_hash_table_el_count_buzy - 1;
+       cur = 0;
+       while (left < right) {
+               cur = (left + right) >> 1;
+
+               d = (struct map_t *)addr_hash_table[cur];
+               if (addr < d->addr) {
+                       right = cur - 1;
+                       continue;
+               }
+               if (addr > d->endaddr) {
+                       left = cur + 1;
+                       continue;
+               }
+
+               /* success */
+               return (addr_hash_table[cur]);
+       }
+
+       if (left == right) {
+               d = (struct map_t *)addr_hash_table[left];
+               if ((d->addr <= addr) && (addr <= d->endaddr))
+                       res = addr_hash_table[left];
+       }
+
+find_exit:
+       return res;
+}
+
+static void maps_reader_lock_all()
+{
+       int i;
+       for (i = 0; i < MAX_READERS_COUNT; i++)
+               sem_wait(&readers_mutex);
+}
+
+static void maps_reader_unlock_all()
+{
+       int i;
+       for (i = 0; i < MAX_READERS_COUNT; i++)
+               sem_post(&readers_mutex);
+}
+
+static inline void maps_reader_lock()
+{
+       sem_wait(&readers_mutex);       /* down semaphore */
+}
+
+static inline void maps_reader_unlock()
+{
+       sem_post(&readers_mutex);       /* up semaphore */
+}
+
+static inline void maps_writer_lock()
+{
+       pthread_mutex_lock(&maps_lock);
+}
+
+static inline void maps_writer_unlock()
+{
+       pthread_mutex_unlock(&maps_lock);
+}
+
+/* TODO refactor this function to alloc map_inst_list_set and copy it frm src*/
+// WARNING! this function use maps_set and set it to NULL
+// so first param must be malloced and do not free maps_set after call
+int set_map_inst_list(char **maps_set, uint32_t maps_count)
+{
+       int res = 0;
+       uint32_t i = 0;
+       char *p;
+
+       maps_writer_lock();
+       maps_reader_lock_all();
+
+       if (map_inst_list != NULL) {
+               free(map_inst_list);
+               map_inst_list = NULL;
+       }
+
+       if (map_inst_list_set != NULL) {
+               free(map_inst_list_set);
+               map_inst_list_set = NULL;
+       }
+
+       map_inst_list = real_malloc(sizeof(*map_inst_list) * maps_count);
+       if (maps_count != 0 && map_inst_list == NULL) {
+               PRINTERR("Cannot allocate data for map_inst_list\n");
+               res = -1;
+               goto unlock_exit;
+       }
+
+       if (maps_set != NULL && *maps_set != NULL && map_inst_list != NULL) {
+               map_inst_list_set = *maps_set;
+               map_inst_count = maps_count;
+
+               /* add library mapping names */
+               p = map_inst_list_set + sizeof(maps_count);
+               for (i = 0; i < maps_count; i++) {
+                       map_inst_list[i] = p;
+                       p += strlen(p) + 1;
+                       PRINTMSG("-------> %s", map_inst_list[i]);
+               }
+       } else {
+               map_inst_count = 0;
+       }
+
+       res = update_is_instrument_lib_attr_nolock();
+
+       if (maps_set != NULL)
+               *maps_set = NULL;
+
+unlock_exit:
+       maps_reader_unlock_all();
+       maps_writer_unlock();
+
+       return res;
+}
+
+int maps_make()
+{
+       int res = 0;
+       maps_writer_lock();
+       maps_reader_lock_all();
+       FILE *f = fopen("/proc/self/maps", "r");
+       struct map_t *map = NULL;
+
+       /* read to exists locations */
+       struct data_list_t *cur = get_first_el(&sections_list);
+       sections_list.count = 0;
+       while (cur != NULL) {
+               map = (struct map_t *)cur->data;
+               if (!read_mapping_line(f, map))
+                       break;
+               if (map->permissions[2] == 'x') {
+                       map->hash = calc_string_hash(map->filename);
+                       cur->hash = map->hash;
+                       sections_list.count++;
+                       cur = get_next_el(cur);
+               }
+       }
+
+       /* add  locations */
+       map = (*real_malloc)(sizeof(*map));
+       if (map == NULL) {
+               PRINTERR("Can not alloc data for map\n");
+               res = -1;
+               goto unlock_exit;
+       }
+       while (read_mapping_line(f, map)) {
+               if (map->permissions[2] == 'x') {
+                       map->hash = calc_string_hash(map->filename);
+                       add_to_map_list(&map);
+                       if (map == NULL)
+                               map = (*real_malloc)(sizeof(*map));
+               }
+       }
+
+       if (map != NULL)
+               free(map);
+
+       create_addr_hash_table();
+       create_name_hash_table();
+
+       update_is_instrument_lib_attr_nolock();
+
+unlock_exit:
+       fclose(f);
+
+       maps_reader_unlock_all();
+       maps_writer_unlock();
+
+       return res;
+}
+
+int maps_print_maps_by_addr(const void *addr)
+{
+       int res = -1;
+       struct map_t *map = NULL;
+
+       maps_reader_lock();
+       map = get_map_by_addr((void *)addr);
+       if (map != NULL)
+               print_map(map);
+       maps_reader_unlock();
+
+       return res;
+}
+
+int maps_is_instrument_section_by_addr_no_remap(const void *addr)
+{
+       int res = -1;
+       struct map_t *map;
+
+       maps_reader_lock();
+       map = get_map_by_addr((void *)addr);
+       if (map != NULL)
+               res = map->is_instrument;
+       maps_reader_unlock();
+
+       return res;
+
+}
+
+/* interface function */
+int maps_is_instrument_section_by_addr(const void *addr)
+{
+       int ret = maps_is_instrument_section_by_addr_no_remap(addr);
+
+       if (ret == -1) {
+               PRINTMSG("========> hz addr %p. remap", addr);
+               if (maps_make() != 0) {
+                       PRINTERR("maps make failed\n");
+                       ret = -1;
+                       goto exit;
+               }
+               ret = maps_is_instrument_section_by_addr_no_remap(addr);
+               if (ret == -1) {
+                       print_list();
+                       PRINTERR("!!!!unknown addr %p", addr);
+                       get_map_by_addr((void *)addr);
+                       sleep(2);
+                       exit(0);
+                       ret = 0;
+               }
+       }
+
+exit:
+       return ret;
+}
+
+/* must be called ones */
+int maps_init()
+{
+       int res = 0;
+
+       probeBlockStart();
+       res = sem_init(&readers_mutex, 0, MAX_READERS_COUNT);
+       set_map_inst_list(NULL, 0);
+       probeBlockEnd();
+
+       return res;
+}
diff --git a/helper/dastdout.c b/helper/dastdout.c
new file mode 100644 (file)
index 0000000..7b2568e
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <errno.h>
+#include "dahelper.h"
+
+static inline int __redirect(int old, int new)
+{
+       int ret = 0;
+
+       if (dup2(old, new) == -1) {
+               /* fail to print up there. there is no sdterr */
+               /* TODO inform about problem */
+               fprintf(stderr, "dup2 fail\n");
+               ret = -1;
+       }
+
+       return ret;
+}
+
+int __redirect_std(void)
+{
+#ifdef STDTOFILE
+       char STDOUT[MAX_PATH_LENGTH];
+       snprintf(STDOUT,sizeof(STDOUT), "/tmp/da_preloaded_%d_%d.log", getppid(), getpid());
+#else
+       #define STDOUT          "/dev/null"
+#endif
+
+       int ret = 0;
+       int fd = open(STDOUT, O_WRONLY | O_CREAT | O_TRUNC, 0777);
+       if (fd != -1) {
+               if (__redirect(fd, 1) != 0 ||
+                   __redirect(fd, 2) != 0) {
+                       /* fail to print up there. there is no sdterr */
+                       /* TODO inform about problem */
+                       /* fprintf(sdterr, "duplicate fd fail\n"); */
+                       ret = -1;
+               }
+
+               close(fd);
+       } else {
+               /* TODO inform about problem */
+               close(1);
+               close(2);
+       }
+
+       close(0);
+       return ret;
+}
diff --git a/helper/dastdout.h b/helper/dastdout.h
new file mode 100644 (file)
index 0000000..fd743e0
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DASDTOUT_H__
+#define __DASDTOUT_H__
+
+int __redirect_std(void);
+
+#endif /* __DASDTOUT_H__ */
diff --git a/helper/libdaprobe.c b/helper/libdaprobe.c
new file mode 100755 (executable)
index 0000000..bc1b5e6
--- /dev/null
@@ -0,0 +1,1001 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Nikita Kalyazin <n.kalyazin@samsung.com>
+ * Vitaliy Cherepanov <v.cherepanov@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>                     // for sprintf
+#include <stdlib.h>                    // for getenv
+#include <string.h>                    // for strstr
+#include <stdbool.h>           // for bool
+#include <stdint.h>                    // fot uint32_t,uint64_t
+#include <stdarg.h>                    // for va_list, va_arg(__appendTypeLog)
+#include <execinfo.h>          // for backtrace, backtrace_symbols
+#include <unistd.h>                    // for write, alarm function, syscall
+#include <pthread.h>           // for pthread_mutex_lock
+#include <signal.h>
+#include <stdint.h>
+
+#include <sys/syscall.h>       // for syscall
+#include <sys/time.h>          // for gettimeofday
+#include <sys/socket.h>                // for socket, connect
+#include <sys/un.h>                    // for sockaddr_un
+#include <sys/timerfd.h>       // for timerfd
+
+#include "probeinfo.h"
+#include "dautil.h"
+#include "dahelper.h"
+#include "dacollection.h"
+#include "da_sync.h"
+#include "daprobe.h"
+
+#include "binproto.h"
+#include "daforkexec.h"
+#include "damaps.h"
+#include "dastdout.h"
+#include "common_probe_init.h"
+#include "real_functions.h"
+
+#define APP_INSTALL_PATH               "/opt/apps"
+#define TISEN_APP_POSTFIX                      ".exe"
+#define UDS_NAME                               "/tmp/da.socket"
+#define TIMERFD_INTERVAL               100000000               // 0.1 sec
+
+__thread int           gProbeBlockCount = 0;
+__thread int           gProbeDepth = 0;
+pid_t gPid = -1;
+__thread pid_t         gTid = -1;
+
+int                    g_timerfd = 0;
+long           g_total_alloc_size = 0;
+pthread_t      g_recvthread_id;
+
+int log_fd = 0;
+
+int getExecutableMappingAddress();
+
+bool printLog(log_t* log, int msgType);
+
+/******************************************************************************
+ * internal functions
+   (this means that these functions do not need to set enter/exit flag)
+ ******************************************************************************/
+
+// runtime configure the probe option
+static void _configure(char* configstr)
+{
+       gTraceInfo.optionflag = atoll(configstr);
+
+       if isOptionEnabled(OPT_SNAPSHOT)
+               SCREENSHOT_SET();
+       else
+               SCREENSHOT_UNSET();
+       PRINTMSG("configure in probe : %s, %llx\n", configstr, gTraceInfo.optionflag);
+}
+
+void application_exit()
+{
+       pid_t gpid;
+       FILE *f = NULL;
+       char buf[MAX_PATH_LENGTH];
+       const char manager_name[] = "da_manager";
+
+       /* TODO think of another way for correct app termination */
+
+       gpid = getpgrp();
+       /* check for parent */
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", gpid);
+       f = fopen(buf, "r");
+       if (f != NULL) {
+               fscanf(f, "%s", buf);
+               fclose(f);
+               if (strlen(buf) == strlen(manager_name) &&
+                   strncmp(buf, manager_name, sizeof(manager_name)) == 0) {
+                       /* Luke, I am your father
+                        * da_manager is our parent
+                        * looks like we are common applicaton
+                        */
+                       PRINTMSG("App termination: EXIT(0)");
+                       exit(0);
+               }
+       }
+
+       /* da_manager is not our father
+        * we are native app or already launched.
+        * Will be troubles up there if we are common already launched app!!!
+        * Kill yourself!!
+        */
+       PRINTMSG("App termination: kill all process group");
+       killpg(gpid, SIGKILL);
+}
+
+// create socket to daemon and connect
+#define MSG_CONFIG_RECV 0x01
+#define MSG_MAPS_INST_LIST_RECV 0x02
+static int createSocket(void)
+{
+       char strerr_buf[MAX_PATH_LENGTH];
+       ssize_t recvlen;
+       int clientLen, ret = 0;
+       struct sockaddr_un clientAddr;
+       log_t log;
+
+       gTraceInfo.socket.daemonSock =
+         socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+       if (gTraceInfo.socket.daemonSock != -1) {
+               memset(&clientAddr, '\0', sizeof(clientAddr));
+               clientAddr.sun_family = AF_UNIX;
+               snprintf(clientAddr.sun_path, sizeof(UDS_NAME), "%s", UDS_NAME);
+
+               clientLen = sizeof(clientAddr);
+               if (connect(gTraceInfo.socket.daemonSock,
+                           (struct sockaddr *)&clientAddr, clientLen) >= 0)
+               {
+                       char buf[64];
+                       int recved = 0;
+
+                       /* send pid and ppid to manager */
+                       snprintf(buf, sizeof(buf), "%d %d", getpid(), getppid());
+                       print_log_str(MSG_PID, buf);
+
+                       /* we need recv this messages right now! */
+                       while (((recved & MSG_CONFIG_RECV) == 0) ||
+                              ((recved & MSG_MAPS_INST_LIST_RECV) == 0))
+                       {
+                               PRINTMSG("wait incoming message %d\n",
+                                        gTraceInfo.socket.daemonSock);
+                               /* recv header */
+                               recvlen = recv(gTraceInfo.socket.daemonSock, &log,
+                                              sizeof(log.type) + sizeof(log.length),
+                                              MSG_WAITALL);
+
+                               fprintf(stderr, "recv %d\n", recvlen);
+                               if (recvlen > 0) {/* recv succeed */
+                                       char *data_buf = NULL;
+
+                                       data_buf = real_malloc(log.length);
+
+                                       if (data_buf == NULL) {
+                                               PRINTERR("cannot allocate buf to recv msg");
+                                               break;
+                                       }
+
+                                       recvlen = recv(gTraceInfo.socket.daemonSock, data_buf,
+                                                      log.length, MSG_WAITALL);
+
+                                       if (recvlen != log.length) {
+                                               PRINTERR("Can not get data from daemon sock\n");
+                                               goto free_data_buf;
+                                       }
+
+                                       if (log.type == MSG_CONFIG) {
+                                               PRINTMSG("MSG_CONFIG");
+                                               _configure(data_buf);
+                                               recved |= MSG_CONFIG_RECV;
+                                       } else if(log.type ==  MSG_MAPS_INST_LIST) {
+                                               PRINTMSG("MSG_MAPS_INST_LIST <%u>", *((uint32_t *)data_buf));
+                                               set_map_inst_list(&data_buf, *((uint32_t *)data_buf));
+                                               recved |= MSG_MAPS_INST_LIST_RECV;
+                                       } else {
+                                               // unexpected case
+                                               PRINTERR("unknown message! %d", log.type);
+                                       }
+
+free_data_buf:
+                                       if (data_buf != NULL)
+                                               free(data_buf);
+
+                               } else if (recvlen < 0) {
+                                       close(gTraceInfo.socket.daemonSock);
+                                       gTraceInfo.socket.daemonSock = -1;
+                                       PRINTERR("recv failed with error(%d)\n",
+                                                recvlen);
+                                       ret = -1;
+                                       application_exit();
+                                       break;
+                               } else {
+                                       /* closed by other peer */
+                                       close(gTraceInfo.socket.daemonSock);
+                                       gTraceInfo.socket.daemonSock = -1;
+                                       PRINTERR("closed by other peer\n");
+                                       ret = -1;
+                                       application_exit();
+                                       break;
+                               }
+
+                       }
+
+                       PRINTMSG("createSocket connect() success\n");
+               } else {
+                       close(gTraceInfo.socket.daemonSock);
+                       gTraceInfo.socket.daemonSock = -1;
+                       strerror_r(errno, strerr_buf, sizeof(strerr_buf));
+                       PRINTERR("cannot connect to da_manager. err <%s>\n",
+                                strerr_buf);
+                       ret = -1;
+               }
+       } else {
+               strerror_r(errno, strerr_buf, sizeof(strerr_buf));
+               PRINTERR("cannot create socket. err <%s>\n", strerr_buf);
+               ret = -1;
+       }
+
+       PRINTMSG("socket create done with result = %d", ret);
+       return ret;
+}
+
+
+// parse backtrace string and find out the caller of probed api function
+// return 0 if caller is user binary, otherwise return 1
+static int determineCaller(char* tracestring)
+{
+       char *substr;
+
+       // determine whether saveptr (caller binary name) is user binary or not
+       substr = strstr(tracestring, APP_INSTALL_PATH);
+
+       if(substr == NULL)      // not user binary
+       {
+               return 1;
+       }
+       else                            // user binary
+       {
+#ifdef TISENAPP
+               substr = strstr(tracestring, TISEN_APP_POSTFIX);
+               if(substr == NULL)
+                       return 1;
+#endif
+               return 0;
+       }
+}
+
+void reset_pid_tid()
+{
+       gPid = -1;
+       gTid = -1;
+}
+
+// return current process id
+pid_t _getpid()
+{
+       if (gPid == -1)
+               gPid = getpid();
+       return gPid;
+}
+
+// return current thread id
+pid_t _gettid()
+{
+       if(gTid == -1)
+               gTid = syscall(__NR_gettid);    // syscall is very expensive
+       return gTid;
+}
+
+static void *recvThread(void __unused * data)
+{
+       fd_set readfds, workfds;
+       int maxfd = 0, rc;
+       uint64_t xtime;
+       uint32_t tmp;
+       ssize_t recvlen;
+       log_t log;
+       char *data_buf = NULL;
+       sigset_t profsigmask;
+
+       if(gTraceInfo.socket.daemonSock == -1)
+               return NULL;
+
+       probeBlockStart();
+
+       sigemptyset(&profsigmask);
+       sigaddset(&profsigmask, SIGPROF);
+       pthread_sigmask(SIG_BLOCK, &profsigmask, NULL);
+
+       FD_ZERO(&readfds);
+       if(g_timerfd > 0)
+       {
+               maxfd = g_timerfd;
+               FD_SET(g_timerfd, &readfds);
+       }
+       if(maxfd < gTraceInfo.socket.daemonSock)
+               maxfd = gTraceInfo.socket.daemonSock;
+       FD_SET(gTraceInfo.socket.daemonSock, &readfds);
+
+       while(1)
+       {
+               workfds = readfds;
+               rc = select(maxfd + 1, &workfds, NULL, NULL, NULL);
+               if(rc < 0)
+               {
+                       continue;
+               }
+
+               if(g_timerfd > 0 && FD_ISSET(g_timerfd, &workfds))
+               {
+                       recvlen = read(g_timerfd, &xtime, sizeof(xtime));
+                       if(recvlen > 0)
+                       {
+                               log.length = snprintf(log.data, sizeof(log.data), "%ld", g_total_alloc_size) + 1;
+                               printLog(&log, MSG_ALLOC);
+                       }
+                       else
+                       {
+                               // read failed
+                       }
+                       continue;
+               }
+               else if(FD_ISSET(gTraceInfo.socket.daemonSock, &workfds))
+               {
+                       recvlen = recv(gTraceInfo.socket.daemonSock, &log,
+                                       sizeof(log.type) + sizeof(log.length), MSG_WAITALL);
+
+                       if(recvlen > 0) // recv succeed
+                       {
+
+                               if(log.length > 0) {
+                                       data_buf = real_malloc(log.length);
+                                       if (data_buf == NULL) {
+                                               PRINTERR("cannot allocate buf to recv msg");
+                                               break;
+                                       }
+                                       recvlen = recv(gTraceInfo.socket.daemonSock, data_buf,
+                                               log.length, MSG_WAITALL);
+                                       if (recvlen != log.length) {
+                                               PRINTERR("Can not recv data from\n");
+                                               goto free_data_buf;
+                                       }
+                               }
+
+                               if (log.type == MSG_CAPTURE_SCREEN) {
+                                       captureScreen();
+                               } else if (log.type == MSG_CONFIG) {
+                                       _configure(data_buf);
+                               } else if(log.type == MSG_STOP) {
+                                       PRINTMSG("MSG_STOP");
+                                       if (data_buf) {
+                                               free(data_buf);
+                                               data_buf = NULL;
+                                       }
+                                       application_exit();
+                                       break;
+                               } else if(log.type == MSG_MAPS_INST_LIST) {
+                                       if(log.length > 0) {
+                                               tmp = *((uint32_t *)data_buf);
+                                               PRINTMSG("MSG_MAPS_INST_LIST <%u>", tmp);
+                                               set_map_inst_list(&data_buf, tmp);
+                                               continue;
+                                       } else {
+                                               PRINTERR("WRONG MSG_MAPS_INST_LIST");
+                                       }
+                               } else {
+                                       PRINTERR("recv unknown message. id = (%d)", log.type);
+                               }
+
+free_data_buf:
+                               if (data_buf) {
+                                       free(data_buf);
+                                       data_buf = NULL;
+                               }
+
+                       }
+                       else if(recvlen == 0)   // closed by other peer
+                       {
+                               close(gTraceInfo.socket.daemonSock);
+                               gTraceInfo.socket.daemonSock = -1;
+                               break;
+                       }
+                       else    // recv error
+                       {
+                               PRINTERR("recv failed in recv thread with error(%d)", recvlen);
+                               continue;
+                       }
+               }
+               else    // unknown case
+               {
+                       continue;
+               }
+       }
+
+       /* release buffer */
+       if (data_buf)
+               free(data_buf);
+
+       probeBlockEnd();
+       return NULL;
+}
+
+/*****************************************************************************
+ * initialize / finalize function
+ *****************************************************************************/
+static int init_timerfd(void)
+{
+       const struct timespec interval = {
+               .tv_sec = 0,
+               .tv_nsec = TIMERFD_INTERVAL
+       };
+       const struct itimerspec ctime = {
+               .it_interval = interval,
+               .it_value = interval
+       };
+
+       int timer = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
+
+       if (timer == -1) {
+               PRINTMSG("failed to create timerdf\n");
+               return -1;
+       }
+
+       if (timerfd_settime(timer, 0, &ctime, NULL) != 0) {
+               PRINTMSG("failed to set timerfd\n");
+               close(timer);
+               return -1;
+       }
+
+       return timer;
+}
+
+static uint64_t get_app_start_time(void)
+{
+       enum {nsecs_in_sec = 1000 * 1000};
+       struct timeval time;
+
+       gettimeofday(&time, NULL);
+       return nsecs_in_sec * (uint64_t) time.tv_sec + time.tv_usec;
+}
+
+static int create_recv_thread()
+{
+       int err = pthread_create(&g_recvthread_id, NULL, recvThread, NULL);
+
+       if (err)
+               PRINTMSG("failed to crate recv thread\n");
+
+       return err;
+}
+
+int _init_(void)
+{
+       int res = 0;
+
+       probeBlockStart();
+
+       /* redirect stderr and stdout.*/
+       /* if there is no std - print call will crash app */
+       __redirect_std();
+
+       init_exec_fork();
+       initialize_hash_table();
+
+       initialize_screencapture();
+
+       initialize_event();
+
+       getExecutableMappingAddress();
+
+       gTraceInfo.app.startTime = get_app_start_time();
+
+       // create socket for communication with da_daemon
+       if (createSocket() == 0) {
+               g_timerfd = init_timerfd();
+               create_recv_thread();
+               update_heap_memory_size(true, 0);
+       }
+
+
+       PRINTMSG("dynamic analyzer probe helper so loading... pid[%d]\n",
+                getpid());
+
+       gTraceInfo.init_complete = 1;
+       if (maps_make() != 0) {
+               PRINTERR("maps make failed\n");
+               res = -1;
+               goto unlock_exit;
+       }
+
+unlock_exit:
+       probeBlockEnd();
+
+       return res;
+}
+
+void __attribute__((constructor)) _init_probe()
+{
+
+       if (_init_real_functions()) {
+               PRINTERR("cannot init real functions\n");
+               exit(1);
+       }
+       rtdl_next_set_once(real_malloc, "malloc");
+
+        /* init maps */
+       if (maps_init()!=0){
+               perror("cannot init readers semaphores\n");
+               exit(0);
+       };
+
+       /* init library */
+       _init_();
+
+       /* init gl functions */
+       __init_gl_functions__();
+
+       PRINTMSG("<-lib construnctor");
+}
+
+void _uninit_(void)
+{
+       int i;
+       probeBlockStart();
+
+       gTraceInfo.init_complete = -1;
+       PRINTMSG("dynamic analyzer probe helper so unloading... pid[%d]\n",
+                getpid());
+
+       remove_all_glist();
+
+       // close timerfd
+       if(g_timerfd > 0)
+               close(g_timerfd);
+
+       // close socket
+       if(gTraceInfo.socket.daemonSock != -1)
+       {
+               print_log_str(MSG_TERMINATE, NULL);
+               close(gTraceInfo.socket.daemonSock);
+               gTraceInfo.socket.daemonSock = -1;
+       }
+
+       finalize_event();
+
+       finalize_screencapture();
+
+       finalize_hash_table();
+
+       for(i = 0; i < NUM_ORIGINAL_LIBRARY; i++)
+       {
+               if(lib_handle[i] != NULL)
+               {
+                       dlclose(lib_handle[i]);
+               }
+       }
+
+       probeBlockEnd();
+}
+
+void __attribute__((destructor)) _fini_probe()
+{
+       PRINTMSG("->lib destructor. pid[%d]\n", getpid());
+       _uninit_();
+}
+
+
+/**************************************************************************
+ * Helper APIs
+ **************************************************************************/
+
+/************************************************************************
+ * manipulate and print log functions
+ ************************************************************************/
+const char *msg_code_to_srt(enum MessageType type)
+{
+       switch (type) {
+               case MSG_MSG:
+                       return "[INF]";
+               case MSG_ERROR:
+                       return "[ERR]";
+               case MSG_WARNING:
+                       return "[WRN]";
+               default:
+                       return "[???]";
+       }
+}
+
+bool printLog(log_t *log, int msgType)
+{
+       ssize_t res, len;
+       if(unlikely(gTraceInfo.socket.daemonSock == -1))
+               return false;
+
+       if(unlikely(log == NULL))
+               return false;
+
+       probeBlockStart();
+       log->type = msgType;
+       len = sizeof(log->type) + sizeof(log->length) + log->length;
+
+       real_pthread_mutex_lock(&(gTraceInfo.socket.sockMutex));
+       res = send(gTraceInfo.socket.daemonSock, log, len, 0);
+       real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex));
+       probeBlockEnd();
+
+       return (res == len);
+}
+
+/*
+ * Debug function for ld preloaded library
+ * msgType - message type (MSG_TERMINATE, MSG_PID)
+ * str     - string send to host. may be NULL
+ * return  - true on success. false on fail.
+ */
+
+bool print_log_str(int msgType, char *str)
+{
+       log_t log;
+       ssize_t res, len;
+
+       /* Check connection status */
+       if(unlikely(gTraceInfo.socket.daemonSock == -1))
+               return false;
+
+       probeBlockStart();
+
+       /* fill message */
+       log.type = msgType;
+       if (str != NULL)
+               log.length = snprintf(log.data, sizeof(log.data), str);
+       else
+               log.length = 0;
+
+       /* calculate message length */
+       len = sizeof(log.type) + sizeof(log.length) + log.length;
+
+       /* lock socket and send */
+       real_pthread_mutex_lock(&(gTraceInfo.socket.sockMutex));
+       res = send(gTraceInfo.socket.daemonSock, &log, len, 0);
+       real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex));
+       probeBlockEnd();
+
+       return (res == len);
+}
+
+/*
+ * Additional debug function for ld preloaded library can be used in defines
+ * msgType   - message type (MSG_TERMINATE, MSG_PID)
+ * func_name - call function name
+ * line      - call line number
+ * ...       - format and arguments like for sprintf function
+ * return    - true on success. false on fail.
+ */
+bool print_log_fmt(int msgType, const char *func_name, int line, ...)
+{
+       ssize_t res = 0, len = 0;
+       char *fmt, *p;
+       int n;
+       log_t log;
+       va_list ap;
+
+       /* Check connection status */
+
+       probeBlockStart();
+
+       /* fill message */
+       log.type = msgType;
+
+       p = log.data;
+       n = snprintf(p, sizeof(log.data), "[%05d:%05d]%s:%d)", _getpid(), _gettid(),  func_name, line);
+       p += n;
+
+       /* extract params */
+       va_start(ap, line);
+       fmt = va_arg(ap, char *);
+       if (fmt != NULL) {
+               if (strchr(fmt, '%') == NULL)
+                       n += snprintf(p, sizeof(log.data) - n, "%s", fmt);
+               else
+                       n += vsnprintf(p, sizeof(log.data) - n, fmt, ap);
+       }
+       va_end(ap);
+
+       /* check printed symbols count */
+       if (n > -1 && n < (int)sizeof(log.data)) {
+               log.length = n;
+       } else {
+               fprintf(stderr, "Log pack error\n");
+               log.length = 0;
+       }
+
+       /* calculate message length */
+       len = sizeof(log.type) + sizeof(log.length) + log.length;
+
+       /* lock socket and send */
+       real_pthread_mutex_lock(&(gTraceInfo.socket.sockMutex));
+
+       if(unlikely(gTraceInfo.socket.daemonSock != -1)) {
+               res = send(gTraceInfo.socket.daemonSock, &log, len, MSG_DONTWAIT);
+       } else {
+               /* if socket is not connected, out to stderr */
+               fprintf(stderr, "%s %s\n", msg_code_to_srt(msgType), log.data);
+               fflush(stderr);
+       }
+
+       real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex));
+
+       probeBlockEnd();
+
+       /* return result */
+       return (res == len);
+}
+
+// get backtrace string
+// return stack depth if succeed, otherwise return 0
+// parameter 'log' cannot be null
+/* TODO remove unused code (getBacktraceString)*/
+int getBacktraceString(log_t* log, int bufsize)
+{
+       void* array[MAX_STACK_DEPTH];
+       char** strings = NULL;
+       size_t i, size;
+       int initsize;
+       int curlen;
+       int stringlen;
+
+       if(log == NULL)
+               return 0;
+
+       probeBlockStart();
+
+       initsize = log->length;
+       curlen = initsize;
+       log->data[curlen] = '\0';       // is this necessary ?
+       size = backtrace(array, MAX_STACK_DEPTH);
+       if(likely(size > TRIM_STACK_DEPTH))
+       {
+               strings = BACKTRACE_SYMBOLS(array + TRIM_STACK_DEPTH, size - TRIM_STACK_DEPTH);
+
+               if(likely(strings != NULL))
+               {
+                       for(i = TRIM_STACK_DEPTH; i < size; i++)
+                       {
+                               stringlen = strlen(strings[i - TRIM_STACK_DEPTH]) + 14;
+                               if(curlen + stringlen >= bufsize + initsize)
+                                       break;
+
+                               curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,%s`,", (unsigned int)(array[i]), strings[i - TRIM_STACK_DEPTH]);
+                       }
+                       curlen -= 2;
+                       log->data[curlen] = '\0';
+                       log->length = curlen;
+                       free(strings);
+               }
+               else    // failed to get backtrace symbols
+               {
+                       // just print trace address
+                       for(i = TRIM_STACK_DEPTH; i < size; i++)
+                       {
+                               stringlen = 23;
+                               if(curlen + stringlen >= bufsize + initsize)
+                                       break;
+
+                               curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,(unknown)`,", (unsigned int)(array[i]));
+                       }
+                       curlen -= 2;
+                       log->data[curlen] = '\0';
+                       log->length = curlen;
+               }
+
+               probeBlockEnd();
+               return (int)(size - TRIM_STACK_DEPTH);
+       }
+       else
+       {
+               probeBlockEnd();
+               return 0;
+       }
+}
+
+/*************************************************************************
+ * probe block control functions
+ *************************************************************************/
+static inline bool isNoFiltOptionEnabled(enum DaOptions option)
+{
+       return
+               ((option == OPT_ALLOC)
+                && isOptionEnabled(OPT_ALLOC_ALWAYS))
+               || ((option == OPT_FILE)
+                   && isOptionEnabled(OPT_FILE_ALWAYS))
+               || ((option == OPT_THREAD)
+                   && isOptionEnabled(OPT_THREAD_ALWAYS))
+               || ((option == OPT_UI)
+                   && isOptionEnabled(OPT_UI_ALWAYS))
+               || ((option == OPT_NETWORK)
+                   && isOptionEnabled(OPT_NETWORK_ALWAYS))
+               || ((option == OPT_GLES)
+                   && isOptionEnabled(OPT_GLES_ALWAYS));
+}
+
+static inline bool is_user_call(const void *caller)
+{
+       bool user = false;
+       char **strings;
+
+       if (gTraceInfo.exec_map.map_start != NULL) {
+               if (caller >= gTraceInfo.exec_map.map_start &&
+                   caller <= gTraceInfo.exec_map.map_end)
+                       user = true;
+       } else {
+               strings = BACKTRACE_SYMBOLS((void * const *)caller, 1);
+               if (strings != NULL) {
+                       if (determineCaller(strings[0]) == 0)
+                               user = true;
+                       free(strings);
+               }
+       }
+
+       return user;
+}
+
+int preBlockBegin(const void *caller, bool bFiltering, enum DaOptions option)
+{
+       bool opt_nofilt;
+
+       if (gTraceInfo.socket.daemonSock == -1)
+               return 0;
+
+       if(gProbeBlockCount != 0 || gProbeDepth != 0)
+               return 0;
+
+       if(gTraceInfo.init_complete <= 0)
+               return 0;
+
+       opt_nofilt = isNoFiltOptionEnabled(option);
+
+       /* Actually we are considering 3 variables here:
+           - regular option is enabled
+           - non-filtering (always) option is enabled
+           - per-probe filtering
+       */
+       if (!isOptionEnabled(option) && !opt_nofilt)
+               return 0;
+       else if (opt_nofilt)
+               bFiltering = false;
+
+       probeBlockStart();
+
+       if (maps_is_instrument_section_by_addr(caller) == 1) {
+               probingStart();
+               return 2; /* user call */
+       } else {
+               if (bFiltering) {
+                       probeBlockEnd();
+                       return 0; /* not probing */
+               } else {
+                       probingStart();
+                       return 1; /* internal call */
+               }
+       }
+}
+
+int postBlockBegin(int preresult)
+{
+       if(preresult)
+       {
+               probeBlockStart();
+       }
+
+       return preresult;
+}
+
+void preBlockEnd()
+{
+       probeBlockEnd();
+}
+
+void postBlockEnd()
+{
+       probingEnd();
+       probeBlockEnd();
+}
+
+/*************************************************************************
+ * helper info getter functions
+ *************************************************************************/
+// return current time in 1/10000 sec unit
+unsigned long getCurrentTime()
+{
+       struct timeval cTime;
+
+       gettimeofday(&cTime, NULL);
+
+       return (unsigned long)((cTime.tv_sec * 10000 + (cTime.tv_usec/100)));
+}
+
+unsigned int getCurrentEventIndex()
+{
+       return gTraceInfo.index.eventIndex;
+}
+
+uint64_t get_current_nsec(void)
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return (uint64_t)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
+}
+
+/************************************************************************
+ * probe functions
+ ************************************************************************/
+bool setProbePoint(probeInfo_t* iProbe)
+{
+       if(unlikely(iProbe == NULL))
+       {
+               return false;
+       }
+
+       probeBlockStart();
+
+       // atomic operaion(gcc builtin) is more expensive then pthread_mutex
+       real_pthread_mutex_lock(&(gTraceInfo.index.eventMutex));
+       iProbe->eventIndex = gTraceInfo.index.eventIndex++;
+       real_pthread_mutex_unlock(&(gTraceInfo.index.eventMutex));
+
+       iProbe->currentTime = getCurrentTime();
+       iProbe->pID = _getpid();
+       iProbe->tID = _gettid();
+       iProbe->callDepth = gProbeDepth;
+
+       probeBlockEnd();
+       return true;
+}
+
+// update heap memory size through socket
+// return 0 if size is updated through socket
+// return 1 if size is updated into global variable
+int update_heap_memory_size(bool isAdd, size_t size)
+{
+       if(isAdd)
+       {
+               __sync_add_and_fetch(&g_total_alloc_size, (long)size);
+       }
+       else
+       {
+               __sync_sub_and_fetch(&g_total_alloc_size, (long)size);
+       }
+
+       return 0;
+}
+
+/* rtdl_next */
+void *rtdl_next(const char *symname)
+{
+       void *symbol;
+
+       probeBlockStart();
+
+       symbol = dlsym(RTLD_NEXT, symname);
+       if (symbol == NULL || dlerror() != NULL) {
+               PRINTERR("dlsym failed <%s>\n", symname);
+               exit(41);
+       }
+
+       probeBlockEnd();
+
+       return symbol;
+}
diff --git a/helper/private_link.h b/helper/private_link.h
new file mode 100644 (file)
index 0000000..443d911
--- /dev/null
@@ -0,0 +1,374 @@
+/* Data structure for communication from the run-time dynamic linker for
+   loaded ELF shared objects.
+   Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef        _PRIVATE_LINK_H
+#define        _PRIVATE_LINK_H 1
+
+#ifdef _LINK_H
+# error this should be impossible
+#endif
+
+/* Get most of the contents from the public header, but we define a
+   different `struct link_map' type for private use.  The la_objopen
+   prototype uses the type, so we have to declare it separately.  */
+#define link_map       link_map_public
+#define la_objopen     la_objopen_wrongproto
+#include <link.h>
+#undef link_map
+#undef la_objopen
+
+struct link_map;
+extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid, uintptr_t *__cookie);
+
+#include <stddef.h>            // for ptrdiff_t
+//#include <tls.h>
+//#include <bits/libc-lock.h>
+
+/* Number of extra dynamic section entries for this architecture.
+   By default there are none.  */
+#define DT_THISPROCNUM  0
+
+// The type of the return value of fixup/profile_fixup.
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+// Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a link map.
+#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
+// Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
+#define DL_FIXUP_VALUE_ADDR(value) (value)
+#define DL_FIXUP_ADDR_VALUE(addr) (addr)
+
+struct link_map_machine
+{
+       // empty by default
+};
+
+/* Some internal data structures of the dynamic linker used in the
+   linker map.  We only provide forward declarations.  */
+
+/* For the version handling we need an array with only names and their
+   hash values.  */
+struct r_found_version
+{
+       const char *name;
+       ElfW(Word) hash;
+       int hidden;
+       const char *filename;
+};
+
+/* We want to cache information about the searches for shared objects.  */
+
+enum r_dir_status { unknown, nonexisting, existing };
+
+struct r_search_path_elem
+{
+       /* This link is only used in the `all_dirs' member of `r_search_path'.  */
+       struct r_search_path_elem *next;
+
+       /* Strings saying where the definition came from.  */
+       const char *what;
+       const char *where;
+
+       /* Basename for this search path element.  The string must end with     a slash character.  */
+       const char *dirname;
+       size_t dirnamelen;
+
+       enum r_dir_status status[0];
+};
+
+/* A data structure for a simple single linked list of strings.  */
+struct libname_list
+{
+       const char *name;       /* Name requested (before search).  */
+       struct libname_list *next;  /* Link to next name for this object.  */
+       int dont_free;      /* Flag whether this element should be freed
+                                               if the object is not entirely unloaded.  */
+};
+
+/* Forward declaration.  */
+struct link_map;
+
+/* Structure to describe a single list of scope elements.  The lookup
+   functions get passed an array of pointers to such structures.  */
+struct r_scope_elem
+{
+       /* Array of maps for the scope.  */
+       struct link_map **r_list;
+       /* Number of entries in the scope.  */
+       unsigned int r_nlist;
+};
+
+
+/* Structure to record search path and allocation mechanism.  */
+struct r_search_path_struct
+{
+       struct r_search_path_elem **dirs;
+       int malloced;
+};
+
+
+/* Structure describing a loaded shared object.  The `l_next' and `l_prev'
+   members form a chain of all the shared objects loaded at startup.
+
+   These data structures exist in space used by the run-time dynamic linker;
+   modifying them may have disastrous results.
+
+   This data structure might change in future, if necessary.  User-level
+   programs must avoid defining objects of this type.  */
+
+struct link_map
+  {
+    /* These first few members are part of the protocol with the debugger.
+       This is the same format used in SVR4.  */
+
+    ElfW(Addr) l_addr;         /* Base address shared object is loaded at.  */
+    char *l_name;              /* Absolute file name object was found in.  */
+    ElfW(Dyn) *l_ld;           /* Dynamic section of the shared object.  */
+    struct link_map *l_next, *l_prev; /* Chain of loaded objects.  */
+
+    /* All following members are internal to the dynamic linker.
+       They may change without notice.  */
+
+    /* This is an element which is only ever different from a pointer to
+       the very same copy of this type for ld.so when it is used in more
+       than one namespace.  */
+    struct link_map *l_real;
+
+    /* Number of the namespace this link map belongs to.  */
+    Lmid_t l_ns;
+
+    struct libname_list *l_libname;
+    /* Indexed pointers to dynamic section.
+       [0,DT_NUM) are indexed by the processor-independent tags.
+       [DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC.
+       [DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are
+       indexed by DT_VERSIONTAGIDX(tagvalue).
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by
+       DT_EXTRATAGIDX(tagvalue).
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are
+       indexed by DT_VALTAGIDX(tagvalue) and
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM)
+       are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>.  */
+
+    ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
+                     + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
+    const ElfW(Phdr) *l_phdr;  /* Pointer to program header table in core.  */
+    ElfW(Addr) l_entry;                /* Entry point location.  */
+    ElfW(Half) l_phnum;                /* Number of program header entries.  */
+    ElfW(Half) l_ldnum;                /* Number of dynamic segment entries.  */
+
+    /* Array of DT_NEEDED dependencies and their dependencies, in
+       dependency order for symbol lookup (with and without
+       duplicates).  There is no entry before the dependencies have
+       been loaded.  */
+    struct r_scope_elem l_searchlist;
+
+    /* We need a special searchlist to process objects marked with
+       DT_SYMBOLIC.  */
+    struct r_scope_elem l_symbolic_searchlist;
+
+    /* Dependent object that first caused this object to be loaded.  */
+    struct link_map *l_loader;
+
+    /* Array with version names.  */
+    struct r_found_version *l_versions;
+    unsigned int l_nversions;
+
+    /* Symbol hash table.  */
+    Elf_Symndx l_nbuckets;
+    Elf32_Word l_gnu_bitmask_idxbits;
+    Elf32_Word l_gnu_shift;
+    const ElfW(Addr) *l_gnu_bitmask;
+    union
+    {
+      const Elf32_Word *l_gnu_buckets;
+      const Elf_Symndx *l_chain;
+    };
+    union
+    {
+      const Elf32_Word *l_gnu_chain_zero;
+      const Elf_Symndx *l_buckets;
+    };
+
+    unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose.  */
+    enum                       /* Where this object came from.  */
+      {
+       lt_executable,          /* The main executable program.  */
+       lt_library,             /* Library needed by main executable.  */
+       lt_loaded               /* Extra run-time loaded shared object.  */
+      } l_type:2;
+    unsigned int l_relocated:1;        /* Nonzero if object's relocations done.  */
+    unsigned int l_init_called:1; /* Nonzero if DT_INIT function called.  */
+    unsigned int l_global:1;   /* Nonzero if object in _dl_global_scope.  */
+    unsigned int l_reserved:2; /* Reserved for internal use.  */
+    unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
+                                       to by `l_phdr' is allocated.  */
+    unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
+                                     the l_libname list.  */
+    unsigned int l_faked:1;    /* Nonzero if this is a faked descriptor
+                                  without associated file.  */
+    unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
+                                      should be called on this link map
+                                      when relocation finishes.  */
+    unsigned int l_used:1;     /* Nonzero if the DSO is used.  */
+    unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing.  */
+    unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
+                                      is interested in the PLT interception.*/
+    unsigned int l_removed:1;  /* Nozero if the object cannot be used anymore
+                                  since it is removed.  */
+    unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
+                                   mprotected or if no holes are present at
+                                   all.  */
+
+    /* Collected information about own RPATH directories.  */
+    struct r_search_path_struct l_rpath_dirs;
+
+    /* Collected results of relocation while profiling.  */
+    struct reloc_result
+    {
+      DL_FIXUP_VALUE_TYPE addr;
+      struct link_map *bound;
+      unsigned int boundndx;
+      uint32_t enterexit;
+      unsigned int flags;
+    } *l_reloc_result;
+
+    /* Pointer to the version information if available.  */
+    ElfW(Versym) *l_versyms;
+
+    /* String specifying the path where this object was found.  */
+    const char *l_origin;
+
+    /* Start and finish of memory map for this object.  l_map_start
+       need not be the same as l_addr.  */
+    ElfW(Addr) l_map_start, l_map_end;
+    /* End of the executable part of the mapping.  */
+    ElfW(Addr) l_text_end;
+
+    /* Default array for 'l_scope'.  */
+    struct r_scope_elem *l_scope_mem[4];
+    /* Size of array allocated for 'l_scope'.  */
+    size_t l_scope_max;
+    /* This is an array defining the lookup scope for this link map.
+       There are initially at most three different scope lists.  */
+    struct r_scope_elem **l_scope;
+
+    /* A similar array, this time only with the local scope.  This is
+       used occasionally.  */
+    struct r_scope_elem *l_local_scope[2];
+
+    /* This information is kept to check for sure whether a shared
+       object is the same as one already loaded.  */
+    dev_t l_dev;
+    ino64_t l_ino;
+
+    /* Collected information about own RUNPATH directories.  */
+    struct r_search_path_struct l_runpath_dirs;
+
+    /* List of object in order of the init and fini calls.  */
+    struct link_map **l_initfini;
+
+    /* List of the dependencies introduced through symbol binding.  */
+    unsigned int l_reldepsmax;
+    struct link_map_reldeps
+      {
+       unsigned int act;
+       struct link_map *list[];
+      } *l_reldeps;
+
+    /* Various flag words.  */
+    ElfW(Word) l_feature_1;
+    ElfW(Word) l_flags_1;
+    ElfW(Word) l_flags;
+
+    /* Temporarily used in `dl_close'.  */
+    int l_idx;
+
+    struct link_map_machine l_mach;
+
+    struct
+    {
+      const ElfW(Sym) *sym;
+      int type_class;
+      struct link_map *value;
+      const ElfW(Sym) *ret;
+    } l_lookup_cache;
+
+    /* Thread-local storage related info.  */
+
+    /* Start of the initialization image.  */
+    void *l_tls_initimage;
+    /* Size of the initialization image.  */
+    size_t l_tls_initimage_size;
+    /* Size of the TLS block.  */
+    size_t l_tls_blocksize;
+    /* Alignment requirement of the TLS block.  */
+    size_t l_tls_align;
+    /* Offset of first byte module alignment.  */
+    size_t l_tls_firstbyte_offset;
+#ifndef NO_TLS_OFFSET
+# define NO_TLS_OFFSET 0
+#endif
+#ifndef FORCED_DYNAMIC_TLS_OFFSET
+# if NO_TLS_OFFSET == 0
+#  define FORCED_DYNAMIC_TLS_OFFSET 1
+# elif NO_TLS_OFFSET == -1
+#  define FORCED_DYNAMIC_TLS_OFFSET -2
+# else
+#  error "FORCED_DYNAMIC_TLS_OFFSET is not defined"
+# endif
+#endif
+    /* For objects present at startup time: offset in the static TLS block.  */
+    ptrdiff_t l_tls_offset;
+    /* Index of the module in the dtv array.  */
+    size_t l_tls_modid;
+
+    /* Information used to change permission after the relocations are
+       done.  */
+    ElfW(Addr) l_relro_addr;
+    size_t l_relro_size;
+
+    unsigned long long int l_serial;
+
+    /* Audit information.  This array apparent must be the last in the
+       structure.  Never add something after it.  */
+    struct auditstate
+    {
+      uintptr_t cookie;
+      unsigned int bindflags;
+    } l_audit[0];
+  };
+
+
+#if __ELF_NATIVE_CLASS == 32
+# define symbind symbind32
+#elif __ELF_NATIVE_CLASS == 64
+# define symbind symbind64
+#else
+# error "__ELF_NATIVE_CLASS must be defined"
+#endif
+
+extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+                                              size_t size, void *data),
+                             void *data);
+
+#endif /* include/link.h */
diff --git a/helper/real_functions.c b/helper/real_functions.c
new file mode 100644 (file)
index 0000000..ac287fc
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <stdint.h>                    // fot uint32_t,uint64_t
+#include "daprobe.h"
+
+void *(*real_malloc)(size_t) = NULL;
+
+int _init_real_functions()
+{
+       rtdl_next_set_once(real_malloc, "malloc");
+       return 0;
+}
diff --git a/include/binproto.h b/include/binproto.h
new file mode 100644 (file)
index 0000000..5e153fc
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Nikita Kalyazin <n.kalyazin@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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 __BIN_PROTO_H__
+#define __BIN_PROTO_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <sys/time.h>
+
+#include <sys/socket.h>
+#include "dahelper.h"
+#include "api_id_mapping.h"
+
+#define MSG_PROBE_MEMORY 0x0101
+#define MSG_PROBE_UICONTROL 0x0102
+#define MSG_PROBE_UIEVENT 0x0103
+#define MSG_PROBE_RESOURCE 0x0104
+#define MSG_PROBE_LIFECYCLE 0x0105
+#define MSG_PROBE_SCREENSHOT 0x0106
+#define MSG_PROBE_SCENE 0x0107
+#define MSG_PROBE_THREAD 0x0108
+#define MSG_PROBE_CUSTOM 0x0109
+#define MSG_PROBE_SYNC 0x0110
+#define MSG_PROBE_NETWORK 0x0111
+#define MSG_PROBE_GL 0x0112
+
+#define SCREENSHOT_DIRECTORY   "/tmp/da"
+
+#define MAX_PACK_FILENAME_LEN (4 * 1024)
+#define MAX_SHADER_LEN (4 * 1024)
+#define ADD_LOCAL_BUF_SIZE (1024)
+#define MAX_GL_CONTEXT_VALUE_SIZE (1024)
+#define MAX_LOCAL_BUF_SIZE (MAX_SHADER_LEN + ADD_LOCAL_BUF_SIZE)
+#define LOCAL_BUF msg_buf
+
+// TODO: remove this copy-paste
+#define CALLER_ADDRESS                                                 \
+       ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
+
+static inline uint64_t voidp_to_uint64(const void *p)
+{
+       return (uint64_t)(uintptr_t)p;
+}
+
+// COMMON
+static inline char *pack_int32(char *to, uint32_t val)
+{
+       *(uint32_t *)to = val;
+       return to + sizeof(uint32_t);
+}
+
+static inline char *pack_int64(char *to, uint64_t val)
+{
+       *(uint64_t *)to = val;
+       return to + sizeof(uint64_t);
+}
+
+static char __attribute__((used)) *pack_string(char *to, const char *str)
+{
+       if (!str) {
+               *to = '\0';
+               return to + 1;
+       } else {
+               size_t len = strlen(str) + 1;
+               strncpy(to, str, len);
+               return to + len;
+       }
+}
+
+static char __attribute__((used)) *pack_bin(char *to, const char *from,
+                                           uint32_t len)
+{
+       memcpy(to, from, len);
+       return to + len;
+}
+
+static inline char *pack_double(char *to, double val)
+{
+       *(double *)to = val;
+       return to + sizeof(double);
+}
+
+static inline char *pack_timestamp(char *to)
+{
+       struct timeval tv;
+
+       gettimeofday(&tv, NULL);
+       to = pack_int32(to, tv.tv_sec);
+       to = pack_int32(to, tv.tv_usec * 1000);
+
+       return to;
+}
+
+///////////////////////////////////////////////////////////////////
+// function: pack_array
+///////////////////////////////////////////////////////////////////
+// info:
+//  Pack array param to buffer
+// params:
+//  char *to              - destination buffer
+//  va_list *args         - array size and array (pointer)
+//  uint32_t element_size - size of array element
+// return:
+//  char *                - destination pointer end after pack
+static char *pack_array(char *to, va_list *args, uint32_t element_size)
+{
+       uint32_t d;
+       uint64_t p;
+
+       // get array elements count
+       d = va_arg(*args, uint32_t);
+       // get array pointer
+       p = (unsigned long)(uintptr_t)va_arg(*args, uint64_t);
+
+       // pack original pointer
+       memcpy(to, &p, sizeof(p));
+       to += sizeof(p);
+       // pack array elements count
+       memcpy(to, &d, sizeof(d));
+       to += sizeof(d);
+
+       // pack array elements
+       element_size *= d;
+       memcpy(to, (void *)(long)p, element_size);
+       to += element_size;
+
+       return to;
+}
+
+static char __attribute__((used)) *pack_string_to_file(char *to, const char *st,
+                                                      uint32_t data_len,
+                                                      uint32_t max_len)
+{
+       if (data_len < max_len) {
+               /* pack string to buffer */
+               to = pack_string(to, st);
+       } else {
+               /* pack string to file */
+               char template_name[] = SCREENSHOT_DIRECTORY "/swap_XXXXXX";
+               char dst_path_pack[MAX_PATH_LENGTH];
+               FILE *file;
+               mktemp(template_name);
+               file = fopen(template_name, "w");
+               if (file != NULL) {
+                       fwrite(st, data_len, 1, file);
+                       fclose(file);
+               }
+               snprintf(dst_path_pack, sizeof(dst_path_pack), "FILE:%s", template_name);
+               to = pack_string(to, dst_path_pack);
+       }
+       return to;
+}
+
+static char __attribute__((used)) *pack_value_by_type(char *to, const char **t, va_list *args)
+{
+       uint8_t c;
+       uint8_t cs;
+       uint32_t d;
+       uint64_t x;
+       uint64_t p;
+       float f;
+       double w;
+       char *s;
+       int n;
+
+       *to++ = **t;
+
+       switch (**t) {
+       case 'b':
+       case 'c':
+               c = (uint8_t)va_arg(*args, uint32_t);
+               memcpy(to, &c, sizeof(c));
+               to += sizeof(c);
+               break;
+       case 'd':
+               d = va_arg(*args, uint32_t);
+               memcpy(to, &d, sizeof(d));
+               to += sizeof(d);
+               break;
+       case 'x':
+               x = 0; // real value may be less then uint64_t
+               x = (unsigned long)(uint64_t)va_arg(*args, uint64_t);
+               memcpy(to, &x, sizeof(x));
+               to += sizeof(x);
+               break;
+       case 'p':
+               p = 0; // real value may be less then uint64_t
+               p = (unsigned long)(uintptr_t)va_arg(*args, uint64_t);
+               memcpy(to, &p, sizeof(p));
+               to += sizeof(p);
+               break;
+       case 'f':
+               f = (float)va_arg(*args, double);
+               memcpy(to, &f, sizeof(f));
+               to += sizeof(f);
+               break;
+       case 'w':
+               w = va_arg(*args, double);
+               memcpy(to, &w, sizeof(w));
+               to += sizeof(w);
+               break;
+       case 's':
+               cs = *((*t)+1);
+               s = va_arg(*args, char *);
+
+               switch (cs) {
+                       case '4': //"s4" - pack 4K or to file
+                               (*t)++;
+                               to = pack_string_to_file(to, s, strlen(s),
+                                                        MAX_PACK_FILENAME_LEN);
+                               break;
+                       case '0': //"s0" - pack 256 bytes
+                               (*t)++;
+                               n = strlen(s) + 1;
+                               if (n >= 255)
+                                       n = 255;
+                               strncpy(to, s, n);
+                               to[n-1] = '\0';
+                               to += n;
+                               break;
+                       default: //"s" - pack all string
+                               n = strlen(s) + 1;
+                               strncpy(to, s, n);
+                               to += n;
+                               break;
+               }
+
+               break;
+       case 'v':
+       case 'n':
+               break;
+       /* pack arrays params */
+       case 'D':
+               /* array of 'd' uint32_t */
+               to = pack_array(to, args, sizeof(d));
+               break;
+       case 'F':
+               /* array of 'f' float */
+               to = pack_array(to, args, sizeof(f));
+               break;
+       case 'W':
+               /* array of 'w' double */
+               to = pack_array(to, args, sizeof(w));
+               break;
+       default: {
+               PRINTERR("ERROR PACK #%d '%c'!!!", **t, **t);
+               to--;
+               break;
+               }
+       }
+
+       (*t)++;
+       return to;
+}
+
+static char __attribute__((used)) *pack_args(char *to, const char *fmt, ...)
+{
+       va_list args;
+       uint32_t num = 0;
+       const char *t = fmt;
+       char *size_p = to;
+
+       //put dummy num value
+       memcpy(to, &num, sizeof(num));
+       to += sizeof(num);
+
+       va_start(args, fmt);
+
+       for (t = fmt; *t != '\0';) {
+               to = pack_value_by_type(to, &t, &args);
+               num++;
+       }
+
+       //set real num value
+       memcpy(size_p, &num, sizeof(num));
+
+       va_end(args);
+
+       return to;
+}
+
+static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
+{
+       va_list args;
+       char fmt[] = {ret_type, 0};
+       const char *fmtp = (const char *)fmt;
+
+       va_start(args, ret_type);
+       to = pack_value_by_type(to, &fmtp, &args);
+       va_end(args);
+
+       return to;
+}
+
+#define BUF_PTR p
+#define RET_PTR ret_p
+#define PACK_INT32(val)                                \
+       BUF_PTR = pack_int32(BUF_PTR, val);
+#define PACK_INT64(val)                                \
+       BUF_PTR = pack_int64(BUF_PTR, val);
+#define PACK_STRING(str)                       \
+       BUF_PTR = pack_string(BUF_PTR, str);
+
+#define PACK_COMMON_BEGIN(msg_id, api_id, fmt, ...)            \
+       do {    /* PACK_COMMON_BEGIN*/                          \
+               BUF_PTR = pack_int32(BUF_PTR, msg_id);          /* msg id */    \
+               BUF_PTR = pack_int32(BUF_PTR, 0);               /* sequence */  \
+               BUF_PTR = pack_timestamp(BUF_PTR);              /* timestamp */ \
+               BUF_PTR = pack_int32(BUF_PTR, 0);               /* length */    \
+               BUF_PTR = pack_int32(BUF_PTR, api_id);          /* API id */    \
+               BUF_PTR = pack_int32(BUF_PTR, _getpid());       /* PID */       \
+               BUF_PTR = pack_int32(BUF_PTR, _gettid());       /* call pc*/\
+               BUF_PTR = pack_args(BUF_PTR, fmt, __VA_ARGS__); /* args */      \
+               RET_PTR = BUF_PTR;              \
+       } while (0)
+
+#define PACK_COMMON_END(ret_type, ret, errn, intern_call)                      \
+       do {    /* PACK_COMMON_END */                                           \
+               BUF_PTR = pack_ret(RET_PTR, ret_type, (uintptr_t)ret); /* return val */ \
+               BUF_PTR = pack_int64(BUF_PTR, (uint64_t)errn);  /* errno */     \
+               BUF_PTR = pack_int32(BUF_PTR, (uint32_t)intern_call);   /* internal call*/      \
+               BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)CALLER_ADDRESS); /*caller addr*/\
+               BUF_PTR = pack_int32(BUF_PTR, 0);       /* reserved */          \
+               BUF_PTR = pack_int32(BUF_PTR, 0);       /* reserved */          \
+       } while (0)
+
+#define PACK_RETURN_END(ret_type, ret)                                         \
+               RET_PTR = pack_ret(RET_PTR, ret_type, (uintptr_t)ret); /* return val */
+
+#define PACK_MEMORY(size, memory_api_type, addr)                               \
+       do {    /* PACK_MEMORY */                                               \
+               BUF_PTR = pack_int64(BUF_PTR, size);    /* alloc size */        \
+               BUF_PTR = pack_int32(BUF_PTR, memory_api_type); /* alloc type */\
+               BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)addr); /* alloc addr */\
+       } while (0)
+
+#define PACK_UICONTROL(control)                                                \
+       do {                                                            \
+               if (unlikely(control == NULL)) {                        \
+                       BUF_PTR = pack_string(BUF_PTR, "");             \
+                       BUF_PTR = pack_string(BUF_PTR, "");             \
+                       BUF_PTR = pack_int64(BUF_PTR, 0);               \
+               } else {                                                \
+                       char *type = NULL, *name = NULL;                \
+                       if (find_uiobject_hash((void*)(control),        \
+                                            &type, &name) == 1) {      \
+                               BUF_PTR = pack_string(BUF_PTR, type);   \
+                               BUF_PTR = pack_string(BUF_PTR, name);   \
+                       } else {                                        \
+                               BUF_PTR = pack_string(BUF_PTR, "");     \
+                               BUF_PTR = pack_string(BUF_PTR, "");     \
+                       }                                               \
+                       BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(control)); \
+               }                                                       \
+       } while(0)
+
+#define PACK_UIEVENT(event_type, detail_type, x, y, info1, info2)      \
+       do {    /* PACK_UIEVENT */                                      \
+               BUF_PTR = pack_int32(BUF_PTR, event_type);              \
+               BUF_PTR = pack_int32(BUF_PTR, detail_type);             \
+               BUF_PTR = pack_int32(BUF_PTR, x);                       \
+               BUF_PTR = pack_int32(BUF_PTR, y);                       \
+               BUF_PTR = pack_string(BUF_PTR, info1);                  \
+               BUF_PTR = pack_int32(BUF_PTR, info2);                   \
+       } while (0)
+
+#define PACK_RESOURCE(size, fd_value, fd_api_type, file_size,  \
+                     file_path)                                        \
+       do {    /* PACK_RESOURCE */                                     \
+               BUF_PTR = pack_int64(BUF_PTR, size);                    \
+               BUF_PTR = pack_int64(BUF_PTR, fd_value);                \
+               BUF_PTR = pack_int32(BUF_PTR, fd_api_type);             \
+               BUF_PTR = pack_int64(BUF_PTR, file_size);               \
+               BUF_PTR = pack_string_to_file(BUF_PTR, file_path,       \
+                                             strlen(file_path),        \
+                                             MAX_PACK_FILENAME_LEN);   \
+       } while (0)
+
+#define PACK_SCREENSHOT(image_file_path, orientation)                          \
+               do {    /* PACK_SCREENSHOT */                                   \
+                         BUF_PTR = pack_string(BUF_PTR, image_file_path);      \
+                         BUF_PTR = pack_int32(BUF_PTR, orientation);           \
+               } while (0)
+
+#define PACK_SCENE(scene_name, formid, pform, panelid, ppanel, transition, user)       \
+       do {                                                                            \
+               BUF_PTR = pack_string(BUF_PTR,  scene_name);                            \
+               if (unlikely(pform == NULL)) {                                          \
+                       BUF_PTR = pack_string(BUF_PTR, "");                             \
+                       BUF_PTR = pack_int64(BUF_PTR, 0);                               \
+               } else {                                                                \
+                       char *type = NULL, *name = NULL;                                \
+                       if (find_uiobject_hash((void*)(pform), &type, &name) == 1) {    \
+                               BUF_PTR = pack_string(BUF_PTR, name);                   \
+                       } else {                                                        \
+                               BUF_PTR = pack_string(BUF_PTR, "");                     \
+                       }                                                               \
+                       BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)pform);                \
+               }                                                                       \
+               if (unlikely(ppanel == NULL)) {                                         \
+                       BUF_PTR = pack_string(BUF_PTR, "");                             \
+                       BUF_PTR = pack_int64(BUF_PTR, 0);                               \
+               } else {                                                                \
+                       char *type = NULL, *name = NULL;                                \
+                       if (find_uiobject_hash((void*)(ppanel), &type, &name) == 1) {   \
+                               BUF_PTR = pack_string(BUF_PTR, name);                   \
+                       } else {                                                        \
+                               BUF_PTR = pack_string(BUF_PTR, "");                     \
+                       }                                                               \
+                       BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(ppanel));             \
+               }                                                                       \
+               BUF_PTR = pack_int64(BUF_PTR, transition);                              \
+               BUF_PTR = pack_int64(BUF_PTR, user);                                    \
+       } while(0)
+
+#define PACK_THREAD(thread_id, thread_type, api_type, class_name)      \
+        do {                                                           \
+       if(thread_type == THREAD_PTHREAD) {                             \
+           BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
+           BUF_PTR = pack_int64(BUF_PTR, 0);                           \
+       } else if(thread_type == THREAD_TIZENTHREAD_WORKER              \
+                   || thread_type == THREAD_TIZENTHREAD_EVENTDRIVEN) {   \
+           BUF_PTR = pack_int64(BUF_PTR, 0);                           \
+           BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
+       } else {                                                        \
+           BUF_PTR = pack_int64(BUF_PTR, 0);                           \
+           BUF_PTR = pack_int64(BUF_PTR, 0);                           \
+       }                                                               \
+       BUF_PTR = pack_int32(BUF_PTR, thread_type);                     \
+       BUF_PTR = pack_int32(BUF_PTR, api_type);                        \
+       BUF_PTR = pack_string(BUF_PTR, class_name);                     \
+       } while (0)
+
+#define PACK_CUSTOM(handle, type, name, color, value)          \
+       do {                                                    \
+               BUF_PTR = pack_int32(BUF_PTR, handle);          \
+               BUF_PTR = pack_int32(BUF_PTR, type);            \
+               BUF_PTR = pack_string(BUF_PTR, name);           \
+               BUF_PTR = pack_int32(BUF_PTR, color);           \
+               BUF_PTR = pack_double(BUF_PTR, value);          \
+       } while (0)
+
+#define PACK_SYNC(sync_val, sync_type, api_type)                    \
+       do {                                                         \
+               BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)sync_val);  \
+               BUF_PTR = pack_int32(BUF_PTR, sync_type);            \
+               BUF_PTR = pack_int32(BUF_PTR, api_type);             \
+       } while (0)
+
+/* TODO maloc/free for each event turns out expensive: think of buffer
+ * allocator implementation */
+#define PREPARE_LOCAL_BUF()                    \
+               char *LOCAL_BUF = (char *)(*real_malloc)(MAX_LOCAL_BUF_SIZE);   \
+               char *BUF_PTR = LOCAL_BUF;                      \
+               char *RET_PTR = NULL
+
+#define PREPARE_LOCAL_BUF_THOUGH(BUFF)                         \
+               char *LOCAL_BUF = BUFF;                         \
+               char *BUF_PTR = LOCAL_BUF;                      \
+               char *RET_PTR = NULL
+
+#define MSG_LEN_OFFSET 16
+#define MSG_HDR_LEN 20
+
+#define SET_MSG_LEN()                                                  \
+               *(uint32_t *)(msg_buf + MSG_LEN_OFFSET) = (p - msg_buf) - MSG_HDR_LEN;
+
+#define GET_MSG_LEN()                                                  \
+               (p - msg_buf) - MSG_HDR_LEN
+
+#define FLUSH_LOCAL_BUF()                                              \
+               SET_MSG_LEN();                                          \
+               send(gTraceInfo.socket.daemonSock, msg_buf, (p - msg_buf), 0); \
+               free(LOCAL_BUF);                                        \
+               LOCAL_BUF = NULL
+
+// =========================== post block macro ===========================
+
+#define POST_PACK_PROBEBLOCK_BEGIN()                                   \
+       newerrno = errno;                                               \
+       if(postBlockBegin(blockresult)) {
+
+#define POST_PACK_PROBEBLOCK_END()                                     \
+               postBlockEnd();                                         \
+       }                                                               \
+       errno = (newerrno != 0) ? newerrno : olderrno
+
+#define POST_PACK_PROBEBLOCK_ADD_END()                                 \
+               preBlockEnd();                                          \
+       }                                                               \
+       errno = (newerrno != 0) ? newerrno : olderrno
+
+
+/* int main(int argc, char **argv) */
+/* { */
+/*     char buf[1024]; */
+/*     char *p = buf; */
+
+/*     p = PACK_COMMON_BEGIN(p, 42, "cdxpfws", 'a', 10, (uint64_t)80, */
+/*                           (uint64_t)0, 0.19, 0.33, "hello!"); */
+/*     p = PACK_COMMON_END('p', p, 0); */
+
+/*     int fd = creat("out.bin", 0644); */
+/*     if (fd == -1) { */
+/*             printf("error\n"); */
+/*             exit(1); */
+/*     } */
+
+/*     write(fd, buf, p - buf); */
+/*     close(fd); */
+
+/*     return 0; */
+/* } */
+
+extern int _init_(void);
+extern void _uninit_(void);
+
+#endif /* __BIN_PROTO_H__ */
diff --git a/include/common_probe_init.h b/include/common_probe_init.h
new file mode 100644 (file)
index 0000000..418e548
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+#ifndef __COMMON_PROBE_INIT_H__
+#define __COMMON_PROBE_INIT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "dahelper.h"
+#include "da_gles20.h"
+////////////////////////////////////////////////////////////////////////////
+//egl init probe function
+//  params:
+//    func_name    - original function name for dlsym search
+//    func_pointer - original function pointer (return)
+//
+//  info
+//    search original function by name
+//    function have no return becouse on error it terminates main application
+extern void init_probe_egl(const char *func_name, void **func_pointer,
+                          ORIGINAL_LIBRARY id);
+
+extern void init_probe_gl(const char *func_name, void **func_pointer,
+                         ORIGINAL_LIBRARY id, int blockresult, int32_t vAPI_ID);
+
+extern void probe_terminate_with_err(const char *msg, const char *func_name,
+                                    ORIGINAL_LIBRARY id);
+
+void __init_gl_api__(void);
+int __init_gl_functions__(void);
+
+/* links to real functions to call in probes */
+extern void (*real_glGetVertexAttribfv)(GLuint index, GLenum pname,
+                                       GLfloat *params);
+extern void (*real_glGetIntegerv)(GLenum pname, GLint * params);
+extern void (*real_glGetProgramiv)(GLuint program, GLenum pname, GLint *params);
+extern void (*real_glGetShaderiv)(GLuint shader, GLenum pname, GLint *params);
+extern void (*real_glGetActiveAttrib)(GLuint program, GLuint index,
+                                     GLsizei bufSize, GLsizei *length,
+                                     GLint *size, GLenum *type, char *name);
+extern void (*real_glGetActiveUniform)(GLuint program, GLuint index,
+                                      GLsizei bufSize, GLsizei *length,
+                                      GLint *size, GLenum *type, char *name);
+extern void (*real_glGetShaderSource)(GLuint shader, GLsizei bufSize,
+                                     GLsizei *length, char *source);
+extern void (*real_glGetBufferParameteriv)(GLenum target, GLenum value,
+                                          GLint *data);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* __COMMON_PROBE_INIT_H__ */
diff --git a/include/da_gl_api_func_list.h b/include/da_gl_api_func_list.h
new file mode 100644 (file)
index 0000000..5da8ca0
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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 _DA_GL_API_FUNC_LIST_H
+#define _DA_GL_API_FUNC_LIST_H
+
+#define GL_ALL_FUNCTIONS \
+ X(glActiveTexture) \
+ X(glAttachShader) \
+ X(glBindAttribLocation) \
+ X(glBindBuffer) \
+ X(glBindFramebuffer) \
+ X(glBindRenderbuffer) \
+ X(glBindTexture) \
+ X(glBlendColor) \
+ X(glBlendEquation) \
+ X(glBlendEquationSeparate) \
+ X(glBlendFunc) \
+ X(glBlendFuncSeparate) \
+ X(glBufferData) \
+ X(glBufferSubData) \
+ X(glCheckFramebufferStatus) \
+ X(glClear) \
+ X(glClearColor) \
+ X(glClearDepthf) \
+ X(glClearStencil) \
+ X(glColorMask) \
+ X(glCompileShader) \
+ X(glCompressedTexImage2D) \
+ X(glCompressedTexSubImage2D) \
+ X(glCopyTexImage2D) \
+ X(glCopyTexSubImage2D) \
+ X(glCreateProgram) \
+ X(glCreateShader) \
+ X(glCullFace) \
+ X(glDeleteBuffers) \
+ X(glDeleteFramebuffers) \
+ X(glDeleteProgram) \
+ X(glDeleteRenderbuffers) \
+ X(glDeleteShader) \
+ X(glDeleteTextures) \
+ X(glDepthFunc) \
+ X(glDepthMask) \
+ X(glDepthRangef) \
+ X(glDetachShader) \
+ X(glDisable) \
+ X(glDisableVertexAttribArray) \
+ X(glDrawArrays) \
+ X(glDrawElements) \
+ X(glEnable) \
+ X(glEnableVertexAttribArray) \
+ X(glFinish) \
+ X(glFlush) \
+ X(glFramebufferRenderbuffer) \
+ X(glFramebufferTexture2D) \
+ X(glFrontFace) \
+ X(glGenBuffers) \
+ X(glGenFramebuffers) \
+ X(glGenRenderbuffers) \
+ X(glGenTextures) \
+ X(glGenerateMipmap) \
+ X(glGetBooleanv) \
+ X(glGetFloatv) \
+ X(glGetIntegerv) \
+ X(glGetActiveAttrib) \
+ X(glGetActiveUniform) \
+ X(glGetAttachedShaders) \
+ X(glGetAttribLocation) \
+ X(glGetBufferParameteriv) \
+ X(glGetError) \
+ X(glGetFramebufferAttachmentParameteriv) \
+ X(glGetProgramInfoLog) \
+ X(glGetProgramiv) \
+ X(glGetRenderbufferParameteriv) \
+ X(glGetShaderInfoLog) \
+ X(glGetShaderPrecisionFormat) \
+ X(glGetShaderSource) \
+ X(glGetShaderiv) \
+ X(glGetString) \
+ X(glGetTexParameterfv) \
+ X(glGetTexParameteriv) \
+ X(glGetUniformfv) \
+ X(glGetUniformiv) \
+ X(glGetUniformLocation) \
+ X(glGetVertexAttribfv) \
+ X(glGetVertexAttribiv) \
+ X(glGetVertexAttribPointerv) \
+ X(glHint) \
+ X(glIsBuffer) \
+ X(glIsEnabled) \
+ X(glIsFramebuffer) \
+ X(glIsProgram) \
+ X(glIsRenderbuffer) \
+ X(glIsShader) \
+ X(glIsTexture) \
+ X(glLineWidth) \
+ X(glLinkProgram) \
+ X(glPixelStorei) \
+ X(glPolygonOffset) \
+ X(glReadPixels) \
+ X(glReleaseShaderCompiler) \
+ X(glRenderbufferStorage) \
+ X(glSampleCoverage) \
+ X(glScissor) \
+ X(glShaderBinary) \
+ X(glShaderSource) \
+ X(glStencilFunc) \
+ X(glStencilFuncSeparate) \
+ X(glStencilMask) \
+ X(glStencilMaskSeparate) \
+ X(glStencilOp) \
+ X(glStencilOpSeparate) \
+ X(glTexImage2D) \
+ X(glTexParameterf) \
+ X(glTexParameterfv) \
+ X(glTexParameteri) \
+ X(glTexParameteriv) \
+ X(glTexSubImage2D) \
+ X(glUniform1f) \
+ X(glUniform2f) \
+ X(glUniform3f) \
+ X(glUniform4f) \
+ X(glUniform1fv) \
+ X(glUniform2fv) \
+ X(glUniform3fv) \
+ X(glUniform4fv) \
+ X(glUniform1i) \
+ X(glUniform2i) \
+ X(glUniform3i) \
+ X(glUniform4i) \
+ X(glUniform1iv) \
+ X(glUniform2iv) \
+ X(glUniform3iv) \
+ X(glUniform4iv) \
+ X(glUniformMatrix2fv) \
+ X(glUniformMatrix3fv) \
+ X(glUniformMatrix4fv) \
+ X(glUseProgram) \
+ X(glValidateProgram) \
+ X(glVertexAttrib1f) \
+ X(glVertexAttrib2f) \
+ X(glVertexAttrib3f) \
+ X(glVertexAttrib4f) \
+ X(glVertexAttrib1fv) \
+ X(glVertexAttrib2fv) \
+ X(glVertexAttrib3fv) \
+ X(glVertexAttrib4fv) \
+ X(glVertexAttribPointer) \
+ X(glViewport)
+
+
+#endif /*_DA_GL_API_FUNC_LIST_H */
diff --git a/include/da_gles20.h b/include/da_gles20.h
new file mode 100644 (file)
index 0000000..a9b4f43
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Sanghyun Lee <sanghyunnim.lee@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef DA_GLES20_H_
+#define DA_GLES20_H_
+
+/*
+ * TODO find this headers. need for EGL_Context and other
+#include <egl.h>
+#include <eglext.h>
+#include <gl2.h>
+#include <gl2ext.h>
+*/
+
+#include <Evas_GL.h>
+#include <Evas.h>
+
+#include <errno.h>
+#include "daprobe.h"
+#include "dahelper.h"
+
+/* TODO add egl header for next */
+#define EGLContext void *
+extern EGLContext eglGetCurrentContext(void);
+
+#define NO_RETURN_FORMAT "%s"
+#define NO_RETURN_VALUE 0
+#define APITYPE_INIT 0
+#define APITYPE_CONTEXT 1
+#define APITYPE_NO_CONTEXT 2
+
+#define FUNC(FUNCNAME) FUNCNAME
+#define FUNCSTR(FUNCNAME) #FUNCNAME
+#define FUNCID(FUNCNAME) API_ID_##FUNCNAME
+
+#define PACK_GL_ADD_COMMON(GL_api_type, GL_elapsed_time)                       \
+       do {    /* PACK_GL_ADD_COMMON */                                        \
+               /* TODO restore eglGetCurrentContext */                         \
+               /*BUF_PTR = pack_int64(BUF_PTR, voidp_to_uint64((void *)eglGetCurrentContext()));*/\
+               BUF_PTR = pack_int64(BUF_PTR, voidp_to_uint64((void *)0));\
+               BUF_PTR = pack_int32(BUF_PTR, (uint32_t)GL_api_type);   \
+               BUF_PTR = pack_int64(BUF_PTR, (uint64_t)GL_elapsed_time); \
+       } while (0)
+
+#define PACK_GL_ADD(GL_api_type, GL_elapsed_time, GL_context_value)            \
+       do {    /* PACK_GL_ADD */                                               \
+               PACK_GL_ADD_COMMON(GL_api_type, GL_elapsed_time);               \
+               BUF_PTR = pack_string(BUF_PTR, GL_context_value);       \
+       } while (0)
+
+#define PACK_GL_SHADER(GL_api_type, GL_elapsed_time, GL_shader, GL_shader_size)        \
+       do {    /* PACK_GL_SHADER */                                            \
+               PACK_GL_ADD_COMMON(GL_api_type, GL_elapsed_time);               \
+               uint32_t min = (sizeof(LOCAL_BUF) - (BUF_PTR - LOCAL_BUF));     \
+               if (min > MAX_SHADER_LEN)                                       \
+                       min = MAX_SHADER_LEN;                                   \
+               BUF_PTR = pack_string_to_file(BUF_PTR, GL_shader,               \
+                                             GL_shader_size, min);             \
+       } while (0)
+
+#define BEFORE_GL_ORIG(FUNCNAME)                                       \
+       DECLARE_VARIABLE_STANDARD_NORET;                                \
+       GLenum error = GL_NO_ERROR;                                     \
+       static methodType FUNCNAME ## p = 0;                            \
+       int32_t vAPI_ID = API_ID_ ## FUNCNAME;                          \
+       uint64_t start_nsec = 0;                                        \
+       PRE_PROBEBLOCK();                                               \
+       if(blockresult != 0)                                            \
+               start_nsec = get_current_nsec();                        \
+       if(!FUNCNAME##p) {                                              \
+               init_probe_gl(#FUNCNAME, (void **)&FUNCNAME##p,         \
+                             LIBGLES20, blockresult, vAPI_ID);         \
+       }
+
+#define BEFORE_GL_API(FUNCNAME)                                                \
+       DECLARE_VARIABLE_STANDARD_NORET;                                \
+       GLenum error = GL_NO_ERROR;                                     \
+       int32_t vAPI_ID = API_ID_ ## FUNCNAME;                          \
+       uint64_t start_nsec = 0;                                        \
+       PRE_PROBEBLOCK();                                               \
+       if(blockresult != 0)                                            \
+               start_nsec = get_current_nsec();                        \
+       if(!__gl_api->FUNCNAME) {                                               \
+               probe_terminate_with_err("api not initialized",         \
+                                        #FUNCNAME, LIBGLES20);         \
+       }
+
+#define INIT_LIB_ID_STR(LIB_ID, LIB_STR, KEYS)                                                 \
+               if (lib_handle[LIB_ID] == ((void *) 0)) {               \
+                       lib_handle[LIB_ID] = dlopen(LIB_STR, RTLD_LAZY | RTLD_GLOBAL); \
+                       if (lib_handle[LIB_ID] == ((void *) 0)) {       \
+                               char perror_msg[128];                   \
+                               sprintf(perror_msg, "dlopen failed : [%s],%s", \
+                                       __FUNCTION__, LIB_STR);                 \
+                               perror(perror_msg);                             \
+                               exit(0);                                \
+                       }                                               \
+               }
+
+#define INIT_LIB(LIB_ID, KEYS)                                         \
+       INIT_LIB_ID_STR(LIB_ID, lib_string[LIB_ID], KEYS)
+
+
+#define BEFORE_EGL_NATIVE(FUNCNAME)                                    \
+       DECLARE_VARIABLE_STANDARD_NORET;                                \
+       GLenum error = EGL_SUCCESS;                                     \
+       static methodType FUNCNAME ## p = 0;                            \
+       int32_t vAPI_ID = API_ID_ ## FUNCNAME;                          \
+       uint64_t start_nsec = 0;                                        \
+       PRE_PROBEBLOCK();                                               \
+       if(blockresult != 0)                                            \
+               start_nsec = get_current_nsec();                        \
+       if(!FUNCNAME##p)                                                \
+               init_probe_egl(#FUNCNAME, (void **)&FUNCNAME##p, LIBEGL)
+
+#define EGL_GET_ERROR()                                                        \
+       if (blockresult != 0) {                                         \
+               error = eglGetError();                                  \
+       }
+
+#define AFTER(RET_TYPE, RET_VAL, APITYPE, CONTEXT_VAL, INPUTFORMAT, ...)       \
+       POST_PACK_PROBEBLOCK_BEGIN();                                           \
+       PREPARE_LOCAL_BUF();                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_GL, vAPI_ID, INPUTFORMAT, __VA_ARGS__);     \
+       PACK_COMMON_END(RET_TYPE, RET_VAL, error, blockresult);                 \
+       PACK_GL_ADD(APITYPE, get_current_nsec() - start_nsec, CONTEXT_VAL);     \
+       FLUSH_LOCAL_BUF();                                                      \
+       POST_PACK_PROBEBLOCK_END()
+
+#define AFTER_NO_PARAM(RET_TYPE, RETVAL, APITYPE, CONTEXTVALUE) \
+               AFTER(RET_TYPE, RETVAL, APITYPE, CONTEXTVALUE, "", 0)
+
+#define GL_GET_ERROR()                                                 \
+       if (blockresult != 0) {                                         \
+               error = REAL_NAME(glGetError)();                                        \
+       }
+
+#define AFTER_SHADER(RET_TYPE, RET_VAL, APITYPE, CONTEXT_VAL, CONTEXT_SIZE, INPUTFORMAT, ...)  \
+       POST_PACK_PROBEBLOCK_BEGIN();                                           \
+       PREPARE_LOCAL_BUF();                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_GL, vAPI_ID, INPUTFORMAT, __VA_ARGS__);     \
+       PACK_COMMON_END(RET_TYPE, RET_VAL, error, blockresult);                 \
+       PACK_GL_SHADER(APITYPE, get_current_nsec() - start_nsec, CONTEXT_VAL, CONTEXT_SIZE);    \
+       FLUSH_LOCAL_BUF();                                                      \
+       POST_PACK_PROBEBLOCK_END()
+
+#define BEFORE_EVAS_GL(FUNCNAME)                                       \
+       DECLARE_VARIABLE_STANDARD_NORET;                                \
+       GLenum error = GL_NO_ERROR;                                     \
+       static methodType FUNCNAME ## p = 0;                            \
+       int32_t vAPI_ID = API_ID_ ## FUNCNAME;                          \
+       uint64_t start_nsec = 0;                                        \
+       PRE_PROBEBLOCK();                                               \
+       if(blockresult != 0)                                            \
+               start_nsec = get_current_nsec();                        \
+       GET_REAL_FUNC_RTLD_NEXT(FUNCNAME)
+
+GLenum glGetError(void);
+void glGetIntegerv(GLenum pname, GLint * params);
+extern Evas_GL_API *__gl_api;
+extern void save_orig_gl_api_list(Evas_GL_API *api);
+extern void change_gl_api_list(Evas_GL_API *api);
+
+#endif /* DA_GLES20_H_ */
+
diff --git a/include/dacollection.h b/include/dacollection.h
new file mode 100755 (executable)
index 0000000..e67da49
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __COLLECTIONS_H__
+#define __COLLECTIONS_H__
+
+#include <pthread.h>                   // for pthread_mutex_t
+
+#include "khash.h"
+#include "real_functions.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define SYMBOLHASH                     _hashinfo.symHash
+#define SYMBOLHASH_LOCK                pthread_mutex_lock(&(_hashinfo.symHashMutex))
+#define SYMBOLHASH_UNLOCK      pthread_mutex_unlock(&(_hashinfo.symHashMutex))
+
+#define MEMORYHASH                     _hashinfo.memHash
+#define MEMORYHASH_LOCK                pthread_mutex_lock(&(_hashinfo.memHashMutex))
+#define MEMORYHASH_UNLOCK      pthread_mutex_unlock(&(_hashinfo.memHashMutex))
+
+#define UIOBJECTHASH           _hashinfo.uiobjHash
+#define UIOBJECTHASH_LOCK      pthread_mutex_lock(&(_hashinfo.uiobjHashMutex))
+#define UIOBJECTHASH_UNLOCK    pthread_mutex_unlock(&(_hashinfo.uiobjHashMutex))
+
+#define OBJECTHASH                     _hashinfo.objHash
+#define OBJECTHASH_LOCK                pthread_mutex_lock(&(_hashinfo.objHashMutex))
+#define OBJECTHASH_UNLOCK      pthread_mutex_unlock(&(_hashinfo.objHashMutex))
+
+#define DETECTORHASH           _hashinfo.dttHash
+#define DETECTORHASH_LOCK      pthread_mutex_lock(&(_hashinfo.dttHashMutex))
+#define DETECTORHASH_UNLOCK    pthread_mutex_unlock(&(_hashinfo.dttHashMutex))
+
+#define MEMTYPE_ALLOC  0x01
+#define MEMTYPE_FREE   0x01
+#define MEMTYPE_NEW            0x03
+#define MEMTYPE_DELETE 0x03
+
+#define MEM_INTERNAL   0x01
+#define MEM_EXTERNAL   0x02
+
+#define MEMMASK_CALLER 0xFFFF000000000000L
+#define MEMMASK_TYPE   0x0000FFFF00000000L
+#define MEMMASK_SIZE   0x00000000FFFFFFFFL
+
+#define GET_MEMSIZE(_info)             ((size_t)(_info & MEMMASK_SIZE))
+#define GET_MEMCALLER(_info)   ((unsigned short)((_info & MEMMASK_CALLER) >> 48))
+#define GET_MEMTYPE(_info)             ((unsigned short)((_info & MEMMASK_TYPE) >> 32))
+
+#define MAKE_MEMINFO(caller, type, size)       \
+       (((uint64_t)caller << 48) | ((uint64_t)type << 32) | ((uint64_t)size))
+
+#define OBJECT_INTERNAL        0x01
+#define OBJECT_EXTERNAL        0x02
+
+typedef struct
+{
+       char* type;
+       char* name;
+} _uiobjectinfo;
+
+// khash table function definition
+KHASH_MAP_INIT_INT(symbol, char*)
+
+KHASH_MAP_INIT_INT(allocmap, uint64_t)
+
+KHASH_MAP_INIT_INT(uiobject, _uiobjectinfo*)
+
+KHASH_MAP_INIT_INT(object, unsigned short)
+
+KHASH_MAP_INIT_INT(detector, void*)
+
+typedef struct
+{
+       khash_t(symbol)*        symHash;
+       pthread_mutex_t         symHashMutex;
+       khash_t(allocmap)*      memHash;
+       pthread_mutex_t         memHashMutex;
+       khash_t(uiobject)*      uiobjHash;
+       pthread_mutex_t         uiobjHashMutex;
+       khash_t(object)*        objHash;
+       pthread_mutex_t         objHashMutex;
+       khash_t(detector)*      dttHash;
+       pthread_mutex_t         dttHashMutex;
+} __hashInfo;
+
+extern __hashInfo _hashinfo;
+
+// APIs for symdata linked list
+int add_to_glist(char* key, void* data);
+int remove_from_glist(char* key);
+int remove_all_glist();
+void* find_glist(char* key);
+
+// APIs for hash table
+int initialize_hash_table();
+int finalize_hash_table();
+
+int find_symbol_hash(void* ptr, char** psymbol);
+int add_symbol_hash(void* ptr, const char* str, int strlen);
+int add_memory_hash(void* ptr, size_t size, unsigned short type, unsigned short caller);
+int del_memory_hash(void* ptr, unsigned short type, unsigned short* caller);
+
+int find_uiobject_hash(void* ptr, char** type,  char** classname);
+int add_uiobject_hash_class(void* ptr, const char* classname);
+int add_uiobject_hash_type(void* ptr, const char* type);
+int del_uiobject_hash(void* ptr);
+
+int find_object_hash(void* ptr, unsigned short *caller);
+int add_object_hash(void* ptr, unsigned short caller);
+int del_object_hash(void* ptr, unsigned short *caller);
+
+int add_detector_hash(void* ptr, void* listener);
+int del_detector_hash(void* ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __COLLECTIONS_H_ */
diff --git a/include/daerror.h b/include/daerror.h
new file mode 100755 (executable)
index 0000000..82025b4
--- /dev/null
@@ -0,0 +1,54 @@
+/*  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef DAERROR_H_
+#define DAERROR_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define ERR_SUCCESS                            0
+#define ERR_OUTOFMEMORY                        -11
+#define ERR_WRONGPARAMETER             -12
+#define ERR_NOTINITIALIZED             -13
+#define ERR_NOTEXIST                   -21
+#define ERR_ALREADYEXIST               -22
+#define ERR_OTHER                              -30
+#define ERR_DLOPEN                             -101
+#define ERR_DLSYM                              -102
+#define ERR_USER                               -10000
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* DAERROR_H_ */
diff --git a/include/dahelper.h b/include/dahelper.h
new file mode 100755 (executable)
index 0000000..fa956bc
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef _DAHELPER_H_
+#define _DAHELPER_H_
+
+#include <stdbool.h>
+#include <pthread.h>                   // for pthread_mutex_t
+
+#include <Evas.h>
+
+#include "daprobe.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+extern int app_efl_main_flg;
+
+#define MAX_PATH_LENGTH                256
+#define MAX_STACK_DEPTH                128
+#define TRIM_STACK_DEPTH       2
+
+/*
+#define WIN_RENDER_POST 0
+#define CONTROLBAR_RENDER_POST 1
+#define NAVIFRAME_RENDER_POST 2
+#define PAGER_RENDER_POST 3
+#define RENDER_POST_COUNT 4
+
+#define SNAPSHOT_WAIT_TIME_MAX 10000
+*/
+
+#define ENABLE_INTERNAL_MALLOC         0x0001
+#define ENABLE_SNAPSHOT                                0x0002
+
+#define SCREENSHOT_LOCK()                                                                              \
+       do {                                                                                                            \
+               int old;                                                                                                \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               old = gTraceInfo.screenshot.state;                                              \
+               gTraceInfo.screenshot.state = -1;                                               \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+               if(old > 0) {                                                                                   \
+                       if(isOptionEnabled(OPT_SNAPSHOT))                                       \
+                               captureScreen();                                                                \
+               }                                                                                                               \
+       } while(0)
+
+#define SCREENSHOT_UNLOCK()                                                                            \
+       do {                                                                                                            \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               if(gTraceInfo.screenshot.state < 0)                                             \
+                       gTraceInfo.screenshot.state = 1;                                        \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+       } while(0)
+
+#define SCREENSHOT_SET()                                                                               \
+       do {                                                                                                            \
+               int old;                                                                                                \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               old = gTraceInfo.screenshot.state;                                              \
+               if(gTraceInfo.screenshot.state >= 0)                                    \
+                       gTraceInfo.screenshot.state = 1;                                        \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+               if(old == 2) {                                                                                  \
+                       if(isOptionEnabled(OPT_SNAPSHOT))                                       \
+                               captureScreen();                                                                \
+               }                                                                                                               \
+       } while(0)
+
+#define SCREENSHOT_UNSET()                                                                             \
+       do {                                                                                                            \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               if(gTraceInfo.screenshot.state >= 0)                                    \
+                       gTraceInfo.screenshot.state = 0;                                        \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+       } while(0)
+
+#define SCREENSHOT_DONE()                                                                              \
+       do {                                                                                                            \
+               int old;                                                                                                \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               old = gTraceInfo.screenshot.state;                                              \
+               if(gTraceInfo.screenshot.state == 1)                                    \
+                       gTraceInfo.screenshot.state = 2;                                        \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+               if(old == 1) {                                                                                  \
+                       activateCaptureTimer();                                                         \
+               }                                                                                                               \
+       } while(0)
+
+#define SCREENSHOT_TIMEOUT()                                                                   \
+       do {                                                                                                            \
+               int old;                                                                                                \
+               pthread_mutex_lock(&(gTraceInfo.screenshot.ssMutex));   \
+               old = gTraceInfo.screenshot.state;                                              \
+               if(gTraceInfo.screenshot.state == 2)                                    \
+                       gTraceInfo.screenshot.state = 1;                                        \
+               pthread_mutex_unlock(&(gTraceInfo.screenshot.ssMutex)); \
+               if(old == 2) {                                                                                  \
+                       if(isOptionEnabled(OPT_SNAPSHOT))                                       \
+                               captureScreen();                                                                \
+               }                                                                                                               \
+       } while(0)
+
+#define        NUM_ORIGINAL_LIBRARY    9
+
+typedef enum
+{
+       LIB_NO = -1,
+       LIBC = 0,
+       LIBPTHREAD = 1,
+       LIBELEMENTARY = 2,
+       LIBECORE_INPUT_EVAS = 3,
+       LIBDAEMON = 4,
+       LIBCAPI_APPFW_APPLICATION = 5,
+       LIBGLES20 = 6,
+       LIBEGL = 7,
+       LIBSELF = 8
+} ORIGINAL_LIBRARY;
+
+extern const char *lib_string[NUM_ORIGINAL_LIBRARY];
+extern void *lib_handle[NUM_ORIGINAL_LIBRARY];
+
+// type definition for global variable
+typedef struct
+{
+       int eventIndex;
+       pthread_mutex_t eventMutex;
+} __indexInfo;
+
+typedef struct
+{
+       int daemonSock;
+       pthread_mutex_t sockMutex;
+} __socketInfo;
+
+typedef struct
+{
+       char appName[128];
+       uint64_t startTime;
+} __appInfo;
+
+typedef struct
+{
+       int state;
+       pthread_mutex_t ssMutex;
+} __screenshotInfo;
+
+typedef struct
+{
+       void* map_start;
+       void* map_end;
+} __mapInfo;
+
+typedef struct
+{
+       __indexInfo                     index;
+       __socketInfo            socket;
+       __appInfo                       app;
+       __screenshotInfo        screenshot;
+       __mapInfo                       exec_map;
+       int                                     stateTouch;
+       int                                     init_complete;
+       int                                     custom_chart_callback_count;
+       uint64_t                optionflag;
+} __traceInfo;
+
+extern __traceInfo gTraceInfo;
+
+int get_map_address(void* symbol, void** map_start, void** map_end);
+char** da_backtrace_symbols (void* const* array, int size);
+char** cached_backtrace_symbols (void* const* array, int size);
+
+/* pid/tid values */
+pid_t _getpid();
+pid_t _gettid();
+extern void reset_pid_tid();
+
+// profil turned on
+int __profil(int mode);
+
+//wchar_t* -> char*
+void WcharToChar(char* pstrDest, const wchar_t* pwstrSrc);
+char *absolutize_filepath(const char *fname, char *buf, size_t bufsiz);
+
+/* returns the real absolute file path (resolves symlinks) */
+char *real_abs_path(int fd, char *buffer, size_t bufsiz);
+
+// screen capture functions
+int initialize_screencapture();
+int finalize_screencapture();
+int captureScreen();
+int activateCaptureTimer();
+void _cb_render_post(void* data, Evas* e, void* eventinfo);
+
+// event related functions
+int initialize_event();
+int finalize_event();
+int getOrientation();
+void on_orientation_changed(int angle, bool capi);
+
+int remove_indir(const char* dirname);
+
+// query functions
+#define isOptionEnabled(OPT)   ((gTraceInfo.optionflag & OPT) != 0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DAHELPER_H_
diff --git a/include/damaps.h b/include/damaps.h
new file mode 100644 (file)
index 0000000..b1e172e
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+extern int maps_init();
+extern int maps_make();
+extern int maps_is_instrument_section_by_addr(const void *addr);
+extern int set_map_inst_list(char **maps_set, uint32_t maps_count);
diff --git a/include/daprobe.h b/include/daprobe.h
new file mode 100644 (file)
index 0000000..552ab42
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DAPROBE_H__
+#define __DAPROBE_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <dlfcn.h>
+#include <stdint.h>
+#include "probeinfo.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef likely
+#define likely(x)       __builtin_expect((x),1)
+#define unlikely(x)     __builtin_expect((x),0)
+#endif
+#define __unused __attribute__((unused))
+
+#define NUM_OF_MONITOR         3
+#define DA_LOG_MAX                     4096
+#define PERROR_MSG_MAX         128
+
+#define DEFAULT_TOKEN  "`,"
+
+#define CALLER_ADDRESS \
+       ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
+
+#define BACKTRACE_SYMBOLS cached_backtrace_symbols
+
+typedef enum
+{
+       MT_MEMORY,
+       MT_FILE,
+       MT_SOCKET,
+} MonitorType;
+
+enum BlockLocation
+{
+       BL_PRE,
+       BL_POST,
+};
+
+typedef struct
+{
+       int type;
+       int length;
+       char data[DA_LOG_MAX];
+} log_t;
+
+typedef struct
+{
+       int                             eventIndex;
+       int                             pID;
+       int                             tID;
+       unsigned long   currentTime;
+       unsigned int    callDepth;
+} probeInfo_t;
+
+extern __thread int    gProbeBlockCount;
+extern __thread int    gProbeDepth;
+
+#define probeBlockStart()      (gProbeBlockCount++)
+#define probeBlockEnd()                (gProbeBlockCount--)
+#define probingStart()         (gProbeDepth++)
+#define probingEnd()           (gProbeDepth--)
+
+/***************************************************************************
+ * helper apis
+ ***************************************************************************/
+
+int preBlockBegin(const void *caller, bool bFiltering, enum DaOptions);
+void preBlockEnd();
+
+int postBlockBegin(int preresult);
+void postBlockEnd();
+
+unsigned int getCurrentEventIndex();
+unsigned long getCurrentTime();
+uint64_t get_current_nsec(void);
+bool setProbePoint(probeInfo_t * iProbe);
+int update_heap_memory_size(bool isAdd, size_t size);
+
+bool print_log_fmt(int msgType, const char *func_name, int line, ...);
+bool print_log_str(int msgType, char *st);
+bool printLog(log_t* log, int msgType);
+
+int __appendTypeLog(log_t* log, int nInput, char* token, ...);
+int getBacktraceString(log_t* log, int bufsize);
+
+void *rtdl_next(const char *symname);
+
+//char* captureScreenShotX(int* width, int* height);
+//void releaseScreenShotX();
+
+//int printSamplingLog(void);
+
+//bool captureScreen(unsigned int logNum);
+//void captureProbe();
+//int registeScreenChange(int renderID);
+//void detectTouchEvent(int touchID);
+//int getTouchState();
+//int isPossibleCapture();
+
+
+/***************************************************************************
+ * helper macros
+ ***************************************************************************/
+
+// ============================ rtdl ===============================
+
+#define rtdl_next_set_once(symbol, sname)              \
+       do {                                            \
+               if (symbol == NULL)                     \
+                       symbol = rtdl_next(sname);      \
+       } while (0)
+
+#define rtdl_next_current_set_once(symbol)     \
+       rtdl_next_set_once(symbol, __func__)
+
+// ========================= print log =====================================
+#define PRINTMSG(...)  print_log_fmt(MSG_MSG, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define PRINTWRN(...)  print_log_fmt(MSG_WARNING, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define PRINTERR(...)  print_log_fmt(MSG_ERROR, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define INIT_INFO                                              \
+               info.host_ip = 0;                               \
+               info.host_port = 0;                             \
+               info.msg_total_size = 0;                        \
+               info.msg_pack_size = 0;                         \
+               info.sock = NULL;                               \
+               info.msg_buf = (char *)""
+
+typedef struct {
+       uint32_t host_port;
+       uint32_t host_ip;
+       struct sockaddr *sock;
+
+       uint64_t msg_total_size;
+       uint32_t msg_pack_size;
+       char *msg_buf;
+
+} info_t;
+
+// =========================== declare variables ===========================
+// local variable is faster than heap allocated variable
+// array variable initialization with declare is expensive than memset
+#define DECLARE_ERRNO_VARS             \
+       int olderrno = 0;               \
+       int newerrno = 0;
+
+// declare variable for standard api (not tizen related api)
+#define DECLARE_VARIABLE_STANDARD      \
+       probeInfo_t probeInfo;          \
+       int blockresult = 0;            \
+       bool bfiltering = true;         \
+       DECLARE_ERRNO_VARS;             \
+       int __attribute__((unused)) ret = 0
+
+// declare variable for standard api (not tizen related api) without ret
+#define DECLARE_VARIABLE_STANDARD_NORET                \
+               probeInfo_t     probeInfo;                      \
+               int blockresult;                                \
+               bool bfiltering = true;                 \
+               int olderrno, newerrno;                 \
+
+// ========================== get function pointer =========================
+
+#define GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCTIONPOINTER)                      \
+       GET_REAL_FUNCP_STR(#FUNCNAME, SONAME, FUNCTIONPOINTER)
+
+#define GET_REAL_FUNCP_STR(FUNCNAME, SONAME, FUNCTIONPOINTER)                  \
+               do {                                                                                                            \
+                       if (!FUNCTIONPOINTER) {                                                                 \
+                               probeBlockStart();                                                                      \
+                               if (lib_handle[SONAME] == NULL) {                                       \
+                                       lib_handle[SONAME] = dlopen(lib_string[SONAME], RTLD_LAZY);                     \
+                                       if (lib_handle[SONAME] == NULL) {                               \
+                                               fprintf(stderr, "dlopen failed : %s\n", lib_string[SONAME]);    \
+                                               PRINTMSG("dlopen failed : %s\n", lib_string[SONAME]);   \
+                                               exit(0);                                                                        \
+                                       } \
+                               }                                                                                                       \
+                               FUNCTIONPOINTER = dlsym(lib_handle[SONAME], FUNCNAME);          \
+                               if (FUNCTIONPOINTER == NULL || dlerror() != NULL) {             \
+                                       fprintf(stderr, "dlsym failed : <" FUNCNAME ">\n");                     \
+                                       PRINTMSG("dlsym failed : <" FUNCNAME ">\n");                    \
+                                       exit(0);                                                                                \
+                               }                                                                                                       \
+                               probeBlockEnd();                                                                        \
+                       }                                                                                                               \
+               } while(0)
+
+#define GET_REAL_FUNC(FUNCNAME, SONAME)                \
+       GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCNAME##p)
+
+#define GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCTIONPOINTER)                    \
+               do {                                                                                                            \
+                       if(!FUNCTIONPOINTER) {                                                                  \
+                               probeBlockStart();                                                                      \
+                               FUNCTIONPOINTER = dlsym(RTLD_NEXT, #FUNCNAME);          \
+                               if(FUNCTIONPOINTER == NULL || dlerror() != NULL)        \
+                                       probe_terminate_with_err("function not found", #FUNCNAME, LIB_NO);              \
+                               probeBlockEnd();                                                                        \
+                       }                                                                                                               \
+               } while(0)
+
+#define GET_REAL_FUNC_RTLD_NEXT(FUNCNAME)      \
+               GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCNAME##p)
+
+#define GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCTIONPOINTER)                \
+               do {                                                                                                            \
+                       if(!FUNCTIONPOINTER) {                                                                  \
+                               probeBlockStart();                                                                      \
+                               void* funcp = dlsym(RTLD_NEXT, #FUNCNAME);                      \
+                               if(funcp == NULL || dlerror() != NULL) {                        \
+                                       fprintf(stderr, "dlsym failed <%s>\n", #FUNCNAME);                                                      \
+                                       exit(0);                                                                                \
+                               }                                                                                                       \
+                               memcpy(&FUNCTIONPOINTER, &funcp, sizeof(void*));        \
+                               probeBlockEnd();                                                                        \
+                       }                                                                                                               \
+               } while(0)
+
+#define GET_REAL_FUNC_RTLD_NEXT_CPP(FUNCNAME)  \
+               GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCNAME##p)
+
+// ======================= pre block macro ================================
+
+#define PRE_PROBEBLOCK_BEGIN()                                                                                                 \
+       if((blockresult = preBlockBegin(CALLER_ADDRESS, bfiltering, _sopt)) != 0) {     \
+               setProbePoint(&probeInfo)
+
+#define PRE_PROBEBLOCK_END()                                                   \
+               preBlockEnd();                                                  \
+       }                                                                       \
+       olderrno = errno;                                                       \
+       errno = 0
+
+#define PRE_PROBEBLOCK() \
+               PRE_PROBEBLOCK_BEGIN(); \
+               PRE_PROBEBLOCK_END()
+
+// ===================== unconditional probe block ========================
+
+#define PRE_UNCONDITIONAL_BLOCK_BEGIN()        \
+       do {                                                            \
+               probeBlockStart();                              \
+               setProbePoint(&probeInfo)
+
+#define PRE_UNCONDITIONAL_BLOCK_END()  \
+               probeBlockEnd();                                \
+       } while(0)
+
+// =========================== post block macro ===========================
+
+#define POST_PROBEBLOCK_BEGIN(LCTYPE, RETTYPE, RETVALUE, INPUTFORMAT, ...)     \
+       newerrno = errno;                                                                                                               \
+       if(postBlockBegin(blockresult)) {                                                                               \
+               PREPARE_LOCAL_BUF(); \
+               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+               PACK_COMMON_END(RETTYPE, RETVALUE, errno, blockresult);
+
+#define POST_PROBEBLOCK_END()                                          \
+               FLUSH_LOCAL_BUF();                                              \
+               postBlockEnd();                                                         \
+       }                                                                                               \
+       errno = (newerrno != 0) ? newerrno : olderrno
+
+// ========================= simplify macro ================================
+
+#define BEFORE_ORIGINAL(FUNCNAME, LIBNAME)     \
+       DECLARE_VARIABLE_STANDARD;                              \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);               \
+       PRE_PROBEBLOCK()
+
+#define BEFORE_ORIGINAL_NOFILTER(FUNCNAME, LIBNAME)    \
+       DECLARE_VARIABLE_STANDARD;                                              \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
+       bfiltering = false;                                                             \
+       PRE_PROBEBLOCK()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/dautil.h b/include/dautil.h
new file mode 100644 (file)
index 0000000..15d7486
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __DAUTIL_H__
+#define __DAUTIL_H__
+//#define DA_DEBUG_LOG
+#ifdef DA_DEBUG_LOG
+#define HEAR() printf("DA: %s:%s:%d: we are here\n", __FILE__, __func__, __LINE__)
+#else
+#define HEAR() ;
+#endif
+#endif
diff --git a/include/khash.h b/include/khash.h
new file mode 100755 (executable)
index 0000000..a92ec5e
--- /dev/null
@@ -0,0 +1,327 @@
+/* The MIT License
+
+   Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk>
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+   SOFTWARE.
+*/
+
+/*
+  An example:
+
+#include "khash.h"
+KHASH_MAP_INIT_INT(32, char)
+int main() {
+    int ret, is_missing;
+    khiter_t k;
+    khash_t(32) *h = kh_init(32);
+    k = kh_put(32, h, 5, &ret);
+    if (!ret) kh_del(32, h, k);
+    kh_value(h, k) = 10;
+    k = kh_get(32, h, 10);
+    is_missing = (k == kh_end(h));
+    k = kh_get(32, h, 5);
+    kh_del(32, h, k);
+    for (k = kh_begin(h); k != kh_end(h); ++k)
+        if (kh_exist(h, k)) kh_value(h, k) = 1;
+    kh_destroy(32, h);
+    return 0;
+}
+*/
+
+/*
+  2008-09-19 (0.2.3):
+
+    * Corrected the example
+    * Improved interfaces
+
+  2008-09-11 (0.2.2):
+
+    * Improved speed a little in kh_put()
+
+  2008-09-10 (0.2.1):
+
+    * Added kh_clear()
+    * Fixed a compiling error
+
+  2008-09-02 (0.2.0):
+
+    * Changed to token concatenation which increases flexibility.
+
+  2008-08-31 (0.1.2):
+
+    * Fixed a bug in kh_get(), which has not been tested previously.
+
+  2008-08-31 (0.1.1):
+
+    * Added destructor
+*/
+
+
+#ifndef __AC_KHASH_H
+#define __AC_KHASH_H
+
+#define AC_VERSION_KHASH_H "0.2.2"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef uint32_t khint_t;
+typedef khint_t khiter_t;
+
+#define __ac_HASH_PRIME_SIZE 32
+static const uint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] =
+{
+  0ul,          3ul,          11ul,         23ul,         53ul,
+  97ul,         193ul,        389ul,        769ul,        1543ul,
+  3079ul,       6151ul,       12289ul,      24593ul,      49157ul,
+  98317ul,      196613ul,     393241ul,     786433ul,     1572869ul,
+  3145739ul,    6291469ul,    12582917ul,   25165843ul,   50331653ul,
+  100663319ul,  201326611ul,  402653189ul,  805306457ul,  1610612741ul,
+  3221225473ul, 4294967291ul
+};
+
+#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
+#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
+#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
+#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
+#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
+#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
+#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
+
+static const double __ac_HASH_UPPER = 0.77;
+
+#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+    typedef struct {                                                    \
+        khint_t n_buckets, size, n_occupied, upper_bound;               \
+        uint32_t *flags;                                                \
+        khkey_t *keys;                                                  \
+        khval_t *vals;                                                  \
+    } kh_##name##_t;                                                    \
+    static inline kh_##name##_t *kh_init_##name() {                     \
+        return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t));        \
+    }                                                                   \
+    static inline void kh_destroy_##name(kh_##name##_t *h)              \
+    {                                                                   \
+        if (h) {                                                        \
+            free(h->keys); free(h->flags);                              \
+            free(h->vals);                                              \
+            free(h);                                                    \
+        }                                                               \
+    }                                                                   \
+    static inline void kh_clear_##name(kh_##name##_t *h)                \
+    {                                                                   \
+        if (h && h->flags) { \
+            memset(h->flags, 0xaa, ((h->n_buckets>>4) + 1) * sizeof(uint32_t)); \
+            h->size = h->n_occupied = 0;                                \
+        }                                                               \
+    }                                                                   \
+    static inline khint_t kh_get_##name(kh_##name##_t *h, khkey_t key)  \
+    {                                                                   \
+        if (h->n_buckets) {                                             \
+            khint_t inc, k, i, last;                                    \
+            k = __hash_func(key); i = k % h->n_buckets;                 \
+            inc = 1 + k % (h->n_buckets - 1); last = i;                 \
+            while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+                if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
+                else i += inc;                                          \
+                if (i == last) return h->n_buckets;                     \
+            }                                                           \
+            return __ac_iseither(h->flags, i)? h->n_buckets : i;            \
+        } else return 0;                                                \
+    }                                                                   \
+    static inline void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
+    {                                                                   \
+        uint32_t *new_flags = 0;                                        \
+        khint_t j = 1;                                                  \
+        {                                                               \
+            khint_t t = __ac_HASH_PRIME_SIZE - 1;                       \
+            if (new_n_buckets < __ac_prime_list[__ac_HASH_PRIME_SIZE - 1]) { \
+                while (__ac_prime_list[t] > new_n_buckets) {            \
+                    --t;                                                \
+                }                                                       \
+                new_n_buckets = __ac_prime_list[t + 1];                 \
+            }                                                           \
+            if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; \
+            else {                                                      \
+                new_flags = (uint32_t*)real_malloc(((new_n_buckets>>4) + 1) * sizeof(uint32_t)); \
+                memset(new_flags, 0xaa, ((new_n_buckets>>4) + 1) * sizeof(uint32_t)); \
+                if (h->n_buckets < new_n_buckets) {                     \
+                    h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
+                    if (kh_is_map)                                      \
+                        h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
+                }                                                       \
+            }                                                           \
+        }                                                               \
+        if (j) {                                                        \
+            for (j = 0; j != h->n_buckets; ++j) {                       \
+                if (__ac_iseither(h->flags, j) == 0) {                  \
+                    khkey_t key = h->keys[j];                           \
+                    khval_t val;                                        \
+                    if (kh_is_map) val = h->vals[j];                    \
+                    __ac_set_isdel_true(h->flags, j);                   \
+                    while (1) {                                         \
+                        khint_t inc, k, i;                              \
+                        k = __hash_func(key);                           \
+                        i = k % new_n_buckets;                          \
+                        inc = 1 + k % (new_n_buckets - 1);              \
+                        while (!__ac_isempty(new_flags, i)) {           \
+                            if (i + inc >= new_n_buckets) i = i + inc - new_n_buckets; \
+                            else i += inc;                              \
+                        }                                               \
+                        __ac_set_isempty_false(new_flags, i);           \
+                        if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { \
+                            { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
+                            if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
+                            __ac_set_isdel_true(h->flags, i);           \
+                        } else {                                        \
+                            h->keys[i] = key;                           \
+                            if (kh_is_map) h->vals[i] = val;            \
+                            break;                                      \
+                        }                                               \
+                    }                                                   \
+                }                                                       \
+            }                                                           \
+            if (h->n_buckets > new_n_buckets) {                         \
+                h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
+                if (kh_is_map)                                          \
+                    h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
+            }                                                           \
+            free(h->flags);                                             \
+            h->flags = new_flags;                                       \
+            h->n_buckets = new_n_buckets;                               \
+            h->n_occupied = h->size;                                    \
+            h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
+        }                                                               \
+    }                                                                   \
+    static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
+    {                                                                   \
+        khint_t x;                                                      \
+        if (h->n_occupied >= h->upper_bound) {                          \
+            if (h->n_buckets > (h->size<<1)) kh_resize_##name(h, h->n_buckets - 1); \
+            else kh_resize_##name(h, h->n_buckets + 1);                 \
+        }                                                               \
+        {                                                               \
+            khint_t inc, k, i, site, last;                              \
+            x = site = h->n_buckets; k = __hash_func(key); i = k % h->n_buckets; \
+            if (__ac_isempty(h->flags, i)) x = i;                       \
+            else {                                                      \
+                inc = 1 + k % (h->n_buckets - 1); last = i;             \
+                while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+                    if (__ac_isdel(h->flags, i)) site = i;              \
+                    if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
+                    else i += inc;                                      \
+                    if (i == last) { x = site; break; }                 \
+                }                                                       \
+                if (x == h->n_buckets) {                                \
+                    if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
+                    else x = i;                                         \
+                }                                                       \
+            }                                                           \
+        }                                                               \
+        if (__ac_isempty(h->flags, x)) {                                \
+            h->keys[x] = key;                                           \
+            __ac_set_isboth_false(h->flags, x);                         \
+            ++h->size; ++h->n_occupied;                                 \
+            *ret = 1;                                                   \
+        } else if (__ac_isdel(h->flags, x)) {                           \
+            h->keys[x] = key;                                           \
+            __ac_set_isboth_false(h->flags, x);                         \
+            ++h->size;                                                  \
+            *ret = 2;                                                   \
+        } else *ret = 0;                                                \
+        return x;                                                       \
+    }                                                                   \
+    static inline void kh_del_##name(kh_##name##_t *h, khint_t x)       \
+    {                                                                   \
+        if (x != h->n_buckets && !__ac_iseither(h->flags, x)) {         \
+            __ac_set_isdel_true(h->flags, x);                           \
+            --h->size;                                                  \
+        }                                                               \
+    }
+
+/* --- BEGIN OF HASH FUNCTIONS --- */
+
+#define kh_int_hash_func(key) (uint32_t)(key)
+#define kh_int_hash_equal(a, b) (a == b)
+#define kh_int64_hash_func(key) (uint32_t)((key)>>33^(key)^(key)<<11)
+#define kh_int64_hash_equal(a, b) (a == b)
+static inline khint_t __ac_X31_hash_string(const char *s)
+{
+    khint_t h = *s;
+    if (h)
+       {
+               for (++s ; *s; ++s)
+               {
+                       h = (h << 5) - h + *s;
+               }
+       }
+    return h;
+}
+#define kh_str_hash_func(key) __ac_X31_hash_string(key)
+#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
+
+/* --- END OF HASH FUNCTIONS --- */
+
+/* Other necessary macros... */
+
+#define khash_t(name) kh_##name##_t
+
+#define kh_init(name) kh_init_##name()
+#define kh_destroy(name, h) kh_destroy_##name(h)
+#define kh_clear(name, h) kh_clear_##name(h)
+#define kh_resize(name, h, s) kh_resize_##name(h, s)
+#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
+#define kh_get(name, h, k) kh_get_##name(h, k)
+#define kh_del(name, h, k) kh_del_##name(h, k)
+
+#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
+#define kh_key(h, x) ((h)->keys[x])
+#define kh_val(h, x) ((h)->vals[x])
+#define kh_value(h, x) ((h)->vals[x])
+#define kh_begin(h) (khint_t)(0)
+#define kh_end(h) ((h)->n_buckets)
+#define kh_size(h) ((h)->size)
+#define kh_n_buckets(h) ((h)->n_buckets)
+
+/* More conenient interfaces */
+
+#define KHASH_SET_INIT_INT(name)                                        \
+    KHASH_INIT(name, uint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+
+#define KHASH_MAP_INIT_INT(name, khval_t)                               \
+    KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+
+#define KHASH_SET_INIT_INT64(name)                                      \
+    KHASH_INIT(name, uint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+
+#define KHASH_MAP_INIT_INT64(name, khval_t)                             \
+    KHASH_INIT(name, uint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
+
+typedef const char *kh_cstr_t;
+#define KHASH_SET_INIT_STR(name)                                        \
+    KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
+
+#define KHASH_MAP_INIT_STR(name, khval_t)                               \
+    KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
+
+#endif /* __AC_KHASH_H */
diff --git a/include/probeinfo.h b/include/probeinfo.h
new file mode 100755 (executable)
index 0000000..acb2a93
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __PROBEINFO_H__
+#define __PROBEINFO_H__
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define                VT_INT                  'd'
+#define                VT_UINT                 'd'
+#define                VT_LONG                 'x'
+#define                VT_ULONG                'x'
+#define                VT_STR                  's'
+#define                VT_CHAR                 'c'
+#define                VT_PTR                  'p'
+#define                VT_NULL                 'x'
+#define                VT_OFF_T                'd'
+#define                VT_SIZE_T               'x'
+#define                VT_SSIZE_T              'x'
+#define                VT_SOCKLEN_T            'd'
+#define                VT_UINT16_T             'd'
+#define                VT_UINT32_T             'd'
+#define                VT_UINT64_T             'x'
+#define                VT_MODE_T               'd'
+#define                VT_DEV_T                'd'
+
+/* #define             LC_MEMORY               1 */
+/* #define             LC_UICREATE             2 */
+/* #define             LC_UIEVENT              3 */
+/* #define             LC_USERFUNC             4 */
+/* #define             LC_RESOURCE             5 */
+/* #define             LC_LIFECYCLE            6 */
+/* #define             LC_SNAPSHOT             7 */
+/* #define             LC_SCENE                8 */
+/* #define             LC_DEVICE               9 */
+/* #define             LC_ALLOCMEM             10 */
+/* #define             LC_SAMPLE               11 */
+/* #define             LC_THREAD               12 */
+/* #define             LC_CUSTOM               13 */
+/* #define             LC_SYNC                 14 */
+/* #define             LC_SOCKET               15 */
+/* #define             LC_GLES20               16 */
+
+
+#define                FD_API_OPEN                     0
+#define                FD_API_CLOSE                    1
+#define                FD_API_READ_START               2
+#define                FD_API_READ_END                 3
+#define                FD_API_WRITE_START              4
+#define                FD_API_WRITE_END                5
+#define                FD_API_DIRECTORY                6
+#define                FD_API_PERMISSION               7
+#define                FD_API_OTHER                    8
+#define                FD_API_SEND                     9
+#define                FD_API_RECEIVE                  10
+#define                FD_API_OPTION                   11
+#define                FD_API_MANAGE                   12
+#define                FD_API_LOCK_START               14
+#define                FD_API_LOCK_END                 15
+#define                FD_API_LOCK_RELEASE             16
+
+
+#define                SOCKET_API_FD_OPEN              0
+#define                SOCKET_API_FD_CLOSE             1
+#define                SOCKET_API_RECV_START           2
+#define                SOCKET_API_RECV_END             3
+#define                SOCKET_API_SEND_START           4
+#define                SOCKET_API_SEND_END             5
+#define                SOCKET_API_BIND                 6
+#define                SOCKET_API_LISTEN               7
+#define                SOCKET_API_CONNECT              8
+#define                SOCKET_API_ACCEPT_START         9
+#define                SOCKET_API_ACCEPT_END           10
+#define                SOCKET_API_EVENT_START          11
+#define                SOCKET_API_EVENT_END            12
+#define                SOCKET_API_OTHER                13
+#define                HTTP_API_SESSION_CONSTRUCT      14
+#define                HTTP_API_SESSION_CLOSE          15
+#define                HTTP_API_TRANSACTION_OPEN       16
+#define                HTTP_API_TRANSACTION_CLOSE      17
+#define                HTTP_API_ALLOCATION             18
+#define                HTTP_API_SUBMIT                 19
+#define                HTTP_API_REQUEST                20
+#define                HTTP_API_RESPONSE               21
+#define                HTTP_API_OTHER                  22
+#define                HTTP_API_CLOSE                  23
+
+
+#define                MEMORY_API_ALLOC        0
+#define                MEMORY_API_FREE         1
+#define                MEMORY_API_MANAGE       2
+
+//#define              SNAPSHOT_API_WIN                0
+//#define              SNAPSHOT_API_CONTROLBAR         1
+//#define              SNAPSHOT_API_NAVIFRAME          2
+//#define              SNAPSHOT_API_PAGER              3
+
+#define        EVENT_TYPE_DOWN         0
+#define        EVENT_TYPE_UP           1
+#define        EVENT_TYPE_MOVE         2
+
+#define                USERFUNC_ENTER          0
+#define                USERFUNC_EXIT           1
+
+#define                THREAD_PTHREAD                  0
+#define                THREAD_TIZENTHREAD_WORKER               1
+#define                THREAD_TIZENTHREAD_EVENTDRIVEN  2
+
+#define THREAD_CLASS_BLANK ""
+
+#define                THREAD_API_NEW                          0
+#define                THREAD_API_START                        1
+#define                THREAD_API_STOP                         2
+#define                THREAD_API_EXIT                         3
+#define                THREAD_API_WAIT_START                   4
+#define                THREAD_API_WAIT_END                     5
+#define                THREAD_API_INTERNAL_START               6
+#define                THREAD_API_INTERNAL_STOP                7
+#define                THREAD_API_OTHER                        8
+
+#define        SYNC_TIZEN_MUTEX                                0
+#define                SYNC_TIZEN_MONITOR                      1
+#define                SYNC_TIZEN_SEMAPHORE                    2
+#define                SYNC_PTHREAD_MUTEX                      3
+#define                SYNC_PTHREAD_COND_VARIABLE              4
+#define                SYNC_PTHREAD_RWLOCK                     5
+#define                SYNC_PTHREAD_SPINLOCK                   6
+#define                SYNC_PTHREAD_BARRIER                    7
+
+#define                SYNC_API_NEW                            0
+#define                SYNC_API_ACQUIRE_WAIT_START             1
+#define                SYNC_API_ACQUIRE_WAIT_END               2
+#define                SYNC_API_RELEASE                        3
+#define                SYNC_API_TRY_ACQUIRE                    4
+#define                SYNC_API_COND_WAIT_START                5
+#define                SYNC_API_COND_WAIT_END                  6
+#define                SYNC_API_NOTIFY                         7
+#define                SYNC_API_NOTIFY_ALL                     8
+#define                SYNC_API_OTHER                          9
+
+enum MessageType
+{
+       MSG_DEVICE = 1,
+       MSG_TIME,
+       MSG_SAMPLE,
+       MSG_LOG = 5,
+       MSG_IMAGE = 6,
+       MSG_TERMINATE = 7,
+       MSG_PID = 8,
+       MSG_MSG = 9,
+       MSG_ALLOC = 10,
+       MSG_ERROR = 11,
+       MSG_WARNING = 12,
+       MSG_STOP = 101,
+       MSG_CONFIG = 103,
+       MSG_CAPTURE_SCREEN= 108,
+       MSG_MAPS_INST_LIST= 109
+};
+
+enum DaOptions
+{
+       OPT_ALWAYSOFF           =       0x000000000,
+       OPT_ALLOC               =       0x000000008,
+       OPT_FILE                =       0x000000010,
+       OPT_THREAD              =       0x000000020,
+       OPT_UI                  =       0x000000040,
+       OPT_SNAPSHOT            =       0x000000080,
+       OPT_EVENT               =       0x000000100,
+       OPT_RECORD              =       0x000000200,
+       OPT_NETWORK             =       0x000020000,
+       OPT_GLES                =       0x000040000,
+       OPT_ALWAYSON            =       0xfffffffff,
+       OPT_ALLOC_ALWAYS        =       0x010000000,
+       OPT_FILE_ALWAYS         =       0x020000000,
+       OPT_THREAD_ALWAYS       =       0x040000000,
+       OPT_UI_ALWAYS           =       0x080000000,
+       OPT_NETWORK_ALWAYS      =       0x100000000ULL,
+       OPT_GLES_ALWAYS         =       0x200000000ULL
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/real_functions.h b/include/real_functions.h
new file mode 100644 (file)
index 0000000..b06904e
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef _REAL_FUNCTIONS_H_
+#define _REAL_FUNCTIONS_H_
+
+/* real malloc function pointer */
+extern void *(*real_malloc)(size_t);
+
+extern int _init_real_functions();
+#endif /* _REAL_FUNCTIONS_H_ */
diff --git a/include/tizen_probe.h b/include/tizen_probe.h
new file mode 100755 (executable)
index 0000000..64f0802
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __BADA_PROBE_H__
+#define __BADA_PROBE_H__
+
+#include <string.h>
+#include <dlfcn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define GET_REAL_FUNC_TIZEN(FUNCNAME, LIBNAME, FUNCTIONPOINTER)                                                \
+       do {                                                                                            \
+               if(!FUNCTIONPOINTER) {                                                                  \
+                       probeBlockStart();                                                              \
+                       if(lib_handle[LIBNAME] == NULL) {                                               \
+                               lib_handle[LIBNAME] = dlopen(lib_string[LIBNAME], RTLD_LAZY);           \
+                               if(lib_handle[LIBNAME] == NULL) {                                       \
+                                       char perror_msg[PERROR_MSG_MAX];                                \
+                                       sprintf(perror_msg, "dlopen failed : %s", lib_string[LIBNAME]); \
+                                       perror(perror_msg);                                             \
+                                       exit(0);                                                        \
+                               }                                                                       \
+                       }                                                                               \
+                       void* funcp = dlsym(lib_handle[LIBNAME], #FUNCNAME);                            \
+                       if(funcp == NULL || dlerror() != NULL) {                                        \
+                               perror("dlsym failed : " #FUNCNAME);                                    \
+                               exit(0);                                                                \
+                       }                                                                               \
+                       memcpy(&FUNCTIONPOINTER, &funcp, sizeof(void*));                                \
+                       probeBlockEnd();                                                                \
+               }                                                                                       \
+       } while(0)
+
+#define PRE_PROBEBLOCK_TIZEN(FILTER)                                                                                           \
+       do {                                                                                                                                            \
+               if((blockresult = preBlockBegin(CALLER_ADDRESS, FILTER, _sopt)) != 0) { \
+                       setProbePoint(&probeInfo);                                      \
+                       preBlockEnd();                                                  \
+               }                                                                       \
+       } while(0)
+
+extern int SceneManagerUsed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/packaging/dynamic-analysis-probe.changes b/packaging/dynamic-analysis-probe.changes
new file mode 100644 (file)
index 0000000..3cd68c4
--- /dev/null
@@ -0,0 +1,9 @@
+* Fri Jul 12 2013 Woojin Jung <woojin2.jung@samsung.com>
+- bug fix for ThreadProc, File::Seek probe
+- add filesize value for probe log of Tizen::Io::File APIs
+- function call inside app loader is excluded from user call
+- use original header files for Tizen APIs
+
+* Wed Jul 3 2013 Jaewon Lim <jaewon81.lim@samsung.com>
+- change screenshot file name for multiprocess application
+
diff --git a/packaging/swap-probe.spec b/packaging/swap-probe.spec
new file mode 100644 (file)
index 0000000..c2eb3d9
--- /dev/null
@@ -0,0 +1,44 @@
+Name:       swap-probe
+Summary:    SWAP probe library
+Version:    3.0
+Release:    1
+Group:      System/Libraries
+License:       GNU Lesser General Public License, Version 2.1
+Source:    %{name}_%{version}.tar.gz
+BuildRequires:  ecore-input-evas
+BuildRequires:  elementary-devel
+BuildRequires:  capi-appfw-application-devel
+BuildRequires:  capi-system-runtime-info-devel
+BuildRequires:  libXext-devel
+Provides:  swap-probe
+
+%description
+SWAP probe is a part of data collection back-end for DA.
+This library will be installed in target.
+
+%prep
+%setup -q -n %{name}_%{version}
+
+%build
+make rmheaders
+make headers
+make -j
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+%make_install
+
+%files
+/usr/share/license/%{name}
+
+%manifest swap-probe.manifest
+%defattr(-,root,root,-)
+%{_prefix}/lib/da_probe_tizen.so
+%{_prefix}/lib/libdaprobe.so
+%{_prefix}/lib/da_api_map
+
+
+%changelog
+
diff --git a/probe_capi/capi_appfw.c b/probe_capi/capi_appfw.c
new file mode 100644 (file)
index 0000000..9c9b68a
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <app.h>
+#include <Ecore.h>
+#include "damaps.h"
+#include "daprobe.h"
+#include "dahelper.h"
+#include "probeinfo.h"
+#include "binproto.h"
+#include "real_functions.h"
+#include "common_probe_init.h"
+#include "api_config.h"
+
+Ecore_Event_Handler *register_orientation_event_listener();
+void unregister_orientation_event_listener(Ecore_Event_Handler *handler);
+
+app_event_callback_s gAppCallback;
+ui_app_lifecycle_callback_s uiAppCallback;
+
+#define PACK_ORIGINAL_APPFWCYCLE(API_ID, RTYPE, RVAL, INPUTFORMAT, ...)                \
+       newerrno = errno;                                                       \
+       do {                                                                    \
+               PREPARE_LOCAL_BUF();                                    \
+               PACK_COMMON_BEGIN(MSG_PROBE_LIFECYCLE, API_ID, INPUTFORMAT, __VA_ARGS__);       \
+               PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);    \
+               FLUSH_LOCAL_BUF();                                      \
+       } while(0);                                                             \
+       errno = (newerrno != 0) ? newerrno : olderrno
+
+static bool _dalc_app_create(void *user_data)
+{
+       bool bret = false;
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       bret = gAppCallback.create(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_create, 'b', bret, "p",
+                                voidp_to_uint64(user_data));
+
+       return bret;
+}
+
+static void _dalc_app_terminate(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       gAppCallback.terminate(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_terminate, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+static void _dalc_app_pause(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       gAppCallback.pause(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_pause, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+static void _dalc_app_resume(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       gAppCallback.resume(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_resume, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+#ifdef PRIVATE_CAPI_APPFW
+static void _dalc_app_control(app_control_h handle, void *user_data)
+#else /* !PRIVATE_CAPI_APPFW */
+static void _dalc_app_service(service_h handle, void *user_data)
+#endif /* PRIVATE_CAPI_APPFW */
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+#ifdef PRIVATE_CAPI_APPFW
+       gAppCallback.app_control(handle, user_data);
+#else /* !PRIVATE_CAPI_APPFW */
+       gAppCallback.service(handle, user_data);
+#endif /* PRIVATE_CAPI_APPFW */
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_service, 'v', 0, "dp",
+                                (unsigned int)handle,
+                                voidp_to_uint64(user_data));
+}
+
+static void _dalc_app_deviceorientationchanged(app_device_orientation_e orientation, void *user_data)
+{
+       on_orientation_changed((int)orientation, true);
+
+       if (gAppCallback.device_orientation)
+               gAppCallback.device_orientation(orientation, user_data);
+}
+
+int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data)
+{
+       static int (*app_efl_mainp)(int *argc, char ***argv, app_event_callback_s *callback, void *user_data);
+       Ecore_Event_Handler* handler;
+       int ret;
+
+       GET_REAL_FUNCP_RTLD_NEXT(app_efl_main, app_efl_mainp);
+
+       probeBlockStart();
+       handler = register_orientation_event_listener();
+       gAppCallback.create = callback->create;
+       gAppCallback.terminate = callback->terminate;
+       gAppCallback.pause = callback->pause;
+       gAppCallback.resume = callback->resume;
+#ifdef PRIVATE_CAPI_APPFW
+       gAppCallback.app_control = callback->app_control;
+#else /* !PRIVATE_CAPI_APPFW */
+       gAppCallback.service = callback->service;
+#endif /* PRIVATE_CAPI_APPFW */
+       gAppCallback.device_orientation = callback->device_orientation;
+
+       if (callback->create)
+               callback->create = _dalc_app_create;
+       if (callback->terminate)
+               callback->terminate = _dalc_app_terminate;
+       if (callback->pause)
+               callback->pause = _dalc_app_pause;
+       if (callback->resume)
+               callback->resume = _dalc_app_resume;
+#ifdef PRIVATE_CAPI_APPFW
+       if (callback->app_control)
+               callback->app_control = _dalc_app_control;
+#else /* !PRIVATE_CAPI_APPFW */
+       if (callback->service)
+               callback->service = _dalc_app_service;
+#endif /* PRIVATE_CAPI_APPFW */
+       callback->device_orientation = _dalc_app_deviceorientationchanged;
+       probeBlockEnd();
+
+       ret = app_efl_mainp(argc, argv, callback, user_data);
+
+       probeBlockStart();
+       unregister_orientation_event_listener(handler);
+       callback->create = gAppCallback.create;
+       callback->terminate = gAppCallback.terminate;
+       callback->pause = gAppCallback.pause;
+       callback->resume = gAppCallback.resume;
+#ifdef PRIVATE_CAPI_APPFW
+       callback->app_control = gAppCallback.app_control;
+#else /* !PRIVATE_CAPI_APPFW */
+       callback->service = gAppCallback.service;
+#endif /* PRIVATE_CAPI_APPFW */
+       callback->device_orientation = gAppCallback.device_orientation;
+       probeBlockEnd();
+
+       return ret;
+}
+
+
+/************************************ UI APP ******************************************/
+static bool _ui_dalc_app_create(void *user_data)
+{
+       bool bret = false;
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       bret = uiAppCallback.create(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_create, 'b', bret, "p",
+                                voidp_to_uint64(user_data));
+
+       return bret;
+}
+
+static void _ui_dalc_app_terminate(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       uiAppCallback.terminate(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_terminate, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+static void _ui_dalc_app_pause(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       uiAppCallback.pause(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_pause, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+static void _ui_dalc_app_resume(void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       uiAppCallback.resume(user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_resume, 'v', 0, "p",
+                                voidp_to_uint64(user_data));
+}
+
+static void _ui_dalc_app_control(app_control_h handle, void *user_data)
+{
+       DECLARE_ERRNO_VARS;
+       int blockresult = 1;
+
+       uiAppCallback.app_control(handle, user_data);
+
+       PACK_ORIGINAL_APPFWCYCLE(API_ID__dalc_app_service, 'v', 0, "dp",
+                                (unsigned int)handle,
+                                voidp_to_uint64(user_data));
+}
+
+int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
+{
+       static int (*ui_app_mainp)(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data);
+       Ecore_Event_Handler* handler;
+       int ret;
+
+       GET_REAL_FUNCP_RTLD_NEXT(ui_app_main, ui_app_mainp);
+
+       probeBlockStart();
+       handler = register_orientation_event_listener();
+       uiAppCallback.create = callback->create;
+       uiAppCallback.terminate = callback->terminate;
+       uiAppCallback.pause = callback->pause;
+       uiAppCallback.resume = callback->resume;
+
+       uiAppCallback.app_control = callback->app_control;
+
+       if (callback->create)
+               callback->create = _ui_dalc_app_create;
+       if (callback->terminate)
+               callback->terminate = _ui_dalc_app_terminate;
+       if (callback->pause)
+               callback->pause = _ui_dalc_app_pause;
+       if (callback->resume)
+               callback->resume = _ui_dalc_app_resume;
+
+       if (callback->app_control)
+               callback->app_control = _ui_dalc_app_control;
+
+       probeBlockEnd();
+
+       ret = ui_app_mainp(argc, argv, callback, user_data);
+
+       probeBlockStart();
+       unregister_orientation_event_listener(handler);
+
+       callback->create = uiAppCallback.create;
+       callback->terminate = uiAppCallback.terminate;
+       callback->pause = uiAppCallback.pause;
+       callback->resume = uiAppCallback.resume;
+       callback->app_control = uiAppCallback.app_control;
+
+       probeBlockEnd();
+
+       return ret;
+}
diff --git a/probe_event/da_event.c b/probe_event/da_event.c
new file mode 100755 (executable)
index 0000000..935f5b6
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <appfw/app.h>
+#include <runtime_info.h>
+
+#include <Ecore.h>
+#include <Eina.h>
+#include <Ecore_X.h>
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "da_event.h"
+
+#include "binproto.h"
+#include "real_functions.h"
+
+static int external_angle = 0;
+static int internal_angle = 0;
+
+// ===================================================================
+// orientation related functions
+// ===================================================================
+
+static int convert_angle(int angle)
+{
+       int os = _OS_NONE;
+
+       switch(angle)
+       {
+       case 0:
+               os = _OS_PORTRAIT;
+               break;
+       case 90:
+               os = _OS_LANDSCAPE_REVERSE;
+               break;
+       case 180:
+               os = _OS_PORTRAIT_REVERSE;
+               break;
+       case 270:
+               os = _OS_LANDSCAPE;
+               break;
+       default:
+               break;
+       }
+
+       return os;
+}
+
+void on_orientation_changed(int angle, bool capi)
+{
+       probeInfo_t     probeInfo;
+
+       probeBlockStart();
+
+       internal_angle = angle;
+       external_angle = internal_angle;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_UIEVENT,
+                                 API_ID_on_orientation_changed,
+                                 "dd", angle, (uint32_t)capi);
+               PACK_COMMON_END('v', 0, 0, 0);
+               PACK_UIEVENT(_EVENT_ORIENTATION, 0, 0, 0, "", convert_angle(external_angle));
+               FLUSH_LOCAL_BUF();
+       }
+
+       SCREENSHOT_SET();
+//     if(!capi)
+//     {
+//             SCREENSHOT_DONE();
+//     }
+
+       probeBlockEnd();
+}
+
+int getOrientation()
+{
+       return external_angle;
+}
+
+// ====================================================================
+// initialize and finalize event
+// ====================================================================
+
+int initialize_event()
+{
+       external_angle = internal_angle = app_get_device_orientation();
+       return 0;
+}
+
+int finalize_event()
+{
+       return 0;
+}
+
+
diff --git a/probe_event/da_event.h b/probe_event/da_event.h
new file mode 100755 (executable)
index 0000000..af7e679
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_EVENT_H__
+#define __DA_EVENT_H__
+
+#include "daprobe.h"
+
+/*******************************************************************
+ * Type definition
+ *******************************************************************/
+
+enum __event_type
+{
+       _EVENT_KEY = 1,
+       _EVENT_TOUCH = 2,
+       _EVENT_GESTURE = 3,
+       _EVENT_ORIENTATION = 4,
+       _EVENT_LISTENER = 5
+} EVENT_TYPE;
+
+enum __key_status
+{
+       _KEY_PRESSED = 0,
+       _KEY_RELEASED = 1
+} KEY_STATUS;
+
+enum __touch_status
+{
+       _TOUCH_PRESSED = 0,
+       _TOUCH_LONG_PRESSED = 1,
+       _TOUCH_RELEASED = 2,
+       _TOUCH_MOVED = 3,
+       _TOUCH_DOUBLE_PRESSED = 4,
+       _TOUCH_FOCUS_IN = 5,
+       _TOUCH_FOCUS_OUT = 6,
+       _TOUCH_CANCELED = 7
+} _TOUCH_STATUS;
+
+enum __gesture_type
+{
+       _GESTURE_FLICK = 0,
+       _GESTURE_LONGPRESS = 1,
+       _GESTURE_PANNING = 2,
+       _GESTURE_PINCH = 3,
+       _GESTURE_ROTATION = 4,
+       _GESTURE_TAP = 5,
+       _GESTURE_CUSTOM = 6
+} GESTURE_TYPE;
+
+enum _orientation_status
+{
+       _OS_NONE = 0,
+       _OS_PORTRAIT = 1,
+       _OS_LANDSCAPE = 2,
+       _OS_PORTRAIT_REVERSE = 3,
+       _OS_LANDSCAPE_REVERSE = 4
+} ORIENTATION_STATUS;
+
+
+/*******************************************************************
+ * macros for event probe
+ *
+ * log format:
+ *             SeqNumber`,ApiName`,Time`,Pid`,Tid`,InputParm`,Return`,PCAddr`,Error`,x`,y`,\n
+ *             callstack_start`,callstack`,callstack_end
+ *
+ *******************************************************************/
+
+#define DECLARE_VARIABLE_EVENT                 \
+       probeInfo_t     probeInfo;                              \
+       static unsigned int oldtime = 0;        \
+       int blockresult = 0
+
+#define PRE_PROBEBLOCK_BEGIN_EVENT(FUNCNAME, LIBNAME, EVENTTYPE)       \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                                                               \
+       do {                                                                                                                    \
+               if(oldtime != timestamp && (EVENTTYPE != EVENT_TYPE_MOVE ||     \
+                       getTouchState() == EVENT_TYPE_DOWN ||                                   \
+                       getTouchState() == EVENT_TYPE_MOVE))                                    \
+               {                                                                                                                       \
+                       blockresult = 1;                                                                                \
+                       detectTouchEvent(EVENTTYPE);                                                    \
+                       PRE_UNCONDITIONAL_BLOCK_BEGIN()
+
+#define PRE_PROBEBLOCK_END_EVENT()                     \
+                       PRE_UNCONDITIONAL_BLOCK_END();  \
+               }                                                                       \
+       } while(0)
+
+#define BEFORE_ORIGINAL_EVENT(FUNCNAME, LIBNAME, EVENTTYPE)            \
+       DECLARE_VARIABLE_EVENT;                                                                         \
+       PRE_PROBEBLOCK_BEGIN_EVENT(FUNCNAME, LIBNAME, EVENTTYPE);       \
+       PRE_PROBEBLOCK_END_EVENT()
+
+#define AFTER_ORIGINAL_EVENT(EVENTTYPE, INPUTFORMAT, ...)              \
+       do {                                                                                                            \
+               if(blockresult == 1) {                                                                  \
+                       POST_UNCONDITIONAL_BLOCK_BEGIN(LC_UIEVENT);                     \
+                       APPEND_LOG_INPUT(INPUTFORMAT, __VA_ARGS__);                     \
+                       log.length += sprintf(log.data + log.length,            \
+                                       "`,`,`,`,1`,`,%d`,%d`,%d", x, y, EVENTTYPE);\
+                       APPEND_LOG_NULL_CALLSTACK();                                            \
+                       POST_UNCONDITIONAL_BLOCK_END();                                         \
+                       oldtime = timestamp;                                                            \
+               }                                                                                                               \
+       } while(0)
+
+
+#endif // __DA_EVENT_H__
diff --git a/probe_event/gesture.cpp b/probe_event/gesture.cpp
new file mode 100755 (executable)
index 0000000..72820bd
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "probeinfo.h"
+#include "tizen_probe.h"
+#include "dacollection.h"
+#include "da_event.h"
+#include "gesture.h"
+#include "binproto.h"
+
+#define PACK_GESTURE_EVENT(API_ID, _GESTURETYPE, _X, _Y, _INFO1, _INFO2, _ARGDETECTOR) \
+       do {                                                                                                                                            \
+               char info1_str[16];                                                                                                             \
+               setProbePoint(&probeInfo);                                                                                              \
+               PREPARE_LOCAL_BUF();                                                                                                    \
+               PACK_COMMON_BEGIN(MSG_PROBE_UIEVENT, API_ID, "p", voidp_to_uint64(_ARGDETECTOR));       \
+               PACK_COMMON_END('v', 0, 0, 0);                                                                                          \
+               sprintf(info1_str, "%d", _INFO1);                                                                               \
+               PACK_UIEVENT(_EVENT_GESTURE, _GESTURETYPE, _X, _Y, info1_str, _INFO2);  \
+               FLUSH_LOCAL_BUF();                                                                                                              \
+       } while (0)
+
+GestureEventListener GestureEventListener::rInstance;
+
+GestureEventListener::GestureEventListener()
+{
+
+}
+
+GestureEventListener::~GestureEventListener()
+{
+
+}
+
+void GestureEventListener::OnCustomGestureCanceled (TouchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnCustomGestureCanceled__TouchGestureDetector__gestureDetector_,
+                                  _GESTURE_CUSTOM, 0, 0, 0, 0, &gestureDetector);
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnCustomGestureChanged (TouchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnCustomGestureChanged__TouchGestureDetector__gestureDetector_,
+                                  _GESTURE_CUSTOM, 0, 0, 0, 0, &gestureDetector);
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnCustomGestureFinished (TouchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnCustomGestureFinished__TouchGestureDetector__gestureDetector_,
+                                  _GESTURE_CUSTOM, 0, 0, 0, 0, &gestureDetector);
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnCustomGestureStarted (TouchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnCustomGestureStarted__TouchGestureDetector__gestureDetector_,
+                                  _GESTURE_CUSTOM, 0, 0, 0, 0, &gestureDetector);
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnFlickGestureCanceled (TouchFlickGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int x = 0, y = 0, dur = 0;
+                       FlickDirection direction = FLICK_DIRECTION_NONE;
+
+                       gestureDetector.GetDistance(x, y);
+                       dur = gestureDetector.GetDuration();
+                       direction = gestureDetector.GetDirection();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnFlickGestureCanceled__TouchFlickGestureDetector__gestureDetector_,
+                                          _GESTURE_FLICK, x, y, dur, (int)direction, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnFlickGestureDetected (TouchFlickGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int x = 0, y = 0, dur = 0;
+                       FlickDirection direction = FLICK_DIRECTION_NONE;
+
+                       gestureDetector.GetDistance(x, y);
+                       dur = gestureDetector.GetDuration();
+                       direction = gestureDetector.GetDirection();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnFlickGestureDetected__TouchFlickGestureDetector__gestureDetector_,
+                                          _GESTURE_FLICK, x, y, dur, (int)direction, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnLongPressGestureCanceled (TouchLongPressGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int moveallow = 0, tcount = 0, dur = 0;
+
+                       moveallow = gestureDetector.GetMoveAllowance();
+                       dur = gestureDetector.GetDuration();
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnLongPressGestureCanceled__TouchLongPressGestureDetector__gestureDetector_,
+                                          _GESTURE_LONGPRESS, moveallow, 0, dur, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnLongPressGestureDetected (TouchLongPressGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int moveallow = 0, tcount = 0, dur = 0;
+
+                       moveallow = gestureDetector.GetMoveAllowance();
+                       dur = gestureDetector.GetDuration();
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnLongPressGestureDetected__TouchLongPressGestureDetector__gestureDetector_,
+                                          _GESTURE_LONGPRESS, moveallow, 0, dur, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPanningGestureCanceled (TouchPanningGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int tcount = 0;
+
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPanningGestureCanceled__TouchPanningGestureDetector__gestureDetector_,
+                                          _GESTURE_PANNING, 0, 0, 0, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPanningGestureChanged (TouchPanningGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int tcount = 0;
+
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPanningGestureChanged__TouchPanningGestureDetector__gestureDetector_,
+                                          _GESTURE_PANNING, 0, 0, 0, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPanningGestureFinished (TouchPanningGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int tcount = 0;
+
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPanningGestureFinished__TouchPanningGestureDetector__gestureDetector_,
+                                          _GESTURE_PANNING, 0, 0, 0, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPanningGestureStarted (TouchPanningGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int tcount = 0;
+
+                       tcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPanningGestureStarted__TouchPanningGestureDetector__gestureDetector_,
+                                          _GESTURE_PANNING, 0, 0, 0, tcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPinchGestureCanceled (TouchPinchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       Tizen::Graphics::Point point;
+                       int scale = 0;
+
+                       point = gestureDetector.GetCenterPoint();
+                       scale = gestureDetector.GetScale();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPinchGestureCanceled__TouchPinchGestureDetector__gestureDetector_,
+                                          _GESTURE_PINCH, point.x, point.y, scale, 0, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPinchGestureChanged (TouchPinchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       Tizen::Graphics::Point point;
+                       int scale = 0;
+
+                       point = gestureDetector.GetCenterPoint();
+                       scale = gestureDetector.GetScale();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPinchGestureChanged__TouchPinchGestureDetector__gestureDetector_,
+                                          _GESTURE_PINCH, point.x, point.y, scale, 0, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPinchGestureFinished (TouchPinchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       Tizen::Graphics::Point point;
+                       int scale = 0;
+
+                       point = gestureDetector.GetCenterPoint();
+                       scale = gestureDetector.GetScale();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPinchGestureFinished__TouchPinchGestureDetector__gestureDetector_,
+                                          _GESTURE_PINCH, point.x, point.y, scale, 0, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnPinchGestureStarted (TouchPinchGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       Tizen::Graphics::Point point;
+                       int scale = 0;
+
+                       point = gestureDetector.GetCenterPoint();
+                       scale = gestureDetector.GetScale();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnPinchGestureStarted__TouchPinchGestureDetector__gestureDetector_,
+                                          _GESTURE_PINCH, point.x, point.y, scale, 0, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnRotationGestureCanceled (TouchRotationGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int distance = 0;
+                       float angle = 0.0f;
+
+                       distance = gestureDetector.GetDistance();
+                       angle = gestureDetector.GetAngle();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnRotationGestureCanceled__TouchRotationGestureDetector__gestureDetector_,
+                                          _GESTURE_ROTATION, 0, 0, distance, static_cast<int>(angle), &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnRotationGestureChanged (TouchRotationGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int distance = 0;
+                       float angle = 0.0f;
+
+                       distance = gestureDetector.GetDistance();
+                       angle = gestureDetector.GetAngle();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnRotationGestureChanged__TouchRotationGestureDetector__gestureDetector_,
+                                          _GESTURE_ROTATION, 0, 0, distance, static_cast<int>(angle), &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnRotationGestureFinished (TouchRotationGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int distance = 0;
+                       float angle = 0.0f;
+
+                       distance = gestureDetector.GetDistance();
+                       angle = gestureDetector.GetAngle();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnRotationGestureFinished__TouchRotationGestureDetector__gestureDetector_,
+                                          _GESTURE_ROTATION, 0, 0, distance, static_cast<int>(angle), &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnRotationGestureStarted (TouchRotationGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int distance = 0;
+                       float angle = 0.0f;
+
+                       distance = gestureDetector.GetDistance();
+                       angle = gestureDetector.GetAngle();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnRotationGestureStarted__TouchRotationGestureDetector__gestureDetector_,
+                                          _GESTURE_ROTATION, 0, 0, distance, static_cast<int>(angle), &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int move = 0, tapcount = 0, touchcount = 0, interval = 0;
+
+                       move = gestureDetector.GetMoveAllowance();
+                       tapcount = gestureDetector.GetTapCount();
+                       interval = gestureDetector.GetTapInterval();
+                       touchcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnTapGestureCanceled__TouchTapGestureDetector__gestureDetector_,
+                                          _GESTURE_TAP, move, tapcount, interval, touchcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+void GestureEventListener::OnTapGestureDetected (TouchTapGestureDetector &gestureDetector)
+{
+       probeInfo_t     probeInfo;
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               {
+                       int move = 0, tapcount = 0, touchcount = 0, interval = 0;
+
+                       move = gestureDetector.GetMoveAllowance();
+                       tapcount = gestureDetector.GetTapCount();
+                       interval = gestureDetector.GetTapInterval();
+                       touchcount = gestureDetector.GetTouchCount();
+                       PACK_GESTURE_EVENT(API_ID_void_GestureEventListener__OnTapGestureDetected__TouchTapGestureDetector__gestureDetector_,
+                                          _GESTURE_TAP, move, tapcount, interval, touchcount, &gestureDetector);
+               }
+               probeBlockEnd();
+       }
+}
+
+GestureEventListener& GestureEventListener::GetInstance()
+{
+       return rInstance;
+}
diff --git a/probe_event/gesture.h b/probe_event/gesture.h
new file mode 100644 (file)
index 0000000..612b766
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __GESTURE_H__
+#define __GESTURE_H__
+
+#include <FUi.h>
+
+using namespace Tizen::Ui;
+
+class GestureEventListener :
+               public ITouchCustomGestureEventListener,
+               public ITouchFlickGestureEventListener,
+               public ITouchLongPressGestureEventListener,
+               public ITouchPanningGestureEventListener,
+               public ITouchPinchGestureEventListener,
+               public ITouchRotationGestureEventListener,
+               public ITouchTapGestureEventListener
+{
+public:
+       GestureEventListener();
+       virtual ~GestureEventListener();
+
+       virtual void    OnCustomGestureStarted (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureChanged (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureFinished (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureCanceled (TouchGestureDetector &gestureDetector);
+
+       virtual void    OnFlickGestureDetected (TouchFlickGestureDetector &gestureDetector);
+       virtual void    OnFlickGestureCanceled (TouchFlickGestureDetector &gestureDetector);
+
+       virtual void    OnLongPressGestureDetected (TouchLongPressGestureDetector &gestureDetector);
+       virtual void    OnLongPressGestureCanceled (TouchLongPressGestureDetector &gestureDetector);
+
+       virtual void    OnPanningGestureStarted (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureChanged (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureFinished (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureCanceled (TouchPanningGestureDetector &gestureDetector);
+
+       virtual void    OnPinchGestureStarted (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureChanged (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureFinished (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureCanceled (TouchPinchGestureDetector &gestureDetector);
+
+       virtual void    OnRotationGestureStarted (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureChanged (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureFinished (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureCanceled (TouchRotationGestureDetector &gestureDetector);
+
+       virtual void    OnTapGestureDetected (TouchTapGestureDetector &gestureDetector);
+       virtual void    OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector);
+
+       static GestureEventListener& GetInstance(void);
+
+private:
+       static GestureEventListener rInstance;
+};
+
+#endif
diff --git a/probe_event/keytouch.c b/probe_event/keytouch.c
new file mode 100755 (executable)
index 0000000..bf15682
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+//#include <fcntl.h>
+//#include <dlfcn.h>
+//#include <unistd.h>
+//#include <errno.h>
+#include <Eina.h>
+#include <Ecore_Input.h>
+#include <Evas.h>
+//#include <linux/input.h>
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "probeinfo.h"
+//#include "dautil.h"
+#include "da_event.h"
+
+#include "binproto.h"
+#include "real_functions.h"
+
+bool touch_pressed = false;
+
+#define PACK_HW_EVENT(API_ID, _EVENTTYPE, _DETAILTYPE, _X, _Y, _KEYCODE, _EXTRA, \
+       _ARGDATA, _ARGTYPE, _ARGEVENT)                                                                                          \
+       do {                                                                                                                                            \
+               setProbePoint(&probeInfo);                                                                                              \
+               PREPARE_LOCAL_BUF();                                                                                                    \
+               PACK_COMMON_BEGIN(MSG_PROBE_UIEVENT, API_ID, "pdp",                                     \
+                                 voidp_to_uint64(_ARGDATA), _ARGTYPE,  \
+                                 voidp_to_uint64(_ARGEVENT));          \
+               PACK_COMMON_END('c', 0, 0, 0);                                                                                          \
+               PACK_UIEVENT(_EVENTTYPE, _DETAILTYPE, _X, _Y, _KEYCODE, _EXTRA);                \
+               FLUSH_LOCAL_BUF();                                                                                                              \
+       } while (0)
+
+Eina_Bool ecore_event_evas_key_down(void *data, int type, void *event)
+{
+       static Eina_Bool (*ecore_event_evas_key_downp)(void *data, int type, void *event);
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(ecore_event_evas_key_down, LIBECORE_INPUT_EVAS);
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               if(event != NULL)
+               {
+                       Ecore_Event_Key* pEv = (Ecore_Event_Key*)event;
+                       if(strcasestr(pEv->keyname, "volume") == NULL)
+                       {
+                               PACK_HW_EVENT(API_ID_ecore_event_evas_key_down,
+                                             _EVENT_KEY, _KEY_PRESSED, 0, 0, pEv->keyname, 0, \
+                                             data, type, event);
+                       }
+               }
+               probeBlockEnd();
+       }
+
+       return ecore_event_evas_key_downp(data, type, event);
+}
+
+Eina_Bool ecore_event_evas_key_up(void *data, int type, void *event)
+{
+       static Eina_Bool (*ecore_event_evas_key_upp)(void *data, int type, void *event);
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(ecore_event_evas_key_up, LIBECORE_INPUT_EVAS);
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               if(event != NULL)
+               {
+                       Ecore_Event_Key* pEv = (Ecore_Event_Key*)event;
+                       if(strcasestr(pEv->keyname, "volume") == NULL)
+                       {
+                               PACK_HW_EVENT(API_ID_ecore_event_evas_key_up,
+                                             _EVENT_KEY, _KEY_RELEASED, 0, 0, pEv->keyname, 0, \
+                                             data, type, event);
+                       }
+               }
+               probeBlockEnd();
+       }
+
+       return ecore_event_evas_key_upp(data, type, event);
+}
+
+Eina_Bool ecore_event_evas_mouse_button_down(void *data, int type, void *event)
+{
+       static Eina_Bool (*ecore_event_evas_mouse_button_downp)(void *data, int type, void *event);
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(ecore_event_evas_mouse_button_down, LIBECORE_INPUT_EVAS);
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               if(event != NULL)
+               {
+                       Ecore_Event_Mouse_Button* pEv = (Ecore_Event_Mouse_Button*)event;
+                       touch_pressed = true;
+                       PACK_HW_EVENT(API_ID_ecore_event_evas_mouse_button_down,
+                                     _EVENT_TOUCH, _TOUCH_PRESSED, pEv->root.x, pEv->root.y, "", pEv->multi.device, \
+                                     data, type, event);
+               }
+               probeBlockEnd();
+       }
+
+       return ecore_event_evas_mouse_button_downp(data, type, event);
+}
+
+Eina_Bool ecore_event_evas_mouse_button_up(void *data, int type, void *event)
+{
+       static Eina_Bool (*ecore_event_evas_mouse_button_upp)(void *data, int type, void *event);
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(ecore_event_evas_mouse_button_up, LIBECORE_INPUT_EVAS);
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               if(event != NULL)
+               {
+                       Ecore_Event_Mouse_Button* pEv = (Ecore_Event_Mouse_Button*)event;
+                       touch_pressed = false;
+                       PACK_HW_EVENT(API_ID_ecore_event_evas_mouse_button_up,
+                                     _EVENT_TOUCH, _TOUCH_RELEASED, pEv->root.x, pEv->root.y, "", pEv->multi.device, \
+                                     data, type, event);
+               }
+               probeBlockEnd();
+       }
+
+       return ecore_event_evas_mouse_button_upp(data, type, event);
+}
+
+Eina_Bool ecore_event_evas_mouse_move(void *data, int type, void *event)
+{
+       static Eina_Bool (*ecore_event_evas_mouse_movep)(void *data, int type, void *event);
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(ecore_event_evas_mouse_move, LIBECORE_INPUT_EVAS);
+
+       if(isOptionEnabled(OPT_EVENT))
+       {
+               probeBlockStart();
+               if(touch_pressed)
+               {
+                       if(event != NULL)
+                       {
+                               Ecore_Event_Mouse_Move* pEv = (Ecore_Event_Mouse_Move*)event;
+                               PACK_HW_EVENT(API_ID_ecore_event_evas_mouse_move,
+                                             _EVENT_TOUCH, _TOUCH_MOVED, pEv->root.x, pEv->root.y, "", pEv->multi.device, \
+                                             data, type, event);
+                       }
+               }
+               probeBlockEnd();
+       }
+
+       return ecore_event_evas_mouse_movep(data, type, event);
+}
diff --git a/probe_event/orientation.c b/probe_event/orientation.c
new file mode 100644 (file)
index 0000000..20bce75
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <Ecore.h>
+#include <Ecore_X.h>
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "common_probe_init.h"
+
+
+Ecore_Event_Handler *register_orientation_event_listener();
+void unregister_orientation_event_listener(Ecore_Event_Handler *handler);
+
+Ecore_Event_Handler *handler = NULL;
+
+
+Eina_Bool _da_onclientmessagereceived(void __unused *pData, int __unused type,
+                                     void *pEvent)
+{
+       Ecore_X_Event_Client_Message *pClientEvent;
+
+       probeBlockStart();
+       pClientEvent = (Ecore_X_Event_Client_Message*)pEvent;
+
+       if (pClientEvent != NULL) {
+
+               //This code from ecore_x
+               //So I don't know what 32 does mean
+               if (pClientEvent->format != 32) {
+                       probeBlockEnd();
+                       return ECORE_CALLBACK_PASS_ON;
+               }
+
+               if (pClientEvent->message_type ==
+                   ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE) {
+                       int orientation = (int)pClientEvent->data.l[1];
+                       on_orientation_changed(orientation, false);
+               }
+       }
+       probeBlockEnd();
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+Ecore_Event_Handler *register_orientation_event_listener()
+{
+       Ecore_Event_Handler *handler;
+       probeBlockStart();
+
+       handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
+                                         _da_onclientmessagereceived, NULL);
+
+       probeBlockEnd();
+
+       return handler;
+}
+
+void unregister_orientation_event_listener(Ecore_Event_Handler *handler)
+{
+       probeBlockStart();
+
+       if (handler)
+               ecore_event_handler_del(handler);
+
+       probeBlockEnd();
+}
+
+EAPI int ecore_x_init(const char *name)
+{
+       static Ecore_Event_Handler *event_handler = NULL;
+
+       int res = 0;
+       static int (*ecore_x_initp)(const char *name);
+       PRINTMSG("(%s)", name);
+
+       GET_REAL_FUNC_RTLD_NEXT(ecore_x_init);
+       res = ecore_x_initp(name);
+
+       if (event_handler == NULL) {
+               event_handler = register_orientation_event_listener();
+               if (event_handler == NULL)
+                       PRINTERR("Fail to init event listener");
+       }
+       return res;
+}
diff --git a/probe_file/da_io.h b/probe_file/da_io.h
new file mode 100755 (executable)
index 0000000..06c9a88
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_IO_H__
+#define __DA_IO_H__
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "daprobe.h"
+
+/********************************************************************
+ * RESOURCE PROBE MACRO
+ *
+ * log format
+ *             SeqNumber`,ApiName`,Time`,Pid`,Tid`,InputParm`,Return`,PCAddr`,Error`,
+ *             Size`,FDValue`,FDType`,FDApiType`,                                      \n
+ *             callstack_start`,callstack`,callstack_end
+ *
+ * fd type
+ *             FD_TYPE_FILE, FD_TYPE_SOCKET
+ *
+ * fd api type
+ *             FD_API_TYPE_OPEN, FD_API_TYPE_CLOSE, FD_API_TYPE_READ, FD_API_TYPE_WRITE,
+ *             FD_API_TYPE_DIRECTORY, FD_API_TYPE_PERMISSION, FD_API_TYPE_OTHER,
+ *             FD_API_TYPE_SEND, FD_API_TYPE_RECEIVE, FD_API_TYPE_OPTION, FD_API_TYPE_MANAGE
+ *
+ ************************************************************************/
+
+// ===================================================================
+// macro for file probe
+// ===================================================================
+
+#define GET_FD_FROM_FILEP(FILEP)                               \
+       do {                                                    \
+               _fd = (FILEP != NULL) ? fileno(FILEP) : -1;     \
+       } while (0);
+
+#define DECLARE_VARIABLE_FD                                    \
+               DECLARE_VARIABLE_STANDARD;                      \
+               const char *_filepath = "";                     \
+               int __attribute((unused)) _fd = -1;             \
+               ssize_t __attribute((unused)) _filesize = 0;    \
+               int __attribute((unused)) _fstatret = -1;       \
+               struct stat __attribute((unused)) _statbuf
+
+// =================================================================
+// POST_PROBEBLOCK_MIDDLE for file
+// =================================================================
+
+#define POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, FD, APITYPE)                              \
+       do {                                                                            \
+               PACK_RESOURCE(SIZE, FD, APITYPE,                                        \
+                             (_fstatret == 0 ? _statbuf.st_size : 0), _filepath);      \
+               FLUSH_LOCAL_BUF();                                                      \
+       } while (0)
+
+#define POST_PACK_PROBEBLOCK_MIDDLE_NOFD(SIZE, APITYPE)                \
+       do {                                                    \
+               PACK_RESOURCE(SIZE, 0, APITYPE, 0, _filepath);  \
+               FLUSH_LOCAL_BUF();                              \
+       } while (0)
+
+// ==================================================================
+// BEFORE_ORIGINAL macro for file
+// ==================================================================
+
+#define BEFORE_ORIGINAL_FILE(FUNCNAME, LIBNAME)                \
+       DECLARE_VARIABLE_FD;                            \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);               \
+       PRE_PROBEBLOCK();
+
+#define BEFORE_ORIGINAL_FILE_NOFILTER(FUNCNAME, LIBNAME)       \
+       DECLARE_VARIABLE_FD;                                    \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                       \
+       bfiltering = false;                                     \
+       PRE_PROBEBLOCK()
+
+// ==================================================================
+// macro for filesize
+// ==================================================================
+
+#define DEFINE_FILESIZE_FD(fd) _fd = (fd); _filesize = get_fd_filesize(_fd);
+#define DEFINE_FILESIZE_FP(fp) _fd = checked_fileno(fp); _filesize = get_fd_filesize(_fd);
+#define DEFINE_FILESIZE_0() _fd = _filesize = 0;
+
+/*!
+ * Macro AFTER_PACK_ORIGINAL_FD is used in and only in functions, which should report
+ * only about regular files or sockets, so this logic implemented in macro.
+ * Watch out when reusing it somewhere else
+ */
+#define AFTER_PACK_ORIGINAL_FD(API_ID, RTYPE, RVAL, SIZE, FD, APITYPE, INPUTFORMAT, ...)       \
+do {                                                                                           \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                           \
+       _fstatret = fstat(FD, &_statbuf);                                                       \
+       if (stat_regular_or_socket_p(&_statbuf)) {                                              \
+               PREPARE_LOCAL_BUF();                                                            \
+               PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+               PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                            \
+               POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, FD, APITYPE);                              \
+       }                                                                                       \
+       POST_PACK_PROBEBLOCK_END();                                                             \
+} while(0)
+
+#define AFTER_PACK_ORIGINAL_FD_MIDDLE(API_ID, RTYPE, RVAL, SIZE, FD, APITYPE, INPUTFORMAT, ...)        \
+do {                                                                                           \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                           \
+       _fstatret = fstat(FD, &_statbuf);                                                       \
+       if (stat_regular_or_socket_p(&_statbuf)) {                                              \
+               PREPARE_LOCAL_BUF();                                                            \
+               PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+               PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                            \
+               POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, FD, APITYPE);                              \
+       }                                                                                       \
+       POST_PACK_PROBEBLOCK_ADD_END();                                                         \
+} while(0)
+
+#define AFTER_PACK_ORIGINAL_NOFD(API_ID, RTYPE, RVAL, SIZE, APITYPE, INPUTFORMAT, ...) \
+do {                                                                                   \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                   \
+       PREPARE_LOCAL_BUF();                                                            \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+       PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                            \
+       POST_PACK_PROBEBLOCK_MIDDLE_NOFD(SIZE, APITYPE);                                \
+       POST_PACK_PROBEBLOCK_END();                                                     \
+} while(0)
+
+#define AFTER_PACK_ORIGINAL_FILEP(API_ID, RTYPE, RVAL, SIZE, FILEP, APITYPE, INPUTFORMAT, ...) \
+do {                                                                                   \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                   \
+       GET_FD_FROM_FILEP(FILEP);                                                       \
+       if(_fd != -1) {                                                                 \
+               _fstatret = fstat(_fd, &_statbuf);                                      \
+       }                                                                               \
+       PREPARE_LOCAL_BUF();                                                            \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+       PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                            \
+       POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, _fd, APITYPE);                             \
+       POST_PACK_PROBEBLOCK_END();                                                     \
+} while(0)
+
+/*!
+ * Macros {BEFORE,AFTER}_ORIGINAL_START_END_FD only used in {p,v,}{read,write}
+ * in which we should log only about files and sockets. Given this lucky
+ * coincidence we can implement this login in macros. As such, they should not
+ * be used in functions for which this logic do not apply.
+ */
+static inline bool stat_regular_or_socket_p(struct stat *buf)
+{
+  return S_ISREG(buf->st_mode) || S_ISSOCK(buf->st_mode);
+}
+#define BEFORE_ORIGINAL_START_END_FD(API_ID, RTYPE, FUNCNAME, LIBNAME, FD, APITYPE, INPUTFORMAT, ...)  \
+       DECLARE_VARIABLE_FD;                                                                    \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                                                       \
+       PRE_PROBEBLOCK_BEGIN();                                                                 \
+       _fstatret = fstat(FD, &_statbuf);                                                       \
+       if (stat_regular_or_socket_p(&_statbuf)) {                                              \
+               DEFINE_FILESIZE_FD(fd);                                                         \
+               PREPARE_LOCAL_BUF();                                                            \
+               PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+               PACK_COMMON_END(RTYPE, 0, 0, blockresult);                                      \
+               PACK_RESOURCE(0, FD, APITYPE, _filesize, _filepath);                            \
+               FLUSH_LOCAL_BUF();                                                              \
+       }                                                               \
+       PRE_PROBEBLOCK_END();                                                           \
+
+#define AFTER_ORIGINAL_START_END_FD(API_ID, RTYPE, RVAL, SIZE, FD, APITYPE, INPUTFORMAT, ...)          \
+do {                                                                   \
+       POST_PACK_PROBEBLOCK_BEGIN();                                   \
+       setProbePoint(&probeInfo);                                      \
+       _fstatret = fstat(FD, &_statbuf);                               \
+       if (stat_regular_or_socket_p(&_statbuf)) {                      \
+               PREPARE_LOCAL_BUF();                                                            \
+               PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__); \
+               PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);            \
+               PACK_RESOURCE(SIZE, FD, APITYPE, _filesize, _filepath); \
+               FLUSH_LOCAL_BUF();                                                              \
+       }                                                               \
+       POST_PACK_PROBEBLOCK_END();                                                             \
+} while(0)
+
+
+
+#define BEFORE_ORIGINAL_START_END_NOFD(API_ID, RTYPE, FUNCNAME, LIBNAME, APITYPE, INPUTFORMAT, ...)    \
+       DECLARE_VARIABLE_FD;                                                            \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                                               \
+       PRE_PROBEBLOCK_BEGIN();                                                         \
+       DEFINE_FILESIZE_0();                                                            \
+       PREPARE_LOCAL_BUF();                                                            \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);        \
+       PACK_COMMON_END(RTYPE, 0, 0, blockresult);                                      \
+       POST_PACK_PROBEBLOCK_MIDDLE_NOFD(0, APITYPE);                                   \
+       PRE_PROBEBLOCK_END()
+
+#define BEFORE_ORIGINAL_START_END_FILEP(API_ID, RTYPE, FUNCNAME, LIBNAME, FILEP, APITYPE, INPUTFORMAT, ...)    \
+       DECLARE_VARIABLE_FD;                                                                    \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                                                       \
+       PRE_PROBEBLOCK_BEGIN();                                                                 \
+       GET_FD_FROM_FILEP(FILEP);                                                               \
+       if(_fd != -1) {                                                                         \
+               _fstatret = fstat(_fd, &_statbuf);                                              \
+       }                                                                                       \
+       PREPARE_LOCAL_BUF();                                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);                \
+       PACK_COMMON_END(RTYPE, 0, 0, blockresult);                                              \
+       POST_PACK_PROBEBLOCK_MIDDLE_FD(0, _fd, APITYPE);                                        \
+       PRE_PROBEBLOCK_END()
+
+#define AFTER_ORIGINAL_START_END_NOFD(API_ID, RTYPE, RVAL, SIZE, APITYPE, INPUTFORMAT, ...)    \
+do {                                                                                           \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                           \
+       setProbePoint(&probeInfo);                                                              \
+       PREPARE_LOCAL_BUF();                                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);                \
+       PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                                    \
+       POST_PACK_PROBEBLOCK_MIDDLE_NOFD(SIZE, APITYPE);                                        \
+       POST_PACK_PROBEBLOCK_END();                                                             \
+} while(0)
+
+#define AFTER_ORIGINAL_START_END_FILEP(API_ID, RTYPE, RVAL, SIZE, FILEP, APITYPE, INPUTFORMAT, ...)    \
+do {                                                                                           \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                           \
+       setProbePoint(&probeInfo);                                                              \
+       GET_FD_FROM_FILEP(FILEP);                                                               \
+       if(_fd != -1) {                                                                         \
+               _fstatret = fstat(_fd, &_statbuf);                                              \
+       }                                                                                       \
+       PREPARE_LOCAL_BUF();                                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__);                \
+       PACK_COMMON_END(RTYPE, RVAL, newerrno, blockresult);                                    \
+       POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, _fd, APITYPE);                                     \
+       POST_PACK_PROBEBLOCK_END();                                                             \
+} while(0)
+
+
+static inline ssize_t get_fd_filesize(int fd)
+{
+       /**
+        * Calling library function on invalid file descriptiors is okay,
+        * for such cases we assume size == 0
+        * FIXME: Separate empty files and invalid descriptors.
+        **/
+       struct stat buf;
+       int err = fstat(fd, &buf);
+       if (err)
+               return 0;
+       return buf.st_size ?: 0;
+}
+
+static inline int checked_fileno(FILE *fp)
+{
+       assert((fp != NULL) &&
+              "This function (checked_fileno) is only called from probes\n"
+              "on library functions. Passing NULL instead of file pointer\n"
+              "to standart C functions is undefined behavior\n"
+              "and as such fatal error.\n");
+       return fileno(fp);
+}
+
+
+#endif // __DA_IO_H__
diff --git a/probe_file/da_io_posix.c b/probe_file/da_io_posix.c
new file mode 100755 (executable)
index 0000000..1be3048
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <dlfcn.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dautil.h"
+#include "dahelper.h"
+#include "da_io.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <utime.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/uio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "binproto.h"
+#include "real_functions.h"
+
+static enum DaOptions _sopt = OPT_FILE;
+
+static inline char *get_abs_path(int fd, const char *fname,
+                                char *buf, size_t bufsiz)
+{
+       char *path = real_abs_path(fd, buf, bufsiz);
+
+       if (!path)
+               path = absolutize_filepath(fname, buf, bufsiz);
+
+       return path;
+}
+
+int open(const char* path, int oflag, ...)
+{
+       static int (*openp)(const char* path, int oflag, ...);
+       char buffer[PATH_MAX];
+       int mode = 0;
+
+       BEFORE_ORIGINAL_FILE(open, LIBC);
+
+       if(oflag & O_CREAT)
+       {
+               va_list arg;
+               va_start(arg, oflag);
+               mode = va_arg(arg, int);
+               va_end(arg);
+       }
+
+       ret = openp(path, oflag, mode);
+
+       _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_open, 'd', ret, 0, ret, FD_API_OPEN,
+                              "s4dd", path, oflag, mode);
+
+       return ret;
+}
+
+int openat(int fd, const char* path, int oflag, ...)
+{
+       static int (*openatp)(int fd, const char* path, int oflag, ...);
+       char buffer[PATH_MAX];
+       int mode = 0;
+
+       BEFORE_ORIGINAL_FILE(openat, LIBC);
+
+       if(oflag & O_CREAT)
+       {
+               va_list arg;
+               va_start(arg, oflag);
+               mode = va_arg(arg, int);
+               va_end(arg);
+       }
+
+       ret = openatp(fd, path, oflag, mode);
+
+       _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_openat, 'd', ret, 0, ret, FD_API_OPEN,
+                              "ds4dd", fd, path, oflag, mode);
+
+       return ret;
+}
+
+int creat(const char* path, mode_t mode)
+{
+       static int (*creatp)(const char* path, mode_t mode);
+       char buffer[PATH_MAX];
+
+       BEFORE_ORIGINAL_FILE(creat, LIBC);
+
+       ret = creatp(path, mode);
+
+       _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_creat, 'd', ret, 0, ret, FD_API_OPEN,
+                              "s4d", path, mode);
+
+       return ret;
+}
+
+int close(int fd)
+{
+       static int (*closep)(int fd);
+       DECLARE_VARIABLE_FD;
+
+       GET_REAL_FUNC(close, LIBC);
+
+       bfiltering = false;
+       PRE_PROBEBLOCK_BEGIN();
+       _fstatret = fstat(fd, &_statbuf);
+       PRE_PROBEBLOCK_END();
+
+       ret = closep(fd);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE,
+                         API_ID_close,
+                         "d", fd);
+       PACK_COMMON_END('d', ret, newerrno, blockresult);
+       POST_PACK_PROBEBLOCK_MIDDLE_FD(0, fd, FD_API_CLOSE);
+       POST_PACK_PROBEBLOCK_END();
+
+       return ret;
+}
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+       static int (*lseekp)(int fd, off_t offset, int whence);
+       off_t offret;
+
+       BEFORE_ORIGINAL_FILE(lseek, LIBC);
+
+       offret = lseekp(fd, offset, whence);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_lseek,
+                                  'x', offret, (unsigned int)offset, fd, FD_API_OTHER,
+                                  "dxd", fd, (uint64_t)(offset), whence);
+
+       return offret;
+}
+
+int fsync(int fd)
+{
+       static int (*fsyncp)(int fd);
+
+       BEFORE_ORIGINAL_FILE(fsync, LIBC);
+
+       ret = fsyncp(fd);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_fsync,
+                                  'd', ret, 0, fd, FD_API_OTHER, "d", fd);
+
+       return ret;
+}
+
+int fdatasync(int fd)
+{
+       static int (*fdatasyncp)(int fd);
+
+       BEFORE_ORIGINAL_FILE(fdatasync, LIBC);
+
+       ret = fdatasyncp(fd);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_fdatasync,
+                                  'd', ret, 0, fd, FD_API_OTHER, "d", fd);
+
+       return ret;
+}
+
+
+
+int ftruncate(int fd, off_t length)
+{
+       static int (*ftruncatep)(int fd, off_t length);
+
+       BEFORE_ORIGINAL_FILE(ftruncate, LIBC);
+
+       ret = ftruncatep(fd, length);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_ftruncate,
+                              'd', ret, (unsigned int)length, fd,
+                              FD_API_DIRECTORY, "dx", fd, (uint64_t)(length));
+
+       return ret;
+}
+
+int fchown(int fd, uid_t owner, gid_t group)
+{
+       static int (*fchownp)(int fd, uid_t owner, gid_t group);
+
+       BEFORE_ORIGINAL_FILE(fchown, LIBC);
+       ret = fchownp(fd, owner, group);
+       AFTER_PACK_ORIGINAL_FD(API_ID_fchown, 'd', ret, 0, fd, FD_API_PERMISSION,
+                         "ddd", fd, owner, group);
+       return ret;
+}
+
+
+
+
+int lockf(int fd, int function, off_t size)
+{
+       static int (*lockfp)(int fd, int function, off_t size);
+       int api_type = FD_API_PERMISSION;
+
+       BEFORE_ORIGINAL_FILE(lockf, LIBC);
+       ret = lockfp(fd, function, size);
+
+       switch (function) {
+       case F_LOCK:
+       case F_TLOCK:
+               api_type = FD_API_LOCK_START;
+               break;
+       case F_ULOCK:
+               api_type = FD_API_LOCK_END;
+               break;
+       }
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_lockf,
+                              'd', ret, (unsigned int)size, fd, api_type,
+                              "ddx", fd, function, (uint64_t)(size));
+       return ret;
+}
+
+
+
+int fchmod(int fd, mode_t mode)
+{
+       static int (*fchmodp)(int fd, mode_t mode);
+
+       BEFORE_ORIGINAL_FILE(fchmod, LIBC);
+       ret = fchmodp(fd, mode);
+       AFTER_PACK_ORIGINAL_FD(API_ID_fchmod,
+                                  'd', ret, 0, fd, FD_API_PERMISSION, "dd", fd, mode);
+       return ret;
+}
+
+// *****************************************************************
+// Read / Write APIs
+// *****************************************************************
+
+ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset)
+{
+       static ssize_t (*preadp)(int fd, void *buf, size_t nbyte, off_t offset);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_START_END_FD(API_ID_pread, 'x', pread, LIBC, fd,
+                                    FD_API_READ_START, "dpxx", fd,
+                                    voidp_to_uint64(buf),
+                                    (uint64_t)(nbyte),
+                                    (uint64_t)(offset));
+
+       sret = preadp(fd, buf, nbyte, offset);
+
+       AFTER_ORIGINAL_START_END_FD(API_ID_pread, 'x', sret, (unsigned int)sret, fd,
+                                   FD_API_READ_END, "dpxx", fd,
+                                   voidp_to_uint64(buf),
+                                   (uint64_t)(nbyte),
+                                   (uint64_t)(offset));
+
+       return sret;
+}
+ssize_t read(int fd, void *buf, size_t nbyte)
+{
+       static ssize_t (*readp)(int fildes, void *buf, size_t nbyte);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_START_END_FD(API_ID_read, 'x', read, LIBC, fd, FD_API_READ_START,
+                                    "dpx", fd, voidp_to_uint64(buf),
+                                    (uint64_t)(nbyte));
+
+       sret = readp(fd, buf, nbyte);
+
+       AFTER_ORIGINAL_START_END_FD(API_ID_read, 'x', sret, (unsigned int)sret, fd,
+                                   FD_API_READ_END, "dpx", fd,
+                                   voidp_to_uint64(buf),
+                                   (uint64_t)(nbyte));
+
+       return sret;
+}
+
+ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
+{
+       static ssize_t (*pwritep)(int fd, const void *buf, size_t nbyte, off_t offset);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_START_END_FD(API_ID_pwrite, 'x', pwrite, LIBC, fd, FD_API_WRITE_START,
+                                    "dpxx", fd, voidp_to_uint64(buf),
+                                    (uint64_t)(nbyte),
+                                    (uint64_t)(offset));
+
+       sret = pwritep(fd, buf, nbyte, offset);
+
+       DEFINE_FILESIZE_FD(fd);
+       AFTER_ORIGINAL_START_END_FD(API_ID_pwrite, 'x', sret, (unsigned int)sret, fd,
+                                  FD_API_WRITE_END, "dpxx", fd,
+                                   voidp_to_uint64(buf),
+                                   (uint64_t)(nbyte),
+                                   (uint64_t)(offset));
+
+       return sret;
+}
+
+ssize_t write(int fd, const void *buf, size_t nbyte)
+{
+       static ssize_t (*writep)(int fildes, const void *buf, size_t nbyte);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_START_END_FD(API_ID_write, 'x', write, LIBC, fd, FD_API_WRITE_START,
+                                    "dpx", fd, voidp_to_uint64(buf),
+                                    (uint64_t)(nbyte));
+
+       sret = writep(fd, buf, nbyte);
+
+       DEFINE_FILESIZE_FD(fd);
+       AFTER_ORIGINAL_START_END_FD(API_ID_write, 'x', sret, (unsigned int)sret, fd,
+                                   FD_API_WRITE_END, "dpx", fd,
+                                   voidp_to_uint64(buf),
+                                   (uint64_t)(nbyte));
+
+       return sret;
+}
+
+
+ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+{
+       static ssize_t (*readvp)(int fd, const struct iovec *iov, int iovcnt);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_START_END_FD(API_ID_readv, 'x', readv, LIBC, fd, FD_API_READ_START,
+                                    "dpd", fd, voidp_to_uint64(iov), iovcnt);
+
+       sret = readvp(fd,iov,iovcnt);
+
+       AFTER_ORIGINAL_START_END_FD(API_ID_readv, 'x', sret, (unsigned int)sret, fd,
+                                   FD_API_READ_END, "dpd", fd,
+                                   voidp_to_uint64(iov), iovcnt);
+
+       return sret;
+}
+
+// why writev is commented ?
+#if 0
+ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+{
+       static ssize_t (*writevp)(int fd, const struct iovec *iov, int iovcnt);
+
+       MAKE_RESOURCE_PREBLOCK(writev, LIBC,3,VT_INT,fd,VT_PTR,iov,VT_INT,iovcnt);
+       ssize_t ret;
+       ret = writevp(fd,iov,iovcnt);
+       MAKE_RESOURCE_POSTBLOCK(VT_SSIZE_T,ret,VT_SSIZE_T,ret,VT_INT,fd, FD_API_WRITE);
+       return ret;
+}
+#endif
+
+
+
+
+
+
+
+
+// *****************************************************************
+// File Attributes APIs
+// *****************************************************************
+int fcntl(int fd, int cmd, ...)
+{
+       static int (*fcntlp)(int fd, int cmd, ...);
+       int arg = 0, api_type = FD_API_OTHER;
+       int64_t start = 0;
+       int64_t len = 0;
+       int type = 0;
+       int whence = 0;
+
+       BEFORE_ORIGINAL_FILE(fcntl, LIBC);
+
+       va_list argl;
+       va_start(argl, cmd);
+       arg = va_arg(argl, int);
+       va_end(argl);
+
+       if (cmd == F_SETLK || cmd == F_SETLKW) {
+               struct flock *flock = (struct flock *)arg;
+               type = flock->l_type;
+               whence = flock->l_whence;
+               start = flock->l_start;
+               len = flock->l_len;
+
+               switch (type) {
+               case F_RDLCK:
+               case F_WRLCK:
+                       api_type = FD_API_LOCK_START;
+                       break;
+               case F_UNLCK:
+                       api_type = FD_API_LOCK_RELEASE;
+                       break;
+               }
+       }
+
+       /* before lock event */
+       if (api_type == FD_API_LOCK_START)
+               AFTER_PACK_ORIGINAL_FD_MIDDLE(API_ID_fcntl,
+                                             'd', ret, 0, fd, api_type,
+                                             "ddddxx", fd, cmd, type,
+                                             whence, start, len);
+
+       /* call original lock function */
+       ret = fcntlp(fd, cmd, arg);
+
+       /* after lock event */
+       if (api_type != FD_API_OTHER) {
+               if (api_type == FD_API_LOCK_START)
+                       api_type = FD_API_LOCK_END;
+               /* pack FD_API_LOCK_END or FD_API_UNLOCK events */
+               AFTER_PACK_ORIGINAL_FD(API_ID_fcntl,
+                                      'd', ret, 0, fd, api_type,
+                                      "ddddxx", fd, cmd, type,
+                                      whence, start, len);
+       } else {
+               /* pack FD_API_OTHER */
+               AFTER_PACK_ORIGINAL_FD(API_ID_fcntl,
+                                      'd', ret, 0, fd, api_type,
+                                      "ddd", fd, cmd, arg);
+       }
+
+       return ret;
+}
+
+int dup(int fd)
+{
+       static int (*dupp)(int fd);
+
+       BEFORE_ORIGINAL_FILE(dup, LIBC);
+
+       ret = dupp(fd);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_dup,
+                                  'd', ret, 0, ret, FD_API_OPEN, "d", fd);
+
+       return ret;
+}
+
+int dup2(int fd, int fd2)
+{
+       static int (*dup2p)(int fd, int fd2);
+
+       BEFORE_ORIGINAL_FILE(dup2, LIBC);
+
+       ret = dup2p(fd, fd2);
+
+       AFTER_PACK_ORIGINAL_FD(API_ID_dup2,
+                                  'd', ret, 0, ret, FD_API_OPEN, "dd", fd, fd2);
+
+       return ret;
+}
+
+//FIXME dlsym error
+// fstat is not in LIBC
+#if 0
+int fstat(int fd, struct stat *buf)
+{
+       static int (*fstatp)(int fd, struct stat *buf);
+
+       BEFORE_ORIGINAL_FILE(fstat, LIBC);
+       ret = fstatp(fd, buf);
+       AFTER_PACK_ORIGINAL_FD(ret, 0, fd, FD_API_OTHER, "dp", fd,
+                              voidp_to_uint64(buf));
+       return ret;
+}
+#endif
+
+int futimens(int fd, const struct timespec times[2])
+{
+       static int (*futimensp)(int fd, const struct timespec times[2]);
+
+       BEFORE_ORIGINAL_FILE(futimens, LIBC);
+       ret = futimensp(fd, times);
+       AFTER_PACK_ORIGINAL_FD(API_ID_futimens,
+                              'd', ret, 0, fd, FD_API_OTHER, "dp", fd,
+                              voidp_to_uint64(times));
+       return ret;
+}
diff --git a/probe_file/da_io_stdc.c b/probe_file/da_io_stdc.c
new file mode 100644 (file)
index 0000000..35ebd4f
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dautil.h"
+#include "dahelper.h"
+#include "da_io.h"
+
+#include "binproto.h"
+#include "real_functions.h"
+
+static enum DaOptions _sopt = OPT_FILE;
+
+static inline char *get_abs_path(FILE *file, const char *fname,
+                                char *buf, size_t bufsiz)
+{
+       char *path = file ? real_abs_path(fileno(file), buf, bufsiz): NULL;
+
+       if (!path)
+               path = absolutize_filepath(fname, buf, bufsiz);
+
+       return path;
+}
+
+FILE* fopen(const char* filename, const char* mode)
+{
+       static FILE* (*fopenp)(const char* filename, const char* mode);
+       char buffer[PATH_MAX];
+       FILE* fret;
+
+       BEFORE_ORIGINAL_FILE(fopen, LIBC);
+
+       fret = fopenp(filename, mode);
+
+       _filepath = get_abs_path(fret, filename, buffer, PATH_MAX);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fopen,
+                                 'p', fret, 0, fret, FD_API_OPEN, "s4s",
+                                 filename, mode);
+
+       return fret;
+}
+
+FILE* freopen(const char * filename, const char * mode, FILE * stream)
+{
+       static FILE* (*freopenp)(const char *filename, const char *mode,
+                                FILE *stream);
+       char buffer[PATH_MAX];
+       FILE* fret;
+
+       BEFORE_ORIGINAL_FILE(freopen, LIBC);
+
+       fret = freopenp(filename, mode, stream);
+
+       _filepath = get_abs_path(fret, filename, buffer, PATH_MAX);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_freopen, 'p', fret, 0, fret, FD_API_OPEN,
+                                 "s4sp", filename, mode,
+                                 voidp_to_uint64(stream));
+
+       return fret;
+}
+
+FILE* fdopen(int fildes, const char *mode)
+{
+       static FILE* (*fdopenp)(int fildes, const char *mode);
+       FILE* fret;
+
+       BEFORE_ORIGINAL_FILE(fdopen, LIBC);
+
+       fret = fdopenp(fildes, mode);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fdopen,
+                                 'p', fret, 0, fret, FD_API_OPEN, "ds", fildes, mode);
+
+       return fret;
+}
+
+int fflush(FILE* stream)
+{
+       static int (*fflushp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(fflush, LIBC);
+       ret = fflushp(stream);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fflush,
+                                 'd', ret, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+       return ret;
+}
+
+int fclose(FILE* stream)
+{
+       static int (*fclosep)(FILE* stream);
+       DECLARE_VARIABLE_FD;
+
+       GET_REAL_FUNC(fclose, LIBC);
+
+       PRE_PROBEBLOCK_BEGIN();
+       GET_FD_FROM_FILEP(stream);
+       if(_fd != -1) {
+               _fstatret = fstat(_fd, &_statbuf);
+       }
+       PRE_PROBEBLOCK_END();
+
+       ret = fclosep(stream);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE,
+                         API_ID_fclose,
+                         "p", voidp_to_uint64(stream));
+       PACK_COMMON_END('d', ret, newerrno, blockresult);
+       POST_PACK_PROBEBLOCK_MIDDLE_FD(0, _fd, FD_API_CLOSE);
+       POST_PACK_PROBEBLOCK_END();
+
+       return ret;
+}
+
+FILE * tmpfile ( void )
+{
+       static FILE* (*tmpfilep) ( void );
+       FILE* fret;
+
+       BEFORE_ORIGINAL_FILE(tmpfile, LIBC);
+       _filepath = "<temp file>";
+       fret = tmpfilep();
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_tmpfile,
+                                 'p', fret, 0, fret, FD_API_OPEN, "s", "");
+       return fret;
+}
+
+int fgetpos(FILE* stream, fpos_t* position)
+{
+       static int (*fgetposp)(FILE* stream, fpos_t* position);
+
+       BEFORE_ORIGINAL_FILE(fgetpos, LIBC);
+       ret = fgetposp(stream, position);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fgetpos,
+                                 'd', ret, 0, stream, FD_API_OTHER, "pp",
+                                 voidp_to_uint64(stream),
+                                 voidp_to_uint64(position));
+       return ret;
+}
+
+int fseek(FILE* stream, long int offset, int origin)
+{
+       static int (*fseekp)(FILE* stream, long int offset, int origin);
+
+       BEFORE_ORIGINAL_FILE(fseek, LIBC);
+       ret = fseekp(stream, offset, origin);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fseek,
+                                 'd', ret, (unsigned int)offset, stream, FD_API_OTHER,
+                                 "pxd", voidp_to_uint64(stream),
+                                 (uint64_t)(offset), origin);
+       return ret;
+}
+
+int fsetpos(FILE* stream, const fpos_t* pos)
+{
+       static int (*fsetposp)(FILE* stream, const fpos_t* pos);
+
+       BEFORE_ORIGINAL_FILE(fsetpos, LIBC);
+       ret = fsetposp(stream, pos);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fsetpos,
+                                 'd', ret, 0, stream, FD_API_OTHER, "pp",
+                                 voidp_to_uint64(stream), voidp_to_uint64(pos));
+       return ret;
+}
+
+long int ftell(FILE* stream)
+{
+       static long int (*ftellp)(FILE* stream);
+       long int lret;
+
+       BEFORE_ORIGINAL_FILE(ftell, LIBC);
+
+       lret = ftellp(stream);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_ftell,
+                                 'x', lret, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+
+       return lret;
+}
+
+void rewind(FILE* stream)
+{
+       static void (*rewindp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(rewind, LIBC);
+
+       rewindp(stream);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_rewind,
+                                 'v', 0, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+}
+
+void clearerr(FILE* stream)
+{
+       static void (*clearerrp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(clearerr, LIBC);
+
+       clearerrp(stream);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_clearerr,
+                                 'v', 0, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+}
+
+int feof(FILE* stream)
+{
+       static int (*feofp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(feof, LIBC);
+       ret = feofp(stream);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_feof,
+                                 'd', ret, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+       return ret;
+}
+
+int ferror(FILE* stream)
+{
+       static int (*ferrorp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(ferror, LIBC);
+       ret = ferrorp(stream);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_ferror,
+                                 'd', ret, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+       return ret;
+}
+
+int fileno(FILE* stream)
+{
+       static int (*filenop)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(fileno, LIBC);
+       ret = filenop(stream);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_fileno,
+                                 'd', ret, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+       return ret;
+}
+
+
+
+// *******************************************************************
+// File read / write APIs
+// *******************************************************************
+
+int vfprintf(FILE* stream, const char* format, va_list arg)
+{
+       static int (*vfprintfp)(FILE* stream, const char* format, va_list arg);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_vfprintf, 'd', vfprintf, LIBC, stream,
+                                       FD_API_WRITE_START, "ps",
+                                       voidp_to_uint64(stream), format);
+
+       ret = vfprintfp(stream, format, arg);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_vfprintf, 'd', ret, ret, stream,
+                                      FD_API_WRITE_END, "ps",
+                                      voidp_to_uint64(stream), format);
+
+       return ret;
+}
+
+int vfscanf(FILE* stream, const char* format, va_list arg)
+{
+       static int (*vfscanfp)(FILE* stream, const char* format, va_list arg);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_vfscanf, 'd', vfscanf, LIBC, stream,
+                                       FD_API_READ_START, "ps",
+                                       voidp_to_uint64(stream), format);
+
+       ret = vfscanfp(stream, format, arg);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_vfscanf, 'd', ret, ret, stream,
+                                      FD_API_READ_END, "ps",
+                                      voidp_to_uint64(stream), format);
+
+       return ret;
+}
+
+int fgetc(FILE* stream)
+{
+       static int (*fgetcp)(FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fgetc, 'd', fgetc, LIBC, stream,
+                                       FD_API_READ_START, "p",
+                                       voidp_to_uint64(stream));
+
+       ret = fgetcp(stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fgetc, 'd', ret, (ret != EOF), stream,
+                                      FD_API_READ_END, "p",
+                                      voidp_to_uint64(stream));
+
+       return ret;
+}
+
+#if 0  // why is this commented?
+char* fgets(char* str, int size, FILE* stream)
+{
+       static char* (*fgetsp)(char* str, int num, FILE* stream);
+       char* cret;
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fgets, 'p', FD_API_READ_START,
+                               fgets, LIBC, stream, "sdp", str, size, stream);
+
+       cret = fgetsp(str, size, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fgets, 'p', cret, (ret == NULL ? 0 : strlen(cret)),
+                       stream, FD_API_READ_END, "sdp", str, size, stream);
+
+       return cret;
+}
+#endif
+
+int fputc(int character, FILE* stream)
+{
+       static int (*fputcp)(int character, FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fputc, 'd', fputc, LIBC, stream,
+                                       FD_API_WRITE_START, "dp", character,
+                                       voidp_to_uint64(stream));
+
+       ret = fputcp(character, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fputc, 'd', ret, (ret == EOF ? 0 : 1),
+                                      stream, FD_API_WRITE_END, "dp",
+                                      character, voidp_to_uint64(stream));
+
+       return ret;
+}
+
+int fputs(const char* str, FILE* stream)
+{
+       static int (*fputsp)(const char* str, FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fputs, 'd', fputs, LIBC, stream,
+                                       FD_API_WRITE_START, "sp", str,
+                                       voidp_to_uint64(stream));
+
+       ret = fputsp(str, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fputs, 'd', ret, ret, stream,
+                                      FD_API_WRITE_END, "sp", str,
+                                      voidp_to_uint64(stream));
+
+       return ret;
+}
+
+int getc(FILE* stream)
+{
+       static int (*getcp)(FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_getc, 'd', getc, LIBC, stream,
+                                       FD_API_READ_START, "p",
+                                       voidp_to_uint64(stream));
+
+       ret = getcp(stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_getc, 'd', ret, (ret == EOF ? 0 : 1), stream,
+                                      FD_API_READ_END, "p",
+                                      voidp_to_uint64(stream));
+
+       return ret;
+}
+
+int putc(int character, FILE* stream)
+{
+       static int (*putcp)(int character, FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_putc, 'd', putc, LIBC, stream,
+                                       FD_API_WRITE_START, "dp", character,
+                                       voidp_to_uint64(stream));
+
+       ret = putcp(character, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_putc, 'd', ret, (ret == EOF ? 0 : 1),
+                                      stream, FD_API_WRITE_END, "dp",
+                                      character, voidp_to_uint64(stream));
+
+       return ret;
+}
+
+int ungetc(int character, FILE* stream)
+{
+       static int (*ungetcp)(int character, FILE* stream);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_putc, 'd', ungetc, LIBC, stream,
+                                       FD_API_WRITE_START, "dp", character,
+                                       voidp_to_uint64(stream));
+
+       ret = ungetcp(character, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_ungetc, 'd', ret, 0, stream,
+                                      FD_API_OTHER, "dp", character,
+                                      voidp_to_uint64(stream));
+
+       return ret;
+}
+
+size_t fread(void* ptr, size_t size, size_t count, FILE* stream)
+{
+       static size_t (*freadp)(void* ptr, size_t size, size_t count, FILE* stream);
+       size_t tret;
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fread, 'x', fread, LIBC, stream,
+                                       FD_API_READ_START, "pxxp",
+                                       voidp_to_uint64(ptr),
+                                       (uint64_t)(size),
+                                       (uint64_t)(count),
+                                       voidp_to_uint64(stream));
+
+       tret = freadp(ptr, size, count, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fread, 'x', tret, tret*size, stream,
+                                      FD_API_READ_END, "pxxp",
+                                      voidp_to_uint64(ptr),
+                                      (uint64_t)(size),
+                                      (uint64_t)(count),
+                                      voidp_to_uint64(stream));
+
+       return tret;
+}
+
+size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream)
+{
+       static size_t (*fwritep)(const void* ptr, size_t size, size_t count, FILE* stream);
+       size_t tret;
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fwrite, 'x', fwrite, LIBC, stream,
+                                       FD_API_WRITE_START, "pxxp",
+                                       voidp_to_uint64(ptr),
+                                       (uint64_t)(size),
+                                       (uint64_t)(count),
+                                       voidp_to_uint64(stream));
+
+       tret = fwritep(ptr, size, count, stream);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fwrite, 'x', tret, tret*size, stream,
+                                      FD_API_WRITE_END, "pxxp",
+                                      voidp_to_uint64(ptr),
+                                      (uint64_t)(size),
+                                      (uint64_t)(count),
+                                      voidp_to_uint64(stream));
+
+       return tret;
+}
+
+// *********************************************************
+// variable parameter function
+// *********************************************************
+int fprintf(FILE* stream, const char* format, ...)
+{
+       static int (*vfprintfp)(FILE* stream, const char* format, ...);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fprintf, 'd', vfprintf, LIBC, stream,
+                                       FD_API_WRITE_START, "ps",
+                                       voidp_to_uint64(stream), format);
+
+       va_list arg;
+       va_start(arg, format);
+
+       ret = vfprintfp(stream, format, arg);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fprintf, 'd', ret, ret, stream,
+                                      FD_API_WRITE_END, "ps",
+                                      voidp_to_uint64(stream), format);
+
+       va_end(arg);
+
+       return ret;
+}
+
+int fscanf(FILE* stream, const char* format, ...)
+{
+       static int (*vfscanfp)(FILE* stream, const char* format, ...);
+
+       BEFORE_ORIGINAL_START_END_FILEP(API_ID_fscanf, 'd', vfscanf, LIBC, stream,
+                                       FD_API_READ_START, "ps",
+                                       voidp_to_uint64(stream), format);
+
+       va_list arg;
+       va_start(arg, format);
+
+       ret = vfscanfp(stream, format, arg);
+
+       AFTER_ORIGINAL_START_END_FILEP(API_ID_fscanf, 'd', ret, ret, stream,
+                                      FD_API_READ_END, "ps",
+                                      voidp_to_uint64(stream), format);
+
+       va_end(arg);
+
+       return ret;
+}
+
+#if !defined(DA_DEBUG_LOG) && !defined(PRINT_STDOUT)
+int printf(const char* format, ...)
+{
+       static int (*vprintfp)(const char* format, ...);
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_printf, 'd', vprintf, LIBC,
+                               FD_API_WRITE_START, "s", format);
+
+       va_list arg;
+       va_start(arg, format);
+       ret = vprintfp(format, arg);
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_printf, 'd', ret, ret,
+                               FD_API_WRITE_END, "s", format);
+
+       va_end(arg);
+
+       return ret;
+}
+#endif
+
+int scanf(const char* format, ...)
+{
+       static int (*vscanfp)(const char* format, ...);
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_scanf, 'd', vscanf, LIBC,
+                               FD_API_READ_START, "s", format);
+
+       va_list arg;
+       va_start(arg, format);
+       ret = vscanfp(format, arg);
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_scanf, 'd', ret, ret,
+                                FD_API_READ_END, "s", format);
+
+       va_end(arg);
+
+       return ret;
+}
+
+int getchar()
+{
+       static int (*getcharp)();
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_getchar, 'd', getchar, LIBC,
+                               FD_API_READ_START, "", 0);
+
+       ret = getcharp();
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_getchar, 'd', ret, (ret == EOF ? 0 : 1),
+                               FD_API_READ_END, "", 0);
+
+       return ret;
+}
+
+int putchar(int c)
+{
+       static int (*putcharp)(int c);
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_putchar, 'd', putchar, LIBC,
+                               FD_API_WRITE_START, "d", c);
+
+       ret = putcharp(c);
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_putchar, 'd', ret, (ret == EOF ? 0 : 1),
+                               FD_API_WRITE_END, "d", c);
+
+       return ret;
+}
+
+char* gets(char* str)
+{
+       static char* (*getsp)(char* str);
+       char* cret;
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_gets, 'p', gets, LIBC,
+                               FD_API_READ_START, "s", str);
+
+       cret = getsp(str);
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_gets, 'p', cret, strlen(cret),
+                               FD_API_READ_END, "s", str);
+
+       return cret;
+}
+
+#if !defined(DA_DEBUG_LOG) && !defined(PRINT_STDOUT)
+int puts(const char* str)
+{
+       static int (*putsp)(const char* str);
+
+       BEFORE_ORIGINAL_START_END_NOFD(API_ID_puts, 'd', puts, LIBC,
+                               FD_API_WRITE_START, "s", str);
+
+       ret = putsp(str);
+
+       AFTER_ORIGINAL_START_END_NOFD(API_ID_puts, 'd', ret, ret,
+                               FD_API_WRITE_END, "s", str);
+
+       return ret;
+}
+#endif
+
+
+
+void setbuf(FILE* stream, char* buf)
+{
+       static void (*setbufp)(FILE* stream, char* buf);
+
+       BEFORE_ORIGINAL_FILE(setbuf, LIBC);
+
+       setbufp(stream, buf);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_setbuf,
+                                 'v', 0, 0, stream, FD_API_OTHER, "pp",
+                                 voidp_to_uint64(stream),
+                                 voidp_to_uint64(buf));
+}
+
+void setbuffer(FILE* stream, char* buf, size_t size)
+{
+       static void (*setbufferp)(FILE* stream, char* buf, size_t size);
+
+       BEFORE_ORIGINAL_FILE(setbuffer, LIBC);
+
+       setbufferp(stream, buf, size);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_setbuffer,
+                                 'v', 0, size, stream, FD_API_OTHER,
+                                 "ppx", voidp_to_uint64(stream),
+                                 voidp_to_uint64(buf), (uint64_t)(size));
+}
+
+void setlinebuf(FILE* stream)
+{
+       static int (*setlinebufp)(FILE* stream);
+
+       BEFORE_ORIGINAL_FILE(setlinebuf, LIBC);
+
+       setlinebufp(stream);
+
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_setlinebuf,
+                                 'v', 0, 0, stream, FD_API_OTHER, "p",
+                                 voidp_to_uint64(stream));
+}
+
+int setvbuf(FILE* stream, char* buf, int mode, size_t size)
+{
+       static int (*setvbufp)(FILE* stream, char* buf, int mode, size_t size);
+
+       BEFORE_ORIGINAL_FILE(setvbuf, LIBC);
+       ret = setvbufp(stream,buf,mode,size);
+       AFTER_PACK_ORIGINAL_FILEP(API_ID_setvbuf,
+                                 'd', ret, size, stream, FD_API_OTHER,
+                                 "ppdx",
+                                 voidp_to_uint64(stream),
+                                 voidp_to_uint64(buf), mode,
+                                 (uint64_t)(size));
+       return ret;
+}
diff --git a/probe_graphics/da_egl_native.cpp b/probe_graphics/da_egl_native.cpp
new file mode 100644 (file)
index 0000000..db2f01f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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
+ *
+ */
+
+//disable tizen redefines
+#define _EGL_MACRO_H_
+
+//define search real function in library
+#define BEFORE_EGL BEFORE_EGL_NATIVE
+
+/*
+ * this include to make native open egl functions
+ * probe prototypes
+ *
+ */
+
+#include "da_egl_tizen.cpp"
+
+#undef _EGL_MACRO_H_
diff --git a/probe_graphics/da_egl_tizen.cpp b/probe_graphics/da_egl_tizen.cpp
new file mode 100644 (file)
index 0000000..368f38b
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <egl_macro.h>
+#include <egl.h>
+#include "da_gles20.h"
+#include "daprobe.h"
+#include "binproto.h"
+#include "common_probe_init.h"
+
+#ifndef BEFORE_EGL
+#define BEFORE_EGL     BEFORE_EGL_TIZEN
+#endif
+
+static enum DaOptions _sopt = OPT_GLES;
+static __thread EGLint egl_error_external = EGL_SUCCESS;
+
+EGLint eglGetError(void)
+{
+       typedef EGLint (*methodType)(void);
+       BEFORE_EGL(eglGetError);
+       EGLint ret = eglGetErrorp();
+
+       if (egl_error_external == EGL_SUCCESS)
+               egl_error_external = ret;
+
+       if (blockresult) {
+               //external call
+               ret = egl_error_external;
+               egl_error_external = EGL_SUCCESS;
+       }
+
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+
+       return ret;
+}
+
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+       typedef EGLDisplay (*methodType)(EGLNativeDisplayType display_id);
+       /* probe prepare */
+       BEFORE_EGL(eglGetDisplay);
+       /* call original function */
+       EGLDisplay ret = eglGetDisplayp(display_id);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(display_id));
+       return ret;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLint *major,
+                                        EGLint *minor);
+       /* probe prepare */
+       BEFORE_EGL(eglInitialize);
+       /* call original function */
+       EGLBoolean ret = eglInitializep(dpy, major, minor);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "", "ppp", voidp_to_uint64(dpy),
+             voidp_to_uint64(major), voidp_to_uint64(minor));
+       return ret;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy);
+       /* probe prepare */
+       BEFORE_EGL(eglTerminate);
+       /* call original function */
+       EGLBoolean ret = eglTerminatep(dpy);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "", "p", voidp_to_uint64(dpy));
+       return ret;
+}
+
+const char *eglQueryString(EGLDisplay dpy, EGLint name)
+{
+       typedef const char *(*methodType)(EGLDisplay dpy, EGLint name);
+       /* probe prepare */
+       BEFORE_EGL(eglQueryString);
+       /* call original function */
+       const char *ret = eglQueryStringp(dpy, name);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('s', ret, APITYPE_CONTEXT, "", "pd", voidp_to_uint64(dpy), name);
+       return ret;
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size,
+                        EGLint *num_config)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLConfig *configs,
+                                        EGLint config_size,
+                                        EGLint *num_config);
+       /* probe prepare */
+       BEFORE_EGL(eglGetConfigs);
+       /* call original function */
+       EGLBoolean ret = eglGetConfigsp(dpy, configs, config_size, num_config);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "", "ppdp",
+             voidp_to_uint64(dpy), voidp_to_uint64(configs), config_size,
+             voidp_to_uint64(num_config));
+       return ret;
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+                          EGLConfig *configs, EGLint config_size,
+                          EGLint *num_config)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy,
+                                        const EGLint *attrib_list,
+                                        EGLConfig *configs, EGLint config_size,
+                                        EGLint *num_config);
+       /* probe prepare */
+       BEFORE_EGL(eglChooseConfig);
+       /* call original function */
+       EGLBoolean ret = eglChooseConfigp(dpy, attrib_list, configs,
+                                         config_size, num_config);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pppdp", voidp_to_uint64(dpy), voidp_to_uint64(attrib_list),
+             voidp_to_uint64(configs), config_size,
+             voidp_to_uint64(num_config));
+       return ret;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+                             EGLint attribute, EGLint *value)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLConfig config,
+                                        EGLint attribute, EGLint *value);
+       /* probe prepare */
+       BEFORE_EGL(eglGetConfigAttrib);
+       /* call original function */
+       EGLBoolean ret = eglGetConfigAttribp(dpy, config, attribute, value);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppdp", voidp_to_uint64(dpy), voidp_to_uint64(config), attribute,
+             voidp_to_uint64(value));
+       return ret;
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+                                 EGLNativeWindowType win,
+                                 const EGLint *attrib_list)
+{
+       typedef EGLSurface (*methodType)(EGLDisplay dpy, EGLConfig config,
+                                        EGLNativeWindowType win,
+                                        const EGLint *attrib_list);
+       /* probe prepare */
+       BEFORE_EGL(eglCreateWindowSurface);
+       /* call original function */
+       EGLSurface ret = eglCreateWindowSurfacep(dpy, config, win, attrib_list);
+
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "pppp", voidp_to_uint64(dpy), voidp_to_uint64(config),
+             voidp_to_uint64(win), voidp_to_uint64(attrib_list));
+       return ret;
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+                                  const EGLint *attrib_list)
+{
+       typedef EGLSurface (*methodType)(EGLDisplay dpy, EGLConfig config,
+                                        const EGLint *attrib_list);
+       /* probe prepare */
+       BEFORE_EGL(eglCreatePbufferSurface);
+       /* call original function */
+       EGLSurface ret = eglCreatePbufferSurfacep(dpy, config, attrib_list);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "ppp", voidp_to_uint64(dpy), voidp_to_uint64(config),
+             voidp_to_uint64(attrib_list));
+       return ret;
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+                                 EGLNativePixmapType pixmap,
+                                 const EGLint *attrib_list)
+{
+       typedef EGLSurface (*methodType)(EGLDisplay dpy, EGLConfig config,
+                                        EGLNativePixmapType pixmap,
+                                        const EGLint *attrib_list);
+       /* probe prepare */
+       BEFORE_EGL(eglCreatePixmapSurface);
+       /* call original function */
+       EGLSurface ret = eglCreatePixmapSurfacep(dpy, config, pixmap,
+                                                attrib_list);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "pppp", voidp_to_uint64(dpy), voidp_to_uint64(config),
+             voidp_to_uint64(pixmap), voidp_to_uint64(attrib_list));
+       return ret;
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface);
+       /* probe prepare */
+       BEFORE_EGL(eglDestroySurface);
+       /* call original function */
+       EGLBoolean ret = eglDestroySurfacep(dpy, surface);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pp", voidp_to_uint64(dpy), voidp_to_uint64(surface));
+       return ret;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
+                          EGLint *value)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface,
+                                        EGLint attribute, EGLint *value);
+       /* probe prepare */
+       BEFORE_EGL(eglQuerySurface);
+       /* call original function */
+       EGLBoolean ret = eglQuerySurfacep(dpy, surface, attribute, value);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppdp", voidp_to_uint64(dpy), voidp_to_uint64(surface),
+             attribute, voidp_to_uint64(value));
+       return ret;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+       typedef EGLBoolean (*methodType)(EGLenum api);
+       /* probe prepare */
+       BEFORE_EGL(eglBindAPI);
+       /* call original function */
+       EGLBoolean ret = eglBindAPIp(api);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "d", api);
+       return ret;
+}
+
+EGLenum eglQueryAPI(void)
+{
+       typedef EGLenum (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglQueryAPI);
+       /* call original function */
+       EGLenum ret = eglQueryAPIp();
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLBoolean eglWaitClient(void)
+{
+       typedef EGLBoolean (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglWaitClient);
+       /* call original function */
+       EGLBoolean ret = eglWaitClientp();
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLBoolean eglReleaseThread(void)
+{
+       typedef EGLBoolean (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglReleaseThread);
+       /* call original function */
+       EGLBoolean ret = eglReleaseThreadp();
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
+                                           EGLClientBuffer buffer,
+                                           EGLConfig config,
+                                           const EGLint *attrib_list)
+{
+       typedef EGLSurface (*methodType)(EGLDisplay dpy, EGLenum buftype,
+                                        EGLClientBuffer buffer,
+                                        EGLConfig config,
+                                        const EGLint *attrib_list);
+       /* probe prepare */
+       BEFORE_EGL(eglCreatePbufferFromClientBuffer);
+       /* call original function */
+       EGLSurface ret = eglCreatePbufferFromClientBufferp(dpy, buftype, buffer,
+                                                          config, attrib_list);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "pdppp", voidp_to_uint64(dpy), buftype, voidp_to_uint64(buffer),
+             voidp_to_uint64(config), voidp_to_uint64(attrib_list));
+       return ret;
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+                           EGLint attribute, EGLint value)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface,
+                                        EGLint attribute, EGLint value);
+       /* probe prepare */
+       BEFORE_EGL(eglSurfaceAttrib);
+       /* call original function */
+       EGLBoolean ret = eglSurfaceAttribp(dpy, surface, attribute, value);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppdd", voidp_to_uint64(dpy), voidp_to_uint64(surface), attribute,
+             value);
+       return ret;
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface,
+                                        EGLint buffer);
+       /* probe prepare */
+       BEFORE_EGL(eglBindTexImage);
+       /* call original function */
+       EGLBoolean ret = eglBindTexImagep(dpy, surface, buffer);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppd", voidp_to_uint64(dpy), voidp_to_uint64(surface), buffer);
+       return ret;
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface,
+                                        EGLint buffer);
+       /* probe prepare */
+       BEFORE_EGL(eglReleaseTexImage);
+       /* call original function */
+       EGLBoolean ret = eglReleaseTexImagep(dpy, surface, buffer);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppd", voidp_to_uint64(dpy), voidp_to_uint64(surface), buffer);
+       return ret;
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLint interval);
+       /* probe prepare */
+       BEFORE_EGL(eglSwapInterval);
+       /* call original function */
+       EGLBoolean ret = eglSwapIntervalp(dpy, interval);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pd", voidp_to_uint64(dpy), interval);
+       return ret;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+                           EGLContext share_context, const EGLint *attrib_list)
+{
+       typedef EGLContext (*methodType)(EGLDisplay dpy, EGLConfig config,
+                                        EGLContext share_context,
+                                        const EGLint *attrib_list);
+       /* probe prepare */
+       BEFORE_EGL(eglCreateContext);
+       /* call original function */
+       EGLContext ret = eglCreateContextp(dpy, config, share_context,
+                                          attrib_list);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "pppp", voidp_to_uint64(dpy), voidp_to_uint64(config),
+             voidp_to_uint64(share_context), voidp_to_uint64(attrib_list));
+       return ret;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLContext ctx);
+       /* probe prepare */
+       BEFORE_EGL(eglDestroyContext);
+       /* call original function */
+       EGLBoolean ret = eglDestroyContextp(dpy, ctx);
+       /* get error code */
+       EGL_GET_ERROR()
+
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pp", voidp_to_uint64(dpy), voidp_to_uint64(ctx));
+       return ret;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
+                         EGLContext ctx)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface draw,
+                                        EGLSurface read, EGLContext ctx);
+       /* probe prepare */
+       BEFORE_EGL(eglMakeCurrent);
+       /* call original function */
+       EGLBoolean ret = eglMakeCurrentp(dpy, draw, read, ctx);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pppp", voidp_to_uint64(dpy), voidp_to_uint64(draw),
+             voidp_to_uint64(read), voidp_to_uint64(ctx));
+       return ret;
+}
+
+EGLContext eglGetCurrentContext(void)
+{
+       typedef EGLContext (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglGetCurrentContext);
+       /* call original function */
+       EGLContext ret = eglGetCurrentContextp();
+
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+       typedef EGLSurface (*methodType)(EGLint readdraw);
+       /* probe prepare */
+       BEFORE_EGL(eglGetCurrentSurface);
+       /* call original function */
+       EGLSurface ret = eglGetCurrentSurfacep(readdraw);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "",
+             "d", readdraw);
+       return ret;
+}
+
+EGLDisplay eglGetCurrentDisplay(void)
+{
+       typedef EGLDisplay (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglGetCurrentDisplay);
+       /* call original function */
+       EGLDisplay ret = eglGetCurrentDisplayp();
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('p', voidp_to_uint64(ret), APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute,
+                          EGLint *value)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLContext ctx,
+                                        EGLint attribute, EGLint *value);
+       /* probe prepare */
+       BEFORE_EGL(eglQueryContext);
+       /* call original function */
+       EGLBoolean ret = eglQueryContextp(dpy, ctx, attribute, value);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppdp", voidp_to_uint64(dpy), voidp_to_uint64(ctx),
+             attribute, voidp_to_uint64(value));
+       return ret;
+}
+
+EGLBoolean eglWaitGL(void)
+{
+       typedef EGLBoolean (*methodType)(void);
+       /* probe prepare */
+       BEFORE_EGL(eglWaitGL);
+       /* call original function */
+       EGLBoolean ret = eglWaitGLp();
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+       return ret;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+       typedef EGLBoolean (*methodType)(EGLint engine);
+       /* probe prepare */
+       BEFORE_EGL(eglWaitNative);
+       /* call original function */
+       EGLBoolean ret = eglWaitNativep(engine);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "d", engine);
+       return ret;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface);
+       BEFORE_EGL(eglSwapBuffers);
+       EGLBoolean ret = eglSwapBuffersp(dpy, surface);
+       EGL_GET_ERROR();
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "pp", voidp_to_uint64(dpy), voidp_to_uint64(surface));
+       return ret;
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
+                         EGLNativePixmapType target)
+{
+       typedef EGLBoolean (*methodType)(EGLDisplay dpy, EGLSurface surface,
+                                        EGLNativePixmapType target);
+       /* probe prepare */
+       BEFORE_EGL(eglCopyBuffers);
+       /* call original function */
+       EGLBoolean ret = eglCopyBuffersp(dpy, surface, target);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('d', ret, APITYPE_CONTEXT, "",
+             "ppp", voidp_to_uint64(dpy), voidp_to_uint64(surface),
+             voidp_to_uint64(target));
+       return ret;
+}
+
+#define __eglGetProcAddress_t __eglMustCastToProperFunctionPointerType
+EGLAPI __eglGetProcAddress_t eglGetProcAddress(const char *procname)
+{
+       typedef EGLAPI __eglGetProcAddress_t(*methodType)(const char *procname);
+       /* probe prepare */
+       BEFORE_EGL(eglGetProcAddress);
+       /* call original function */
+       __eglGetProcAddress_t ret = eglGetProcAddressp(procname);
+       /* get error code */
+       EGL_GET_ERROR();
+       /* pack and send */
+       AFTER('p', voidp_to_uint64((void *)ret), APITYPE_CONTEXT, "",
+             "s", procname);
+       return ret;
+}
+
diff --git a/probe_graphics/da_evas_gl.c b/probe_graphics/da_evas_gl.c
new file mode 100644 (file)
index 0000000..b1facc0
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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 "da_gles20.h"
+#include "daprobe.h"
+#include "binproto.h"
+#include "common_probe_init.h"
+#include "real_functions.h"
+
+static enum DaOptions _sopt = OPT_GLES;
+
+/* Evas open gl API functions */
+
+void evas_gl_free(Evas_GL *evas_gl)
+{
+       typedef void (*methodType)(Evas_GL *evas_gl);
+       BEFORE_EVAS_GL(evas_gl_free);
+       evas_gl_freep(evas_gl);
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(evas_gl));
+}
+
+void evas_gl_config_free(Evas_GL_Config *cfg)
+{
+       typedef void (*methodType)(Evas_GL_Config *cfg);
+       BEFORE_EVAS_GL(evas_gl_config_free);
+       evas_gl_config_freep(cfg);
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(cfg));
+}
+
+void evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
+{
+       typedef void (*methodType)(Evas_GL *evas_gl, Evas_GL_Surface *surf);
+       BEFORE_EVAS_GL(evas_gl_surface_destroy);
+       evas_gl_surface_destroyp(evas_gl, surf);
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "pp",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(surf));
+}
+
+void evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx)
+{
+       typedef void (*methodType)(Evas_GL *evas_gl, Evas_GL_Context *ctx);
+       BEFORE_EVAS_GL(evas_gl_context_destroy);
+       evas_gl_context_destroyp(evas_gl, ctx);
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "pp",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(ctx));
+}
+
+Evas_GL *evas_gl_new(Evas *e)
+{
+       typedef Evas_GL *(*methodType)(Evas *e);
+       BEFORE_EVAS_GL(evas_gl_new);
+       Evas_GL *res = evas_gl_newp(e);
+       AFTER('p', voidp_to_uint64(res), APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(e));
+       return res;
+}
+
+Evas_GL_Config *evas_gl_config_new(void)
+{
+       typedef Evas_GL_Config *(*methodType)(void);
+       BEFORE_EVAS_GL(evas_gl_config_new);
+       Evas_GL_Config *res = evas_gl_config_newp();
+       AFTER_NO_PARAM('p', voidp_to_uint64(res), APITYPE_CONTEXT, "");
+       return res;
+}
+
+Evas_GL_Surface *evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *cfg,
+                                       int w, int h)
+{
+       typedef Evas_GL_Surface *(*methodType)(Evas_GL *evas_gl,
+                                              Evas_GL_Config *cfg,
+                                              int w, int h);
+       BEFORE_EVAS_GL(evas_gl_surface_create);
+       Evas_GL_Surface *res = evas_gl_surface_createp(evas_gl, cfg, w, h);
+       AFTER('p', voidp_to_uint64(res), APITYPE_CONTEXT, "", "ppdd",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(cfg), w, h);
+       return res;
+}
+
+Evas_GL_Context *evas_gl_context_create(Evas_GL *evas_gl,
+                                       Evas_GL_Context *share_ctx)
+{
+       typedef Evas_GL_Context *(*methodType)(Evas_GL *evas_gl,
+                                              Evas_GL_Context *share_ctx);
+       BEFORE_EVAS_GL(evas_gl_context_create);
+       Evas_GL_Context *res = evas_gl_context_createp(evas_gl, share_ctx);
+       AFTER('p', voidp_to_uint64(res), APITYPE_CONTEXT, "", "pp",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(share_ctx));
+       return res;
+}
+
+Eina_Bool evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf,
+                              Evas_GL_Context *ctx)
+{
+       typedef Eina_Bool (*methodType)(Evas_GL *evas_gl, Evas_GL_Surface *surf,
+                                       Evas_GL_Context *ctx);
+       BEFORE_EVAS_GL(evas_gl_make_current);
+       Eina_Bool res = evas_gl_make_currentp(evas_gl, surf, ctx);
+       AFTER('b', res, APITYPE_CONTEXT, "", "ppp",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(surf), voidp_to_uint64(ctx));
+       return res;
+}
+
+const char *evas_gl_string_query(Evas_GL *evas_gl, int name)
+{
+       typedef const char *(*methodType)(Evas_GL *evas_gl, int name);
+       BEFORE_EVAS_GL(evas_gl_string_query);
+       const char *res = evas_gl_string_queryp(evas_gl, name);
+       AFTER('s', res, APITYPE_CONTEXT, "", "pd",
+             voidp_to_uint64(evas_gl), name);
+       return res;
+}
+
+Evas_GL_Func evas_gl_proc_address_get(Evas_GL *evas_gl, const char *name)
+{
+       typedef Evas_GL_Func(*methodType)(Evas_GL *evas_gl, const char *name);
+       BEFORE_EVAS_GL(evas_gl_proc_address_get);
+       Evas_GL_Func res = evas_gl_proc_address_getp(evas_gl, name);
+       AFTER('p', voidp_to_uint64(res), APITYPE_CONTEXT, "", "ps",
+             voidp_to_uint64(evas_gl), name);
+       return res;
+}
+
+Eina_Bool evas_gl_native_surface_get(Evas_GL *evas_gl, Evas_GL_Surface *surf,
+                                    Evas_Native_Surface *ns)
+{
+       typedef Eina_Bool(*methodType)(Evas_GL *evas_gl, Evas_GL_Surface *surf,
+                                  Evas_Native_Surface *ns);
+       BEFORE_EVAS_GL(evas_gl_native_surface_get);
+       Eina_Bool res = evas_gl_native_surface_getp(evas_gl, surf, ns);
+       AFTER('b', res, APITYPE_CONTEXT, "", "ppp",
+             voidp_to_uint64(evas_gl), voidp_to_uint64(surf), voidp_to_uint64(ns));
+       return res;
+}
+
+/* ----------------- api get functions -------------- */
+
+Evas_GL_API *evas_gl_api_get(Evas_GL *evas_gl)
+{
+       typedef Evas_GL_API *(*methodType)(Evas_GL *evas_gl);
+       BEFORE_EVAS_GL(evas_gl_api_get);
+       Evas_GL_API *res = evas_gl_api_getp(evas_gl);
+
+       /* save original api functions and rewrite it by probes */
+       if (res != NULL) {
+               save_orig_gl_api_list(res);
+               change_gl_api_list(res);
+       }
+
+       AFTER('p', res, APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(evas_gl));
+
+       return res;
+}
+
+Evas_GL_API* elm_glview_gl_api_get(const Evas_Object *obj)
+{
+       typedef Evas_GL_API *(*methodType)(const Evas_Object *obj);
+       BEFORE_EVAS_GL(elm_glview_gl_api_get);
+       Evas_GL_API *res = elm_glview_gl_api_getp(obj);
+
+       /* save original api functions and rewrite it by probes */
+       if (res != NULL) {
+               save_orig_gl_api_list(res);
+               change_gl_api_list(res);
+       }
+
+       /*clean error code*/
+       __gl_api->glGetError();
+
+       AFTER('p', res, APITYPE_CONTEXT, "", "p",
+             voidp_to_uint64(obj));
+
+       return res;
+}
+
+Evas_GL_API *evas_gl_context_api_get(Evas_GL *evas_gl, Evas_GL_Context *ctx)
+{
+       typedef Evas_GL_API *(*methodType)(Evas_GL *evas_gl, Evas_GL_Context *ctx);
+       static methodType evas_gl_context_api_getp = 0;
+
+       GET_REAL_FUNC_RTLD_NEXT(evas_gl_context_api_get);
+
+       Evas_GL_API *res = evas_gl_context_api_getp(evas_gl, ctx);
+
+       /* save original api functions and rewrite it by probes */
+       if (res != NULL) {
+               save_orig_gl_api_list(res);
+               change_gl_api_list(res);
+       }
+
+       return res;
+}
diff --git a/probe_graphics/da_gl_api_init.c b/probe_graphics/da_gl_api_init.c
new file mode 100644 (file)
index 0000000..1edfee8
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <unistd.h>
+#include "da_gles20.h"
+#include "binproto.h"
+#include "common_probe_init.h"
+#include "real_functions.h"
+
+/* GL __local_* functions prototypes */
+#define X(func) extern void __local_##func(void);
+#include "da_gl_api_func_list.h"
+       GL_ALL_FUNCTIONS;
+#undef X
+/* --------------------------------- */
+
+
+static bool __gl_api_initialized = 0;
+Evas_GL_API *__gl_api = NULL;
+
+void __init_gl_api__(void)
+{
+       if (__gl_api == NULL)
+               __gl_api = real_malloc(sizeof(*__gl_api));
+       memset(__gl_api, 0, sizeof(*__gl_api));
+}
+
+void save_orig_gl_api_list(Evas_GL_API *api)
+{
+       /* TODO make this check more pretty */
+       if (__gl_api_initialized == 0) {
+               memcpy(__gl_api, api, sizeof(*api));
+               __gl_api_initialized = 1;
+       }
+}
+
+/* IMPORTANT this code must be right before change_gl_api_list function!
+ *
+ * next define is GL api replacing by probe functions
+ *
+ */
+#define X(func) \
+       do {                                                    \
+               api->func = (typeof(api->func)) __local_##func; \
+               if (api->func == NULL)                          \
+                       PRINTWRN("api->%s not setted", #func);  \
+       } while(0);
+#include "da_gl_api_func_list.h"
+/* --------------------------------------------------------------------- */
+
+void change_gl_api_list(Evas_GL_API *api)
+{
+       /* change links */
+       GL_ALL_FUNCTIONS;
+}
+
+#undef X
diff --git a/probe_graphics/da_gles20_native.cpp b/probe_graphics/da_gles20_native.cpp
new file mode 100644 (file)
index 0000000..ed84d10
--- /dev/null
@@ -0,0 +1,1892 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Sanghyun Lee <sanghyunnim.lee@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Vitaliy Cherepanov <v.cherepanov@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include "da_gles20.h"
+#include "daprobe.h"
+#include "binproto.h"
+#include "real_functions.h"
+#include "common_probe_init.h"
+
+#ifndef REAL_NAME
+       #define REAL_NAME(func) func
+#endif
+
+#ifndef CALL_ORIG
+       #define CALL_ORIG(func, ...) func##p(__VA_ARGS__)
+#endif
+
+#ifndef BEFORE
+       #define BEFORE BEFORE_GL_ORIG
+#endif
+
+#ifndef TYPEDEF
+       #define TYPEDEF(type) typedef type
+#endif
+
+static char contextValue[MAX_GL_CONTEXT_VALUE_SIZE]; /* maybe it should not be gobal static variable */
+static enum DaOptions _sopt = OPT_GLES;
+static __thread GLenum gl_error_external = GL_NO_ERROR;
+
+static void __ui_array_to_str(char *to, GLuint *arr ,int count, size_t bufsize)
+{
+       int i = 0, len = 0;
+
+       for (i = 0; i < count; i++) {
+               if (bufsize < sizeof(GLuint) * 4) {
+                       PRINTERR("too small buffer.");
+                       break;
+               }
+
+               len = snprintf(to, bufsize,"%u, ", *arr++);
+
+               to += len;
+               bufsize -= len;
+       }
+
+       if (count != 0) {
+               to -= 2;
+               *to = '\0';
+       }
+}
+
+GLenum REAL_NAME(glGetError)(void)
+{
+       TYPEDEF(GLenum (*methodType)(void));
+       BEFORE(glGetError);
+       GLenum ret = CALL_ORIG(glGetError,);
+
+       if (gl_error_external == GL_NO_ERROR)
+               gl_error_external = ret;
+
+       if (blockresult) {
+               //external call
+               ret = gl_error_external;
+               gl_error_external = GL_NO_ERROR;
+       }
+
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+
+       return ret;
+}
+
+// ==================================================================
+// A 2
+// ==================================================================
+
+void REAL_NAME(glActiveTexture)(GLenum texture)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glActiveTexture);
+       CALL_ORIG(glActiveTexture, texture);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(texture));
+}
+
+void REAL_NAME(glAttachShader)(GLuint program, GLuint shader)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint));
+       BEFORE(glAttachShader);
+       CALL_ORIG(glAttachShader, program, shader);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd", program, shader);
+}
+
+// ==================================================================
+// B 12
+// ==================================================================
+void __get_context_buf_data(GLenum target, char *buf, int buf_size)
+{
+       GLint n_buffer_size, n_buffer_usage_size;
+       int print_size;
+
+       if (buf == NULL)
+               return;
+
+       real_glGetBufferParameteriv(target, GL_BUFFER_SIZE,
+                                   &n_buffer_size);
+       real_glGetBufferParameteriv(target, GL_BUFFER_USAGE,
+                                   &n_buffer_usage_size);
+
+       print_size = snprintf(buf, buf_size, "%u,%u,%u",
+                             target, n_buffer_size, n_buffer_usage_size);
+
+       if (print_size >= buf_size) {
+               /* data was truncated. so data is invalid */
+               buf[0]='\0';
+       }
+
+}
+
+void REAL_NAME(glBindAttribLocation)(GLuint program, GLuint index, const char *name)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint, const char *));
+       BEFORE(glBindAttribLocation);
+       CALL_ORIG(glBindAttribLocation, program, index, name);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dds",
+             program, index, name);
+}
+
+void REAL_NAME(glBindBuffer)(GLenum target, GLuint buffer)
+{
+       char context_value[MAX_GL_CONTEXT_VALUE_SIZE] = {0,};
+
+       TYPEDEF(void (*methodType)(GLenum, GLuint));
+       BEFORE(glBindBuffer);
+       CALL_ORIG(glBindBuffer, target, buffer);
+
+       if (blockresult && buffer)
+               __get_context_buf_data(target, &context_value[0],
+                                      sizeof(context_value));
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, context_value, "xd",
+             (uint64_t)(target), buffer);
+}
+
+void REAL_NAME(glBindFramebuffer)(GLenum target, GLuint framebuffer)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLuint));
+       BEFORE(glBindFramebuffer);
+       CALL_ORIG(glBindFramebuffer, target, framebuffer);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xd",
+             (uint64_t)(target), framebuffer);
+}
+
+void REAL_NAME(glBindRenderbuffer)(GLenum target, GLuint renderbuffer)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLuint));
+       BEFORE(glBindRenderbuffer);
+       CALL_ORIG(glBindRenderbuffer, target, renderbuffer);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xd",
+             (uint64_t)(target), renderbuffer);
+}
+
+void REAL_NAME(glBindTexture)(GLenum target, GLuint texture)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLuint));
+       BEFORE(glBindTexture);
+       CALL_ORIG(glBindTexture, target, texture);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xd",
+             (uint64_t)(target), texture);
+}
+
+void REAL_NAME(glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+       TYPEDEF(void (*methodType)(GLclampf, GLclampf, GLclampf, GLclampf));
+       BEFORE(glBlendColor);
+       CALL_ORIG(glBlendColor, red, green, blue, alpha);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ffff",
+             red, green, blue, alpha);
+}
+
+void REAL_NAME(glBlendEquation)(GLenum mode)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glBlendEquation);
+       CALL_ORIG(glBlendEquation, mode);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(mode));
+}
+
+void REAL_NAME(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum));
+       BEFORE(glBlendEquationSeparate);
+       CALL_ORIG(glBlendEquationSeparate, modeRGB, modeAlpha);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(modeRGB), (uint64_t)(modeAlpha));
+}
+
+void REAL_NAME(glBlendFunc)(GLenum sfactor, GLenum dfactor)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum));
+       BEFORE(glBlendFunc);
+       CALL_ORIG(glBlendFunc, sfactor, dfactor);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(sfactor), (uint64_t)(dfactor));
+}
+
+void REAL_NAME(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
+                        GLenum dstAlpha)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum, GLenum));
+       BEFORE(glBlendFuncSeparate);
+       CALL_ORIG(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxxx",
+             (uint64_t)(srcRGB), (uint64_t)(dstRGB),
+             (uint64_t)(srcAlpha), (uint64_t)(dstAlpha));
+}
+
+void REAL_NAME(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid * data,
+                 GLenum usage)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLsizeiptr, const GLvoid *, GLenum));
+       BEFORE(glBufferData);
+       CALL_ORIG(glBufferData, target, size, data, usage);
+
+       char context_value[MAX_GL_CONTEXT_VALUE_SIZE];
+       if (blockresult)
+               __get_context_buf_data(target, &context_value[0],
+                                      sizeof(context_value));
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, context_value, "xxpx",
+             (uint64_t)(target), (uint64_t)(size),
+             voidp_to_uint64(data), (uint64_t)(usage));
+}
+
+void REAL_NAME(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size,
+                    const GLvoid * data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLintptr, GLsizeiptr,
+                                  const GLvoid *));
+       BEFORE(glBufferSubData);
+
+       char context_value[MAX_GL_CONTEXT_VALUE_SIZE];
+       if (blockresult)
+               __get_context_buf_data(target, &context_value[0],
+                                      sizeof(context_value));
+       CALL_ORIG(glBufferSubData, target, offset, size, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, context_value, "xxxp",
+             (uint64_t)(target), (uint64_t)(offset),
+             (uint64_t)(size), voidp_to_uint64(data));
+}
+
+// ==================================================================
+// C 14
+// ==================================================================
+
+GLenum REAL_NAME(glCheckFramebufferStatus)(GLenum target)
+{
+       TYPEDEF(GLenum (*methodType)(GLenum));
+       BEFORE(glCheckFramebufferStatus);
+       GLenum ret = CALL_ORIG(glCheckFramebufferStatus, target);
+       GL_GET_ERROR();
+       AFTER('d', ret, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(target));
+
+       return ret;
+}
+
+void REAL_NAME(glClear)(GLbitfield mask)
+{
+       TYPEDEF(void (*methodType)(GLbitfield));
+       BEFORE(glClear);
+       CALL_ORIG(glClear, mask);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(mask));
+}
+
+void REAL_NAME(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+       TYPEDEF(void (*methodType)(GLclampf, GLclampf, GLclampf, GLclampf));
+       BEFORE(glClearColor);
+       CALL_ORIG(glClearColor, red, green, blue, alpha);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ffff",
+             red, green, blue, alpha);
+}
+
+void REAL_NAME(glClearDepthf)(GLclampf depth)
+{
+       TYPEDEF(void (*methodType)(GLclampf));
+       BEFORE(glClearDepthf);
+       CALL_ORIG(glClearDepthf, depth);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "f", depth);
+}
+
+void REAL_NAME(glClearStencil)(GLint s)
+{
+       TYPEDEF(void (*methodType)(GLint));
+       BEFORE(glClearStencil);
+       CALL_ORIG(glClearStencil, s);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", s);
+}
+
+void REAL_NAME(glColorMask)(GLboolean red, GLboolean green, GLboolean blue,
+                GLboolean alpha)
+{
+       TYPEDEF(void (*methodType)(GLboolean, GLboolean, GLboolean, GLboolean));
+       BEFORE(glColorMask);
+       CALL_ORIG(glColorMask, red, green, blue, alpha);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dddd",
+             red, green, blue, alpha);
+}
+
+void REAL_NAME(glCompileShader)(GLuint shader)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glCompileShader);
+       CALL_ORIG(glCompileShader, shader);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(shader));
+}
+
+void REAL_NAME(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat,
+                           GLsizei width, GLsizei height, GLint border,
+                           GLsizei imageSize, const GLvoid * data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLenum, GLsizei, GLsizei,
+                                  GLint, GLsizei, const GLvoid *));
+       BEFORE(glCompressedTexImage2D);
+       CALL_ORIG(glCompressedTexImage2D, target, level, internalformat, width,
+                 height, border, imageSize, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdxddddp",
+             (uint64_t)(target), level,
+             (uint64_t)(internalformat), width, height, border, imageSize,
+             voidp_to_uint64(data));
+}
+
+void REAL_NAME(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset,
+                              GLint yoffset, GLsizei width, GLsizei height,
+                              GLenum format, GLsizei imageSize,
+                              const GLvoid * data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLint, GLint, GLsizei,
+                                  GLsizei, GLenum, GLsizei, const GLvoid *));
+       BEFORE(glCompressedTexSubImage2D);
+       CALL_ORIG(glCompressedTexSubImage2D, target, level, xoffset, yoffset,
+                 width, height, format, imageSize, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdddddxdp",
+             (uint64_t)(target), level, xoffset, yoffset, width, height,
+             (uint64_t)(format), imageSize, voidp_to_uint64(data));
+}
+
+void REAL_NAME(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat,
+                     GLint x, GLint y, GLsizei width, GLsizei height,
+                     GLint border)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLenum, GLint, GLint,
+                                  GLsizei, GLsizei, GLint));
+       BEFORE(glCopyTexImage2D);
+       CALL_ORIG(glCopyTexImage2D, target, level, internalformat, x, y, width,
+                 height, border);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdxddddd",
+             (uint64_t)(target), level,
+             (uint64_t)(internalformat), x, y, width, height, border);
+}
+
+void REAL_NAME(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset,
+                        GLint yoffset, GLint x, GLint y, GLsizei width,
+                        GLsizei height)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLint, GLint, GLint, GLint,
+                                  GLsizei, GLsizei));
+       BEFORE(glCopyTexSubImage2D);
+       CALL_ORIG(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
+                 width, height);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xddddddd",
+             (uint64_t)(target), level, xoffset, yoffset, x, y, width,
+             height);
+}
+
+GLuint REAL_NAME(glCreateProgram)(void)
+{
+       TYPEDEF(GLuint (*methodType)(void));
+       BEFORE(glCreateProgram);
+       GLuint ret = CALL_ORIG(glCreateProgram,);
+       GL_GET_ERROR();
+       AFTER_NO_PARAM('d', ret, APITYPE_CONTEXT, "");
+
+       return ret;
+}
+
+GLuint REAL_NAME(glCreateShader)(GLenum shaderType)
+{
+       TYPEDEF(GLuint (*methodType)(GLenum));
+       BEFORE(glCreateShader);
+       GLuint ret = CALL_ORIG(glCreateShader, shaderType);
+       GL_GET_ERROR();
+       AFTER('d', ret, APITYPE_CONTEXT, "", "x", (uint64_t)(shaderType));
+
+       return ret;
+}
+
+void REAL_NAME(glCullFace)(GLenum mode)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glCullFace);
+       CALL_ORIG(glCullFace, mode);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(mode));
+}
+
+// ==================================================================
+// D 14
+// ==================================================================
+
+void REAL_NAME(glDeleteBuffers)(GLsizei n, const GLuint * buffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, const GLuint *));
+       BEFORE(glDeleteBuffers);
+
+       char context_value[MAX_GL_CONTEXT_VALUE_SIZE];
+       CALL_ORIG(glDeleteBuffers, n, buffers);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, context_value, "dp",
+             n, voidp_to_uint64(buffers));
+}
+
+void REAL_NAME(glDeleteFramebuffers)(GLsizei n, const GLuint * framebuffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, const GLuint *));
+       BEFORE(glDeleteFramebuffers);
+       CALL_ORIG(glDeleteFramebuffers, n, framebuffers);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dp",
+             n, voidp_to_uint64(framebuffers));
+}
+
+void REAL_NAME(glDeleteProgram)(GLuint program)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glDeleteProgram);
+       CALL_ORIG(glDeleteProgram, program);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", program);
+}
+
+void REAL_NAME(glDeleteRenderbuffers)(GLsizei n, const GLuint * renderbuffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, const GLuint *));
+       BEFORE(glDeleteRenderbuffers);
+       CALL_ORIG(glDeleteRenderbuffers, n, renderbuffers);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dp",
+             n, voidp_to_uint64(renderbuffers));
+}
+
+void REAL_NAME(glDeleteShader)(GLuint shader)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glDeleteShader);
+       CALL_ORIG(glDeleteShader, shader);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", shader);
+}
+
+void REAL_NAME(glDeleteTextures)(GLsizei n, const GLuint *textures)
+{
+       TYPEDEF(void (*methodType)(GLsizei, const GLuint *));
+       char buf[128] = "";
+
+       BEFORE(glDeleteTextures);
+       CALL_ORIG(glDeleteTextures, n, textures);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR)
+               __ui_array_to_str(buf, (GLuint *)textures, n, sizeof(buf));
+
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, buf, "dp",
+             n, voidp_to_uint64(textures));
+}
+
+void REAL_NAME(glDepthFunc)(GLenum func)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glDepthFunc);
+       CALL_ORIG(glDepthFunc, func);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(func));
+}
+
+void REAL_NAME(glDepthMask)(GLboolean flag)
+{
+       TYPEDEF(void (*methodType)(GLboolean));
+       BEFORE(glDepthMask);
+       CALL_ORIG(glDepthMask, flag);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(flag));
+}
+
+void REAL_NAME(glDepthRangef)(GLclampf nearVal, GLclampf farVal)
+{
+       TYPEDEF(void (*methodType)(GLclampf, GLclampf));
+       BEFORE(glDepthRangef);
+       CALL_ORIG(glDepthRangef, nearVal, farVal);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ff",
+             nearVal, farVal);
+}
+
+void REAL_NAME(glDetachShader)(GLuint program, GLuint shader)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint));
+       BEFORE(glDetachShader);
+       CALL_ORIG(glDetachShader, program, shader);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             program, shader);
+}
+
+void REAL_NAME(glDisable)(GLenum cap)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glDisable);
+       CALL_ORIG(glDisable, cap);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x", (uint64_t)(cap));
+}
+
+void REAL_NAME(glDisableVertexAttribArray)(GLuint index)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glDisableVertexAttribArray);
+       CALL_ORIG(glDisableVertexAttribArray, index);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", index);
+}
+
+void REAL_NAME(glDrawArrays)(GLenum mode, GLint first, GLsizei count)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLsizei));
+       BEFORE(glDrawArrays);
+       CALL_ORIG(glDrawArrays, mode, first, count);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdd",
+             (uint64_t)(mode), first, count);
+}
+
+void REAL_NAME(glDrawElements)(GLenum mode, GLsizei count, GLenum type,
+               const GLvoid *indices)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLsizei, GLenum, const GLvoid *));
+       BEFORE(glDrawElements);
+       CALL_ORIG(glDrawElements, mode, count, type, indices);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdxp",
+             (uint64_t)(mode), count, (uint64_t)(type), indices);
+}
+
+// ==================================================================
+// E 2
+// ==================================================================
+
+void REAL_NAME(glEnable)(GLenum cap)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glEnable);
+       CALL_ORIG(glEnable, cap);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x", (uint64_t)(cap));
+}
+
+void REAL_NAME(glEnableVertexAttribArray)(GLuint index)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glEnableVertexAttribArray);
+       CALL_ORIG(glEnableVertexAttribArray, index);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", index);
+}
+
+// ==================================================================
+// F 5
+// ==================================================================
+
+void REAL_NAME(glFinish)(void)
+{
+       TYPEDEF(void (*methodType)(void));
+       BEFORE(glFinish);
+       CALL_ORIG(glFinish,);
+       GL_GET_ERROR();
+       AFTER_NO_PARAM('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "");
+}
+
+void REAL_NAME(glFlush)(void)
+{
+       TYPEDEF(void (*methodType)(void));
+       BEFORE(glFlush);
+       CALL_ORIG(glFlush,);
+       GL_GET_ERROR();
+       AFTER_NO_PARAM('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "");
+}
+
+void REAL_NAME(glFramebufferRenderbuffer)(GLenum target, GLenum attachment,
+                              GLenum renderbuffertarget, GLuint renderbuffer)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum, GLuint));
+       BEFORE(glFramebufferRenderbuffer);
+       CALL_ORIG(glFramebufferRenderbuffer, target, attachment,
+                 renderbuffertarget, renderbuffer);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxxd",
+             (uint64_t)(target), (uint64_t)(attachment),
+             (uint64_t)(renderbuffertarget), renderbuffer);
+}
+
+void REAL_NAME(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget,
+                           GLuint texture, GLint level)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum, GLuint, GLint));
+       BEFORE(glFramebufferTexture2D);
+       CALL_ORIG(glFramebufferTexture2D, target, attachment, textarget,
+                 texture, level);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxxdd",
+             (uint64_t)(target), (uint64_t)(attachment),
+             (uint64_t)(textarget), texture, level);
+}
+
+void REAL_NAME(glFrontFace)(GLenum mode)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glFrontFace);
+       CALL_ORIG(glFrontFace, mode);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(mode));
+}
+
+// ==================================================================
+// G 31
+// ==================================================================
+
+void REAL_NAME(glGenBuffers)(GLsizei n, GLuint * buffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, GLuint *));
+       char buf[128] = "";
+
+       BEFORE(glGenBuffers);
+       CALL_ORIG(glGenBuffers, n, buffers);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR)
+               __ui_array_to_str(buf, buffers, n, sizeof(buf));
+
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, buf, "dp",
+             n, voidp_to_uint64(buffers));
+}
+
+void REAL_NAME(glGenFramebuffers)(GLsizei n, GLuint * framebuffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, GLuint *));
+       BEFORE(glGenFramebuffers);
+       CALL_ORIG(glGenFramebuffers, n, framebuffers);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dp",
+             n, voidp_to_uint64(framebuffers));
+}
+
+void REAL_NAME(glGenRenderbuffers)(GLsizei n, GLuint * renderbuffers)
+{
+       TYPEDEF(void (*methodType)(GLsizei, GLuint *));
+       BEFORE(glGenRenderbuffers);
+       CALL_ORIG(glGenRenderbuffers, n, renderbuffers);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dp",
+             n, voidp_to_uint64(renderbuffers));
+}
+
+void REAL_NAME(glGenTextures)(GLsizei n, GLuint * textures)
+{
+       TYPEDEF(void (*methodType)(GLsizei, GLuint *));
+       char buf[128] = "";
+
+       BEFORE(glGenTextures);
+       CALL_ORIG(glGenTextures, n, textures);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR)
+               __ui_array_to_str(buf, textures, n, sizeof(buf));
+
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, buf, "dp",
+             n, voidp_to_uint64(textures));
+}
+
+void REAL_NAME(glGenerateMipmap)(GLenum target)
+{
+       TYPEDEF(void (*methodType)(GLenum));
+       BEFORE(glGenerateMipmap);
+       CALL_ORIG(glGenerateMipmap, target);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(target));
+}
+
+//lsh_get
+void REAL_NAME(glGetBooleanv)(GLenum pname, GLboolean * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLboolean *));
+       BEFORE(glGetBooleanv);
+       CALL_ORIG(glGetBooleanv, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetFloatv)(GLenum pname, GLfloat * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLfloat *));
+       BEFORE(glGetFloatv);
+       CALL_ORIG(glGetFloatv, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetIntegerv)(GLenum pname, GLint * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint *));
+       BEFORE(glGetIntegerv);
+       CALL_ORIG(glGetIntegerv, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "x",
+             (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize,
+                      GLsizei *length, GLint *size, GLenum *type, char *name)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint, GLsizei, GLsizei *, GLint *,
+                                  GLenum *, char *));
+       BEFORE(glGetActiveAttrib);
+       CALL_ORIG(glGetActiveAttrib, program, index, bufSize, length, size,
+                 type, name);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddd",
+             program, index, bufSize);
+}
+
+//lsh_get
+void REAL_NAME(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize,
+                       GLsizei *length, GLint *size, GLenum *type, char *name)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint, GLsizei, GLsizei *, GLint *,
+                                  GLenum *, char *));
+       BEFORE(glGetActiveUniform);
+       CALL_ORIG(glGetActiveUniform, program, index, bufSize, length, size,
+                 type, name);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddd",
+             program, index, bufSize);
+}
+
+//lsh_get
+void REAL_NAME(glGetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *count,
+                         GLuint *shaders)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLsizei, GLsizei *, GLuint *));
+       BEFORE(glGetAttachedShaders);
+       CALL_ORIG(glGetAttachedShaders, program, maxCount, count, shaders);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             program, maxCount);
+}
+
+//lsh_get
+int REAL_NAME(glGetAttribLocation)(GLuint program, const char *name)
+{
+       TYPEDEF(int (*methodType)(GLuint, const char*));
+       BEFORE(glGetAttribLocation);
+       int ret = CALL_ORIG(glGetAttribLocation, program, name);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xs",
+             (uint64_t)(program), name);
+       return ret;
+}
+
+//lsh_get
+void REAL_NAME(glGetBufferParameteriv)(GLenum target, GLenum value, GLint * data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint *));
+       BEFORE(glGetBufferParameteriv);
+       CALL_ORIG(glGetBufferParameteriv, target, value, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(target), (uint64_t)(value));
+}
+
+//lsh_get
+void REAL_NAME(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment,
+                                          GLenum pname, GLint * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum, GLint *));
+       BEFORE(glGetFramebufferAttachmentParameteriv);
+       CALL_ORIG(glGetFramebufferAttachmentParameteriv, target, attachment,
+                 pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxx",
+             (uint64_t)(target), (uint64_t)(attachment), (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetProgramInfoLog)(GLuint program, GLsizei maxLength, GLsizei *length,
+                        char *infoLog)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLsizei, GLsizei *, char *));
+       BEFORE(glGetProgramInfoLog);
+       CALL_ORIG(glGetProgramInfoLog, program, maxLength, length, infoLog);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             program, maxLength);
+}
+
+//lsh_get
+void REAL_NAME(glGetProgramiv)(GLuint program, GLenum pname, GLint *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLenum, GLint *));
+       BEFORE(glGetProgramiv);
+       CALL_ORIG(glGetProgramiv, program, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dx",
+             program, (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint *));
+       BEFORE(glGetRenderbufferParameteriv);
+       CALL_ORIG(glGetRenderbufferParameteriv, target, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(target), (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetShaderInfoLog)(GLuint shader, GLsizei maxLength, GLsizei *length,
+                       char *infoLog)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLsizei, GLsizei *, char *));
+       BEFORE(glGetShaderInfoLog);
+       CALL_ORIG(glGetShaderInfoLog, shader, maxLength, length, infoLog);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             shader, maxLength);
+}
+
+//lsh_get
+void REAL_NAME(glGetShaderPrecisionFormat)(GLenum shaderType, GLenum precisionType,
+                               GLint *range, GLint *precision)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint *, GLint *));
+       BEFORE(glGetShaderPrecisionFormat);
+       CALL_ORIG(glGetShaderPrecisionFormat, shaderType, precisionType, range,
+                 precision);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(shaderType), (uint64_t)(precisionType));
+}
+
+//lsh_get
+void REAL_NAME(glGetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length,
+                      char *source)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLsizei, GLsizei *, char *));
+       BEFORE(glGetShaderSource);
+       CALL_ORIG(glGetShaderSource, shader, bufSize, length, source);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             shader, bufSize);
+}
+
+//lsh_get
+void REAL_NAME(glGetShaderiv)(GLuint shader, GLenum pname, GLint *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLenum, GLint *));
+       BEFORE(glGetShaderiv);
+       CALL_ORIG(glGetShaderiv, shader, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dx",
+             shader, (uint64_t)(pname));
+}
+
+const GLubyte *REAL_NAME(glGetString)(GLenum name)
+{
+       TYPEDEF(const GLubyte *(*methodType)(GLenum));
+       BEFORE(glGetString);
+       const GLubyte *ret = CALL_ORIG(glGetString, name);
+       GL_GET_ERROR();
+       AFTER('p', ret, APITYPE_CONTEXT, "", "x", (uint64_t)(name));
+
+       return ret;
+}
+
+//lsh_get
+void REAL_NAME(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLfloat *));
+       BEFORE(glGetTexParameterfv);
+       CALL_ORIG(glGetTexParameterfv, target, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(target), (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetTexParameteriv)(GLenum target, GLenum pname, GLint * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint *));
+       BEFORE(glGetTexParameteriv);
+       CALL_ORIG(glGetTexParameteriv, target, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(target), (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetUniformfv)(GLuint program, GLint location, GLfloat *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint, GLfloat *));
+       BEFORE(glGetUniformfv);
+       CALL_ORIG(glGetUniformfv, program, location, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             program, location);
+}
+
+//lsh_get
+void REAL_NAME(glGetUniformiv)(GLuint program, GLint location, GLint *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLuint, GLint *));
+       BEFORE(glGetUniformiv);
+       CALL_ORIG(glGetUniformiv, program, location, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             program, location);
+}
+
+//lsh_get
+GLint REAL_NAME(glGetUniformLocation)(GLuint program, const char *name)
+{
+       TYPEDEF(GLint (*methodType)(GLuint, const char *));
+       BEFORE(glGetUniformLocation);
+       GLint ret = CALL_ORIG(glGetUniformLocation, program, name);
+       GL_GET_ERROR();
+       AFTER('d', ret, APITYPE_CONTEXT, "", "d", program);
+
+       return ret;
+}
+
+//lsh_get
+void REAL_NAME(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLenum, GLfloat *));
+       BEFORE(glGetVertexAttribfv);
+       CALL_ORIG(glGetVertexAttribfv, index, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dx",
+             index, (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint *params)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLenum, GLint *));
+       BEFORE(glGetVertexAttribiv);
+       CALL_ORIG(glGetVertexAttribiv, index, pname, params);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dx",
+             index, (uint64_t)(pname));
+}
+
+//lsh_get
+void REAL_NAME(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid **pointer)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLenum, GLvoid **));
+       BEFORE(glGetVertexAttribPointerv);
+       CALL_ORIG(glGetVertexAttribPointerv, index, pname, pointer);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dx",
+             index, (uint64_t)(pname));
+}
+
+// ==================================================================
+// H 1
+// ==================================================================
+
+void REAL_NAME(glHint)(GLenum target, GLenum mode)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum));
+       BEFORE(glHint);
+       CALL_ORIG(glHint, target, mode);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xx",
+             (uint64_t)(target), (uint64_t)(mode));
+}
+
+// ==================================================================
+// I 7
+// ==================================================================
+
+GLboolean REAL_NAME(glIsBuffer)(GLuint buffer)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsBuffer);
+       GLboolean ret = CALL_ORIG(glIsBuffer, buffer);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", buffer);
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsEnabled)(GLenum cap)
+{
+       TYPEDEF(GLboolean (*methodType)(GLenum));
+       BEFORE(glIsEnabled);
+       GLboolean ret = CALL_ORIG(glIsEnabled, cap);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "x", (uint64_t)(cap));
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsFramebuffer)(GLuint framebuffer)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsFramebuffer);
+       GLboolean ret = CALL_ORIG(glIsFramebuffer, framebuffer);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", framebuffer);
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsProgram)(GLuint program)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsProgram);
+       GLboolean ret = CALL_ORIG(glIsProgram, program);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", program);
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsRenderbuffer)(GLuint renderbuffer)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsRenderbuffer);
+       GLboolean ret = CALL_ORIG(glIsRenderbuffer, renderbuffer);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", renderbuffer);
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsShader)(GLuint shader)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsShader);
+       GLboolean ret = CALL_ORIG(glIsShader, shader);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", shader);
+
+       return ret;
+}
+
+GLboolean REAL_NAME(glIsTexture)(GLuint texture)
+{
+       TYPEDEF(GLboolean (*methodType)(GLuint));
+       BEFORE(glIsTexture);
+       GLboolean ret = CALL_ORIG(glIsTexture, texture);
+       GL_GET_ERROR();
+       AFTER('c', ret, APITYPE_CONTEXT, "", "d", texture);
+
+       return ret;
+}
+
+// ==================================================================
+// L 2
+// ==================================================================
+
+void REAL_NAME(glLineWidth)(GLfloat width)
+{
+       TYPEDEF(void (*methodType)(GLfloat));
+       BEFORE(glLineWidth);
+       CALL_ORIG(glLineWidth, width);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "f", width);
+}
+
+/* TODO refactor snprintf check*/
+void REAL_NAME(glLinkProgram)(GLuint program)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glLinkProgram);
+       CALL_ORIG(glLinkProgram, program);
+       GL_GET_ERROR();
+       char buf[512] = "";
+       if (error == GL_NO_ERROR) {
+               char *to = buf;
+               int i, len;
+               size_t avail;
+               GLint activeNum[1];
+               GLint maxLength[1];
+               GLsizei length[1];
+               GLint size[1];
+               GLenum type[1];
+
+               avail = sizeof(buf);
+
+               real_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, activeNum);
+               real_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
+                                   maxLength);
+
+               char name1[maxLength[0]];
+               len = snprintf(to, avail, "%d", activeNum[0]);
+               to += len;
+               avail -= len;
+               for (i = 0; i < activeNum[0]; i++) {
+                       real_glGetActiveAttrib(program, i, maxLength[0], length,
+                                              size, type, name1);
+                       len = snprintf(to, avail, ",%d,%s,%d,%x", i, name1, size[0],
+                                      type[0]);
+
+                       if (avail <= (unsigned int)len) {
+                               PRINTERR("fatal. too small buf");
+                               break;
+                       }
+
+                       to += len;
+                       avail -= len;
+               }
+
+               real_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, activeNum);
+               real_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH,
+                                   maxLength);
+
+               char name2[maxLength[0]];
+               len = snprintf(to, avail, ",%d", activeNum[0]);
+
+               if (avail <= (unsigned int)len) {
+                       PRINTERR("fatal. too small buf");
+               } else {
+                       to += len;
+                       avail -= len;
+               }
+
+               for (i = 0; i < activeNum[0]; i++) {
+                       real_glGetActiveUniform(program, i, maxLength[0],
+                                               length, size, type, name2);
+                       len = snprintf(to, avail, ",%d,%s,%d,%x", i, name2,
+                                      size[0], type[0]);
+
+                       if (avail <= (unsigned int)len) {
+                               PRINTERR("fatal. too small buf");
+                               break;
+                       }
+
+                       to += len;
+                       avail -= len;
+
+               }
+       }
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, buf, "d",
+             program);
+}
+
+// ==================================================================
+// P 2
+// ==================================================================
+
+void REAL_NAME(glPixelStorei)(GLenum pname, GLint param)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint));
+       BEFORE(glPixelStorei);
+       CALL_ORIG(glPixelStorei, pname, param);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xd",
+             (uint64_t)(pname), param);
+}
+
+void REAL_NAME(glPolygonOffset)(GLfloat factor, GLfloat units)
+{
+       TYPEDEF(void (*methodType)(GLfloat, GLfloat));
+       BEFORE(glPolygonOffset);
+       CALL_ORIG(glPolygonOffset, factor, units);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ff",
+             factor, units);
+}
+
+// ==================================================================
+// R 3
+// ==================================================================
+
+//lsh_get
+void REAL_NAME(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
+                 GLenum format, GLenum type, GLvoid * data)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLsizei, GLsizei, GLenum,
+                                  GLenum, GLvoid *));
+       BEFORE(glReadPixels);
+       CALL_ORIG(glReadPixels, x, y, width, height, format, type, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "",
+             "ddddxx", x, y, width, height,
+             (uint64_t)(format), (uint64_t)(type));
+}
+
+void REAL_NAME(glReleaseShaderCompiler)(void)
+{
+       TYPEDEF(void (*methodType)(void));
+       BEFORE(glReleaseShaderCompiler);
+       CALL_ORIG(glReleaseShaderCompiler,);
+       GL_GET_ERROR();
+       AFTER_NO_PARAM('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "");
+}
+
+void REAL_NAME(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width,
+                          GLsizei height)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLsizei, GLsizei));
+       BEFORE(glRenderbufferStorage);
+       CALL_ORIG(glRenderbufferStorage, target, internalformat, width, height);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxdd",
+             (uint64_t)(target), (uint64_t)(internalformat), width, height);
+}
+
+// ==================================================================
+// S 10
+// ==================================================================
+
+void REAL_NAME(glSampleCoverage)(GLclampf value, GLboolean invert)
+{
+       TYPEDEF(void (*methodType)(GLclampf, GLboolean));
+       BEFORE(glSampleCoverage);
+       CALL_ORIG(glSampleCoverage, value, invert);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "fx",
+             value, (uint64_t)(invert));
+}
+
+void REAL_NAME(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLsizei, GLsizei));
+       BEFORE(glScissor);
+       CALL_ORIG(glScissor, x, y, width, height);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dddd",
+             x, y, width, height);
+}
+
+//lsh_param
+void REAL_NAME(glShaderBinary)(GLsizei n, const GLuint *shaders, GLenum binaryformat,
+                   const void *binary, GLsizei length)
+{
+       TYPEDEF(void (*methodType)(GLsizei, const GLuint *, GLenum,
+                                  const void *, GLsizei));
+       BEFORE(glShaderBinary);
+       CALL_ORIG(glShaderBinary, n, shaders, binaryformat, binary, length);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "",
+             "dpxpd", n, voidp_to_uint64(shaders),
+             (uint64_t)(binaryformat), voidp_to_uint64(binary), length);
+}
+
+//lsh_param
+void REAL_NAME(glShaderSource)(GLuint shader, GLsizei count, const char **string,
+                   const GLint *length)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLsizei, const char **,
+                                  const GLint*));
+       BEFORE(glShaderSource);
+       CALL_ORIG(glShaderSource, shader, count, string, length);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR) {
+               GLint length[1];
+               real_glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, length);
+               char buf[length[0]];
+               real_glGetShaderSource(shader, length[0], NULL, buf);
+               AFTER_SHADER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, buf,
+                            length[0], "ddpp", shader, count,
+                            voidp_to_uint64(string), voidp_to_uint64(length));
+       } else {
+               AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "",
+                     "ddpp", shader, count,
+                     voidp_to_uint64(string), voidp_to_uint64(length));
+       }
+}
+
+void REAL_NAME(glStencilFunc)(GLenum func, GLint ref, GLuint mask)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLint));
+       BEFORE(glStencilFunc);
+       CALL_ORIG(glStencilFunc, func, ref, mask);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdd",
+             (uint64_t)(func), ref, mask);
+}
+
+void REAL_NAME(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint, GLuint));
+       BEFORE(glStencilFuncSeparate);
+       CALL_ORIG(glStencilFuncSeparate, face, func, ref, mask);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxdd",
+             (uint64_t)(face), (uint64_t)(func), ref, mask);
+}
+
+void REAL_NAME(glStencilMask)(GLuint mask)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glStencilMask);
+       CALL_ORIG(glStencilMask, mask);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d", mask);
+}
+
+void REAL_NAME(glStencilMaskSeparate)(GLenum face, GLuint mask)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLuint));
+       BEFORE(glStencilMaskSeparate);
+       CALL_ORIG(glStencilMaskSeparate, face, mask);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xd",
+             (uint64_t)(face), mask);
+}
+
+void REAL_NAME(glStencilOp)(GLenum sfail, GLenum dpfail, GLenum dppass)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum));
+       BEFORE(glStencilOp);
+       CALL_ORIG(glStencilOp, sfail, dpfail, dppass);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxx",
+             (uint64_t)(sfail), (uint64_t)(dpfail),
+             (uint64_t)(dppass));
+}
+
+void REAL_NAME(glStencilOpSeparate)(GLenum face, GLenum sfail, GLenum dpfail,
+                        GLenum dppass)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLenum, GLenum));
+       BEFORE(glStencilOpSeparate);
+       CALL_ORIG(glStencilOpSeparate, face, sfail, dpfail, dppass);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxxx",
+             (uint64_t)(face), (uint64_t)(sfail), (uint64_t)(dpfail),
+             (uint64_t)(dppass));
+}
+
+// ==================================================================
+// T 6
+// ==================================================================
+
+void REAL_NAME(glTexImage2D)(GLenum target, GLint level, GLenum internalformat,
+                 GLsizei width, GLsizei height, GLint border, GLenum format,
+                 GLenum type, const GLvoid *data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLint, GLsizei, GLsizei,
+                                  GLint, GLenum, GLenum, const GLvoid *));
+       BEFORE(glTexImage2D);
+       CALL_ORIG(glTexImage2D, target, level, internalformat, width,
+                 height, border, format, type, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xdddddxxp",
+             (uint64_t)(target), level, internalformat, width, height,
+             border, (uint64_t)(format), (uint64_t)(type),
+             voidp_to_uint64(data));
+}
+
+void REAL_NAME(glTexParameterf)(GLenum target, GLenum pname, GLfloat param)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLfloat));
+       BEFORE(glTexParameterf);
+       CALL_ORIG(glTexParameterf, target, pname, param);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxf",
+             (uint64_t)(target), (uint64_t)(pname), param);
+}
+
+void REAL_NAME(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, const GLfloat *));
+       BEFORE(glTexParameterfv);
+       CALL_ORIG(glTexParameterfv, target, pname, params);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR) {
+               char param0[sizeof(GLenum) * 4];
+               snprintf(param0, sizeof(param0), "%x", (GLenum)params[0]);
+               AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, param0, "xxp",
+                     (uint64_t)(target), (uint64_t)(pname),
+                     voidp_to_uint64(params));
+       } else {
+               AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxp",
+                     (uint64_t)(target), (uint64_t)(pname),
+                     voidp_to_uint64(params));
+       }
+}
+
+void REAL_NAME(glTexParameteri)(GLenum target, GLenum pname, GLint param)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, GLint));
+       BEFORE(glTexParameteri);
+       CALL_ORIG(glTexParameteri, target, pname, param);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxx",
+             (uint64_t)(target), (uint64_t)(pname),
+             (uint64_t)(param));
+}
+
+void REAL_NAME(glTexParameteriv)(GLenum target, GLenum pname, const GLint * params)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLenum, const GLint *));
+       BEFORE(glTexParameteriv);
+       CALL_ORIG(glTexParameteriv, target, pname, params);
+       GL_GET_ERROR();
+       if (error == GL_NO_ERROR) {
+               char param0[sizeof(GLenum) * 4];
+               snprintf(param0, sizeof(param0), "%x", (GLenum)params[0]);
+               AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, param0, "xxp",
+                     (uint64_t)(target), (uint64_t)(pname),
+                     voidp_to_uint64(params));
+       } else {
+               AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "xxp",
+                     (uint64_t)(target),
+                     (uint64_t)(pname),
+                     voidp_to_uint64(params));
+       }
+}
+
+void REAL_NAME(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                    GLsizei width, GLsizei height, GLenum format, GLenum type,
+                    const GLvoid * data)
+{
+       TYPEDEF(void (*methodType)(GLenum, GLint, GLint, GLint, GLsizei,
+                                  GLsizei, GLenum, GLenum, const GLvoid *));
+       BEFORE(glTexSubImage2D);
+       CALL_ORIG(glTexSubImage2D, target, level, xoffset, yoffset, width,
+                 height, format, type, data);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "",
+             "xdddddxxp",
+             (uint64_t)(target), level, xoffset, yoffset, width, height,
+             (uint64_t)(format), (uint64_t)(type), voidp_to_uint64(data));
+}
+
+// ==================================================================
+// U 20
+// ==================================================================
+
+void REAL_NAME(glUniform1f)(GLint location, GLfloat v0)
+{
+       TYPEDEF(void (*methodType)(GLint, GLfloat));
+       BEFORE(glUniform1f);
+       CALL_ORIG(glUniform1f, location, v0);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "df",
+             location, v0);
+}
+
+void REAL_NAME(glUniform2f)(GLint location, GLfloat v0, GLfloat v1)
+{
+       TYPEDEF(void (*methodType)(GLint, GLfloat, GLfloat));
+       BEFORE(glUniform2f);
+       CALL_ORIG(glUniform2f, location, v0, v1);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dff",
+             location, v0, v1);
+}
+
+void REAL_NAME(glUniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+       TYPEDEF(void (*methodType)(GLint, GLfloat, GLfloat, GLfloat));
+       BEFORE(glUniform3f);
+       CALL_ORIG(glUniform3f, location, v0, v1, v2);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dfff",
+             location, v0, v1, v2);
+}
+
+void REAL_NAME(glUniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+       TYPEDEF(void (*methodType)(GLint, GLfloat, GLfloat, GLfloat, GLfloat));
+       BEFORE(glUniform4f);
+       CALL_ORIG(glUniform4f, location, v0, v1, v2, v3);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dffff",
+             location, v0, v1, v2, v3);
+}
+
+void REAL_NAME(glUniform1fv)(GLint location, GLsizei count, const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLfloat *));
+       BEFORE(glUniform1fv);
+       CALL_ORIG(glUniform1fv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddF",
+             location, count, count * 1, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform2fv)(GLint location, GLsizei count, const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLfloat *));
+       BEFORE(glUniform2fv);
+       CALL_ORIG(glUniform2fv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddF",
+             location, count, count * 2, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform3fv)(GLint location, GLsizei count, const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLfloat *));
+       BEFORE(glUniform3fv);
+       CALL_ORIG(glUniform3fv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddF",
+             location, count, count * 3, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform4fv)(GLint location, GLsizei count, const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLfloat *));
+       BEFORE(glUniform4fv);
+       CALL_ORIG(glUniform4fv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddF",
+             location, count, count * 4, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform1i)(GLint location, GLint v0)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint));
+       BEFORE(glUniform1i);
+       CALL_ORIG(glUniform1i, location, v0);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dd",
+             location, v0);
+}
+
+void REAL_NAME(glUniform2i)(GLint location, GLint v0, GLint v1)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLint));
+       BEFORE(glUniform2i);
+       CALL_ORIG(glUniform2i, location, v0, v1);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddd",
+             location, v0, v1);
+}
+
+void REAL_NAME(glUniform3i)(GLint location, GLint v0, GLint v1, GLint v2)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLint, GLint));
+       BEFORE(glUniform3i);
+       CALL_ORIG(glUniform3i, location, v0, v1, v2);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dddd",
+             location, v0, v1, v2);
+}
+
+void REAL_NAME(glUniform4i)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLint, GLint, GLint));
+       BEFORE(glUniform4i);
+       CALL_ORIG(glUniform4i, location, v0, v1, v2, v3);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddddd",
+             location, v0, v1, v2, v3);
+}
+
+void REAL_NAME(glUniform1iv)(GLint location, GLsizei count, const GLint *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLint *));
+       BEFORE(glUniform1iv);
+       CALL_ORIG(glUniform1iv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddD",
+             location, count, count * 1, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform2iv)(GLint location, GLsizei count, const GLint *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLint *));
+       BEFORE(glUniform2iv);
+       CALL_ORIG(glUniform2iv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddD",
+             location, count, count * 2, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform3iv)(GLint location, GLsizei count, const GLint *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLint *));
+       BEFORE(glUniform3iv);
+       CALL_ORIG(glUniform3iv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddD",
+             location, count, count * 3, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniform4iv)(GLint location, GLsizei count, const GLint *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, const GLint *));
+       BEFORE(glUniform4iv);
+       CALL_ORIG(glUniform4iv, location, count, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddD",
+             location, count, count * 4, voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose,
+                       const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, GLboolean, const GLfloat *));
+       BEFORE(glUniformMatrix2fv);
+       CALL_ORIG(glUniformMatrix2fv, location, count, transpose, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddxF",
+             location, count, (uint64_t)(transpose), count * 2 * 2,
+             voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose,
+                       const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, GLboolean, const GLfloat *));
+       BEFORE(glUniformMatrix3fv);
+       CALL_ORIG(glUniformMatrix3fv, location, count, transpose, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddxF",
+             location, count, (uint64_t)(transpose), count * 3 * 3,
+             voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose,
+                       const GLfloat *value)
+{
+       TYPEDEF(void (*methodType)(GLint, GLsizei, GLboolean, const GLfloat *));
+       BEFORE(glUniformMatrix4fv);
+       CALL_ORIG(glUniformMatrix4fv, location, count, transpose, value);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddxF",
+             location, count, (uint64_t)(transpose), count * 4 * 4,
+             voidp_to_uint64(value));
+}
+
+void REAL_NAME(glUseProgram)(GLuint program)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glUseProgram);
+       CALL_ORIG(glUseProgram, program);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d",
+             program);
+}
+
+// ==================================================================
+// V 7
+// ==================================================================
+
+void REAL_NAME(glValidateProgram)(GLuint program)
+{
+       TYPEDEF(void (*methodType)(GLuint));
+       BEFORE(glValidateProgram);
+       CALL_ORIG(glValidateProgram, program);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "d",
+             program);
+}
+
+void REAL_NAME(glVertexAttrib1f)(GLuint index, GLfloat v0)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLfloat));
+       BEFORE(glVertexAttrib1f);
+       CALL_ORIG(glVertexAttrib1f, index, v0);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue, "df",
+             index, v0);
+}
+
+void REAL_NAME(glVertexAttrib2f)(GLuint index, GLfloat v0, GLfloat v1)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLfloat, GLfloat));
+       BEFORE(glVertexAttrib2f);
+       CALL_ORIG(glVertexAttrib2f, index, v0, v1);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue, "dff",
+             index, v0, v1);
+}
+
+void REAL_NAME(glVertexAttrib3f)(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLfloat, GLfloat, GLfloat));
+       BEFORE(glVertexAttrib3f);
+       CALL_ORIG(glVertexAttrib3f, index, v0, v1, v2);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue, "dfff",
+             index, v0, v1, v2);
+}
+
+void REAL_NAME(glVertexAttrib4f)(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2,
+                     GLfloat v3)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat));
+       BEFORE(glVertexAttrib4f);
+       CALL_ORIG(glVertexAttrib4f, index, v0, v1, v2, v3);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue, "dffff",
+             index, v0, v1, v2, v3);
+}
+
+void REAL_NAME(glVertexAttrib1fv)(GLuint index, const GLfloat *v)
+{
+       TYPEDEF(void (*methodType)(GLuint, const GLfloat *));
+       BEFORE(glVertexAttrib1fv);
+       CALL_ORIG(glVertexAttrib1fv, index, v);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue,
+             "dp", index, voidp_to_uint64(v));
+}
+
+void REAL_NAME(glVertexAttrib2fv)(GLuint index, const GLfloat *v)
+{
+       TYPEDEF(void (*methodType)(GLuint, const GLfloat *));
+       BEFORE(glVertexAttrib2fv);
+       CALL_ORIG(glVertexAttrib2fv, index, v);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue,
+             "dp", index, voidp_to_uint64(v));
+}
+
+void REAL_NAME(glVertexAttrib3fv)(GLuint index, const GLfloat *v)
+{
+       TYPEDEF(void (*methodType)(GLuint, const GLfloat *));
+       BEFORE(glVertexAttrib3fv);
+       CALL_ORIG(glVertexAttrib3fv, index, v);
+
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue,
+             "dp", index, voidp_to_uint64(v));
+}
+
+void REAL_NAME(glVertexAttrib4fv)(GLuint index, const GLfloat *v)
+{
+       TYPEDEF(void (*methodType)(GLuint, const GLfloat *));
+       BEFORE(glVertexAttrib4fv);
+       CALL_ORIG(glVertexAttrib4fv, index, v);
+       GLfloat cv[4];
+       real_glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, cv);
+       snprintf(contextValue, sizeof(contextValue), "%f,%f,%f,%f",
+                cv[0], cv[1], cv[2], cv[3]);
+
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, contextValue,
+             "dp", index, voidp_to_uint64(v));
+}
+
+void REAL_NAME(glVertexAttribPointer)(GLuint index, GLint size, GLenum type,
+                          GLboolean normalized, GLsizei stride,
+                          const GLvoid *pointer)
+{
+       TYPEDEF(void (*methodType)(GLuint, GLint, GLenum, GLboolean, GLsizei,
+                                  const GLvoid *));
+       BEFORE(glVertexAttribPointer);
+       CALL_ORIG(glVertexAttribPointer, index, size, type, normalized, stride,
+                 pointer);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "ddxxdp",
+             index, size, (uint64_t)(type), (uint64_t)(normalized),
+             stride, voidp_to_uint64(pointer));
+}
+
+void REAL_NAME(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+       TYPEDEF(void (*methodType)(GLint, GLint, GLsizei, GLsizei));
+
+       BEFORE(glViewport);
+
+       CALL_ORIG(glViewport, x, y, width, height);
+       GL_GET_ERROR();
+       AFTER('v', NO_RETURN_VALUE, APITYPE_CONTEXT, "", "dddd",
+             x, y, width, height);
+}
+
+#undef CALL_ORIG
+#undef BEFORE
diff --git a/probe_graphics/da_gles20_tizen.cpp b/probe_graphics/da_gles20_tizen.cpp
new file mode 100644 (file)
index 0000000..4e3ae7d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@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
+ *
+ */
+
+//disable tizen redefines
+#define _GL2_MACRO_H_
+#define _GL_MACRO_H_
+
+#include "common_probe_init.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REAL_NAME(func) __local_##func
+#define BEFORE BEFORE_GL_API
+#define CALL_ORIG(func, ...) __gl_api->func(__VA_ARGS__)
+#define TYPEDEF(type)
+
+/*
+ * this include to make tizen open gl api functions
+ * probe prototypes
+ *
+ */
+#include "da_gles20_native.cpp"
+
+#ifdef __cplusplus
+} /* extern C */
+#endif
+
+#undef _GL2_MACRO_H_
+#undef _GL_MACRO_H_
+
diff --git a/probe_memory/da_memory.h b/probe_memory/da_memory.h
new file mode 100644 (file)
index 0000000..a8ae788
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_MEMORY_H__
+#define __DA_MEMORY_H__
+
+#include "daprobe.h"
+
+//#define INTERNALFILTERING            (!isEnableInternalMalloc())
+#define INTERNAL_MALLOC_FILTERING              true
+#define INTERNAL_FREE_FILTERING                        true
+#define INTERNAL_NEW_FILTERING                 true
+#define INTERNAL_DELETE_FILTERING              true
+
+/*******************************************************************
+ * MEMORY PROBE MACRO
+ *
+ * log format
+ *             SeqNumber`,ApiName`,Time`,Pid`,Tid`,InputParm`,Return`,PCAddr`,Error`,
+ *             Size`,MemoryAPIType`,Addr`,\n
+ *             callstack_start`,callstack`,callstack_end
+ *
+ ********************************************************************/
+
+#endif // __DA_MEMORY_H__
diff --git a/probe_memory/libdamemalloc.c b/probe_memory/libdamemalloc.c
new file mode 100755 (executable)
index 0000000..4086a24
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@samsung.com>
+ * Dmitry Bogatov <d.bogatov@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+#include <memory.h>
+#include <errno.h>
+#include <malloc.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dacollection.h"
+#include "dautil.h"
+#include "da_memory.h"
+#include "binproto.h"
+
+static enum DaOptions _sopt = OPT_ALLOC;
+
+void *malloc(size_t size)
+{
+       static void* (*mallocp)(size_t);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       rtdl_next_current_set_once(mallocp);
+
+       PRE_PROBEBLOCK();
+
+       pret = (*mallocp)(size);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+               add_memory_hash(pret, size, MEMTYPE_ALLOC,
+                               blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, API_ID_malloc,
+                         "x", (int64_t) size);
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+void free(void *ptr)
+{
+       static void (*freep)(void *);
+       DECLARE_VARIABLE_STANDARD;
+
+       rtdl_next_current_set_once(freep);
+
+       PRE_PROBEBLOCK();
+
+       if(ptr != NULL && gProbeBlockCount == 0)
+               del_memory_hash(ptr, MEMTYPE_FREE, NULL);
+
+       (*freep)(ptr);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, API_ID_free, 
+                         "p", (int64_t)(int) ptr);
+       PACK_COMMON_END('v', 0, newerrno, blockresult);
+       PACK_MEMORY(0, MEMORY_API_FREE, ptr);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+}
+
+void *realloc(void *memblock, size_t size)
+{
+       static void* (*reallocp)(void*, size_t);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       rtdl_next_current_set_once(reallocp);
+       PRE_PROBEBLOCK();
+
+       if(memblock != NULL && gProbeBlockCount == 0)
+               del_memory_hash(memblock, MEMTYPE_FREE, NULL);
+
+       pret = (*reallocp)(memblock, size);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+               add_memory_hash(pret, size, MEMTYPE_ALLOC,
+                               blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, API_ID_realloc,
+                         "px", voidp_to_uint64(memblock), (uint64_t) size);
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+
+void *temp_calloc(size_t nelem, size_t elsize)
+{
+       /* Magic number, but somewhy it is sufficent */
+       static char extra_mem[20] = {0};
+       return (nelem * elsize > sizeof(extra_mem))
+               ? extra_mem
+               : NULL;
+}
+
+void *calloc(size_t nelem, size_t elsize)
+{
+       static void* (*callocp)(size_t, size_t);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       if (!callocp) {
+               /**
+                * Calloc is called by `dlsym`, so we provide small amount
+                * of static memory via `temp_calloc`.
+                */
+               callocp = temp_calloc;
+               callocp = rtdl_next(__func__);
+       }
+
+       PRE_PROBEBLOCK();
+
+       pret = (*callocp)(nelem, elsize);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+               add_memory_hash(pret, nelem * elsize, MEMTYPE_ALLOC,
+                               blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, API_ID_calloc,
+                         "xx", (uint64_t)nelem, (uint64_t)elsize);
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(nelem * elsize, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+
+       return pret;
+}
diff --git a/probe_memory/libdamemmanage.c b/probe_memory/libdamemmanage.c
new file mode 100644 (file)
index 0000000..d0fb3fa
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+#include <memory.h>
+#include <errno.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dautil.h"
+#include "da_memory.h"
+#include "binproto.h"
+#include "common_probe_init.h"
+#include "real_functions.h"
+
+static enum DaOptions _sopt = OPT_ALLOC;
+
+void *memset(void *memblock, int c, size_t n)
+{
+       static void *(*memsetp)(void *,int,size_t);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNC_RTLD_NEXT(memset);
+
+       PRE_PROBEBLOCK();
+
+       pret = memsetp(memblock, c, n);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_memset,
+                         "pdx", voidp_to_uint64(memblock), c,
+                         (uint64_t)(n));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(n, MEMORY_API_MANAGE, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+int memcmp(const void * ptr1, const void * ptr2, size_t num)
+{
+       static int(*memcmpp)(const void *,const void *,size_t);
+       DECLARE_VARIABLE_STANDARD;
+
+       GET_REAL_FUNC_RTLD_NEXT(memcmp);
+
+       PRE_PROBEBLOCK();
+
+       ret = memcmpp(ptr1, ptr2, num);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_memcmp,
+                         "ppx", voidp_to_uint64(ptr1), voidp_to_uint64(ptr2),
+                         (uint64_t)(num));
+       PACK_COMMON_END('d', ret, newerrno, blockresult);
+       PACK_MEMORY(num, MEMORY_API_MANAGE, ret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return ret;
+}
+
+void *memcpy(void * destination, const void * source, size_t num )
+{
+       static void *(*memcpyp)(void *,const void *,size_t);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNC_RTLD_NEXT(memcpy);
+
+       PRE_PROBEBLOCK();
+
+       pret = memcpyp(destination, source, num);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_memcpy,
+                         "ppx", voidp_to_uint64(destination),
+                         voidp_to_uint64(source),
+                         (uint64_t)(num));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(num, MEMORY_API_MANAGE, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
diff --git a/probe_memory/libdanew.cpp b/probe_memory/libdanew.cpp
new file mode 100644 (file)
index 0000000..7a3e220
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <new>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dacollection.h"
+#include "da_memory.h"
+#include "binproto.h"
+
+static enum DaOptions _sopt = OPT_ALLOC;
+
+void *operator new(std::size_t size) throw (std::bad_alloc)
+{
+       static void*(*newp)(std::size_t size);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_Znwj,newp);
+
+       bfiltering = INTERNAL_NEW_FILTERING;
+       PRE_PROBEBLOCK();
+
+       pret = newp(size);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+       {
+               add_memory_hash(pret, size, MEMTYPE_NEW, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+       }
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void__operator_new_std__size_t_size__throw__std__bad_alloc_,
+                         "x", (uint64_t)(size));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+void *operator new[](std::size_t size) throw (std::bad_alloc)
+{
+       static void*(*newp)(std::size_t size);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_Znaj, newp);
+
+       bfiltering = INTERNAL_NEW_FILTERING;
+       PRE_PROBEBLOCK();
+
+       pret = newp(size);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+       {
+               add_memory_hash(pret, size, MEMTYPE_NEW, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+       }
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void__operator_new___std__size_t_size__throw__std__bad_alloc_,
+                         "x", (uint64_t)(size));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+void operator delete(void *ptr) throw()
+{
+       static void (*deletep)(void *ptr);
+       DECLARE_VARIABLE_STANDARD;
+       unsigned short caller;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZdlPv, deletep);
+
+       bfiltering = INTERNAL_DELETE_FILTERING;
+       PRE_PROBEBLOCK();
+
+       if(ptr != NULL && gProbeBlockCount == 0)
+       {
+               probeBlockStart();
+               ret = del_memory_hash(ptr, MEMTYPE_DELETE, &caller);
+               if(blockresult == 0 && ret == 0 && caller == MEM_EXTERNAL)
+               {
+                       setProbePoint(&probeInfo);
+                       blockresult = 2;
+                       probingStart();
+               }
+               probeBlockEnd();
+       }
+
+       deletep(ptr);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void_operator_delete_void__ptr__throw__,
+                         "p", voidp_to_uint64(ptr));
+       PACK_COMMON_END('v', 0, newerrno, blockresult);
+       PACK_MEMORY(0, MEMORY_API_FREE, ptr);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+}
+
+void operator delete[](void *ptr) throw()
+{
+       static void (*deletep)(void *ptr);
+       DECLARE_VARIABLE_STANDARD;
+       unsigned short caller;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZdaPv, deletep);
+
+       bfiltering = INTERNAL_DELETE_FILTERING;
+       PRE_PROBEBLOCK();
+
+       if(ptr != NULL && gProbeBlockCount == 0)
+       {
+               probeBlockStart();
+               ret = del_memory_hash(ptr, MEMTYPE_DELETE, &caller);
+               if(blockresult == 0 && ret == 0 && caller == MEM_EXTERNAL)
+               {
+                       setProbePoint(&probeInfo);
+                       blockresult = 2;
+                       probingStart();
+               }
+               probeBlockEnd();
+       }
+
+       deletep(ptr);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void_operator_delete___void__ptr__throw__,
+                         "p", voidp_to_uint64(ptr));
+       PACK_COMMON_END('v', 0, newerrno, blockresult);
+       PACK_MEMORY(0, MEMORY_API_FREE, ptr);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+}
+
+void *operator new(std::size_t size, const std::nothrow_t& nothrow) throw()
+{
+       static void*(*newp)(std::size_t size, const std::nothrow_t& nothrow);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZnwjRKSt9nothrow_t, newp);
+
+       bfiltering = INTERNAL_NEW_FILTERING;
+       PRE_PROBEBLOCK();
+
+       pret = newp(size, nothrow);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+       {
+               add_memory_hash(pret, size, MEMTYPE_NEW, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+       }
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void__operator_new_std__size_t_size__const_std__nothrow_t__nothrow__throw__,
+                         "xp", (uint64_t)(size), voidp_to_uint64(&nothrow));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+void *operator new[](std::size_t size, const std::nothrow_t& nothrow) throw()
+{
+       static void*(*newp)(std::size_t size, const std::nothrow_t& nothrow);
+       DECLARE_VARIABLE_STANDARD;
+       void *pret;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZnajRKSt9nothrow_t, newp);
+
+       bfiltering = INTERNAL_NEW_FILTERING;
+       PRE_PROBEBLOCK();
+
+       pret = newp(size, nothrow);
+
+       if(pret != NULL && gProbeBlockCount == 0)
+       {
+               add_memory_hash(pret, size, MEMTYPE_NEW, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
+       }
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void__operator_new___std__size_t_size__const_std__nothrow_t__nothrow__throw__,
+                         "xp", (uint64_t)(size), voidp_to_uint64(&nothrow));
+       PACK_COMMON_END('p', pret, newerrno, blockresult);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+
+       return pret;
+}
+
+void operator delete(void *ptr, const std::nothrow_t& nothrow) throw()
+{
+       static void (*deletep)(void *ptr, const std::nothrow_t& nothrow);
+       DECLARE_VARIABLE_STANDARD;
+       unsigned short caller;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZdlPvRKSt9nothrow_t, deletep);
+
+       bfiltering = INTERNAL_DELETE_FILTERING;
+       PRE_PROBEBLOCK();
+
+       if(ptr != NULL && gProbeBlockCount == 0)
+       {
+               probeBlockStart();
+               ret = del_memory_hash(ptr, MEMTYPE_DELETE, &caller);
+               if(blockresult == 0 && ret == 0 && caller == MEM_EXTERNAL)
+               {
+                       setProbePoint(&probeInfo);
+                       blockresult = 2;
+                       probingStart();
+               }
+               probeBlockEnd();
+       }
+
+       deletep(ptr, nothrow);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void_operator_delete_void__ptr__const_std__nothrow_t__nothrow__throw__,
+                         "pp", voidp_to_uint64(ptr), voidp_to_uint64(&nothrow));
+       PACK_COMMON_END('v', 0, newerrno, blockresult);
+       PACK_MEMORY(0, MEMORY_API_FREE, ptr);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+}
+
+void operator delete[](void *ptr, const std::nothrow_t& nothrow) throw()
+{
+       static void (*deletep)(void *ptr, const std::nothrow_t& nothrow);
+       DECLARE_VARIABLE_STANDARD;
+       unsigned short caller;
+
+       GET_REAL_FUNCP_RTLD_NEXT_CPP(_ZdaPvRKSt9nothrow_t, deletep);
+
+       bfiltering = INTERNAL_DELETE_FILTERING;
+       PRE_PROBEBLOCK();
+
+       if(ptr != NULL && gProbeBlockCount == 0)
+       {
+               probeBlockStart();
+               ret = del_memory_hash(ptr, MEMTYPE_DELETE, &caller);
+               if(blockresult == 0 && ret == 0 && caller == MEM_EXTERNAL)
+               {
+                       setProbePoint(&probeInfo);
+                       blockresult = 2;
+                       probingStart();
+               }
+               probeBlockEnd();
+       }
+
+       deletep(ptr, nothrow);
+
+       POST_PACK_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
+                         API_ID_void_operator_delete___void__ptr__const_std__nothrow_t__nothrow__throw__,
+                         "pp", voidp_to_uint64(ptr), voidp_to_uint64(&nothrow));
+       PACK_COMMON_END('v', 0, newerrno, blockresult);
+       PACK_MEMORY(0, MEMORY_API_FREE, ptr);
+       FLUSH_LOCAL_BUF();
+
+       POST_PACK_PROBEBLOCK_END();
+}
+
diff --git a/probe_socket/da_socket.h b/probe_socket/da_socket.h
new file mode 100644 (file)
index 0000000..12f1072
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Hyunjong Park <phjwithyou.park@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_SOCKET_H__
+#define __DA_SOCKET_H__
+
+#include "daprobe.h"
+
+
+#define SOCKET_SEND_SIZE 1024
+#define NO_TOTAL_INFO (NULL)
+#define POST_PROBEBLOCK_MIDDLE_LIBC_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO)                              \
+       do {                                                    \
+               BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)OBJECTPTR);            \
+               BUF_PTR = pack_int64(BUF_PTR, FDVALUE);         \
+               BUF_PTR = pack_int32(BUF_PTR, APITYPE);         \
+               struct sockaddr *tmp_dest = ((struct sockaddr *)TOTAL_INFO.sock); \
+               if ( tmp_dest != NO_TOTAL_INFO) { \
+                       switch (tmp_dest->sa_family) { \
+                               case AF_INET:\
+                                       BUF_PTR = pack_int32(BUF_PTR, ((struct sockaddr_in *)tmp_dest)->sin_addr.s_addr ); \
+                                       BUF_PTR = pack_int32(BUF_PTR, ntohs(((struct sockaddr_in *)tmp_dest)->sin_port ) ); \
+                                       break;\
+                               /*case AF_INET6:\
+                                       BUF_PTR = pack_int32(BUF_PTR, ((struct sockaddr_in6 *)tmp_dest)->sin6_addr.s6_addr32 ); \
+                                       BUF_PTR = pack_int32(BUF_PTR, ((struct sockaddr_in6 *)tmp_dest)->sin6_port ); \
+                                       break;*/ \
+                               default:\
+                                       BUF_PTR = pack_int32(BUF_PTR, (uint32_t) 0);    \
+                                       BUF_PTR = pack_int32(BUF_PTR, (uint32_t) 0);    \
+                                       break; \
+                       } \
+               } else { \
+                       BUF_PTR = pack_int32(BUF_PTR, (uint32_t) 0);    \
+                       BUF_PTR = pack_int32(BUF_PTR, (uint32_t) 0);    \
+               }; \
+               BUF_PTR = pack_int64(BUF_PTR, TOTAL_INFO.msg_total_size);               \
+               BUF_PTR = pack_bin(BUF_PTR, TOTAL_INFO.msg_buf, TOTAL_INFO.msg_pack_size);              \
+       } while (0)
+
+
+//lib Common Function
+#define AFTER_ORIGINAL_LIBC_SOCK(RTYPE, RVAL, OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...)      \
+               POST_PROBEBLOCK_BEGIN(LC_SOCKET, RTYPE, RVAL, INPUTFORMAT, __VA_ARGS__);                \
+               POST_PROBEBLOCK_MIDDLE_LIBC_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                                             \
+               POST_PROBEBLOCK_END();
+
+//lib START Function
+#define AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START(RTYPE, RVAL,OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...)        \
+       POST_PROBEBLOCK_FUNC_START_BEGIN(LC_SOCKET, RTYPE, RVAL, INPUTFORMAT, __VA_ARGS__);                             \
+       POST_PROBEBLOCK_MIDDLE_LIBC_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                     \
+       FLUSH_LOCAL_BUF();                                                                                              \
+       PRE_PROBEBLOCK_END()
+
+#define POST_PROBEBLOCK_FUNC_START_BEGIN(LCTYPE, RTYPE, RETVALUE, INPUTFORMAT, ...)    \
+               newerrno = errno;                                                                                                               \
+                       if(postBlockBegin(blockresult)) {                                                                               \
+                               PREPARE_LOCAL_BUF(); \
+                               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+                               PACK_COMMON_END(RTYPE, RETVALUE, errno, blockresult)
+
+
+//lib END Function
+#define AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END(RTYPE, RVAL, OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...) \
+       POST_PROBEBLOCK_FUNC_END_BEGIN(LC_SOCKET, RTYPE, RVAL,  INPUTFORMAT, __VA_ARGS__);              \
+       POST_PROBEBLOCK_MIDDLE_LIBC_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                                             \
+       POST_PROBEBLOCK_END()
+
+#define POST_PROBEBLOCK_FUNC_END_BEGIN(LCTYPE, RTYPE, RETVALUE, INPUTFORMAT, ...)      \
+       newerrno = errno;                                                                                                               \
+       if(postBlockBegin(blockresult)) {                                                                               \
+               setProbePoint(&probeInfo);                                                                              \
+               PREPARE_LOCAL_BUF(); \
+               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+               PACK_COMMON_END(RTYPE, RETVALUE, errno, blockresult)
+
+#define POST_PROBEBLOCK_MIDDLE_TIZEN_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO )                            \
+       do {                                                                    \
+               BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)OBJECTPTR);            \
+               BUF_PTR = pack_int64(BUF_PTR, FDVALUE);                         \
+               BUF_PTR = pack_int32(BUF_PTR, APITYPE);                         \
+               BUF_PTR = pack_int32(BUF_PTR, TOTAL_INFO.host_ip);              \
+               BUF_PTR = pack_int32(BUF_PTR, TOTAL_INFO.host_port);            \
+               BUF_PTR = pack_int64(BUF_PTR, TOTAL_INFO.msg_total_size);       \
+               BUF_PTR = pack_bin(BUF_PTR, TOTAL_INFO.msg_buf,                 \
+                                  TOTAL_INFO.msg_pack_size);                   \
+       } while (0)
+
+
+
+//Tizen Common Function
+#define AFTER_ORIGINAL_TIZEN_SOCK(APINAME, RTYPE, RVAL, OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...)     \
+       POST_PROBEBLOCK_TIZEN_BEGIN(APINAME, LC_SOCKET, RTYPE, RVAL, INPUTFORMAT, __VA_ARGS__);         \
+       POST_PROBEBLOCK_MIDDLE_TIZEN_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                                            \
+       POST_PROBEBLOCK_END()
+
+// Tizen Start Function
+#define AFTER_ORIGINAL_TIZEN_SOCK_WAIT_FUNC_START(APINAME, RTYPE, RVAL,OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...)      \
+       POST_PROBEBLOCK_TIZEN_FUNC_START_BEGIN(APINAME,LC_SOCKET, RTYPE, RVAL, INPUTFORMAT, __VA_ARGS__);               \
+       POST_PROBEBLOCK_MIDDLE_TIZEN_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                                            \
+       FLUSH_LOCAL_BUF();                                              \
+       PRE_PROBEBLOCK_END();
+
+//Tizen END Function
+#define AFTER_ORIGINAL_TIZEN_SOCK_WAIT_FUNC_END(APINAME,RTYPE, RVAL,OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO, INPUTFORMAT, ...) \
+       POST_PROBEBLOCK_TIZEN_FUNC_END_BEGIN(APINAME,LC_SOCKET, RTYPE, RVAL, INPUTFORMAT, __VA_ARGS__);         \
+       POST_PROBEBLOCK_MIDDLE_TIZEN_SOCK(OBJECTPTR, FDVALUE, APITYPE, TOTAL_INFO );                                                            \
+       POST_PROBEBLOCK_END()
+
+#define POST_PROBEBLOCK_TIZEN_BEGIN(APINAME, LCTYPE, RTYPE, RETVALUE, INPUTFORMAT, ...)        \
+       if(postBlockBegin(blockresult)) {                                                                               \
+               PREPARE_LOCAL_BUF(); \
+               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+               PACK_COMMON_END(RTYPE, RETVALUE, errno, blockresult)
+
+#define APPEND_NETWORK_LOG_BASIC(LCTYPE, APINAME)                                                              \
+       log.length = sprintf(log.data, "%d`,%d`,%s`,%lu`,%d`,%d",       \
+                       LCTYPE, probeInfo.eventIndex, APINAME,                          \
+                       probeInfo.currentTime, probeInfo.pID, probeInfo.tID)
+
+#define POST_PROBEBLOCK_TIZEN_FUNC_START_BEGIN(APINAME, LCTYPE, RTYPE, RETVALUE, INPUTFORMAT, ...)     \
+                       if(postBlockBegin(blockresult)) {                                                                               \
+                               PREPARE_LOCAL_BUF(); \
+                               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+                               PACK_COMMON_END(RTYPE, RETVALUE, errno, blockresult)
+
+#define POST_PROBEBLOCK_TIZEN_FUNC_END_BEGIN(APINAME, LCTYPE, RTYPE, RETVALUE, INPUTFORMAT, ...)       \
+       if(postBlockBegin(blockresult)) {                                                                               \
+               setProbePoint(&probeInfo);                                                                              \
+               PREPARE_LOCAL_BUF(); \
+               PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
+               PACK_COMMON_END(RTYPE, RETVALUE, errno, blockresult)
+
+#define BEFORE_ORIGINAL_SOCK(FUNCNAME, LIBNAME)                                \
+       DECLARE_VARIABLE_STANDARD;                                      \
+       info_t info;                                                    \
+       INIT_INFO;                                                      \
+       int32_t __attribute__((unused)) vAPI_ID = API_ID_ ## FUNCNAME;  \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
+       PRE_PROBEBLOCK()
+
+#endif // __DA_SOCKET_H__
diff --git a/probe_socket/libdasocket.c b/probe_socket/libdasocket.c
new file mode 100644 (file)
index 0000000..939d72a
--- /dev/null
@@ -0,0 +1,1901 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Hyunjong Park <phjwithyou.park@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/epoll.h>
+#include <sys/poll.h>
+#include "probeinfo.h"
+#include "dautil.h"
+#include "da_socket.h"
+#include "daprobe.h"
+#include "dahelper.h"
+#include "api_id_mapping.h"
+#include "binproto.h"
+#include "real_functions.h"
+
+#define OBJ_DUMMY 0
+
+static enum DaOptions _sopt = OPT_NETWORK;
+void getAddress(const struct sockaddr *sa, char *address) {
+       char buff[INET6_ADDRSTRLEN];
+       char *path;
+
+       if (sa == NULL) {
+               const char sa_is_null[] = "<addr is NULL>";
+               memcpy(address, sa_is_null, sizeof(sa_is_null));
+               return;
+       }
+
+       switch (sa->sa_family) {
+       case AF_INET:
+               snprintf(address, MAX_PATH_LENGTH, "%s:%d",
+                        inet_ntoa(((struct sockaddr_in*) sa)->sin_addr),
+                        (int) ntohs(((struct sockaddr_in*) sa)->sin_port));
+               break;
+       case AF_INET6:
+               snprintf(address, MAX_PATH_LENGTH, "%s:%d",
+                        inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) sa)->sin6_addr),
+                        buff, sizeof(buff)),
+                               ntohs(((struct sockaddr_in6*) sa)->sin6_port));
+               break;
+       case AF_UNIX:
+               path = ((struct sockaddr_un*)sa)->sun_path;
+               if (path[0] == '\0')
+                       snprintf(address, MAX_PATH_LENGTH, "%s", path + 1);
+               else
+                       snprintf(address, MAX_PATH_LENGTH, "%s", path);
+               break;
+       default:
+               snprintf(address, MAX_PATH_LENGTH, "<unknown socket type #%d>",
+                        sa->sa_family);
+               break;
+       }
+}
+
+//FD
+int socket(int domain, int type, int protocol) {
+       static int (*socketp)(int domain, int type, int protocol);
+       BEFORE_ORIGINAL_SOCK(socket, LIBC);
+       ret = socketp(domain, type, protocol);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, ret, SOCKET_API_FD_OPEN, info,
+                                "ddd", domain, type, protocol);
+
+       return ret;
+}
+
+int accept(int socket, struct sockaddr *address, socklen_t *address_len) {
+
+       static int (*acceptp)(int socket, struct sockaddr *address,
+                       socklen_t *address_len);
+
+       BEFORE_ORIGINAL_SOCK(accept, LIBC);
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(address, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_ACCEPT_START, info,
+                                                "dsp", socket, callAddress,
+                                                voidp_to_uint64(address_len));
+
+       ret = acceptp(socket, address, address_len);
+       info.sock = (struct sockaddr *)address;
+
+       getAddress(address, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, socket,
+                                              SOCKET_API_ACCEPT_END, info,
+                                              "dsp", socket, callAddress,
+                                              voidp_to_uint64(address_len));
+
+       return ret;
+}
+
+int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
+       static int (*accept4p)(int sockfd, struct sockaddr *addr,
+                       socklen_t *addrlen, int flags);
+
+       BEFORE_ORIGINAL_SOCK(accept4, LIBC);
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(addr, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, sockfd,
+                                                SOCKET_API_ACCEPT_START, info,
+                                                "dspd", sockfd, callAddress,
+                                                voidp_to_uint64(addrlen),
+                                                flags);
+
+       ret = accept4p(sockfd, addr, addrlen, flags);
+       info.sock = (struct sockaddr *)addr;
+
+       getAddress(addr, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, sockfd,
+                                              SOCKET_API_ACCEPT_END, info,
+                                              "dspd", sockfd, callAddress,
+                                              voidp_to_uint64(addrlen), flags);
+
+       return ret;
+}
+
+int connect(int socket, const struct sockaddr *address, socklen_t address_len) {
+       static int (*connectp)(int socket, const struct sockaddr *address,
+                       socklen_t address_len);
+
+       BEFORE_ORIGINAL_SOCK(connect, LIBC);
+
+       ret = connectp(socket, address, address_len);
+       info.sock = (struct sockaddr *)address;
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(address, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_CONNECT,
+                       info, "dsd",
+                       socket, callAddress, address_len);
+
+       return ret;
+}
+
+int shutdown(int socket, int how) {
+       static int (*shutdownp)(int socket, int how);
+
+       BEFORE_ORIGINAL_SOCK(shutdown, LIBC);
+
+       ret = shutdownp(socket, how);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_FD_CLOSE,
+                       info, "dd", socket, how);
+
+       return ret;
+}
+
+int bind(int socket, const struct sockaddr *address, socklen_t address_len) {
+       static int (*bindp)(int socket, const struct sockaddr *address,
+                       socklen_t address_len);
+
+       BEFORE_ORIGINAL_SOCK(bind, LIBC);
+
+       ret = bindp(socket, address, address_len);
+       info.sock = (struct sockaddr *)address;
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(address, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_BIND,
+                       info, "dsd", socket, callAddress, address_len);
+
+       return ret;
+}
+
+int listen(int socket, int backlog) {
+       static int (*listenp)(int socket, int backlog);
+       BEFORE_ORIGINAL_SOCK(listen, LIBC);
+       ret = listenp(socket, backlog);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_LISTEN,
+                                info, "dd", socket, backlog);
+
+       return ret;
+}
+
+ssize_t send(int socket, const void *message, size_t length, int flags) {
+       static ssize_t (*sendp)(int socket, const void *message, size_t length,
+                       int flags);
+       ssize_t sret, result;
+       BEFORE_ORIGINAL_SOCK(send, LIBC);
+
+       char *messagP = (char *)message;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                 SOCKET_API_SEND_START, info,
+                                                 "dpdd", socket,
+                                                 voidp_to_uint64(messagP),
+                                                 length, flags);
+
+       sret = sendp(socket, message, length, flags);
+       result = sret;
+       if (result < 0)
+               result = 0;
+       info.msg_total_size = result;
+       info.msg_pack_size = result>SOCKET_SEND_SIZE?SOCKET_SEND_SIZE:result;
+       info.msg_buf = messagP;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_SEND_END, info,
+                                              "dpdd", socket,
+                                              voidp_to_uint64(messagP),
+                                              length, flags);
+       return sret;
+}
+
+ssize_t recv(int socket, void *buffer, size_t length, int flags) {
+       static ssize_t (*recvp)(int socket, void *buffer, size_t length, int flags);
+       ssize_t sret, result;
+
+       BEFORE_ORIGINAL_SOCK(recv, LIBC);
+
+       char *bufferP = (char *)buffer;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_RECV_START, info,
+                                                "dpdd", socket,
+                                                voidp_to_uint64(bufferP),
+                                                length, flags);
+
+       sret = recvp(socket, buffer, length, flags);
+       result = sret;
+       if (result < 0)
+               result = 0;
+       info.msg_total_size = result;
+       info.msg_pack_size = result>SOCKET_SEND_SIZE?SOCKET_SEND_SIZE:result;
+       info.msg_buf = bufferP;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_RECV_END, info,
+                                              "dpdd", socket,
+                                              voidp_to_uint64(bufferP),
+                                              length, flags);
+       return sret;
+}
+
+ssize_t sendto(int socket, const void *message, size_t length, int flags,
+               const struct sockaddr *dest_addr, socklen_t dest_len) {
+       static ssize_t (*sendtop)(int socket, const void *message, size_t length,
+                       int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
+       ssize_t sret, result;
+
+       BEFORE_ORIGINAL_SOCK(sendto, LIBC);
+
+       char *bufferP = (char *)message;
+       info.sock = (struct sockaddr *) dest_addr;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_SEND_START, info,
+                                                "dpddpd", socket,
+                                                voidp_to_uint64(bufferP),
+                                                length, flags,
+                                                voidp_to_uint64(dest_addr),
+                                                dest_len);
+
+       sret = sendtop(socket, message, length, flags, dest_addr, dest_len);
+       result = sret;
+       if (result < 0)
+               result = 0;
+       info.msg_total_size = result;
+       info.msg_pack_size = result>SOCKET_SEND_SIZE?SOCKET_SEND_SIZE:result;
+       info.msg_buf = bufferP;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_SEND_END, info,
+                                              "dpddpd", socket,
+                                              voidp_to_uint64(bufferP),
+                                              length, flags,
+                                              voidp_to_uint64(dest_addr), dest_len);
+       return sret;
+}
+
+ssize_t recvfrom(int socket, void *buffer, size_t length, int flags,
+               struct sockaddr *address, socklen_t *address_len) {
+       static ssize_t (*recvfromp)(int socket, void *buffer, size_t length,
+                       int flags, struct sockaddr *address, socklen_t *address_len);
+       ssize_t sret, result;
+
+       BEFORE_ORIGINAL_SOCK(recvfrom, LIBC);
+
+       char *bufferP = (char *)buffer;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_RECV_START, info,
+                                                "dpddpp", socket,
+                                                voidp_to_uint64(bufferP),
+                                                length, flags,
+                                                voidp_to_uint64(address),
+                                                voidp_to_uint64(address_len));
+
+       sret = recvfromp(socket, buffer, length, flags, address, address_len);
+       info.sock = (struct sockaddr *)address;
+
+       result = sret;
+       if (result < 0)
+               result = 0;
+       info.msg_total_size = result;
+       info.msg_pack_size = result>SOCKET_SEND_SIZE?SOCKET_SEND_SIZE:result;
+       info.msg_buf = bufferP;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_RECV_END, info,
+                                              "dpddpp", socket,
+                                              voidp_to_uint64(bufferP),
+                                              length, flags,
+                                              voidp_to_uint64(address),
+                                              voidp_to_uint64(address_len));
+       return sret;
+}
+
+ssize_t recvmsg(int socket, struct msghdr *message, int flags) {
+       static ssize_t (*recvmsgp)(int socket, struct msghdr *message, int flags);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_SOCK(recvmsg, LIBC);
+
+       int* bufferP = (int*) message->msg_name;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_RECV_START, info,
+                                                "dpd", socket,
+                                                voidp_to_uint64(message),
+                                                flags);
+
+       sret = recvmsgp(socket, message, flags);
+       if (sret <= 0) {
+               memset(&message, 0, sizeof(message));
+       }
+
+       int sendMaxSize = SOCKET_SEND_SIZE;
+       char* out = (char*) real_malloc(sendMaxSize + 5);
+       if (sret <= 0) {
+               out[0] = '\0';
+       } else {
+               memcpy(out, message, sendMaxSize + 5);
+               if (sret > sendMaxSize + 5) {
+                       out[sendMaxSize] = '.';
+                       out[sendMaxSize + 1] = '.';
+                       out[sendMaxSize + 2] = '.';
+                       out[sendMaxSize + 3] = '\0';
+               } else {
+                       out[sret] = '\0';
+               }
+       }
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_RECV_END, info, "dpd",
+                                              socket, voidp_to_uint64(bufferP),
+                                              flags);
+       free(out);
+       return sret;
+}
+
+ssize_t sendmsg(int socket, const struct msghdr *message, int flags) {
+       static ssize_t (*sendmsgp)(int socket, const struct msghdr *message,
+                       int flags);
+       ssize_t sret;
+
+       BEFORE_ORIGINAL_SOCK(sendmsg, LIBC);
+
+       int* bufferP = (int*) message->msg_name;
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('x', NULL, OBJ_DUMMY, socket,
+                                                SOCKET_API_SEND_START, info,
+                                                "dpd", socket,
+                                                voidp_to_uint64(message),
+                                                flags);
+
+       sret = sendmsgp(socket, message, flags);
+       if (sret <= 0) {
+               memset(&message, 0, sizeof(message));
+       }
+       int sendMaxSize = SOCKET_SEND_SIZE;
+       char* out = (char*) real_malloc(sendMaxSize + 5);
+       if (sret <= 0) {
+               out[0] = '\0';
+       } else {
+               memcpy(out, message, sendMaxSize + 5);
+               if (sret > sendMaxSize + 5) {
+                       out[sendMaxSize] = '.';
+                       out[sendMaxSize + 1] = '.';
+                       out[sendMaxSize + 2] = '.';
+                       out[sendMaxSize + 3] = '\0';
+               } else {
+                       out[sret] = '\0';
+               }
+       }
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('x', sret, OBJ_DUMMY, socket,
+                                              SOCKET_API_SEND_END, info, "dpd",
+                                              socket, voidp_to_uint64(bufferP),
+                                              flags);
+       free(out);
+       return sret;
+}
+
+int getsockopt(int socket, int level, int option_name, void *option_value,
+               socklen_t *option_len) {
+       static int (*getsockoptp)(int socket, int level, int option_name,
+                       void *option_value, socklen_t *option_len);
+
+       BEFORE_ORIGINAL_SOCK(getsockopt, LIBC);
+
+       ret = getsockoptp(socket, level, option_name, option_value, option_len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_OTHER,
+                                info, "dddpp", socket, level, option_name,
+                                voidp_to_uint64(option_value),
+                                voidp_to_uint64(option_len));
+
+       return ret;
+}
+
+int setsockopt(int socket, int level, int option_name, const void *option_value,
+               socklen_t option_len) {
+       static int (*setsockoptp)(int socket, int level, int option_name,
+                       const void *option_value, socklen_t option_len);
+
+       BEFORE_ORIGINAL_SOCK(setsockopt, LIBC);
+
+       ret = setsockoptp(socket, level, option_name, option_value, option_len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket, SOCKET_API_OTHER,
+                                info, "dddpd", socket, level, option_name,
+                                voidp_to_uint64(option_value), option_len);
+
+       return ret;
+}
+
+int getpeername(int fd, struct sockaddr *addr, socklen_t *len) {
+       static int (*getpeernamep)(int s, struct sockaddr *addr, socklen_t *len);
+
+       BEFORE_ORIGINAL_SOCK(getpeername, LIBC);
+
+       ret = getpeernamep(fd, addr, len);
+       info.sock = (struct sockaddr *)addr;
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(addr, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, fd, SOCKET_API_OTHER,
+                                info, "dsp", fd, callAddress,
+                                voidp_to_uint64(len));
+       return ret;
+}
+
+int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+       static int (*getsocknamep)(int sockfd, struct sockaddr *addr,
+                       socklen_t *addrlen);
+
+       BEFORE_ORIGINAL_SOCK(getsockname, LIBC);
+
+       ret = getsocknamep(sockfd, addr, addrlen);
+       info.sock = (struct sockaddr *)addr;
+
+       char callAddress[MAX_PATH_LENGTH];
+       getAddress(addr, callAddress);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, sockfd, SOCKET_API_OTHER,
+                                info, "dsp", sockfd, callAddress,
+                                voidp_to_uint64(addrlen));
+
+       return ret;
+}
+
+int socketpair(int domain, int type, int protocol, int socket_vector[2]) {
+       static int (*socketpairp)(int domain, int type, int protocol,
+                       int socket_vector[2]);
+
+       BEFORE_ORIGINAL_SOCK(socketpair, LIBC);
+
+       ret = socketpairp(domain, type, protocol, socket_vector);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, socket_vector[0],
+                       SOCKET_API_FD_OPEN, info, "ddddd",
+                       domain, type, protocol, socket_vector[0], socket_vector[1]);
+
+       return ret;
+}
+
+int sockatmark(int __fd) {
+       static int (*sockatmarkp)(int __fd);
+
+       BEFORE_ORIGINAL_SOCK(sockatmark, LIBC);
+
+       ret = sockatmarkp(__fd);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, __fd,
+                       SOCKET_API_OTHER, info, "d", __fd);
+       return ret;
+}
+
+int isfdtype(int __fd, int __fdtype) {
+       static int (*isfdtypep)(int __fd, int __fdtype);
+
+       BEFORE_ORIGINAL_SOCK(isfdtype, LIBC);
+
+       ret = isfdtypep(__fd, __fdtype);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, __fd, SOCKET_API_OTHER, info,
+                                "dd", __fd, __fdtype);
+       return ret;
+}
+
+int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+               struct timeval *timeout) {
+       static int (*selectp)(int nfds, fd_set *readfds, fd_set *writefds,
+                       fd_set *exceptfds, struct timeval *timeout);
+
+       BEFORE_ORIGINAL_SOCK(select, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, 0,
+                                                SOCKET_API_EVENT_START, info,
+                                                "dpppp", nfds,
+                                                voidp_to_uint64(readfds),
+                                                voidp_to_uint64(writefds),
+                                                voidp_to_uint64(exceptfds),
+                                                voidp_to_uint64(timeout));
+
+       ret = selectp(nfds, readfds, writefds, exceptfds, timeout);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, 0,
+                                              SOCKET_API_EVENT_END, info,
+                                              "dpppp", nfds,
+                                              voidp_to_uint64(readfds),
+                                              voidp_to_uint64(writefds),
+                                              voidp_to_uint64(exceptfds),
+                                              voidp_to_uint64(timeout));
+
+       return ret;
+}
+
+int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+               const struct timespec *ntimeout, const sigset_t *sigmask) {
+       static int (*pselectp)(int nfds, fd_set *readfds, fd_set *writefds,
+                       fd_set *exceptfds, const struct timespec *ntimeout,
+                       const sigset_t *sigmask);
+
+       BEFORE_ORIGINAL_SOCK(pselect, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, 0,
+                                                SOCKET_API_EVENT_START, info,
+                                                "dppppp",nfds,
+                                                voidp_to_uint64(readfds),
+                                                voidp_to_uint64(writefds),
+                                                voidp_to_uint64(exceptfds),
+                                                voidp_to_uint64(ntimeout),
+                                                voidp_to_uint64(sigmask));
+
+       ret = pselectp(nfds, readfds, writefds, exceptfds, ntimeout, sigmask);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, 0,
+                                              SOCKET_API_EVENT_END, info,
+                                              "dppppp", nfds,
+                                              voidp_to_uint64(readfds),
+                                              voidp_to_uint64(writefds),
+                                              voidp_to_uint64(exceptfds),
+                                              voidp_to_uint64(ntimeout),
+                                              voidp_to_uint64(sigmask));
+
+       return ret;
+}
+
+int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+       static int (*pollp)(struct pollfd *ufds, unsigned int nfds, int timeout);
+
+       BEFORE_ORIGINAL_SOCK(poll, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, fds->fd,
+                                                SOCKET_API_EVENT_START, info,
+                                                "pxd", voidp_to_uint64(fds),
+                                                (uint64_t)(nfds), timeout);
+
+       ret = pollp(fds, nfds, timeout);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, fds->fd,
+                                              SOCKET_API_EVENT_END, info,
+                                              "pxd", voidp_to_uint64(fds),
+                                              (uint64_t)(nfds), timeout);
+
+       return ret;
+}
+
+int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
+               const sigset_t *sigmask) {
+       static int (*ppollp)(struct pollfd *fds, nfds_t nfds,
+                       const struct timespec *timeout_ts, const sigset_t *sigmask);
+
+       BEFORE_ORIGINAL_SOCK(ppoll, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, fds->fd,
+                                                SOCKET_API_EVENT_START, info,
+                                                "pxpp",
+                                                voidp_to_uint64(fds),
+                                                (uint64_t)(nfds),
+                                                voidp_to_uint64(timeout_ts),
+                                                voidp_to_uint64(sigmask));
+
+       ret = ppollp(fds, nfds, timeout_ts, sigmask);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, fds->fd,
+                                              SOCKET_API_EVENT_END, info,
+                                              "pxpp",
+                                              voidp_to_uint64(fds),
+                                              (uint64_t)(nfds),
+                                              voidp_to_uint64(timeout_ts),
+                                              voidp_to_uint64(sigmask));
+
+       return ret;
+}
+
+int epoll_create(int __size) {
+       static int (*epoll_createp)(int __size);
+       BEFORE_ORIGINAL_SOCK(epoll_create, LIBC);
+
+       ret = epoll_createp(__size);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, ret, SOCKET_API_FD_OPEN, info,
+                                "d", __size);
+       return ret;
+}
+
+int epoll_create1(int __flags) {
+       static int (*epoll_create1p)(int __size);
+       BEFORE_ORIGINAL_SOCK(epoll_create1, LIBC);
+
+       ret = epoll_create1p(__flags);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, ret, SOCKET_API_FD_OPEN, info,
+                                "d", __flags);
+       return ret;
+}
+
+int epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents,
+               int __timeout) {
+       static int (*epoll_waitp)(int __epfd, struct epoll_event *__events,
+                       int __maxevents, int __timeout);
+       BEFORE_ORIGINAL_SOCK(epoll_wait, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, __epfd,
+                                                SOCKET_API_EVENT_START, info,
+                                                "dpdd", __epfd,
+                                                voidp_to_uint64(__events),
+                                                __maxevents, __timeout);
+
+       ret = epoll_waitp(__epfd, __events, __maxevents, __timeout);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, __epfd,
+                                              SOCKET_API_EVENT_END, info,
+                                              "dpdd", __epfd,
+                                              voidp_to_uint64(__events),
+                                              __maxevents, __timeout);
+
+       return ret;
+}
+
+int epoll_pwait(int __epfd, struct epoll_event *__events, int __maxevents,
+               int __timeout, __const                          __sigset_t *__ss) {
+       static int (*epoll_pwaitp)(int __epfd, struct epoll_event *__events,
+                       int __maxevents, int __timeout, __const                          __sigset_t *__ss);
+       BEFORE_ORIGINAL_SOCK(epoll_pwait, LIBC);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_START('d', NULL, OBJ_DUMMY, __epfd,
+                                                SOCKET_API_EVENT_START, info,
+                                                "dpddp", __epfd,
+                                                voidp_to_uint64(__events),
+                                                __maxevents, __timeout,
+                                                voidp_to_uint64(__ss));
+
+       ret = epoll_pwaitp(__epfd, __events, __maxevents, __timeout, __ss);
+
+       AFTER_ORIGINAL_LIBC_SOCK_WAIT_FUNC_END('d', ret, OBJ_DUMMY, __epfd,
+                                              SOCKET_API_EVENT_END, info,
+                                              "dpddp", __epfd,
+                                              voidp_to_uint64(__events),
+                                              __maxevents, __timeout,
+                                              voidp_to_uint64(__ss));
+
+       return ret;
+}
+
+int epoll_ctl(int __epfd, int __op, int __fd, struct epoll_event *__event) {
+       static int (*epoll_ctlp)(int __epfd, int __op, int __fd,
+                       struct epoll_event *__event);
+
+       BEFORE_ORIGINAL_SOCK(epoll_ctl, LIBC);
+
+       ret = epoll_ctlp(__epfd, __op, __fd, __event);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, __fd, SOCKET_API_OTHER,
+                                info, "dddp", __epfd, __op, __fd,
+                                voidp_to_uint64(__event));
+       return ret;
+}
+
+#if 0
+//OPTION _//NO FD
+
+uint32_t htonl(uint32_t hostlong) {
+       static uint32_t (*htonlp)(uint32_t hostlong);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htonl, LIBC);
+
+       uret = htonlp(hostlong);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', uret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", hostlong);
+
+       return uret;
+}
+
+uint16_t htons(uint16_t hostshort) {
+       static uint16_t (*htonsp)(uint16_t hostshort);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htons, LIBC);
+
+       uret = htonsp(hostshort);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', (uint32_t)uret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", hostshort);
+
+       return uret;
+}
+
+int inet_aton(const char *cp, struct in_addr *inp) {
+       static int (*inet_atonp)(const char *cp, struct in_addr *inp);
+
+       BEFORE_ORIGINAL_SOCK(inet_aton, LIBC);
+
+       ret = inet_atonp(cp, inp);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pp", voidp_to_uint64(cp),
+                                voidp_to_uint64(inp));
+
+       return ret;
+}
+
+in_addr_t inet_addr(const char *cp) {
+       static in_addr_t (*inet_addrp)(const char *cp);
+       in_addr_t iret;
+
+       BEFORE_ORIGINAL_SOCK(inet_addr, LIBC);
+
+       iret = inet_addrp(cp);
+
+       AFTER_ORIGINAL_LIBC_SOCK(iret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(cp));
+
+       return iret;
+}
+
+in_addr_t inet_network(const char *cp) {
+       static in_addr_t (*inet_networkp)(const char *cp);
+       in_addr_t iret;
+
+       BEFORE_ORIGINAL_SOCK(inet_network, LIBC);
+
+       iret = inet_networkp(cp);
+
+       AFTER_ORIGINAL_LIBC_SOCK(iret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(cp));
+
+       return iret;
+}
+
+char *inet_ntoa(struct in_addr in) {
+       static char * (*inet_ntoap)(struct in_addr in);
+       char* sret;
+
+       BEFORE_ORIGINAL_SOCK(inet_ntoa, LIBC);
+
+       sret = inet_ntoap(in);
+
+       AFTER_ORIGINAL_LIBC_SOCK(sret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "d", in.s_addr);
+
+       return sret;
+}
+
+uint32_t ntohl(uint32_t netlong) {
+       static uint32_t (*ntohlp)(uint32_t netlong);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(ntohl, LIBC);
+
+       uret = ntohlp(netlong);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', uret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "d", netlong);
+
+       return uret;
+}
+
+uint16_t ntohs(uint16_t netshort) {
+       static uint16_t (*ntohsp)(uint16_t netshort);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(ntohs, LIBC);
+
+       uret = ntohsp(netshort);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', (uint32_t)uret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "d", netshort);
+
+       return uret;
+}
+
+in_addr_t inet_lnaof(struct in_addr in) {
+       static in_addr_t (*inet_lnaofp)(struct in_addr in);
+       in_addr_t iret;
+
+       BEFORE_ORIGINAL_SOCK(inet_lnaof, LIBC);
+
+       iret = inet_lnaofp(in);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', iret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "d", in.s_addr);
+
+       return iret;
+}
+
+in_addr_t inet_netof(struct in_addr in) {
+       static in_addr_t (*inet_netofp)(struct in_addr in);
+       in_addr_t iret;
+
+       BEFORE_ORIGINAL_SOCK(inet_netof, LIBC);
+
+       iret = inet_netofp(in);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', iret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "d", in.s_addr);
+
+       return iret;
+}
+
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
+       static const char* (*inet_ntopp)(int af, const void *src, char *dst,
+                       socklen_t size);
+       const char* cret;
+
+       BEFORE_ORIGINAL_SOCK(inet_ntop, LIBC);
+
+       cret = inet_ntopp(af, src, dst, size);
+
+       AFTER_ORIGINAL_LIBC_SOCK(cret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dppd", af, voidp_to_uint64(src), voidp_to_uint64(dst), size);
+
+       return cret;
+}
+
+int inet_pton(int af, const char *src, void *dst) {
+       static int (*inet_ptonp)(int af, const char *src, void *dst);
+
+       BEFORE_ORIGINAL_SOCK(inet_pton, LIBC);
+
+       ret = inet_ptonp(af, src, dst);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dpp", af, voidp_to_uint64(src), voidp_to_uint64(dst));
+
+       return ret;
+}
+
+int getaddrinfo(const char *node, const char *service,
+               const struct addrinfo *hints, struct addrinfo **res) {
+       static int (*getaddrinfop)(const char *node, const char *service,
+                       const struct addrinfo *hints, struct addrinfo **res);
+
+       BEFORE_ORIGINAL_NOFILTER(getaddrinfo, LIBC);
+
+       ret = getaddrinfop(node, service, hints, res);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pppp", voidp_to_uint64(node), voidp_to_uint64(service), voidp_to_uint64(hints), voidp_to_uint64(res));
+
+       return ret;
+}
+
+void freeaddrinfo(struct addrinfo *res) {
+       static void (*freeaddrinfop)(struct addrinfo *res);
+
+       BEFORE_ORIGINAL_NOFILTER(freeaddrinfo, LIBC);
+
+       freeaddrinfop(res);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(res));
+}
+
+const char *gai_strerror(int errcode) {
+       static const char * (*gai_strerrorp)(int errcode);
+       const char * cret;
+
+       BEFORE_ORIGINAL_SOCK(gai_strerror, LIBC);
+
+       cret = gai_strerrorp(errcode);
+
+       AFTER_ORIGINAL_LIBC_SOCK(cret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", errcode);
+
+       return cret;
+}
+
+int gai_suspend(const struct gaicb* const list[], int nitems,
+               const struct timespec *timeout) {
+       static int (*gai_suspendp)(const struct gaicb* const list[], int nitems,
+                       const struct timespec *timeout);
+
+       BEFORE_ORIGINAL_SOCK(gai_suspend, LIBC);
+
+       ret = gai_suspendp(list, nitems, timeout);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pdp", voidp_to_uint64(list), nitems, voidp_to_uint64(timeout));
+
+       return ret;
+}
+
+int gai_error(struct gaicb *req) {
+       static int (*gai_errorp)(struct gaicb *req);
+
+       BEFORE_ORIGINAL_SOCK(gai_error, LIBC);
+
+       ret = gai_errorp(req);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(req));
+
+       return ret;
+}
+
+int gai_cancel(struct gaicb *req) {
+       static int (*gai_cancelp)(struct gaicb *req);
+
+       BEFORE_ORIGINAL_SOCK(gai_cancel, LIBC);
+
+       ret = gai_cancelp(req);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(req));
+
+       return ret;
+}
+
+int getaddrinfo_a(int mode, struct gaicb *list[], int nitems,
+               struct sigevent *sevp) {
+       static int (*getaddrinfo_ap)(int mode, struct gaicb *list[], int nitems,
+                       struct sigevent *sevp);
+
+       BEFORE_ORIGINAL_SOCK(getaddrinfo_a, LIBC);
+
+       ret = getaddrinfo_ap(mode, list, nitems, sevp);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dpdp", mode, voidp_to_uint64(list), nitems, voidp_to_uint64(sevp));
+
+       return ret;
+}
+
+int getdomainname(char *name, size_t len) {
+       static int (*getdomainnamep)(char *name, size_t len);
+
+       BEFORE_ORIGINAL_SOCK(getdomainname, LIBC);
+
+       ret = getdomainnamep(name, len);
+
+       //AFTER_ORIGINAL_NOSOCK(FD_API_OTHER, "pd", voidp_to_uint64(name), len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pd", voidp_to_uint64(name), len);
+
+       return ret;
+}
+
+int setdomainname(const char *name, size_t len) {
+       static int (*setdomainnamep)(const char *name, size_t len);
+
+       BEFORE_ORIGINAL_SOCK(setdomainname, LIBC);
+
+       ret = setdomainnamep(name, len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pd", voidp_to_uint64(name), len);
+
+       return ret;
+}
+
+int gethostname(char *name, size_t len) {
+       static int (*gethostnamep)(char *name, size_t len);
+
+       BEFORE_ORIGINAL_SOCK(gethostname, LIBC);
+
+       ret = gethostnamep(name, len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pd", voidp_to_uint64(name), len);
+
+       return ret;
+}
+
+int sethostname(const char *name, size_t len) {
+       static int (*sethostnamep)(const char *name, size_t len);
+
+       BEFORE_ORIGINAL_SOCK(sethostname, LIBC);
+
+       ret = sethostnamep(name, len);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pd", voidp_to_uint64(name), len);
+
+       return ret;
+}
+
+int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
+               socklen_t hostlen, char *serv, socklen_t servlen, unsigned int flags) {
+       static int (*getnameinfop)(const struct sockaddr *sa, socklen_t salen,
+                       char *host, socklen_t hostlen, char *serv, socklen_t servlen,
+                       unsigned int flags);
+
+       BEFORE_ORIGINAL_SOCK(getnameinfo, LIBC);
+
+       ret = getnameinfop(sa, salen, host, hostlen, serv, servlen, flags);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pdpdpdd", voidp_to_uint64(sa), salen,
+                                voidp_to_uint64(host), hostlen,
+                                voidp_to_uint64(serv), servlen, flags);
+
+       return ret;
+}
+
+struct hostent *gethostbyname(const char *name) {
+       static struct hostent * (*gethostbynamep)(const char *name);
+       struct hostent* pret;
+
+       BEFORE_ORIGINAL_SOCK(gethostbyname, LIBC);
+
+       pret = gethostbynamep(name);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(name));
+
+       return pret;
+}
+
+struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
+       static struct hostent * (*gethostbyaddrp)(const void *addr, socklen_t len,
+                       int type);
+       struct hostent* pret;
+
+       BEFORE_ORIGINAL_SOCK(gethostbyaddr, LIBC);
+
+       pret = gethostbyaddrp(addr, len, type);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pdd", voidp_to_uint64(addr), len, type);
+
+       return pret;
+}
+
+void sethostent(int stayopen) {
+       static void (*sethostentp)(int stayopen);
+
+       BEFORE_ORIGINAL_SOCK(sethostent, LIBC);
+
+       sethostentp(stayopen);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", stayopen);
+}
+
+void endhostent(void) {
+       static void (*endhostentp)(void);
+
+       BEFORE_ORIGINAL_SOCK(endhostent, LIBC);
+
+       endhostentp();
+
+       //AFTER_ORIGINAL_NOSOCK_RET(NULL, 0, FD_API_OTHER, "s", "");
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+}
+
+void herror(const char *s) {
+       static void (*herrorp)(const char *s);
+
+       BEFORE_ORIGINAL_SOCK(herror, LIBC);
+
+       herrorp(s);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(s));
+}
+
+const char *hstrerror(int err) {
+       static const char* (*hstrerrorp)(int err);
+       const char* cret;
+
+       BEFORE_ORIGINAL_SOCK(hstrerror, LIBC);
+
+       cret = hstrerrorp(err);
+
+       AFTER_ORIGINAL_LIBC_SOCK(cret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", err);
+
+       return cret;
+}
+
+struct hostent *gethostent(void) {
+       static struct hostent* (*gethostentp)(void);
+       struct hostent* pret;
+
+       BEFORE_ORIGINAL_SOCK(gethostent, LIBC);
+
+       pret = gethostentp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+
+       return pret;
+}
+
+struct hostent *gethostbyname2(const char *name, int af) {
+       static struct hostent * (*gethostbyname2p)(const char *name, int af);
+       struct hostent* pret;
+
+       BEFORE_ORIGINAL_SOCK(gethostbyname2, LIBC);
+
+       pret = gethostbyname2p(name, af);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pd", voidp_to_uint64(name), af);
+
+       return pret;
+}
+
+int gethostent_r(struct hostent *rret, char *buf, size_t buflen,
+               struct hostent **result, int *h_errnop) {
+       static int (*gethostent_rp)(struct hostent *rret, char *buf, size_t buflen,
+                       struct hostent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(gethostent_r, LIBC);
+
+       ret = gethostent_rp(rret, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ppdpp", voidp_to_uint64(rret),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+int gethostbyaddr_r(const void *addr, socklen_t len, int type,
+               struct hostent *rret, char *buf, size_t buflen, struct hostent **result,
+               int *h_errnop) {
+       static int (*gethostbyaddr_rp)(const void *addr, socklen_t len, int type,
+                       struct hostent *rret, char *buf, size_t buflen,
+                       struct hostent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(gethostbyaddr_r, LIBC);
+
+       ret = gethostbyaddr_rp(addr, len, type, rret, buf, buflen, result,
+                       h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pddppdpp", voidp_to_uint64(addr), len,
+                                type, voidp_to_uint64(rret),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+int gethostbyname_r(const char *name, struct hostent *rret, char *buf,
+               size_t buflen, struct hostent **result, int *h_errnop) {
+       static int (*gethostbyname_rp)(const char *name, struct hostent *rret,
+                       char *buf, size_t buflen, struct hostent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(gethostbyname_r, LIBC);
+
+       ret = gethostbyname_rp(name, rret, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pppdpp", voidp_to_uint64(name),
+                                voidp_to_uint64(rret), voidp_to_uint64(buf),
+                                buflen, voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+int gethostbyname2_r(const char *name, int af, struct hostent *rret, char *buf,
+               size_t buflen, struct hostent **result, int *h_errnop) {
+       static int (*gethostbyname2_rp)(const char *name, int af,
+                       struct hostent *rret, char *buf, size_t buflen,
+                       struct hostent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(gethostbyname2_r, LIBC);
+
+       ret = gethostbyname2_rp(name, af, rret, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pdppdpp", voidp_to_uint64(name), af,
+                                voidp_to_uint64(rret), voidp_to_uint64(buf),
+                                buflen, voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+struct servent *getservbyname(const char *name, const char *proto) {
+       static struct servent * (*getservbynamep)(const char *name,
+                       const char *proto);
+       struct servent* pret;
+
+       BEFORE_ORIGINAL_SOCK(getservbyname, LIBC);
+
+       pret = getservbynamep(name, proto);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pp", voidp_to_uint64(name),
+                                voidp_to_uint64(proto));
+
+       return pret;
+}
+
+void setservent(int stayopen) {
+       static void (*setserventp)(int stayopen);
+
+       BEFORE_ORIGINAL_SOCK(setservent, LIBC);
+
+       setserventp(stayopen);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", stayopen);
+}
+
+void endservent(void) {
+       static void (*endserventp)(void);
+
+       BEFORE_ORIGINAL_SOCK(endservent, LIBC);
+
+       endserventp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+}
+
+struct servent *getservent(void) {
+       static struct servent * (*getserventp)(void);
+       struct servent* pret;
+
+       BEFORE_ORIGINAL_SOCK(getservent, LIBC);
+
+       pret = getserventp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+
+       return pret;
+}
+
+struct servent *getservbyport(int port, const char *proto) {
+       static struct servent * (*getservbyportp)(int port, const char *proto);
+       struct servent* pret;
+
+       BEFORE_ORIGINAL_SOCK(getservbyport, LIBC);
+
+       pret = getservbyportp(port, proto);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dp", port, voidp_to_uint64(proto));
+
+       return pret;
+}
+
+int getservent_r(struct servent *result_buf, char *buf, size_t buflen,
+               struct servent **result) {
+       static int (*getservent_rp)(struct servent *result_buf, char *buf,
+                       size_t buflen, struct servent **result);
+
+       BEFORE_ORIGINAL_SOCK(getservent_r, LIBC);
+
+       ret = getservent_rp(result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ppdp", voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+int getservbyname_r(const char *name, const char *proto,
+               struct servent *result_buf, char *buf, size_t buflen,
+               struct servent **result) {
+       static int (*getservbyname_rp)(const char *name, const char *proto,
+                       struct servent *result_buf, char *buf, size_t buflen,
+                       struct servent **result);
+
+       BEFORE_ORIGINAL_SOCK(getservbyname_r, LIBC);
+
+       ret = getservbyname_rp(name, proto, result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ppppdp", voidp_to_uint64(name),
+                                voidp_to_uint64(proto),
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+int getservbyport_r(int port, const char *proto, struct servent *result_buf,
+               char *buf, size_t buflen, struct servent **result) {
+       static int (*getservbyport_rp)(int port, const char *proto,
+                       struct servent *result_buf, char *buf, size_t buflen,
+                       struct servent **result);
+
+       BEFORE_ORIGINAL_SOCK(getservbyport_r, LIBC);
+
+       ret = getservbyport_rp(port, proto, result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dpppdp", port, voidp_to_uint64(proto),
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+struct netent* getnetent(void) {
+       static struct netent * (*getnetentp)(void);
+       struct netent* pret;
+
+       BEFORE_ORIGINAL_SOCK(getnetent, LIBC);
+
+       pret = getnetentp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+
+       return pret;
+}
+
+struct netent *getnetbyname(const char *name) {
+       static struct netent * (*getnetbynamep)(const char *name);
+       struct netent* pret;
+
+       BEFORE_ORIGINAL_SOCK(getnetbyname, LIBC);
+
+       pret = getnetbynamep(name);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(name));
+
+       return pret;
+}
+
+struct netent *getnetbyaddr(uint32_t net, int type) {
+       static struct netent * (*getnetbyaddrp)(uint32_t net, int type);
+       struct netent * pret;
+
+       BEFORE_ORIGINAL_SOCK(getnetbyaddr, LIBC);
+
+       pret = getnetbyaddrp(net, type);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "dd", net, type);
+
+       return pret;
+}
+
+void setnetent(int stayopen) {
+       static void (*setnetentp)(int stayopen);
+
+       BEFORE_ORIGINAL_SOCK(setnetent, LIBC);
+
+       setnetentp(stayopen);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", stayopen);
+}
+
+void endnetent(void) {
+       static void (*endnetentp)(void);
+
+       BEFORE_ORIGINAL_SOCK(endnetent, LIBC);
+
+       endnetentp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+}
+
+int getnetent_r(struct netent *result_buf, char *buf, size_t buflen,
+               struct netent **result, int *h_errnop) {
+       static int (*getnetent_rp)(struct netent *result_buf, char *buf,
+                       size_t buflen, struct netent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(getnetent_r, LIBC);
+
+       ret = getnetent_rp(result_buf, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ppdpp", voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+int getnetbyname_r(const char *name, struct netent *result_buf, char *buf,
+               size_t buflen, struct netent **result, int *h_errnop) {
+       static int (*getnetbyname_rp)(const char *name, struct netent *result_buf,
+                       char *buf, size_t buflen, struct netent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(getnetbyname_r, LIBC);
+
+       ret = getnetbyname_rp(name, result_buf, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pppdpp", voidp_to_uint64(name),
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+int getnetbyaddr_r(uint32_t net, int type, struct netent *result_buf, char *buf,
+               size_t buflen, struct netent **result, int *h_errnop) {
+       static int (*getnetbyaddr_rp)(uint32_t net, int type,
+                       struct netent *result_buf, char *buf, size_t buflen,
+                       struct netent **result, int *h_errnop);
+
+       BEFORE_ORIGINAL_SOCK(getnetbyaddr_r, LIBC);
+
+       ret = getnetbyaddr_rp(net, type, result_buf, buf, buflen, result, h_errnop);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ddppdpp", net, type,
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result),
+                                voidp_to_uint64(h_errnop));
+
+       return ret;
+}
+
+struct protoent *getprotoent(void) {
+       static struct protoent * (*getprotoentp)(void);
+       struct protoent * pret;
+
+       BEFORE_ORIGINAL_SOCK(getprotoent, LIBC);
+
+       pret = getprotoentp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+
+       return pret;
+}
+
+struct protoent *getprotobyname(const char *name) {
+       static struct protoent * (*getprotobynamep)(const char *name);
+       struct protoent * pret;
+
+       BEFORE_ORIGINAL_SOCK(getprotobyname, LIBC);
+
+       pret = getprotobynamep(name);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(name));
+
+       return pret;
+}
+
+struct protoent *getprotobynumber(int proto) {
+       static struct protoent * (*getprotobynumberp)(int proto);
+       struct protoent * pret;
+
+       BEFORE_ORIGINAL_SOCK(getprotobynumber, LIBC);
+
+       pret = getprotobynumberp(proto);
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", proto);
+
+       return pret;
+}
+
+void setprotoent(int stayopen) {
+       static void (*setprotoentp)(int stayopen);
+
+       BEFORE_ORIGINAL_SOCK(setprotoent, LIBC);
+
+       setprotoentp(stayopen);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "d", stayopen);
+}
+
+void endprotoent(void) {
+       static void (*endprotoentp)(void);
+
+       BEFORE_ORIGINAL_SOCK(endprotoent, LIBC);
+
+       endprotoentp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+}
+
+int getprotoent_r(struct protoent *result_buf, char *buf, size_t buflen,
+               struct protoent **result) {
+       static int (*getprotoent_rp)(struct protoent *result_buf, char *buf,
+                       size_t buflen, struct protoent **result);
+
+       BEFORE_ORIGINAL_SOCK(getprotoent_r, LIBC);
+
+       ret = getprotoent_rp(result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "ppdp", voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+int getprotobyname_r(const char *name, struct protoent *result_buf, char *buf,
+               size_t buflen, struct protoent **result) {
+       static int (*getprotobyname_rp)(const char *name,
+                       struct protoent *result_buf, char *buf, size_t buflen,
+                       struct protoent **result);
+
+       BEFORE_ORIGINAL_SOCK(getprotobyname_r, LIBC);
+
+       ret = getprotobyname_rp(name, result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "pppdp", voidp_to_uint64(name),
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+int getprotobynumber_r(int proto, struct protoent *result_buf, char *buf,
+               size_t buflen, struct protoent **result) {
+       static int (*getprotobynumber_rp)(int proto, struct protoent *result_buf,
+                       char *buf, size_t buflen, struct protoent **result);
+
+       BEFORE_ORIGINAL_SOCK(getprotobynumber_r, LIBC);
+
+       ret = getprotobynumber_rp(proto, result_buf, buf, buflen, result);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dppdp", proto,
+                                voidp_to_uint64(result_buf),
+                                voidp_to_uint64(buf), buflen,
+                                voidp_to_uint64(result));
+
+       return ret;
+}
+
+unsigned int if_nametoindex(__const char *__ifname) {
+       static unsigned int (*if_nametoindexp)(__const char *__ifname);
+       unsigned int uret;
+
+       BEFORE_ORIGINAL_SOCK(if_nametoindex, LIBC);
+
+       uret = if_nametoindexp(__ifname);
+
+       AFTER_ORIGINAL_LIBC_SOCK(uret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(__ifname));
+
+       return uret;
+}
+
+char *if_indextoname(unsigned int __ifindex, char *__ifname) {
+       static char * (*if_indextonamep)(unsigned int __ifindex, char *__ifname);
+       char * cret;
+
+       BEFORE_ORIGINAL_SOCK(if_indextoname, LIBC);
+
+       cret = if_indextonamep(__ifindex, __ifname);
+
+       AFTER_ORIGINAL_LIBC_SOCK(cret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "dp", __ifindex,
+                                voidp_to_uint64(__ifname));
+
+       return cret;
+}
+
+struct if_nameindex *if_nameindex(void) {
+       static struct if_nameindex * (*if_nameindexp)(void);
+       struct if_nameindex * pret;
+
+       BEFORE_ORIGINAL_NOFILTER(if_nameindex, LIBC);
+
+       pret = if_nameindexp();
+
+       AFTER_ORIGINAL_LIBC_SOCK(pret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                       info, "s", "");
+
+       return pret;
+}
+
+void if_freenameindex(struct if_nameindex *__ptr) {
+       static void (*if_freenameindexp)(struct if_nameindex *__ptr);
+
+       BEFORE_ORIGINAL_NOFILTER(if_freenameindex, LIBC);
+
+       if_freenameindexp(__ptr);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(__ptr));
+}
+
+int getifaddrs(struct ifaddrs **ifap) {
+       static int (*getifaddrsp)(struct ifaddrs **ifap);
+
+       BEFORE_ORIGINAL_NOFILTER(getifaddrs, LIBC);
+
+       ret = getifaddrsp(ifap);
+
+       AFTER_ORIGINAL_LIBC_SOCK('d', ret, OBJ_DUMMY, 0, SOCKET_API_OTHER,
+                                info, "p", voidp_to_uint64(ifap));
+
+       return ret;
+}
+
+void freeifaddrs(struct ifaddrs *ifa) {
+       static void (*freeifaddrsp)(struct ifaddrs *ifa);
+
+       BEFORE_ORIGINAL_NOFILTER(freeifaddrs, LIBC);
+
+       freeifaddrsp(ifa);
+
+       AFTER_ORIGINAL_LIBC_SOCK(NULL, OBJ_DUMMY, 0, SOCKET_API_OTHER, info,
+                                "p", voidp_to_uint64(ifa));
+}
+
+//To do
+
+uint16_t htobe16(uint16_t host_16bits)
+{
+       static uint16_t (*htobe16p)(uint16_t host_16bits);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htobe16, LIBC);
+
+       uret = htobe16p(host_16bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', (uint32_t)uret, 0, FD_API_OTHER, "d", host_16bits);
+
+       return uret;
+}
+
+uint16_t htole16(uint16_t host_16bits)
+{
+       static uint16_t (*htole16p)(uint16_t host_16bits);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htole16, LIBC);
+
+       uret = htole16p(host_16bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', (uint32_t)uret, 0, FD_API_OTHER, "d", host_16bits);
+
+       return uret;
+}
+
+uint16_t be16toh(uint16_t big_endian_16bits)
+{
+       static uint16_t (*be16tohp)(uint16_t big_endian_16bits);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(be16toh, LIBC);
+
+       uret = be16tohp(big_endian_16bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', (uint32_t)uret, 0, FD_API_OTHER,
+                       "d", big_endian_16bits);
+
+       return uret;
+}
+
+uint16_t le16toh(uint16_t little_endian_16bits)
+{
+       static uint16_t (*le16tohp)(uint16_t little_endian_16bits);
+       uint16_t uret;
+
+       BEFORE_ORIGINAL_SOCK(le16toh, LIBC);
+
+       uret = le16tohp(little_endian_16bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', (uint32_t)uret, 0, FD_API_OTHER,
+                       "d", little_endian_16bits);
+
+       return uret;
+}
+
+uint32_t htobe32(uint32_t host_32bits)
+{
+       static uint32_t (*htobe32p)(uint32_t host_32bits);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htobe32, LIBC);
+
+       uret = htobe32p(host_32bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', uret, 0, FD_API_OTHER,
+                       "d", host_32bits);
+
+       return uret;
+}
+
+uint32_t htole32(uint32_t host_32bits)
+{
+       static uint32_t (*htole32p)(uint32_t host_32bits);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htole32, LIBC);
+
+       uret = htole32p(host_32bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', uret, 0, FD_API_OTHER,
+                       "d", host_32bits);
+
+       return uret;
+}
+
+uint32_t be32toh(uint32_t big_endian_32bits)
+{
+       static uint32_t (*be32tohp)(uint32_t big_endian_32bits);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(be32toh, LIBC);
+
+       uret = be32tohp(big_endian_32bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', uret, 0, FD_API_OTHER,
+                       "d", big_endian_32bits);
+
+       return uret;
+}
+
+uint32_t le32toh(uint32_t little_endian_32bits)
+{
+       static uint32_t (*le32tohp)(uint32_t little_endian_32bits);
+       uint32_t uret;
+
+       BEFORE_ORIGINAL_SOCK(le32toh, LIBC);
+
+       uret = le32tohp(little_endian_32bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', uret, 0, FD_API_OTHER,
+                       "d", little_endian_32bits);
+
+       return uret;
+}
+
+uint64_t htobe64(uint64_t host_64bits)
+{
+       static uint64_t (*htobe64p)(uint64_t host_64bits);
+       uint64_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htobe64, LIBC);
+
+       uret = htobe64p(host_64bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('x', uret, 0, FD_API_OTHER,
+                       "d", host_64bits);
+
+       return uret;
+}
+
+uint64_t htole64(uint64_t host_64bits)
+{
+       static uint64_t (*htole64p)(uint64_t host_64bits);
+       uint64_t uret;
+
+       BEFORE_ORIGINAL_SOCK(htole64, LIBC);
+
+       uret = htole64p(host_64bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('x', uret, 0, FD_API_OTHER,
+                       "d", host_64bits);
+
+       return uret;
+}
+
+uint64_t be64toh(uint64_t big_endian_64bits)
+{
+       static uint64_t (*be64tohp)(uint64_t big_endian_64bits);
+       uint64_t uret;
+
+       BEFORE_ORIGINAL_SOCK(be64toh, LIBC);
+
+       uret = be64tohp(big_endian_64bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('x', uret, 0, FD_API_OTHER,
+                       "d", big_endian_64bits);
+
+       return uret;
+}
+
+uint64_t le64toh(uint64_t little_endian_64bits)
+{
+       static uint64_t (*le64tohp)(uint64_t little_endian_64bits);
+       uint64_t uret;
+
+       BEFORE_ORIGINAL_SOCK(le64toh, LIBC);
+
+       uret = le64tohp(little_endian_64bits);
+
+       AFTER_ORIGINAL_NOSOCK_RET('x', uret, 0, FD_API_OTHER,
+                       "d", little_endian_64bits);
+
+       return uret;
+}
+
+struct in_addr inet_makeaddr(int net, int host)
+{
+       static struct in_addr (*inet_makeaddrp)(int net, int host);
+       struct in_addr iret;
+
+       BEFORE_ORIGINAL_SOCK(inet_makeaddr, LIBC);
+
+       iret = inet_makeaddrp(net,host);
+
+       AFTER_ORIGINAL_NOSOCK_RET('d', iret.s_addr, 0, FD_API_OTHER,
+                       "dd", net, host);
+
+       return iret;
+}
+
+#endif
diff --git a/probe_third/libdaemon.c b/probe_third/libdaemon.c
new file mode 100644 (file)
index 0000000..8778cad
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <string.h>    // for memcpy
+#include <errno.h>     // for errno
+
+#include "daprobe.h"
+#include "dahelper.h"
+
+#include "real_functions.h"
+
+int daemon_close_allv(const int except_fds[])
+{
+       static int (*daemon_close_allvp)(const int except_fds[]);
+       int i, saved_errno, ret;
+       int* fds;
+
+       GET_REAL_FUNCP(daemon_close_allv, LIBDAEMON, daemon_close_allvp);
+
+       probeBlockStart();
+       // get number of fds
+       for(i = 0; ; i++)
+       {
+               if(except_fds[i] == -1)
+                       break;
+       }
+
+       // allocate memory for new except fds
+       fds = (int*)real_malloc((i + 2) * sizeof(int));
+
+       // copy fds
+       if(fds)
+       {
+               if(i > 0)
+                       memcpy(fds, except_fds, i * sizeof(int));
+               fds[i] = gTraceInfo.socket.daemonSock;
+               fds[i + 1] = -1;
+       }
+       else
+       {
+               // do nothing
+       }
+       probeBlockEnd();
+
+       // call original function
+       if(fds)
+       {
+               ret = daemon_close_allvp(fds);
+       }
+       else
+       {
+               ret = daemon_close_allvp(except_fds);
+       }
+
+       probeBlockStart();
+       saved_errno = errno;
+       free(fds);
+       errno = saved_errno;
+       probeBlockEnd();
+
+       return ret;
+}
+
diff --git a/probe_thread/da_sync.h b/probe_thread/da_sync.h
new file mode 100644 (file)
index 0000000..c7a283a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_SYNC_H__
+#define __DA_SYNC_H__
+
+#include "daprobe.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+int real_pthread_mutex_lock(pthread_mutex_t *mutex);
+int real_pthread_mutex_unlock(pthread_mutex_t *mutex);
+int real_pthread_setcancelstate(int state, int *oldstate);
+
+#define BEFORE_ORIGINAL_SYNC(FUNCNAME, LIBNAME)        \
+       DECLARE_VARIABLE_STANDARD;                                              \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
+       PRE_PROBEBLOCK()
+
+#define AFTER_PACK_ORIGINAL_SYNC(API_ID, RTYPE, RVAL, SYNCVAL, SYNCTYPE, APITYPE, INPUTFORMAT, ...)    \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                                   \
+       PREPARE_LOCAL_BUF();                                                                            \
+       PACK_COMMON_BEGIN(MSG_PROBE_SYNC, API_ID, INPUTFORMAT, __VA_ARGS__);                            \
+       PACK_COMMON_END(RTYPE, RVAL, errno, blockresult);                                               \
+       PACK_SYNC(SYNCVAL, SYNCTYPE, APITYPE);                                                          \
+       FLUSH_LOCAL_BUF();                                                                              \
+       POST_PACK_PROBEBLOCK_END()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __DA_SYNC_H__
+
diff --git a/probe_thread/da_thread.h b/probe_thread/da_thread.h
new file mode 100644 (file)
index 0000000..4347b3d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_THREAD_H__
+#define __DA_THREAD_H__
+
+#include "daprobe.h"
+
+#define BEFORE_ORIGINAL_THREAD(FUNCNAME, LIBNAME)      \
+       DECLARE_VARIABLE_STANDARD;                                              \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
+       PRE_PROBEBLOCK()
+
+#define AFTER_PACK_ORIGINAL_THREAD(API_ID, RTYPE, RVAL, THREADVAL, APITYPE, INPUTFORMAT, ...)  \
+       POST_PACK_PROBEBLOCK_BEGIN();                                                           \
+       PREPARE_LOCAL_BUF();                                                                    \
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD, API_ID, INPUTFORMAT, __VA_ARGS__);                  \
+       PACK_COMMON_END(RTYPE, RVAL, errno, blockresult);                                       \
+       PACK_THREAD(THREADVAL, THREAD_PTHREAD, APITYPE, THREAD_CLASS_BLANK);                    \
+       FLUSH_LOCAL_BUF();                                                                      \
+       POST_PACK_PROBEBLOCK_END()
+
+#endif // __DA_THREAD_H__
+
diff --git a/probe_thread/libdasync.c b/probe_thread/libdasync.c
new file mode 100644 (file)
index 0000000..2823b2c
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ *  DA probe
+ *
+ * Copyright 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <pthread.h>
+#include <time.h>
+#include <errno.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dahelper.h"
+#include "da_sync.h"
+
+#include "binproto.h"
+#include "real_functions.h"
+
+static enum DaOptions _sopt = OPT_THREAD;
+
+int pthread_mutex_init(pthread_mutex_t *mutex,
+               const pthread_mutexattr_t *attr) {
+       static int (*pthread_mutex_initp)(pthread_mutex_t *mutex,
+                       const pthread_mutexattr_t *attr);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutex_init, LIBPTHREAD);
+
+       ret = pthread_mutex_initp(mutex, attr);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutex_init,
+                                'd', ret, mutex, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(mutex), voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_destroyp)(pthread_mutex_t *mutex);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutex_destroy, LIBPTHREAD);
+
+       ret = pthread_mutex_destroyp(mutex);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutex_destroy,
+                                'd', ret, mutex, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "p", voidp_to_uint64(mutex));
+
+       return ret;
+}
+
+int real_pthread_mutex_lock(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_lockp)(pthread_mutex_t *mutex);
+
+       GET_REAL_FUNC(pthread_mutex_lock, LIBPTHREAD);
+
+       return pthread_mutex_lockp(mutex);
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_lockp)(pthread_mutex_t *mutex);
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_mutex_lock, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                         API_ID_pthread_mutex_lock,
+                         "p", voidp_to_uint64(mutex));
+       PACK_COMMON_END('d', 0, 0, blockresult);
+       PACK_SYNC(mutex, SYNC_PTHREAD_MUTEX, SYNC_API_ACQUIRE_WAIT_START);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+       ret = pthread_mutex_lockp(mutex);
+
+       // send WAIT_END log
+       newerrno = errno;
+       if(postBlockBegin(blockresult)) {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                                 API_ID_pthread_mutex_lock,
+                                 "p", voidp_to_uint64(mutex));
+               PACK_COMMON_END('d', ret, errno, blockresult);
+               PACK_SYNC(mutex, SYNC_PTHREAD_MUTEX, SYNC_API_ACQUIRE_WAIT_END);
+               FLUSH_LOCAL_BUF();
+
+               postBlockEnd();
+       }
+        errno = (newerrno != 0) ? newerrno : olderrno;
+
+       return ret;
+}
+
+int pthread_mutex_timedlock(pthread_mutex_t *mutex,
+               const struct timespec *abs_timeout) {
+       static int (*pthread_mutex_timedlockp)(pthread_mutex_t *mutex,
+                       const struct timespec *abs_timeout);
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_mutex_timedlock, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                         API_ID_pthread_mutex_timedlock,
+                         "pp", voidp_to_uint64(mutex),
+                         voidp_to_uint64(abs_timeout));
+       PACK_COMMON_END('d', 0, 0, blockresult);
+       PACK_SYNC(mutex, SYNC_PTHREAD_MUTEX, SYNC_API_ACQUIRE_WAIT_START);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+       ret = pthread_mutex_timedlockp(mutex, abs_timeout);
+
+       // send WAIT_END log
+       newerrno = errno;
+       if(postBlockBegin(blockresult)) {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                                 API_ID_pthread_mutex_timedlock,
+                                 "pp", voidp_to_uint64(mutex),
+                                 voidp_to_uint64(abs_timeout));
+               PACK_COMMON_END('d', ret, errno, blockresult);
+               PACK_SYNC(mutex, SYNC_PTHREAD_MUTEX, SYNC_API_ACQUIRE_WAIT_END);
+               FLUSH_LOCAL_BUF();
+
+               postBlockEnd();
+       }
+
+    errno = (newerrno != 0) ? newerrno : olderrno;
+
+       return ret;
+}
+
+int pthread_mutex_trylock(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_trylockp)(pthread_mutex_t *mutex);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutex_trylock, LIBPTHREAD);
+
+       ret = pthread_mutex_trylockp(mutex);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutex_trylock,
+                                'd', ret, mutex, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_TRY_ACQUIRE, "p",
+                                voidp_to_uint64(mutex));
+
+       return ret;
+}
+
+int real_pthread_mutex_unlock(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_unlockp)(pthread_mutex_t *mutex);
+
+       GET_REAL_FUNC(pthread_mutex_unlock, LIBPTHREAD);
+
+       return pthread_mutex_unlockp(mutex);
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex) {
+       static int (*pthread_mutex_unlockp)(pthread_mutex_t *mutex);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutex_unlock, LIBPTHREAD);
+
+       ret = pthread_mutex_unlockp(mutex);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutex_unlock,
+                                'd', ret, mutex, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_RELEASE, "p",
+                                voidp_to_uint64(mutex));
+
+       return ret;
+}
+
+int pthread_mutexattr_init(pthread_mutexattr_t *attr) {
+       static int (*pthread_mutexattr_initp)(pthread_mutexattr_t *attr);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_init, LIBPTHREAD);
+
+       ret = pthread_mutexattr_initp(attr);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_init,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "p",
+                                voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) {
+       static int (*pthread_mutexattr_destroyp)(pthread_mutexattr_t *attr);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_destroy, LIBPTHREAD);
+
+       ret = pthread_mutexattr_destroyp(attr);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_destroy,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "p",
+                                voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr,
+               int *prioceiling) {
+       static int (*pthread_mutexattr_getprioceilingp)(
+                       const pthread_mutexattr_t *attr, int *prioceiling);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_getprioceiling, LIBPTHREAD);
+
+       ret = pthread_mutexattr_getprioceilingp(attr, prioceiling);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_getprioceiling,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(attr),
+                                voidp_to_uint64(prioceiling));
+
+       return ret;
+}
+
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr,
+               int prioceiling) {
+       static int (*pthread_mutexattr_setprioceilingp)(
+                       pthread_mutexattr_t *attr, int prioceiling);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_setprioceiling, LIBPTHREAD);
+
+       ret = pthread_mutexattr_setprioceilingp(attr, prioceiling);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_setprioceiling,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pd", voidp_to_uint64(attr),
+                                prioceiling);
+
+       return ret;
+}
+
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
+               int *protocol) {
+       static int (*pthread_mutexattr_getprotocolp)(
+                       const pthread_mutexattr_t *attr, int *protocol);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_getprotocol, LIBPTHREAD);
+
+       ret = pthread_mutexattr_getprotocolp(attr, protocol);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_getprotocol,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(attr),
+                                voidp_to_uint64(protocol));
+
+       return ret;
+}
+
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr,
+               int protocol) {
+       static int (*pthread_mutexattr_setprotocolp)(
+                       pthread_mutexattr_t *attr, int protocol);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_setprotocol, LIBPTHREAD);
+
+       ret = pthread_mutexattr_setprotocolp(attr, protocol);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_setprotocol,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pd", voidp_to_uint64(attr),
+                                protocol);
+
+       return ret;
+}
+
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,
+               int *pshared) {
+       static int (*pthread_mutexattr_getpsharedp)(
+                       const pthread_mutexattr_t *attr, int *pshared);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_getpshared, LIBPTHREAD);
+
+       ret = pthread_mutexattr_getpsharedp(attr, pshared);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_getpshared,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(attr),
+                                voidp_to_uint64(pshared));
+
+       return ret;
+}
+
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,
+               int pshared) {
+       static int (*pthread_mutexattr_setpsharedp)(
+                       pthread_mutexattr_t *attr, int pshared);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_setpshared, LIBPTHREAD);
+
+       ret = pthread_mutexattr_setpsharedp(attr, pshared);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_setpshared,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pd", voidp_to_uint64(attr),
+                                pshared);
+
+       return ret;
+}
+
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) {
+       static int (*pthread_mutexattr_gettypep)(
+                       const pthread_mutexattr_t *attr, int *type);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_gettype, LIBPTHREAD);
+
+       ret = pthread_mutexattr_gettypep(attr, type);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_gettype,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(attr),
+                                voidp_to_uint64(type));
+
+       return ret;
+}
+
+int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) {
+       static int (*pthread_mutexattr_settypep)(
+                       pthread_mutexattr_t *attr, int type);
+
+       BEFORE_ORIGINAL_SYNC(pthread_mutexattr_settype, LIBPTHREAD);
+
+       ret = pthread_mutexattr_settypep(attr, type);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_mutexattr_settype,
+                                'd', ret, 0, SYNC_PTHREAD_MUTEX,
+                                SYNC_API_OTHER, "pd",
+                                voidp_to_uint64(attr),
+                                type);
+
+       return ret;
+}
+
+/*
+int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex,
+               int *prioceiling);
+int pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
+               int prioceiling, int *old_ceiling);
+*/
+
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
+       static int (*pthread_cond_initp)(pthread_cond_t *cond,
+                       const pthread_condattr_t *attr);
+
+       BEFORE_ORIGINAL_SYNC(pthread_cond_init, LIBPTHREAD);
+
+       ret = pthread_cond_initp(cond, attr);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_cond_init,
+                                'd', ret, cond, SYNC_PTHREAD_COND_VARIABLE,
+                                SYNC_API_OTHER, "pp",
+                                voidp_to_uint64(cond),
+                                voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond) {
+       static int (*pthread_cond_destroyp)(pthread_cond_t *cond);
+
+       BEFORE_ORIGINAL_SYNC(pthread_cond_destroy, LIBPTHREAD);
+
+       ret = pthread_cond_destroyp(cond);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_cond_destroy,
+                                'd', ret, cond, SYNC_PTHREAD_COND_VARIABLE,
+                                SYNC_API_OTHER, "p",
+                                voidp_to_uint64(cond));
+
+       return ret;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
+       static int (*pthread_cond_waitp)(pthread_cond_t *cond,
+                       pthread_mutex_t *mutex);
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_cond_wait, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+       // send WAIT_START log
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                         API_ID_pthread_cond_wait,
+                         "pp",
+                         voidp_to_uint64(cond),
+                         voidp_to_uint64(mutex));
+       PACK_COMMON_END('d', 0, 0, blockresult);
+       PACK_SYNC(cond, SYNC_PTHREAD_COND_VARIABLE, SYNC_API_COND_WAIT_START);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+       ret = pthread_cond_waitp(cond, mutex);
+
+       // send WAIT_END log
+       newerrno = errno;
+       if(postBlockBegin(blockresult)) {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                                 API_ID_pthread_cond_wait,
+                                 "pp",
+                                 voidp_to_uint64(cond),
+                                 voidp_to_uint64(mutex));
+               PACK_COMMON_END('d', ret, errno, blockresult);
+               PACK_SYNC(cond, SYNC_PTHREAD_COND_VARIABLE, SYNC_API_COND_WAIT_END);
+               FLUSH_LOCAL_BUF();
+
+               postBlockEnd();
+       }
+    errno = (newerrno != 0) ? newerrno : olderrno;
+
+       return ret;
+}
+
+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+               const struct timespec *abstime) {
+       static int (*pthread_cond_timedwaitp)(pthread_cond_t *cond,
+                               pthread_mutex_t *mutex, const struct timespec *abstime);
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_cond_timedwait, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+       // send WAIT_START log
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                         API_ID_pthread_cond_timedwait,
+                         "ppp",
+                         voidp_to_uint64(cond),
+                         voidp_to_uint64(mutex),
+                         voidp_to_uint64(abstime));
+       PACK_COMMON_END('d', 0, 0, blockresult);
+       PACK_SYNC(cond, SYNC_PTHREAD_COND_VARIABLE, SYNC_API_COND_WAIT_START);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+       ret = pthread_cond_timedwaitp(cond, mutex, abstime);
+
+       // send WAIT_END log
+       newerrno = errno;
+       if(postBlockBegin(blockresult)) {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_SYNC,
+                                 API_ID_pthread_cond_timedwait,
+                                 "ppp",
+                                 voidp_to_uint64(cond),
+                                 voidp_to_uint64(mutex),
+                                 voidp_to_uint64(abstime));
+               PACK_COMMON_END('d', ret, errno, blockresult);
+               PACK_SYNC(cond, SYNC_PTHREAD_COND_VARIABLE, SYNC_API_COND_WAIT_END);
+               FLUSH_LOCAL_BUF();
+
+               postBlockEnd();
+       }
+
+    errno = (newerrno != 0) ? newerrno : olderrno;
+
+       return ret;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond) {
+       static int (*pthread_cond_signalp)(pthread_cond_t *cond);
+
+       BEFORE_ORIGINAL_SYNC(pthread_cond_signal, LIBPTHREAD);
+
+       ret = pthread_cond_signalp(cond);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_cond_signal,
+                                'd', ret, cond, SYNC_PTHREAD_COND_VARIABLE,
+                                SYNC_API_NOTIFY, "p", voidp_to_uint64(cond));
+
+       return ret;
+}
+
+int pthread_cond_broadcast(pthread_cond_t *cond) {
+       static int (*pthread_cond_broadcastp)(pthread_cond_t *cond);
+
+       BEFORE_ORIGINAL_SYNC(pthread_cond_broadcast, LIBPTHREAD);
+
+       ret = pthread_cond_broadcastp(cond);
+
+       AFTER_PACK_ORIGINAL_SYNC(API_ID_pthread_cond_broadcast,
+                                'd', ret, cond, SYNC_PTHREAD_COND_VARIABLE,
+                                SYNC_API_NOTIFY_ALL, "p", voidp_to_uint64(cond));
+
+       return ret;
+}
diff --git a/probe_thread/libdathread.c b/probe_thread/libdathread.c
new file mode 100644 (file)
index 0000000..018a23a
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ *  DA probe
+ *
+ * Copyright 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <pthread.h>
+#include <errno.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dahelper.h"
+#include "da_thread.h"
+#include "da_sync.h"
+#include "binproto.h"
+#include "real_functions.h"
+
+typedef struct thread_routine_call_t {
+       void *(*thread_routine)(void *);
+       void *argument;
+} thread_routine_call;
+
+static enum DaOptions _sopt = OPT_THREAD;
+
+// called when pthread_exit, pthread_cancel is called
+void _da_cleanup_handler(void *data)
+{
+       pthread_t pSelf;
+
+       probeInfo_t     probeInfo;
+
+       // unlock socket mutex to prevent deadlock
+       // in case of cancellation happened while log sending
+       real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex));
+
+       PRE_UNCONDITIONAL_BLOCK_BEGIN();
+
+       pSelf = pthread_self();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                         API_ID__da_cleanup_handler,
+                         "p", voidp_to_uint64(data));
+       PACK_COMMON_END('v', 0, 0, 1);
+       PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP, THREAD_CLASS_BLANK);
+       FLUSH_LOCAL_BUF();
+
+       PRE_UNCONDITIONAL_BLOCK_END();
+
+       return;
+}
+
+void *_da_ThreadProc(void *params)
+{
+       void *ret;
+       thread_routine_call *ptrc;
+       ptrc = (thread_routine_call *) params;
+       pthread_t pSelf;
+       int old_state;
+       int new_state = PTHREAD_CANCEL_DISABLE;
+
+       probeInfo_t     probeInfo;
+
+       // disable cancellation to prevent deadlock
+       real_pthread_setcancelstate(new_state, &old_state);
+
+       PRE_UNCONDITIONAL_BLOCK_BEGIN();
+
+       pSelf = pthread_self();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                         API_ID__da_ThreadProc,
+                         "p", voidp_to_uint64(params));
+       PACK_COMMON_END('p', 0, 0, 1);
+       PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_START, THREAD_CLASS_BLANK);
+       FLUSH_LOCAL_BUF();
+
+       PRE_UNCONDITIONAL_BLOCK_END();
+
+       // restore cancellation state
+       real_pthread_setcancelstate(old_state, NULL);
+
+       pthread_cleanup_push(_da_cleanup_handler, NULL);
+       // call user-defined thread routine
+       ret = ptrc->thread_routine(ptrc->argument);
+       pthread_cleanup_pop(0);
+
+       // disable cancellation to prevent deadlock
+       real_pthread_setcancelstate(new_state, &old_state);
+
+       PRE_UNCONDITIONAL_BLOCK_BEGIN();
+
+       pSelf = pthread_self();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                         API_ID__da_ThreadProc,
+                         "p", voidp_to_uint64(params));
+       PACK_COMMON_END('p', ret, 0, 1);
+       PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP, THREAD_CLASS_BLANK);
+       FLUSH_LOCAL_BUF();
+
+       PRE_UNCONDITIONAL_BLOCK_END();
+
+       free(ptrc);
+       return ret;
+}
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+               void *(*start_routine) (void*), void *arg)
+{
+       static int (*pthread_createp)(pthread_t *thread,
+                       const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
+
+       BEFORE_ORIGINAL_THREAD(pthread_create, LIBPTHREAD);
+
+       if(blockresult)
+       {
+               probeBlockStart();
+               thread_routine_call *ptrc =
+                       (thread_routine_call *) real_malloc(sizeof(thread_routine_call));
+               ptrc->thread_routine = start_routine;
+               ptrc->argument = arg;
+               probeBlockEnd();
+
+               ret = pthread_createp(thread, attr, _da_ThreadProc, (void *) ptrc);
+       }
+       else // when pthread_create is called inside probe so (ex. custom chart, sampling thread)
+       {
+               ret = pthread_createp(thread, attr, start_routine, arg);
+       }
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_create,
+                                  'd', ret, *thread, THREAD_API_START,
+                                  "pppp",
+                                  voidp_to_uint64(thread),
+                                  voidp_to_uint64(attr),
+                                  voidp_to_uint64(start_routine),
+                                  voidp_to_uint64(arg));
+
+       return ret;
+}
+
+int pthread_join(pthread_t thread, void **retval)
+{
+       static int (*pthread_joinp)(pthread_t thread, void **retval);
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_join, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                         API_ID_pthread_join,
+                         "xp", (uint64_t)(thread), voidp_to_uint64(retval));
+       PACK_COMMON_END('d', 0, 0, blockresult);
+       PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_START, THREAD_CLASS_BLANK);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+       ret = pthread_joinp(thread, retval);
+
+       // send WAIT_END log
+       newerrno = errno;
+       if(postBlockBegin(blockresult)) {
+               setProbePoint(&probeInfo);
+
+               PREPARE_LOCAL_BUF();
+               PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                                 API_ID_pthread_join,
+                                 "xp",
+                                 (uint64_t)(thread),
+                                 voidp_to_uint64(retval));
+               PACK_COMMON_END('d', ret, errno, blockresult);
+               PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_END, THREAD_CLASS_BLANK);
+               FLUSH_LOCAL_BUF();
+
+               postBlockEnd();
+       }
+
+    errno = (newerrno != 0) ? newerrno : olderrno;
+
+       return ret;
+}
+
+void pthread_exit(void *retval)
+{
+       pthread_t pSelf;
+       static void (*pthread_exitp)(void *retval) __attribute__((noreturn));
+
+       DECLARE_VARIABLE_STANDARD;
+       GET_REAL_FUNC(pthread_exit, LIBPTHREAD);
+
+       PRE_PROBEBLOCK_BEGIN();
+       newerrno = 0;
+       pSelf = pthread_self();
+
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
+                         API_ID_pthread_exit,
+                         "p", voidp_to_uint64(retval));
+       PACK_COMMON_END('v', 0, 0, blockresult);
+       PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_EXIT, THREAD_CLASS_BLANK);
+       FLUSH_LOCAL_BUF();
+
+       PRE_PROBEBLOCK_END();
+
+    errno = (newerrno != 0) ? newerrno : olderrno;
+
+       pthread_exitp(retval);
+
+}
+
+int pthread_cancel(pthread_t thread)
+{
+       static int (*pthread_cancelp)(pthread_t thread);
+
+       BEFORE_ORIGINAL_THREAD(pthread_cancel, LIBPTHREAD);
+
+       ret = pthread_cancelp(thread);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_cancel,
+                                  'd', ret, thread, THREAD_API_STOP, "x",
+                                  (uint64_t)(thread));
+
+       return ret;
+}
+
+int pthread_detach(pthread_t thread)
+{
+       static int (*pthread_detachp)(pthread_t thread);
+
+       BEFORE_ORIGINAL_THREAD(pthread_detach, LIBPTHREAD);
+
+       ret = pthread_detachp(thread);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_detach,
+                                  'd', ret, thread, THREAD_API_OTHER, "x",
+                                  (uint64_t)(thread));
+
+       return ret;
+}
+
+pthread_t pthread_self(void)
+{
+       pthread_t ret_pthr;
+       static pthread_t (*pthread_selfp)(void);
+
+       BEFORE_ORIGINAL_THREAD(pthread_self, LIBPTHREAD);
+
+       ret_pthr = pthread_selfp();
+
+       newerrno = errno;
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_self,
+                                  'p', ret_pthr, ret_pthr, THREAD_API_OTHER, "", 0);
+
+       return ret_pthr;
+}
+
+int pthread_equal(pthread_t t1, pthread_t t2)
+{
+       static int (*pthread_equalp)(pthread_t t1, pthread_t t2);
+
+       BEFORE_ORIGINAL_THREAD(pthread_equal, LIBPTHREAD);
+
+       ret = pthread_equalp(t1, t2);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_equal,
+                                  'd', ret, t1, THREAD_API_OTHER, "xx",
+                                  (uint64_t)(t1), (uint64_t)(t2));
+
+       return ret;
+}
+
+int real_pthread_setcancelstate(int state, int *oldstate)
+{
+       static int (*pthread_setcancelstatep)(int state, int *oldstate);
+
+       GET_REAL_FUNC(pthread_setcancelstate, LIBPTHREAD);
+
+       return pthread_setcancelstatep(state, oldstate);
+}
+
+int pthread_setcancelstate(int state, int *oldstate)
+{
+       pthread_t pSelf;
+       static int (*pthread_setcancelstatep)(int state, int *oldstate);
+
+       BEFORE_ORIGINAL_THREAD(pthread_setcancelstate, LIBPTHREAD);
+
+       pSelf = pthread_self();
+       ret = pthread_setcancelstatep(state, oldstate);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_setcancelstate,
+                                  'd', ret, pSelf, THREAD_API_OTHER,
+                                  "dp", state, voidp_to_uint64(oldstate));
+
+       return ret;
+}
+
+int pthread_setcanceltype(int type, int *oldtype)
+{
+       pthread_t pSelf;
+       static int (*pthread_setcanceltypep)(int type, int *oldtype);
+
+       BEFORE_ORIGINAL_THREAD(pthread_setcanceltype, LIBPTHREAD);
+
+       pSelf = pthread_self();
+       ret = pthread_setcanceltypep(type, oldtype);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_setcanceltype,
+                                  'd', ret, pSelf, THREAD_API_OTHER,
+                                  "dp", type, voidp_to_uint64(oldtype));
+
+       return ret;
+}
+
+int pthread_attr_init(pthread_attr_t *attr)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_initp)(pthread_attr_t *attr);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_init, LIBPTHREAD);
+
+       ret = pthread_attr_initp(attr);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_init,
+                                  'd', ret, thread, THREAD_API_OTHER, "p",
+                                  voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_attr_destroy(pthread_attr_t *attr)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_destroyp)(pthread_attr_t *attr);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_destroy, LIBPTHREAD);
+
+       ret = pthread_attr_destroyp(attr);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_destroy,
+                                  'd', ret, thread, THREAD_API_OTHER, "p",
+                                  voidp_to_uint64(attr));
+
+       return ret;
+}
+
+int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getdetachstatep)(const pthread_attr_t *attr,
+                       int *detachstate);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getdetachstate, LIBPTHREAD);
+
+       ret = pthread_attr_getdetachstatep(attr, detachstate);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getdetachstate,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(detachstate));
+
+       return ret;
+}
+
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setdetachstatep)(pthread_attr_t *attr,
+                       int detachstate);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setdetachstate, LIBPTHREAD);
+
+       ret = pthread_attr_setdetachstatep(attr, detachstate);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setdetachstate,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pd", voidp_to_uint64(attr),
+                                  detachstate);
+
+       return ret;
+}
+
+int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getstacksizep)(const pthread_attr_t *attr,
+                       size_t *stacksize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getstacksize, LIBPTHREAD);
+
+       ret = pthread_attr_getstacksizep(attr, stacksize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getstacksize,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(stacksize));
+
+       return ret;
+}
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setstacksizep)(pthread_attr_t *attr,
+                       size_t stacksize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setstacksize, LIBPTHREAD);
+
+       ret = pthread_attr_setstacksizep(attr, stacksize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setstacksize,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "px", voidp_to_uint64(attr),
+                                  (uint64_t)(stacksize));
+
+       return ret;
+}
+
+#if 0
+/* TODO FIXME
+ * this code is disabled because it can not be compiled with some versions
+ * of libpthread. Next error occures:
+ *   multiple definition of `pthread_attr_getstackaddr'
+ *   multiple definition of `pthread_attr_setstackaddr'
+ * Possible because of deprecated attribute
+ *
+ * happens on pthread-2.18 (target TV emul), not happens on pthread-2.13
+ */
+int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getstackaddrp)(const pthread_attr_t *attr,
+                       void **stackaddr);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getstackaddr, LIBPTHREAD);
+
+       ret = pthread_attr_getstackaddrp(attr, stackaddr);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getstackaddr,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(stackaddr));
+
+       return ret;
+}
+
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setstackaddrp)(pthread_attr_t *attr,
+                       void *stackaddr);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setstackaddr, LIBPTHREAD);
+
+       ret = pthread_attr_setstackaddrp(attr, stackaddr);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setstackaddr,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp",
+                                  voidp_to_uint64(attr),
+                                  voidp_to_uint64(stackaddr));
+
+       return ret;
+}
+#endif
+
+int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getinheritschedp)(const pthread_attr_t *attr,
+                       int *inheritsched);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getinheritsched, LIBPTHREAD);
+
+       ret = pthread_attr_getinheritschedp(attr, inheritsched);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getinheritsched,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(inheritsched));
+
+       return ret;
+}
+
+int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setinheritschedp)(pthread_attr_t *attr,
+                       int inheritsched);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setinheritsched, LIBPTHREAD);
+
+       ret = pthread_attr_setinheritschedp(attr, inheritsched);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setinheritsched,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pd", voidp_to_uint64(attr),
+                                  inheritsched);
+
+       return ret;
+}
+
+int pthread_attr_getschedparam(const pthread_attr_t *attr,
+               struct sched_param *param)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getschedparamp)(const pthread_attr_t *attr,
+                       struct sched_param *param);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getschedparam, LIBPTHREAD);
+
+       ret = pthread_attr_getschedparamp(attr, param);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getschedparam,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(param));
+
+       return ret;
+}
+
+int pthread_attr_setschedparam(pthread_attr_t *attr,
+               const struct sched_param *param)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setschedparamp)(pthread_attr_t *attr,
+                       const struct sched_param *param);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setschedparam, LIBPTHREAD);
+
+       ret = pthread_attr_setschedparamp(attr, param);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setschedparam,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp",
+                                  voidp_to_uint64(attr),
+                                  voidp_to_uint64(param));
+
+       return ret;
+}
+
+int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getschedpolicyp)(const pthread_attr_t *attr,
+                       int *policy);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getschedpolicy, LIBPTHREAD);
+
+       ret = pthread_attr_getschedpolicyp(attr, policy);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getschedpolicy,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(policy));
+
+       return ret;
+}
+
+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setschedpolicyp)(pthread_attr_t *attr,
+                       int policy);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setschedpolicy, LIBPTHREAD);
+
+       ret = pthread_attr_setschedpolicyp(attr, policy);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setschedpolicy,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pd", voidp_to_uint64(attr),
+                                  policy);
+
+       return ret;
+}
+
+int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getguardsizep)(const pthread_attr_t *attr,
+                       size_t *guardsize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getguardsize, LIBPTHREAD);
+
+       ret = pthread_attr_getguardsizep(attr, guardsize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getguardsize,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(guardsize));
+
+       return ret;
+}
+
+int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setguardsizep)(pthread_attr_t *attr,
+                       size_t guardsize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setguardsize, LIBPTHREAD);
+
+       ret = pthread_attr_setguardsizep(attr, guardsize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setguardsize,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "px", voidp_to_uint64(attr),
+                                  (uint64_t)(guardsize));
+
+       return ret;
+}
+
+int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getscopep)(const pthread_attr_t *attr,
+                       int *contentionscope);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getscope, LIBPTHREAD);
+
+       ret = pthread_attr_getscopep(attr, contentionscope);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getscope,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(contentionscope));
+
+       return ret;
+}
+
+int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setscopep)(pthread_attr_t *attr,
+                       int contentionscope);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setscope, LIBPTHREAD);
+
+       ret = pthread_attr_setscopep(attr, contentionscope);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setscope,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "pd", voidp_to_uint64(attr), contentionscope);
+
+       return ret;
+}
+
+int pthread_attr_getstack(const pthread_attr_t *attr,
+               void **stackaddr, size_t *stacksize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_getstackp)(const pthread_attr_t *attr,
+                       void **stackaddr, size_t *stacksize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_getstack, LIBPTHREAD);
+
+       ret = pthread_attr_getstackp(attr, stackaddr, stacksize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_getstack,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "ppp", voidp_to_uint64(attr),
+                                  voidp_to_uint64(stackaddr),
+                                  voidp_to_uint64(stacksize));
+
+       return ret;
+}
+
+int pthread_attr_setstack(pthread_attr_t *attr,
+               void *stackaddr, size_t stacksize)
+{
+       pthread_t thread = 0;
+       static int (*pthread_attr_setstackp)(pthread_attr_t *attr,
+                       void *stackaddr, size_t stacksize);
+
+       BEFORE_ORIGINAL_THREAD(pthread_attr_setstack, LIBPTHREAD);
+
+       ret = pthread_attr_setstackp(attr, stackaddr, stacksize);
+
+       AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setstack,
+                                  'd', ret, thread, THREAD_API_OTHER,
+                                  "ppx", voidp_to_uint64(attr),
+                                  voidp_to_uint64(stackaddr),
+                                  (uint64_t)(stacksize));
+
+       return ret;
+}
+
+/*
+void pthread_testcancel(void);
+
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
+int pthread_key_delete(pthread_key_t key);
+
+int pthread_getconcurrency(void);
+int pthread_setconcurrency(int new_level);
+int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id);
+int pthread_getschedparam(pthread_t thread, int *policy,
+               struct sched_param *param);
+int pthread_setschedparam(pthread_t thread, int policy,
+               const struct sched_param *param);
+int pthread_setschedprio(pthread_t thread, int prio);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_setspecific(pthread_key_t key, const void *value);
+
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
+
+int pthread_atfork(void (*prepare)(void), void (*parent)(void),
+               void (*child)(void));
+*/
+
diff --git a/probe_ui/capi_capture.c b/probe_ui/capi_capture.c
new file mode 100755 (executable)
index 0000000..2c713ee
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <Evas.h>
+#include <Elementary.h>
+
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "da_ui.h"
+
+Evas_Object *elm_win_add(Evas_Object *parent, const char* name, Elm_Win_Type type)
+{
+       static Evas_Object * (*elm_win_addp)(Evas_Object *parent, const char* name, Elm_Win_Type type);
+
+       BEFORE_ORIGINAL_SNAPSHOT(elm_win_add, LIBELEMENTARY);
+       ret = elm_win_addp(parent, name, type);
+       AFTER_ORIGINAL_SNAPSHOT(ret);
+
+       return ret;
+}
+
+Evas_Object *elm_controlbar_add (Evas_Object *parent)
+{
+       static Evas_Object * (*elm_controlbar_addp)(Evas_Object *parent);
+
+       BEFORE_ORIGINAL_SNAPSHOT(elm_controlbar_add, LIBELEMENTARY);
+       ret = elm_controlbar_addp(parent);
+       AFTER_ORIGINAL_SNAPSHOT(ret);
+
+       return ret;
+}
+
+Evas_Object *elm_naviframe_add(Evas_Object *parent)
+{
+       static Evas_Object * (*elm_naviframe_addp)(Evas_Object *parent);
+
+       BEFORE_ORIGINAL_SNAPSHOT(elm_naviframe_add, LIBELEMENTARY);
+       ret = elm_naviframe_addp(parent);
+       AFTER_ORIGINAL_SNAPSHOT(ret);
+
+       return ret;
+}
+
+Evas_Object *elm_pager_add(Evas_Object *parent)
+{
+       static Evas_Object * (*elm_pager_addp)(Evas_Object *parent);
+
+       BEFORE_ORIGINAL_SNAPSHOT(elm_pager_add, LIBELEMENTARY);
+       ret = elm_pager_addp(parent);
+       AFTER_ORIGINAL_SNAPSHOT(ret);
+
+       return ret;
+}
diff --git a/probe_ui/da_ui.h b/probe_ui/da_ui.h
new file mode 100755 (executable)
index 0000000..79d9ef1
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __DA_SNAPSHOT_H__
+#define __DA_SNAPSHOT_H__
+
+#include "daprobe.h"
+#include "dahelper.h"
+
+/********************************************************************
+ * SNAPSHOT PROBE MACRO
+ *
+ * log format
+ *             SeqNumber`,ApiName`,Time`,Pid`,Tid`,InputParm`,Return`,PCAddr`,Error`,Size`,FUNCTYPE`,\n
+ *             callstack_start`,callstack`,callstack_end
+ *
+ * FUNCTYPE
+ *             SNAPSHOT_API_TYPE_PAGER,
+ *             SNAPSHOT_API_TYPE_CONTROLBAR,
+ *             SNAPSHOT_API_TYPE_NAVIFRAME,
+ *             SNAPSHOT_API_TYPE_OTHER
+ *
+ **********************************************************************/
+
+#define BEFORE_ORIGINAL_SNAPSHOT(FUNCNAME, LIBNAME)            \
+       Evas_Object* ret;                                                                       \
+       GET_REAL_FUNC(FUNCNAME, LIBNAME)
+
+#define AFTER_ORIGINAL_SNAPSHOT(EVASOBJECT)                                                    \
+       do {                                                                                                                    \
+               probeBlockStart();                                                                                      \
+               evas_event_callback_add(evas_object_evas_get(EVASOBJECT),       \
+                       EVAS_CALLBACK_RENDER_FLUSH_POST,                                                \
+                       _cb_render_post, NULL);                                                                 \
+               probeBlockEnd();                                                                                        \
+       } while(0)
+
+#endif // __DA_SNAPSHOT_H__
diff --git a/probe_ui/tizen_frameani.h b/probe_ui/tizen_frameani.h
new file mode 100644 (file)
index 0000000..07beba6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@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:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __TIZEN_FRAMEANI_H__
+#define __TIZEN_FRAMEANI_H__
+
+#include <FUi.h>
+
+using namespace Tizen::Ui::Animations;
+using namespace Tizen::Ui::Controls;
+
+class DAFrameAnimationEventListener :
+               public IFrameAnimatorEventListener
+{
+public:
+       DAFrameAnimationEventListener();
+       virtual ~DAFrameAnimationEventListener();
+
+       virtual void    OnFormTransitionAnimationFinished (FrameAnimator &source, Frame &frame, Form &form1, Form &form2);
+       virtual void    OnFormTransitionAnimationStarted (FrameAnimator &source, Frame &frame, Form &form1, Form &form2);
+       virtual void    OnFormTransitionAnimationStopped (FrameAnimator &source, Frame &frame, Form &form1, Form &form2);
+
+       static DAFrameAnimationEventListener& GetInstance(void);
+
+private:
+       static DAFrameAnimationEventListener rInstance;
+};
+
+
+#endif // __TIZEN_FRAMEANI_H__
+
diff --git a/probe_userfunc/libdauserfunc.c b/probe_userfunc/libdauserfunc.c
new file mode 100755 (executable)
index 0000000..a918929
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@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:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <time.h>
+#include <execinfo.h>
+#include <unistd.h>
+#include <pthread.h>
+#include "daprobe.h"
+#include "probeinfo.h"
+#include "dautil.h"
+#include "dahelper.h"
+#include "da_sync.h"
+
+//#define USING_BACKTRACE
+
+#define RETURN_ADDRESS(nr) \
+       __builtin_extract_return_addr (__builtin_return_address(nr))
+
+#if defined(__i386__)
+#define GET_PC(ctx)    ((void *) ctx.eip)
+#elif defined (__arm__)
+#define GET_PC(ctx)    ((void *) (ctx)->uc_mcontext.arm_pc)
+#endif
+
+#define USERFUNCTION_MAX_DEPTH                         32
+#define PROFIL_LOG_SENDING_INTERVAL_USEC       100000 // 100 milliseconds
+#define SAMPLE_MAX_IN_INTERVAL                         50
+#define        PROFIL_TRIM_STACK_DEPTH                         2
+
+#define IS_FULL_SAMPLE_ARRAY   ((((sample_write_index + 1) % SAMPLE_MAX_IN_INTERVAL) == sample_read_index) ? 1 : 0)
+#define IS_EMPTY_SAMPLE_ARRAY  ((sample_write_index == sample_read_index) ? 1 : 0)
+
+#define CUSTOM_CB_FUNC_NAME            "_chart_timerThread"
+
+void *custom_cb_addr = (void*)-1;
+
+int profil_option = 0;
+volatile int profil_turned_on = 0;
+volatile int profil_thread_on = 0;
+u_long low_pc, high_pc;
+
+typedef struct elapsed_time_t {
+       struct timeval startTime;
+       struct timeval endTime;
+       struct timeval resultTime;
+       void *self;
+} elapsed_time;
+
+__thread elapsed_time elapsed_time_array[USERFUNCTION_MAX_DEPTH];
+__thread int elapsed_time_index;
+
+pthread_t profil_log_thread;
+pthread_mutex_t profil_log_mutex;
+
+typedef struct sample_info_t {
+       unsigned long time;
+       void *pc;
+       size_t bt_size;
+       void *bt_array[MAX_STACK_DEPTH];
+} sample_info;
+
+int sample_seq = 0;
+int sample_read_index = 0;
+int sample_write_index = 0;
+sample_info sample_info_array[SAMPLE_MAX_IN_INTERVAL];
+
+int __profile_frequency();
+
+/*
+static unsigned long long getElapsedTime(struct timeval eTime)
+{
+       return ((unsigned long long) eTime.tv_sec) * 1000000 + eTime.tv_usec;
+}
+*/
+
+static unsigned long getTime()
+{
+       struct timespec ts;
+       clock_gettime(CLOCK_REALTIME, &ts);
+
+       return (unsigned long)(ts.tv_sec * 10000 + (ts.tv_nsec/100000));
+}
+
+/* TODO refactor close equal code in ifdef/else section */
+/* TODO remove code. it seems unused. */
+#ifdef USING_BACKTRACE
+int profil_backtrace_symbols(log_t *log, int bufsize, int index)
+{
+       char **strings = NULL;
+       size_t i;
+       int initsize;
+       int curlen;
+       int stringlen;
+
+       if(log == NULL)
+               return 0;
+
+       initsize = log->length;
+       curlen = initsize;
+       log->data[curlen] = '\0';       // is this necessary ?
+       if(likely(sample_info_array[index].bt_size > PROFIL_TRIM_STACK_DEPTH))
+       {
+               strings = BACKTRACE_SYMBOLS(sample_info_array[index].bt_array + PROFIL_TRIM_STACK_DEPTH,
+                               sample_info_array[index].bt_size - PROFIL_TRIM_STACK_DEPTH);
+
+               if(likely(strings != NULL))
+               {
+                       for(i = PROFIL_TRIM_STACK_DEPTH; i < sample_info_array[index].bt_size; i++)
+                       {
+                               stringlen = strlen(strings[i - PROFIL_TRIM_STACK_DEPTH]) + 14;
+                               if(curlen + stringlen >= bufsize + initsize)
+                                       break;
+
+                               curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,%s`,",
+                                               (unsigned int)(sample_info_array[index].bt_array[i]),
+                                               strings[i - PROFIL_TRIM_STACK_DEPTH]);
+                       }
+                       curlen -= 2;
+                       log->data[curlen] = '\0';
+                       log->length = curlen;
+                       free(strings);
+               }
+               else
+               {
+                       for(i = PROFIL_TRIM_STACK_DEPTH; i < sample_info_array[index].bt_size; i++)
+                       {
+                               stringlen = 23;
+                               if(curlen + stringlen >= bufsize + initsize)
+                                       break;
+
+                               curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,(unknown)`,",
+                                               (unsigned int)(sample_info_array[index].bt_array[i]));
+                       }
+                       curlen -= 2;
+                       log->data[curlen] = '\0';
+                       log->length = curlen;
+               }
+               return (int)(sample_info_array[index].bt_size - PROFIL_TRIM_STACK_DEPTH);
+       }
+       else
+       {
+               return 0;
+       }
+}
+#else
+int profil_backtrace_symbols(log_t *log, int bufsize, int index)
+{
+       char **strings = NULL;
+       size_t i;
+       int initsize;
+       int curlen;
+       int stringlen;
+
+       if(log == NULL)
+               return 0;
+
+       initsize = log->length;
+       curlen = initsize;
+       log->data[curlen] = '\0';       // is this necessary ?
+       strings = BACKTRACE_SYMBOLS(sample_info_array[index].bt_array,
+                       sample_info_array[index].bt_size);
+
+       if(likely(strings != NULL))
+       {
+               for(i = 0; i < sample_info_array[index].bt_size; i++)
+               {
+                       stringlen = strlen(strings[i]) + 14;
+                       if(curlen + stringlen >= bufsize + initsize)
+                               break;
+
+                       curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,%s`,",
+                                       (unsigned int)(sample_info_array[index].bt_array[i]),
+                                       strings[i]);
+               }
+               curlen -= 2;
+               log->data[curlen] = '\0';
+               log->length = curlen;
+               free(strings);
+       }
+       else
+       {
+               for(i = 0; i < sample_info_array[index].bt_size; i++)
+               {
+                       stringlen = 23;
+                       if(curlen + stringlen >= bufsize + initsize)
+                               break;
+
+                       curlen += snprintf(log->data + curlen, bufsize - curlen, "%010u`,(unknown)`,",
+                                       (unsigned int)(sample_info_array[index].bt_array[i]));
+               }
+               curlen -= 2;
+               log->data[curlen] = '\0';
+               log->length = curlen;
+       }
+       return (int)(sample_info_array[index].bt_size);
+}
+#endif
+
+void *profil_log_func(void __unused * data)
+{
+       probeBlockStart();
+
+       sigset_t profsigmask;
+       sigemptyset(&profsigmask);
+       sigaddset(&profsigmask, SIGPROF);
+       pthread_sigmask(SIG_BLOCK, &profsigmask, NULL);
+
+       while(profil_thread_on)
+       {
+               while(!IS_EMPTY_SAMPLE_ARRAY)
+               {
+                       sample_read_index = (sample_read_index + 1) % SAMPLE_MAX_IN_INTERVAL;
+               }
+               usleep(PROFIL_LOG_SENDING_INTERVAL_USEC);
+       }
+       probeBlockEnd();
+
+       return NULL;
+}
+
+void __cyg_profile_func_enter(void *this, void *callsite)
+{
+       probeInfo_t probeInfo;
+
+       sigset_t profsigmask, oldsigmask;
+       sigemptyset(&profsigmask);
+       sigaddset(&profsigmask, SIGPROF);
+       pthread_sigmask(SIG_BLOCK, &profsigmask, &oldsigmask);
+
+       probeBlockStart();
+       do {
+               // remove custom chart callback function
+               if(gTraceInfo.custom_chart_callback_count > 0)
+               {
+                       if(custom_cb_addr == (void*)-1)
+                       {
+                               char **strings = BACKTRACE_SYMBOLS(&callsite, 1);
+                               if(likely(strings != NULL))
+                               {
+                                       if(strstr(strings[0], CUSTOM_CB_FUNC_NAME) != NULL)
+                                       {
+                                               custom_cb_addr = callsite;
+                                               free(strings);
+                                               break;
+                                       }
+                                       free(strings);
+                               }
+                       }
+                       else
+                       {
+                               if(callsite == custom_cb_addr)
+                                       break;
+                       }
+               }
+
+               setProbePoint(&probeInfo);
+
+               gettimeofday(&(elapsed_time_array[elapsed_time_index].startTime), NULL);
+               elapsed_time_array[elapsed_time_index].self = this;
+               elapsed_time_index++;
+
+       } while(0);
+       probeBlockEnd();
+
+       pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
+       return;
+}
+
+void __cyg_profile_func_exit(void *this, void *callsite)
+{
+       probeInfo_t probeInfo;
+
+       sigset_t profsigmask, oldsigmask;
+       sigemptyset(&profsigmask);
+       sigaddset(&profsigmask, SIGPROF);
+       pthread_sigmask(SIG_BLOCK, &profsigmask, &oldsigmask);
+
+       probeBlockStart();
+       do {
+               // remove custom chart callback function
+               if(gTraceInfo.custom_chart_callback_count > 0)
+               {
+                       if(custom_cb_addr == (void*)-1)
+                       {
+                               char **strings = BACKTRACE_SYMBOLS(&callsite, 1);
+                               if(likely(strings != NULL))
+                               {
+                                       if(strstr(strings[0], CUSTOM_CB_FUNC_NAME) != NULL)
+                                       {
+                                               custom_cb_addr = callsite;
+                                               free(strings);
+                                               break;
+                                       }
+                                       free(strings);
+                               }
+                       }
+                       else
+                       {
+                               if(callsite == custom_cb_addr)
+                                       break;
+                       }
+               }
+
+               elapsed_time_index--;
+
+               if(this != elapsed_time_array[elapsed_time_index].self)
+               { // this should never happen
+                       ;// function exit: enter/exit function matching failed!!
+               }
+
+               gettimeofday(&(elapsed_time_array[elapsed_time_index].endTime), NULL);
+               timersub(&(elapsed_time_array[elapsed_time_index].endTime),
+                               &(elapsed_time_array[elapsed_time_index].startTime),
+                               &(elapsed_time_array[elapsed_time_index].resultTime));
+
+               setProbePoint(&probeInfo);
+       } while(0);
+       probeBlockEnd();
+
+       pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
+       return;
+}
+
+#if defined(__i386__)
+void mcount(void)
+{
+       return;
+}
+
+#elif defined(__arm__)
+void mcount_internal(u_long __unused frompc, u_long __unused selfpc)
+{
+       return;
+}
+
+void __attribute__((__naked__)) __gnu_mcount_nc(void)
+{
+       asm(
+                       "push {r0, r1, r2, r3, lr}\n\t"
+                       "bic r1, lr, #1\n\t"
+                       "ldr r0, [sp, #20]\n\t"
+                       "bl mcount_internal\n\t"
+                       "pop {r0, r1, r2, r3, ip, lr}\n\t"
+                       "bx ip");
+}
+#endif
+
+static inline void profil_count(void *pc)
+{
+#if defined(__arm__)
+       /* This is a hack to prevent profil_count function from being called
+          inside of __gnu_mcount_nc. DO NOT put any other function between
+          __gnu_mcount_nc and profil_count. */
+       if((pc >= (void*)(&profil_count - 0x18)) && (pc <= (void*)(&profil_count)))
+               return;
+#endif
+       if(gProbeBlockCount != 0)
+               return;
+
+       probeBlockStart();
+
+       real_pthread_mutex_lock(&profil_log_mutex);
+       do {
+               if(IS_FULL_SAMPLE_ARRAY)
+               {       // when this happens, array size should be increased
+                       // profil log: sample info array is full
+                       break;
+               }
+               sample_info_array[sample_write_index].time = getTime();
+               sample_info_array[sample_write_index].pc = pc;
+#ifdef USING_BACKTRACE
+               sample_info_array[sample_write_index].bt_size
+                       = backtrace(sample_info_array[sample_write_index].bt_array, MAX_STACK_DEPTH);
+//#if defined(__i386__)
+// restore frame clobbered by signal handler
+               sample_info_array[sample_write_index].bt_array[2] = pc;
+//#endif
+#else
+               sample_info_array[sample_write_index].bt_array[0] = pc;
+               {
+                       int i;
+                       for(i = 0; i < elapsed_time_index; i++)
+                       {
+                               sample_info_array[sample_write_index].bt_array[i + 1]
+                                       = elapsed_time_array[i].self;
+                       }
+                       sample_info_array[sample_write_index].bt_size = elapsed_time_index + 1;
+               }
+#endif
+               sample_write_index = (sample_write_index + 1) % SAMPLE_MAX_IN_INTERVAL;
+       } while(0);
+       real_pthread_mutex_unlock(&profil_log_mutex);
+
+       probeBlockEnd();
+}
+
+#if defined(__i386__)
+static void profil_counter(int __unused signo, const struct sigcontext scp)
+{
+       profil_count((void *) GET_PC(scp));
+
+       /* This is a hack to prevent the compiler from implementing the
+          above function call as a sibcall. The sibcall would overwrite
+          the signal context */
+       asm volatile("");
+}
+#elif defined(__arm__)
+static void profil_counter(int __unused signr, siginfo_t __unused * si,
+                          struct ucontext *uctx)
+{
+       profil_count((void *) GET_PC(uctx));
+
+       /* This is a hack to prevent the compiler from implementing the
+          above function call as a sibcall. The sibcall would overwrite
+          the signal context */
+       asm volatile("");
+}
+#endif
+
+#if 0
+// this function can cause floating point exception.
+int __profile_frequency(void)
+{
+       /*
+        * Discover the tick frequency of the machine if something goes wrong,
+        * we return 0, an impossible hertz.
+        */
+       struct itimerval tim;
+
+       tim.it_interval.tv_sec = 0;
+       tim.it_interval.tv_usec = 1;
+       tim.it_value.tv_sec = 0;
+       tim.it_value.tv_usec = 0;
+       setitimer(ITIMER_REAL, &tim, 0);
+       setitimer(ITIMER_REAL, 0, &tim);
+       if (tim.it_interval.tv_usec < 2)
+               return 0;
+       return (1000000 / tim.it_interval.tv_usec);
+}
+#endif
+
+int __profil(int mode)
+{
+       struct sigaction act;
+       struct itimerval timer;
+
+       static struct sigaction oact;
+       static struct itimerval otimer;
+
+       if(profil_thread_on != 1)
+       {
+               profil_option = mode;
+               return 0;
+       }
+
+       if(mode == 0)
+       {
+               if(profil_turned_on == 0)
+               {
+                       return 0;
+               }
+
+               if(setitimer(ITIMER_PROF, &otimer, NULL) < 0)
+                       return -1;
+               profil_turned_on = 0;
+               return sigaction(SIGPROF, &oact, NULL);
+       }
+
+       if(profil_turned_on == 1)
+       {
+               if(setitimer(ITIMER_PROF, &otimer, NULL) < 0
+                               || sigaction(SIGPROF, &oact, NULL) < 0)
+               {
+                       return -1;
+               }
+       }
+       profil_turned_on = 1;
+
+       act.sa_handler = (sighandler_t) &profil_counter;
+#if defined(__i386__)
+       act.sa_flags = SA_RESTART;
+#elif defined(__arm__)
+       act.sa_flags = SA_RESTART | SA_SIGINFO;
+#endif
+       sigfillset(&act.sa_mask);
+       if(sigaction(SIGPROF, &act, &oact) < 0)
+               return -1;
+
+       timer.it_value.tv_sec = 0;
+       timer.it_value.tv_usec = 1000000 / __profile_frequency();
+       timer.it_interval = timer.it_value;
+       return setitimer(ITIMER_PROF, &timer, &otimer);
+}
+
+void __monstartup(u_long lowpc, u_long highpc)
+{
+       low_pc = lowpc;
+       high_pc = highpc;
+
+       pthread_mutex_init(&profil_log_mutex, NULL);
+       probeBlockStart();
+       profil_thread_on = 1;
+       __profil(profil_option);
+       if(pthread_create(&profil_log_thread, NULL, &profil_log_func, NULL) < 0)
+       {
+               perror("Fail to create profil_log thread");
+       }
+       probeBlockEnd();
+       return;
+}
+
+void _mcleanup(void)
+{
+       __profil(0);
+       profil_thread_on = 0;
+       return;
+}
diff --git a/scripts/api_names.txt b/scripts/api_names.txt
new file mode 100644 (file)
index 0000000..e984497
--- /dev/null
@@ -0,0 +1,702 @@
+result UiApp::Execute(UiAppInstanceFactory pUiAppFactory, const IList* pArguments)
+void _AppImpl::OnTerminate(void* user_data)
+void _AppInfo::SetAppState(AppState appState)
+void _UiAppImpl::OnBackground(void)
+void _UiAppImpl::OnForeground(void)
+
+result Mutex::Create(void)
+result Mutex::Create(const Tizen::Base::String& name)
+result Mutex::Release(void)
+result Mutex::Acquire(void)
+result Mutex::TryToAcquire(void)
+result Semaphore::Create(int count)
+result Semaphore::Create(const Tizen::Base::String& name, int count)
+result Semaphore::Acquire(long timeout)
+result Semaphore::TryToAcquire(void)
+result Semaphore::Release(void)
+result Monitor::Construct(void)
+result Monitor::Enter(void)
+result Monitor::Exit(void)
+result Monitor::Wait(void)
+result Monitor::Notify(void)
+result Monitor::NotifyAll(void)
+
+void *_ThreadImpl::ThreadProc(void* params)
+result Thread::Sleep(long milliSeconds)
+result Thread::Yield(void)
+result Thread::Exit(int exitCode)
+result Thread::Construct(ThreadType threadType, long stackSize, ThreadPriority priority)
+result Thread::Construct(long stackSize, ThreadPriority priority)
+result Thread::Construct(const Tizen::Base::String &name, long stackSize, ThreadPriority priority)
+result Thread::Construct(const Tizen::Base::String &name, ThreadType threadType, long stackSize, ThreadPriority priority)
+result Thread::Construct(IRunnable &target, long stackSize, ThreadPriority priority)
+result Thread::Construct(const Tizen::Base::String &name, IRunnable &target, long stackSize, ThreadPriority priority)
+result Thread::GetExitCode(int &exitCode) const
+const Tizen::Base::String & Thread::GetName(void) const
+result Thread::Join(void)
+result Thread::Start(void)
+result Thread::Stop(void)
+result EventDrivenThread::Construct(long stackSize, ThreadPriority priority)
+result EventDrivenThread::Construct(const Tizen::Base::String &name, long stackSize, ThreadPriority priority)
+result EventDrivenThread::Quit()
+
+result File::Construct(const Tizen::Base::String& filePath, const Tizen::Base::String& openMode, bool createParentDirectories)
+result File::Construct(const Tizen::Base::String& filePath, const Tizen::Base::String& openMode)
+result File::Construct(const Tizen::Base::String& filePath, const char *pOpenMode)
+result File::Construct(const Tizen::Base::String& filePath, const char *pOpenMode, const Tizen::Base::ByteBuffer& secretKey)
+result File::Flush(void)
+Tizen::Base::String File::GetName(void) const
+result File::Read(Tizen::Base::String& buffer)
+result File::Read(Tizen::Base::ByteBuffer& buffer)
+int File::Read(void *buffer, int length)
+result File::Seek(FileSeekPosition position, long offset)
+int File::Tell(void) const
+result File::Truncate(int length)
+result File::Write(const void *buffer, int length)
+result File::Write(const Tizen::Base::ByteBuffer& buffer)
+result File::Write(const Tizen::Base::String& buffer)
+File::~File(void)
+
+result UiApp::AddFrame(const Tizen::Ui::Controls::Frame& frame)
+result UiApp::RemoveFrame(const Tizen::Ui::Controls::Frame &frame)
+void Control::SetName(const Tizen::Base::String &name)
+result Container::AddControl(const Control &control)
+result Container::RemoveControl(const Control &control)
+result Container::RemoveControl(int index)
+void Container::RemoveAllControls(void)
+
+_chart_timerThread
+da_mark
+da_create_chart
+da_create_series
+da_log
+
+malloc
+free
+realloc
+calloc
+
+void *operator new(std::size_t size) throw (std::bad_alloc)
+void *operator new[](std::size_t size) throw (std::bad_alloc)
+void operator delete(void *ptr) throw()
+void operator delete[](void *ptr) throw()
+void *operator new(std::size_t size, const std::nothrow_t& nothrow) throw()
+void *operator new[](std::size_t size, const std::nothrow_t& nothrow) throw()
+void operator delete(void *ptr, const std::nothrow_t& nothrow) throw()
+void operator delete[](void *ptr, const std::nothrow_t& nothrow) throw()
+
+memset
+memcmp
+memcpy
+
+_dalc_app_create
+_dalc_app_terminate
+_dalc_app_pause
+_dalc_app_resume
+_dalc_app_service
+
+_da_cleanup_handler
+_da_ThreadProc
+pthread_create
+pthread_join
+pthread_exit
+pthread_cancel
+pthread_detach
+pthread_self
+pthread_equal
+pthread_setcancelstate
+pthread_setcanceltype
+pthread_attr_init
+pthread_attr_destroy
+pthread_attr_getdetachstate
+pthread_attr_setdetachstate
+pthread_attr_getstacksize
+pthread_attr_setstacksize
+pthread_attr_getstackaddr
+pthread_attr_setstackaddr
+pthread_attr_getinheritsched
+pthread_attr_setinheritsched
+pthread_attr_getschedparam
+pthread_attr_setschedparam
+pthread_attr_getschedpolicy
+pthread_attr_setschedpolicy
+pthread_attr_getguardsize
+pthread_attr_setguardsize
+pthread_attr_getscope
+pthread_attr_setscope
+pthread_attr_getstack
+pthread_attr_setstack
+
+pthread_mutex_init
+pthread_mutex_destroy
+real_pthread_mutex_lock
+pthread_mutex_lock
+pthread_mutex_timedlock
+pthread_mutex_trylock
+real_pthread_mutex_unlock
+pthread_mutex_unlock
+pthread_mutexattr_init
+pthread_mutexattr_destroy
+pthread_mutexattr_getprioceiling
+pthread_mutexattr_setprioceiling
+pthread_mutexattr_getprotocol
+pthread_mutexattr_setprotocol
+pthread_mutexattr_getpshared
+pthread_mutexattr_setpshared
+pthread_mutexattr_gettype
+pthread_mutexattr_settype
+pthread_cond_init
+pthread_cond_destroy
+pthread_cond_wait
+pthread_cond_timedwait
+pthread_cond_signal
+pthread_cond_broadcast
+
+open
+openat
+creat
+close
+access
+faccessat
+lseek
+fsync
+fdatasync
+truncate
+ftruncate
+mkfifo
+mkfifoat
+mknod
+mknodat
+chown
+fchownat
+fchown
+lchown
+lockf
+chmod
+fchmodat
+fchmod
+pread
+read
+pwrite
+write
+readv
+rmdir
+fchdir
+chdir
+link
+linkat
+unlink
+unlinkat
+symlink
+symlinkat
+readlink
+readlinkat
+mkdir
+mkdirat
+closedir
+fdopendir
+opendir
+readdir
+readdir_r
+rewinddir
+seekdir
+telldir
+fcntl
+dup
+dup2
+fstatat
+lstat
+futimens
+utimensat
+utimes
+utime
+
+clearerr
+fclose
+fdopen
+feof
+ferror
+fflush
+fgetc
+fgetpos
+fileno
+fopen
+fprintf
+fputc
+fputs
+fread
+freopen
+fscanf
+fseek
+fsetpos
+fwrite
+getc
+getchar
+gets
+int
+perror
+printf
+putc
+putchar
+puts
+remove
+rename
+rewind
+scanf
+setbuf
+setbuffer
+setlinebuf
+setvbuf
+tmpnam
+ungetc
+vfprintf
+vfscanf
+
+void SceneManagerEventListener::OnSceneTransitionCompleted(const SceneId &previousSceneId, const SceneId &currentSceneId)
+
+void GestureEventListener::OnCustomGestureCanceled (TouchGestureDetector &gestureDetector)
+void GestureEventListener::OnCustomGestureChanged (TouchGestureDetector &gestureDetector)
+void GestureEventListener::OnCustomGestureFinished (TouchGestureDetector &gestureDetector)
+void GestureEventListener::OnCustomGestureStarted (TouchGestureDetector &gestureDetector)
+void GestureEventListener::OnFlickGestureCanceled (TouchFlickGestureDetector &gestureDetector)
+void GestureEventListener::OnFlickGestureDetected (TouchFlickGestureDetector &gestureDetector)
+void GestureEventListener::OnLongPressGestureCanceled (TouchLongPressGestureDetector &gestureDetector)
+void GestureEventListener::OnLongPressGestureDetected (TouchLongPressGestureDetector &gestureDetector)
+void GestureEventListener::OnPanningGestureCanceled (TouchPanningGestureDetector &gestureDetector)
+void GestureEventListener::OnPanningGestureChanged (TouchPanningGestureDetector &gestureDetector)
+void GestureEventListener::OnPanningGestureFinished (TouchPanningGestureDetector &gestureDetector)
+void GestureEventListener::OnPanningGestureStarted (TouchPanningGestureDetector &gestureDetector)
+void GestureEventListener::OnPinchGestureCanceled (TouchPinchGestureDetector &gestureDetector)
+void GestureEventListener::OnPinchGestureChanged (TouchPinchGestureDetector &gestureDetector)
+void GestureEventListener::OnPinchGestureFinished (TouchPinchGestureDetector &gestureDetector)
+void GestureEventListener::OnPinchGestureStarted (TouchPinchGestureDetector &gestureDetector)
+void GestureEventListener::OnRotationGestureCanceled (TouchRotationGestureDetector &gestureDetector)
+void GestureEventListener::OnRotationGestureChanged (TouchRotationGestureDetector &gestureDetector)
+void GestureEventListener::OnRotationGestureFinished (TouchRotationGestureDetector &gestureDetector)
+void GestureEventListener::OnRotationGestureStarted (TouchRotationGestureDetector &gestureDetector)
+void GestureEventListener::OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector)
+void GestureEventListener::OnTapGestureDetected (TouchTapGestureDetector &gestureDetector)
+
+on_orientation_changed
+
+ecore_event_evas_key_down
+ecore_event_evas_key_up
+ecore_event_evas_mouse_button_down
+ecore_event_evas_mouse_button_up
+ecore_event_evas_mouse_move
+
+elm_glview_gl_api_get
+
+evas_gl_free
+evas_gl_config_free
+evas_gl_surface_destroy
+evas_gl_context_destroy
+evas_gl_new
+evas_gl_config_new
+evas_gl_surface_create
+evas_gl_context_create
+evas_gl_make_current
+evas_gl_string_query
+evas_gl_proc_address_get
+evas_gl_native_surface_get
+evas_gl_api_get
+
+accept
+accept4
+bind
+gai_strerror
+hstrerror
+inet_ntop
+connect
+endhostent
+endnetent
+endprotoent
+endservent
+freeaddrinfo
+freeifaddrs
+gai_cancel
+gai_error
+gai_suspend
+getaddrinfo
+getaddrinfo_a
+getdomainname
+gethostbyaddr_r
+gethostbyname2_r
+gethostbyname_r
+gethostent_r
+gethostname
+getifaddrs
+getnameinfo
+getnetbyaddr_r
+getnetbyname_r
+getnetent_r
+getpeername
+getprotobyname_r
+getprotobynumber_r
+getprotoent_r
+getservbyname_r
+getservbyport_r
+getservent_r
+getsockname
+getsockopt
+herror
+gethostbyaddr
+gethostbyname
+gethostbyname2
+gethostent
+htonl
+htons
+if_freenameindex
+if_indextoname
+if_nameindex
+inet_makeaddr
+inet_addr
+inet_aton
+inet_lnaof
+inet_netof
+inet_network
+inet_ntoa
+inet_pton
+if_nametoindex
+le32toh
+le64toh
+listen
+getnetbyaddr
+getnetbyname
+getnetent
+ntohl
+ntohs
+getprotobyname
+getprotobynumber
+getprotoent
+pselect
+recv
+recvfrom
+recvmsg
+select
+send
+sendmsg
+sendto
+getservbyname
+getservbyport
+getservent
+setdomainname
+sethostent
+sethostname
+setnetent
+setprotoent
+setservent
+setsockopt
+shutdown
+socket
+socketpair
+sockatmark
+isfdtype
+poll
+ppoll
+epoll_create
+epoll_create1
+epoll_wait
+epoll_pwait
+epoll_ctl
+
+Thread* Thread::GetCurrentThread(void)
+
+tmpfile
+ftell
+
+captureScreen
+result Container::AddControl(Control* control)
+result Container::RemoveControl(Control* control)
+
+glActiveTexture
+glAttachShader
+glBindAttribLocation
+glBindBuffer
+glBindFramebuffer
+glBindRenderbuffer
+glBindTexture
+glBlendColor
+glBlendEquation
+glBlendEquationSeparate
+glBlendFunc
+glBlendFuncSeparate
+glBufferData
+glBufferSubData
+glClear
+glClearColor
+glClearDepthf
+glClearStencil
+glColorMask
+glCompileShader
+glCompressedTexImage2D
+glCompressedTexSubImage2D
+glCopyTexImage2D
+glCopyTexSubImage2D
+glCullFace
+glDeleteBuffers
+glDeleteFramebuffers
+glDeleteProgram
+glDeleteRenderbuffers
+glDeleteShader
+glDeleteTextures
+glDepthFunc
+glDepthMask
+glDepthRangef
+glDetachShader
+glDisable
+glDisableVertexAttribArray
+glDrawArrays
+glDrawElements
+glEnable
+glEnableVertexAttribArray
+glFinish
+glFlush
+glFramebufferRenderbuffer
+glFramebufferTexture2D
+glFrontFace
+glGenBuffers
+glGenFramebuffers
+glGenRenderbuffers
+glGenTextures
+glGenerateMipmap
+glGetBooleanv
+glGetFloatv
+glGetIntegerv
+glGetActiveAttrib
+glGetActiveUniform
+glGetAttachedShaders
+glGetAttribLocation
+glGetBufferParameteriv
+glGetFramebufferAttachmentParameteriv
+glGetProgramInfoLog
+glGetProgramiv
+glGetRenderbufferParameteriv
+glGetShaderInfoLog
+glGetShaderPrecisionFormat
+glGetShaderSource
+glGetShaderiv
+glGetTexParameterfv
+glGetTexParameteriv
+glGetUniformfv
+glGetUniformiv
+glGetVertexAttribfv
+glGetVertexAttribiv
+glGetVertexAttribPointerv
+glHint
+glLineWidth
+glLinkProgram
+glPixelStorei
+glPolygonOffset
+glReadPixels
+glReleaseShaderCompiler
+glRenderbufferStorage
+glSampleCoverage
+glScissor
+glShaderBinary
+glShaderSource
+glStencilFunc
+glStencilFuncSeparate
+glStencilMask
+glStencilMaskSeparate
+glStencilOp
+glStencilOpSeparate
+glTexImage2D
+glTexParameterf
+glTexParameterfv
+glTexParameteri
+glTexParameteriv
+glTexSubImage2D
+glUniform1f
+glUniform2f
+glUniform3f
+glUniform4f
+glUniform1fv
+glUniform2fv
+glUniform3fv
+glUniform4fv
+glUniform1i
+glUniform2i
+glUniform3i
+glUniform4i
+glUniform1iv
+glUniform2iv
+glUniform3iv
+glUniformMatrix2fv
+glUniformMatrix3fv
+glUniformMatrix4fv
+glUniform4iv
+glUseProgram
+glValidateProgram
+glVertexAttrib1f
+glVertexAttrib2f
+glVertexAttrib3f
+glVertexAttrib4f
+glVertexAttrib1fv
+glVertexAttrib2fv
+glVertexAttrib3fv
+glVertexAttrib4fv
+glVertexAttribPointer
+glViewport
+
+glCheckFramebufferStatus
+glCreateProgram
+glCreateShader
+glGetError
+glGetString
+glGetUniformLocation
+glIsBuffer
+glIsEnabled
+glIsFramebuffer
+glIsProgram
+glIsRenderbuffer
+glIsShader
+glIsTexture
+
+eglBindAPI
+eglBindTexImage
+eglChooseConfig
+eglCopyBuffers
+eglCreateContext
+eglCreatePbufferFromClientBuffer
+eglCreatePbufferSurface
+eglCreatePixmapSurface
+eglCreateWindowSurface
+eglDestroyContext
+eglDestroySurface
+eglGetConfigAttrib
+eglGetConfigs
+eglGetCurrentContext
+eglGetCurrentDisplay
+eglGetCurrentSurface
+eglGetDisplay
+eglGetError
+eglGetProcAddress
+eglInitialize
+eglMakeCurrent
+eglQueryAPI
+eglQueryContext
+eglQueryString
+eglQuerySurface
+eglReleaseTexImage
+eglReleaseThread
+eglSurfaceAttrib
+eglSwapBuffers
+eglSwapInterval
+eglTerminate
+eglUpdateBufferOSP
+eglWaitClient
+eglWaitGL
+eglWaitNative
+
+_SglBindAPI
+_SglBindTexImage
+_SglChooseConfig
+_SglCopyBuffers
+_SglCreateContext
+_SglCreatePbufferFromClientBuffer
+_SglCreatePbufferSurface
+_SglCreatePixmapSurface
+_SglCreateWindowSurface
+_SglDestroyContext
+_SglDestroySurface
+_SglGetConfigAttrib
+_SglGetConfigs
+_SglGetCurrentContext
+_SglGetCurrentDisplay
+_SglGetCurrentSurface
+_SglGetDisplay
+_SglGetError
+_SglGetProcAddress
+_SglInitialize
+_SglMakeCurrent
+_SglQueryAPI
+_SglQueryContext
+_SglQueryString
+_SglQuerySurface
+_SglReleaseTexImage
+_SglReleaseThread
+_SglSurfaceAttrib
+_SglSwapBuffers
+_SglSwapInterval
+_SglTerminate
+_SglUpdateBufferOSP
+_SglWaitClient
+_SglWaitGL
+_SglWaitNative
+
+
+_ZN5Tizen3Net7Sockets6Socket10SetSockOptENS1_17NetSocketOptLevelENS1_16NetSocketOptNameEi###Socket::SetSockOpt
+_ZN5Tizen3Net7Sockets6Socket10SetSockOptENS1_17NetSocketOptLevelENS1_16NetSocketOptNameERKNS1_12LingerOptionE###Socket::SetSockOpt
+_ZN5Tizen3Net7Sockets6Socket17AddSocketListenerERNS1_20ISocketEventListenerE###Socket::AddSocketListener
+_ZN5Tizen3Net7Sockets6Socket20RemoveSocketListenerERNS1_20ISocketEventListenerE###Socket::RemoveSocketListener
+_ZN5Tizen3Net7Sockets6Socket21AsyncSelectByListenerEm###Socket::AsyncSelectByListener
+_ZN5Tizen3Net7Sockets6Socket4BindERKNS0_11NetEndPointE###Socket::Bind
+_ZN5Tizen3Net7Sockets6Socket4SendERNS_4Base10ByteBufferE###Socket::Send
+_ZN5Tizen3Net7Sockets6Socket5CloseEv###Socket::Close
+_ZN5Tizen3Net7Sockets6Socket6ListenEi###Socket::Listen
+_ZN5Tizen3Net7Sockets6Socket6SendToEPviRKNS0_11NetEndPointERi###Socket::SendTo
+_ZN5Tizen3Net7Sockets6Socket6SendToERNS_4Base10ByteBufferERKNS0_11NetEndPointE###Socket::SendTo
+_ZN5Tizen3Net7Sockets6Socket7ConnectERKNS0_11NetEndPointE###Socket::Connect
+_ZN5Tizen3Net7Sockets6Socket9ConstructENS1_22NetSocketAddressFamilyENS1_13NetSocketTypeENS1_17NetSocketProtocolE###Socket::Construct
+_ZN5Tizen3Net7Sockets6Socket9ConstructERKNS0_13NetConnectionENS1_22NetSocketAddressFamilyENS1_13NetSocketTypeENS1_17NetSocketProtocolE###Socket::Construct
+_ZNK5Tizen3Net7Sockets6Socket10GetSockOptENS1_17NetSocketOptLevelENS1_16NetSocketOptNameERi###Socket::GetSockOpt
+_ZNK5Tizen3Net7Sockets6Socket10GetSockOptENS1_17NetSocketOptLevelENS1_16NetSocketOptNameERNS1_12LingerOptionE###Socket::GetSockOpt
+_ZNK5Tizen3Net7Sockets6Socket11ReceiveFromEPviRNS0_11NetEndPointERi###Socket::Receive/Socket::ReceiveFrom
+_ZNK5Tizen3Net7Sockets6Socket11ReceiveFromERNS_4Base10ByteBufferERNS0_11NetEndPointE###Socket::ReceiveFrom
+_ZNK5Tizen3Net7Sockets6Socket5IoctlENS1_17NetSocketIoctlCmdERm###Socket::Ioctl
+_ZNK5Tizen3Net7Sockets6Socket7AcceptNEv###Socket::AcceptN
+_ZNK5Tizen3Net7Sockets6Socket7ReceiveERNS_4Base10ByteBufferE###Socket::Receive
+_ZZN5Tizen3Net7Sockets6Socket4SendEPviRiE19__PRETTY_FUNCTION__###Socket::Send
+
+_ZN5Tizen3Net4Http11HttpRequest15SetCustomMethodERKNS_4Base6StringE###Http::HttpRequest::SetCustomMethod
+_ZN5Tizen3Net4Http11HttpRequest6SetUriERKNS_4Base6StringE###Http::HttpRequest::SetAcceptEncoding/SetUri/SetVersion/
+_ZN5Tizen3Net4Http11HttpRequest9ReadBodyNEv###Http::HttpRequest::ReadBodyN
+_ZN5Tizen3Net4Http11HttpRequest9SetCookieERKNS_4Base6StringE###Http::HttpRequest::SetCookie
+_ZN5Tizen3Net4Http11HttpRequest9SetEntityERNS1_11IHttpEntityE###Http::HttpRequest::SetEntity
+_ZN5Tizen3Net4Http11HttpRequest9SetMethodENS1_13NetHttpMethodE###Http::HttpRequest::SetMethod
+_ZN5Tizen3Net4Http11HttpRequest9WriteBodyERKNS_4Base10ByteBufferE###Http::HttpRequest::WriteBody
+_ZN5Tizen3Net4Http11HttpSession16CloseTransactionERNS1_15HttpTransactionE###Http::HttpSession::CloseTransaction
+_ZN5Tizen3Net4Http11HttpSession16OpenTransactionNERKNS1_18HttpAuthenticationE###Http::HttpSession::OpenTransactionN
+_ZN5Tizen3Net4Http11HttpSession16OpenTransactionNEv###Http::HttpSession::OpenTransactionN
+_ZN5Tizen3Net4Http11HttpSession17CancelTransactionERNS1_15HttpTransactionE###Http::HttpSession::CancelTransaction
+_ZN5Tizen3Net4Http11HttpSession20CloseAllTransactionsEv###Http::HttpSession::CloseAllTransactions
+_ZN5Tizen3Net4Http11HttpSession25SetAutoRedirectionEnabledEb###Http::HttpSession::SetAutoRedirectionEnabled
+_ZN5Tizen3Net4Http11HttpSession9ConstructENS1_18NetHttpSessionModeEPKNS_4Base6StringERS6_PKNS1_10HttpHeaderENS1_17NetHttpCookieFlagE###Http::HttpSession::Construct
+_ZN5Tizen3Net4Http11HttpSession9ConstructERKNS0_13NetConnectionENS1_18NetHttpSessionModeEPKNS_4Base6StringERS9_PKNS1_10HttpHeaderENS1_17NetHttpCookieFlagE###Http::HttpSession::Construct
+_ZN5Tizen3Net4Http12HttpResponse10SetVersionERKNS_4Base6StringE###Http::HttpResponse::SetVersion
+_ZN5Tizen3Net4Http12HttpResponse13SetStatusCodeENS1_17NetHttpStatusCodeE###Http::HttpResponse::SetStatusCode
+_ZN5Tizen3Net4Http12HttpResponse13SetStatusTextERKNS_4Base6StringE###Http::HttpResponse::SetStatusText
+_ZN5Tizen3Net4Http12HttpResponse17SetHttpStatusCodeEi###Http::HttpResponse::SetHttpStatusCode
+_ZN5Tizen3Net4Http12HttpResponse4ReadEiiRiS3_###Http::HttpResponse::Read
+_ZN5Tizen3Net4Http12HttpResponse9ReadBodyNEv###Http::HttpResponse::ReadBodyN
+_ZN5Tizen3Net4Http12HttpResponse9SetCookieEPNS1_10HttpHeaderE###Http::HttpResponse::SetCookie
+_ZN5Tizen3Net4Http12HttpResponse9WriteBodyERKNS_4Base10ByteBufferE###Http::HttpResponse::WriteBody
+_ZN5Tizen3Net4Http15HttpTransaction10SetTimeoutEi###Http::HttpTransaction::SetTimeout
+_ZN5Tizen3Net4Http15HttpTransaction13SetUserObjectEPKNS_4Base6ObjectE###Http::HttpTransaction::SetUserObject
+_ZN5Tizen3Net4Http15HttpTransaction20SetClientCertificateEi###Http::HttpTransaction::SetClientCertificate
+_ZN5Tizen3Net4Http15HttpTransaction23SetHttpProgressListenerERNS1_26IHttpProgressEventListenerE###Http::HttpTransaction::SetHttpProgressListener
+_ZN5Tizen3Net4Http15HttpTransaction26AddHttpTransactionListenerERNS1_29IHttpTransactionEventListenerE###Http::HttpTransaction::AddHttpTransactionListener
+_ZN5Tizen3Net4Http15HttpTransaction29EnableTransactionReadyToWriteEv###Http::HttpTransaction::EnableTransactionReadyToWrite
+_ZN5Tizen3Net4Http15HttpTransaction29RemoveHttpTransactionListenerERNS1_29IHttpTransactionEventListenerE###Http::HttpTransaction::RemoveHttpTransactionListener
+_ZN5Tizen3Net4Http15HttpTransaction32SetServerCertificateVerificationENS1_34NetHttpCertificateVerificationFlagE###Http::HttpTransaction::SetServerCertificateVerification
+_ZN5Tizen3Net4Http15HttpTransaction5PauseEv###Http::HttpTransaction::Pause
+_ZN5Tizen3Net4Http15HttpTransaction6ResumeEv###Http::HttpTransaction::Resume
+_ZN5Tizen3Net4Http15HttpTransaction6SubmitEv###Http::HttpTransaction::Submit
+_ZNK5Tizen3Net4Http10HttpHeader13GetRawHeaderNEv###Http::HttpHeader::GetRawHeaderN
+_ZNK5Tizen3Net4Http11HttpRequest17GetAcceptEncodingEv###Http::HttpRequest::GetAcceptEncoding
+_ZNK5Tizen3Net4Http11HttpRequest9GetCookieEv###Http::HttpRequest::GetCookie
+_ZNK5Tizen3Net4Http11HttpRequest9GetHeaderEv###Http::HttpRequest::GetHeader
+_ZNK5Tizen3Net4Http11HttpSession22GetMaxTransactionCountEv###Http::HttpSession::GetMaxTransactionCount
+_ZNK5Tizen3Net4Http11HttpSession23GetCookieStorageManagerEv###Http::HttpSession::GetCookieStorageManager
+_ZNK5Tizen3Net4Http11HttpSession24IsAutoRedirectionEnabledEv###Http::HttpSession::IsAutoRedirectionEnabled
+_ZNK5Tizen3Net4Http11HttpSession25GetActiveTransactionCountEv###Http::HttpSession::GetActiveTransactionCount
+_ZNK5Tizen3Net4Http12HttpResponse10GetCookiesEv###Http::HttpResponse::GetCookies
+_ZNK5Tizen3Net4Http12HttpResponse10GetVersionEv###Http::HttpResponse::GetVersion
+_ZNK5Tizen3Net4Http12HttpResponse13GetStatusTextEv###Http::HttpResponse::GetStatusText
+_ZNK5Tizen3Net4Http12HttpResponse17GetHttpStatusCodeEv###Http::HttpResponse::GetHttpStatusCode/GetStatusCode
+_ZNK5Tizen3Net4Http12HttpResponse9GetHeaderEv###Http::HttpResponse::GetHeader
+_ZNK5Tizen3Net4Http15HttpTransaction10GetRequestEv###Http::HttpTransaction::GetRequest/OpenAuthenticationInfoN
+_ZNK5Tizen3Net4Http15HttpTransaction11GetResponseEv###Http::HttpTransaction::GetResponse
+_ZNK5Tizen3Net4Http15HttpTransaction13GetUserObjectEv###Http::HttpTransaction::GetUserObject
+
diff --git a/scripts/gen_api_config.sh b/scripts/gen_api_config.sh
new file mode 100755 (executable)
index 0000000..16edfd7
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+function check_feature()
+{
+    FEATURE="$1"
+    SRC="$2"
+    OPTS="$3"
+
+    if gcc ${OPTS} -c ${SRC}; then
+        echo "#define ${FEATURE}"
+    else
+        echo "/* ${FEATURE} config not set */"
+    fi
+}
+
+NEW_CAPI_APPFW=$(check_feature PRIVATE_CAPI_APPFW \
+                               ./feature_tests/new_capi_appfw.cpp \
+                               -I/usr/include/appfw)
+
+API_CONFIG_DEFINES="
+${NEW_CAPI_APPFW}
+"
+
+cat << EOF
+/*
+ * Autogenerated header
+ */
+
+#ifndef __API_CONFIG__
+#define __API_CONFIG__
+${API_CONFIG_DEFINES}
+#endif /* __API_CONFIG__ */
+EOF
diff --git a/scripts/gen_api_id_mapping_header.awk b/scripts/gen_api_id_mapping_header.awk
new file mode 100644 (file)
index 0000000..315a302
--- /dev/null
@@ -0,0 +1,38 @@
+# This script generates api_id_mapping header from api list
+
+BEGIN {
+       print "/*"
+       print " * this file genereted by <swap-probe> project with cmd <make headers>"
+       print " */"
+       print
+       print "#ifndef __API_ID_MAP__"
+       print "#define __API_ID_MAP__"
+       print
+       print "#ifdef __cplusplus"
+       print "extern \"C\"{"
+       print "#endif"
+       print
+       api_id = 1
+       macro_prefix = "API_ID_"
+} {
+       if ( $0 == "" ) {
+               print
+       } else {
+               orig = $0
+               def = orig
+               split(def, splited, "###")
+               def = splited[1]
+               gsub(/[,:()*&~\[\] ]/, "_", def)
+               def = macro_prefix def
+               printf "#define %-135s %d // %s\n", def, api_id, orig
+               api_id = api_id + 1
+       }
+}
+END {
+       print
+       print "#ifdef __cplusplus"
+       print "}"
+       print "#endif"
+       print
+       print "#endif /* __API_ID_MAP__ */"
+}
diff --git a/scripts/gen_api_id_mapping_header_list.awk b/scripts/gen_api_id_mapping_header_list.awk
new file mode 100644 (file)
index 0000000..515eaed
--- /dev/null
@@ -0,0 +1,41 @@
+# This script generates api_id decode list header from api list
+#
+# use:
+# cat api_names.txt | awk -f ./gen_api_id_mapping_header_list.awk > sample.h
+# where api_names.txt is function name list file
+
+BEGIN {
+       api_id = 1
+       print "/*"
+       print " * this file genereted by <swap-probe> project with cmd <make headers>"
+       print " */"
+       print
+       print "#ifdef __cplusplus"
+       print "extern \"C\"{"
+       print "#endif"
+       print
+       print "const char *api_id_list[] = {"
+} {
+       if ( $0 == "" ) {
+               print
+       } else {
+               orig = $0
+               def = orig
+               split(def, splited, "###")
+               if (splited[2] != ""){
+                       def = splited[2]
+               }
+               def = def "\","
+               printf "\"%-135s//%d %s\n", def, api_id, orig
+               api_id = api_id + 1
+       }
+}
+
+END {
+       print
+       print "#ifdef __cplusplus"
+       print "}"
+       print "#endif"
+       print
+       print "};"
+}
diff --git a/scripts/gen_api_id_mapping_list.awk b/scripts/gen_api_id_mapping_list.awk
new file mode 100644 (file)
index 0000000..4310a6b
--- /dev/null
@@ -0,0 +1,15 @@
+# This script generates api_id_mapping text file from api list
+
+BEGIN {
+    api_id = 1
+} {
+       if ( $0 != "" ) {
+               api_name = $0
+               split(api_name, splited, "###")
+               if (splited[2] != ""){
+                       api_name = splited[2]
+               }
+               printf "%d %s\n", api_id, api_name
+               api_id = api_id + 1
+       }
+}
diff --git a/swap-probe.manifest b/swap-probe.manifest
new file mode 100644 (file)
index 0000000..86dbb26
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_" />
+    </request>
+</manifest>
diff --git a/test_preload.sh b/test_preload.sh
new file mode 100644 (file)
index 0000000..7984d56
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -e
+PROGRAMS+="$(echo org.tizen.{clock,email,setting,taskmgr,download-manager})"
+### Some of this is system services, that are not started via
+### launch_app
+#PROGRAMS+=$(cd /usr/apps && find|grep -E '\.exe$'|grep -v /_|sed -e "s#/bin/#.#g" -e "s#^\./##g"  -e "s#\.exe##g")
+echo $PROGRAMS
+for prog in $PROGRAMS
+do
+       printf $prog
+       launch_app $prog __AUL_SDK__ DYNAMIC_ANALYSIS
+       sleep 30
+       last_part=$(echo $prog|sed -e 's#\.#/#g'|xargs basename)
+       pid=$(ps aux|grep /apps/|grep $last_part)
+       if [[ -z "$pid" ]] ; then
+               echo "Error: $prog failed to start"
+       else
+               pid=$(echo $pid|python -c "print(raw_input().split()[1])")
+               echo "Pid = $pid"
+               if ! grep da_probe_osp.so /proc/$pid/maps ; then
+                       echo "Error: $prog is not preloaded."
+               fi
+               kill $pid
+       fi
+done
+