From: jk7744.park Date: Sat, 31 Jan 2015 07:42:52 +0000 (+0900) Subject: tizen 2.3 release X-Git-Tag: submit/tizen_2.3/20150202.063934^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7611e8fd642dd0749ef115f8a712bcec7bfa4995;p=framework%2Fsystem%2Fswap-probe.git tizen 2.3 release --- diff --git a/AUTHOR b/AUTHOR new file mode 100644 index 0000000..c1560be --- /dev/null +++ b/AUTHOR @@ -0,0 +1,9 @@ +Jaewon Lim +Woojin Jung +Yeongtaik Byeon +Jooyoul Lee +Sanghyun Lee +Juyoung Kim +HyunGoo Kang +Nikita Kalyazin +Anastasia Lyupa diff --git a/COPYING b/COPYING new file mode 100644 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 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. + + + Copyright (C) + + 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. + + , 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 index 0000000..fb122a0 --- /dev/null +++ b/LICENSE.MIT @@ -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 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 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 index 0000000..78f80a7 --- /dev/null +++ b/custom_chart/da_chart.c @@ -0,0 +1,598 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include // for signal +#include // for ualarm, sleep +#include // for timerfd +#include +#include // for errno +#include // for memset +#include // 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 index 0000000..93ff214 --- /dev/null +++ b/custom_chart/da_chart.h @@ -0,0 +1,110 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 index 0000000..7b709c2 --- /dev/null +++ b/custom_chart/da_chart_dummy.c @@ -0,0 +1,72 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 index 0000000..549cc9e --- /dev/null +++ b/feature_tests/new_capi_appfw.cpp @@ -0,0 +1,40 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vasily Ulyanov + * + * 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 + +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 index 0000000..dabe6c5 --- /dev/null +++ b/helper/addr-tizen.c @@ -0,0 +1,57 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#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 index 0000000..95f01e7 --- /dev/null +++ b/helper/btsym.c @@ -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 , 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 add hashing for symbols + +2011-12-08 Jaewon Lim get symbol data from binary's symtab when dladdr cannot resolve symbol +*/ + +#include // for assert +#include // for printf, sprintf +#include // for malloc +#include // for strlen +#include // for ptrdiff_t +#include // for program_invocation_name + +#include // for open, fstat +#include // for open, fstat +#include // for open +#include // for fstat +#include // 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 + "(+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 + "(+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 index 0000000..4a94789 --- /dev/null +++ b/helper/common_probe_init.c @@ -0,0 +1,201 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 +#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 index 0000000..11119bc --- /dev/null +++ b/helper/da_call_original.S @@ -0,0 +1,238 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 + * _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 + * #include + * + * 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 and 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 index 0000000..f363987 --- /dev/null +++ b/helper/dacapture.c @@ -0,0 +1,460 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 // for system +#include // for stat, getpid +#include // fot stat, chmod +#include // fot stat, getpid +#include // for shmget, shmat +#include // for mutex + +#include +#include +#include + +#include +#include +#include + +#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 index 0000000..efff256 --- /dev/null +++ b/helper/dacollection.c @@ -0,0 +1,838 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 // for assert +#include // for malloc, free +#include // for strlen, strcpy +#include // 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 index 0000000..d541def --- /dev/null +++ b/helper/daforkexec.c @@ -0,0 +1,212 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 +#include + +#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("", 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 index 0000000..320f6c1 --- /dev/null +++ b/helper/daforkexec.h @@ -0,0 +1,47 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..6ce75e5 --- /dev/null +++ b/helper/dahelper.c @@ -0,0 +1,155 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 // for wcslen +#include // for unlink +#include +#include // for opendir, readdir +#include +#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 index 0000000..ac4da2d --- /dev/null +++ b/helper/damaps.c @@ -0,0 +1,693 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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 +#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(§ions_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(§ions_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(§ions_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(§ions_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 index 0000000..7b2568e --- /dev/null +++ b/helper/dastdout.c @@ -0,0 +1,82 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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 +#include +#include +#include +#include + +#include +#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 index 0000000..fd743e0 --- /dev/null +++ b/helper/dastdout.h @@ -0,0 +1,35 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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 index 0000000..bc1b5e6 --- /dev/null +++ b/helper/libdaprobe.c @@ -0,0 +1,1001 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Nikita Kalyazin + * Vitaliy Cherepanov + * Anastasia Lyupa + * + * 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 // for sprintf +#include // for getenv +#include // for strstr +#include // for bool +#include // fot uint32_t,uint64_t +#include // for va_list, va_arg(__appendTypeLog) +#include // for backtrace, backtrace_symbols +#include // for write, alarm function, syscall +#include // for pthread_mutex_lock +#include +#include + +#include // for syscall +#include // for gettimeofday +#include // for socket, connect +#include // for sockaddr_un +#include // 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 index 0000000..443d911 --- /dev/null +++ b/helper/private_link.h @@ -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 +#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 // for ptrdiff_t +//#include +//#include + +/* 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 . */ + + 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 index 0000000..ac287fc --- /dev/null +++ b/helper/real_functions.c @@ -0,0 +1,38 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 // 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 index 0000000..5e153fc --- /dev/null +++ b/include/binproto.h @@ -0,0 +1,555 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Nikita Kalyazin + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#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 index 0000000..418e548 --- /dev/null +++ b/include/common_probe_init.h @@ -0,0 +1,79 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..5da8ca0 --- /dev/null +++ b/include/da_gl_api_func_list.h @@ -0,0 +1,177 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..a9b4f43 --- /dev/null +++ b/include/da_gles20.h @@ -0,0 +1,192 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Sanghyun Lee + * Juyoung Kim + * Vitaliy Cherepanov + * + * 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 +#include +#include +#include +*/ + +#include +#include + +#include +#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 index 0000000..e67da49 --- /dev/null +++ b/include/dacollection.h @@ -0,0 +1,149 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 // 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 index 0000000..82025b4 --- /dev/null +++ b/include/daerror.h @@ -0,0 +1,54 @@ +/* DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 index 0000000..fa956bc --- /dev/null +++ b/include/dahelper.h @@ -0,0 +1,240 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 +#include // for pthread_mutex_t + +#include + +#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 index 0000000..b1e172e --- /dev/null +++ b/include/damaps.h @@ -0,0 +1,33 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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 index 0000000..552ab42 --- /dev/null +++ b/include/daprobe.h @@ -0,0 +1,320 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#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 index 0000000..15d7486 --- /dev/null +++ b/include/dautil.h @@ -0,0 +1,39 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 index 0000000..a92ec5e --- /dev/null +++ b/include/khash.h @@ -0,0 +1,327 @@ +/* The MIT License + + Copyright (c) 2008, by Attractive Chaos + + 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 +#include +#include +#include + +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 index 0000000..acb2a93 --- /dev/null +++ b/include/probeinfo.h @@ -0,0 +1,217 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 index 0000000..b06904e --- /dev/null +++ b/include/real_functions.h @@ -0,0 +1,36 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..64f0802 --- /dev/null +++ b/include/tizen_probe.h @@ -0,0 +1,79 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 +#include + +#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 index 0000000..3cd68c4 --- /dev/null +++ b/packaging/dynamic-analysis-probe.changes @@ -0,0 +1,9 @@ +* Fri Jul 12 2013 Woojin Jung +- 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 +- change screenshot file name for multiprocess application + diff --git a/packaging/swap-probe.spec b/packaging/swap-probe.spec new file mode 100644 index 0000000..c2eb3d9 --- /dev/null +++ b/packaging/swap-probe.spec @@ -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 index 0000000..9c9b68a --- /dev/null +++ b/probe_capi/capi_appfw.c @@ -0,0 +1,299 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#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 index 0000000..935f5b6 --- /dev/null +++ b/probe_event/da_event.c @@ -0,0 +1,130 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include + +#include +#include +#include + +#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 index 0000000..af7e679 --- /dev/null +++ b/probe_event/da_event.h @@ -0,0 +1,139 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 index 0000000..72820bd --- /dev/null +++ b/probe_event/gesture.cpp @@ -0,0 +1,477 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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(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(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(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(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 index 0000000..612b766 --- /dev/null +++ b/probe_event/gesture.h @@ -0,0 +1,88 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 + +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 index 0000000..bf15682 --- /dev/null +++ b/probe_event/keytouch.c @@ -0,0 +1,195 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +//#include +#include +#include + +//#include +//#include +//#include +//#include +#include +#include +#include +//#include + +#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 index 0000000..20bce75 --- /dev/null +++ b/probe_event/orientation.c @@ -0,0 +1,113 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 +#include + +#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 index 0000000..06c9a88 --- /dev/null +++ b/probe_file/da_io.h @@ -0,0 +1,293 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include + +#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 index 0000000..1be3048 --- /dev/null +++ b/probe_file/da_io_posix.c @@ -0,0 +1,520 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include "daprobe.h" +#include "probeinfo.h" +#include "dautil.h" +#include "dahelper.h" +#include "da_io.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..35ebd4f --- /dev/null +++ b/probe_file/da_io_stdc.c @@ -0,0 +1,698 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#include +#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 = ""; + 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 index 0000000..db2f01f --- /dev/null +++ b/probe_graphics/da_egl_native.cpp @@ -0,0 +1,43 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..368f38b --- /dev/null +++ b/probe_graphics/da_egl_tizen.cpp @@ -0,0 +1,611 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 +#include +#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 index 0000000..b1facc0 --- /dev/null +++ b/probe_graphics/da_evas_gl.c @@ -0,0 +1,220 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..1edfee8 --- /dev/null +++ b/probe_graphics/da_gl_api_init.c @@ -0,0 +1,82 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 +#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 index 0000000..ed84d10 --- /dev/null +++ b/probe_graphics/da_gles20_native.cpp @@ -0,0 +1,1892 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Sanghyun Lee + * Juyoung Kim + * Vitaliy Cherepanov + * + * 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 index 0000000..4e3ae7d --- /dev/null +++ b/probe_graphics/da_gles20_tizen.cpp @@ -0,0 +1,56 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Vitaliy Cherepanov + * + * 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 index 0000000..a8ae788 --- /dev/null +++ b/probe_memory/da_memory.h @@ -0,0 +1,54 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 index 0000000..4086a24 --- /dev/null +++ b/probe_memory/libdamemalloc.c @@ -0,0 +1,186 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * Dmitry Bogatov + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..d0fb3fa --- /dev/null +++ b/probe_memory/libdamemmanage.c @@ -0,0 +1,133 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#include +#include +#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 index 0000000..7a3e220 --- /dev/null +++ b/probe_memory/libdanew.cpp @@ -0,0 +1,335 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#include +#include +#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(¬hrow)); + 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(¬hrow)); + 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(¬hrow)); + 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(¬hrow)); + 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 index 0000000..12f1072 --- /dev/null +++ b/probe_socket/da_socket.h @@ -0,0 +1,170 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Hyunjong Park + * Juyoung Kim + * Anastasia Lyupa 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 index 0000000..939d72a --- /dev/null +++ b/probe_socket/libdasocket.c @@ -0,0 +1,1901 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Hyunjong Park + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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[] = ""; + 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, "", + 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 index 0000000..8778cad --- /dev/null +++ b/probe_third/libdaemon.c @@ -0,0 +1,90 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 // for memcpy +#include // 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 index 0000000..c7a283a --- /dev/null +++ b/probe_thread/da_sync.h @@ -0,0 +1,65 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 index 0000000..4347b3d --- /dev/null +++ b/probe_thread/da_thread.h @@ -0,0 +1,53 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 index 0000000..2823b2c --- /dev/null +++ b/probe_thread/libdasync.c @@ -0,0 +1,538 @@ +/* + * DA probe + * + * Copyright 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#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 index 0000000..018a23a --- /dev/null +++ b/probe_thread/libdathread.c @@ -0,0 +1,743 @@ +/* + * DA probe + * + * Copyright 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#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 index 0000000..2c713ee --- /dev/null +++ b/probe_ui/capi_capture.c @@ -0,0 +1,80 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 +#include + +#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 index 0000000..79d9ef1 --- /dev/null +++ b/probe_ui/da_ui.h @@ -0,0 +1,65 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 index 0000000..07beba6 --- /dev/null +++ b/probe_ui/tizen_frameani.h @@ -0,0 +1,58 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * + * 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 + +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 index 0000000..a918929 --- /dev/null +++ b/probe_userfunc/libdauserfunc.c @@ -0,0 +1,551 @@ +/* + * DA probe + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Woojin Jung + * Jaewon Lim + * Juyoung Kim + * Anastasia Lyupa + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..e984497 --- /dev/null +++ b/scripts/api_names.txt @@ -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 ¤tSceneId) + +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 index 0000000..16edfd7 --- /dev/null +++ b/scripts/gen_api_config.sh @@ -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 index 0000000..315a302 --- /dev/null +++ b/scripts/gen_api_id_mapping_header.awk @@ -0,0 +1,38 @@ +# This script generates api_id_mapping header from api list + +BEGIN { + print "/*" + print " * this file genereted by project with cmd " + 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 index 0000000..515eaed --- /dev/null +++ b/scripts/gen_api_id_mapping_header_list.awk @@ -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 project with cmd " + 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 index 0000000..4310a6b --- /dev/null +++ b/scripts/gen_api_id_mapping_list.awk @@ -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 index 0000000..86dbb26 --- /dev/null +++ b/swap-probe.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/test_preload.sh b/test_preload.sh new file mode 100644 index 0000000..7984d56 --- /dev/null +++ b/test_preload.sh @@ -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 +