From 65b8503f33dfaf3b156d1ab47d51b0c1fd7e305a Mon Sep 17 00:00:00 2001 From: Matula Peter Date: Fri, 17 Jan 2020 22:30:47 +0100 Subject: [PATCH] deps/libdwarf+src/dwarfparser: remove, not needed anymore. --- LICENSE-THIRD-PARTY | 1089 +----------- README.md | 3 +- cmake/options.cmake | 17 +- deps/CMakeLists.txt | 1 - deps/libdwarf/CMakeLists.txt | 88 - include/retdec/dwarfparser/dwarf_base.h | 177 -- include/retdec/dwarfparser/dwarf_cu.h | 68 - include/retdec/dwarfparser/dwarf_file.h | 143 -- include/retdec/dwarfparser/dwarf_functions.h | 79 - .../retdec/dwarfparser/dwarf_linenumbers.h | 88 - include/retdec/dwarfparser/dwarf_locations.h | 115 -- include/retdec/dwarfparser/dwarf_parserdefs.h | 118 -- include/retdec/dwarfparser/dwarf_resources.h | 61 - include/retdec/dwarfparser/dwarf_types.h | 454 ----- include/retdec/dwarfparser/dwarf_utils.h | 77 - include/retdec/dwarfparser/dwarf_vars.h | 85 - .../fileformat-libdwarf-interface/README | 11 - .../bin_interface.h | 326 ---- .../dwarfdump.add | 54 - src/CMakeLists.txt | 1 - src/dwarfparser/CMakeLists.txt | 16 - src/dwarfparser/doxygen.h | 11 - src/dwarfparser/dwarf_base.cpp | 64 - src/dwarfparser/dwarf_cu.cpp | 206 --- src/dwarfparser/dwarf_file.cpp | 713 -------- src/dwarfparser/dwarf_functions.cpp | 314 ---- src/dwarfparser/dwarf_linenumbers.cpp | 347 ---- src/dwarfparser/dwarf_locations.cpp | 1064 ------------ src/dwarfparser/dwarf_resources.cpp | 201 --- src/dwarfparser/dwarf_types.cpp | 1460 ----------------- src/dwarfparser/dwarf_utils.cpp | 856 ---------- src/dwarfparser/dwarf_vars.cpp | 326 ---- 32 files changed, 18 insertions(+), 8615 deletions(-) delete mode 100644 deps/libdwarf/CMakeLists.txt delete mode 100644 include/retdec/dwarfparser/dwarf_base.h delete mode 100644 include/retdec/dwarfparser/dwarf_cu.h delete mode 100644 include/retdec/dwarfparser/dwarf_file.h delete mode 100644 include/retdec/dwarfparser/dwarf_functions.h delete mode 100644 include/retdec/dwarfparser/dwarf_linenumbers.h delete mode 100644 include/retdec/dwarfparser/dwarf_locations.h delete mode 100644 include/retdec/dwarfparser/dwarf_parserdefs.h delete mode 100644 include/retdec/dwarfparser/dwarf_resources.h delete mode 100644 include/retdec/dwarfparser/dwarf_types.h delete mode 100644 include/retdec/dwarfparser/dwarf_utils.h delete mode 100644 include/retdec/dwarfparser/dwarf_vars.h delete mode 100644 include/retdec/fileformat-libdwarf-interface/README delete mode 100644 include/retdec/fileformat-libdwarf-interface/bin_interface.h delete mode 100644 include/retdec/fileformat-libdwarf-interface/dwarfdump.add delete mode 100644 src/dwarfparser/CMakeLists.txt delete mode 100644 src/dwarfparser/doxygen.h delete mode 100644 src/dwarfparser/dwarf_base.cpp delete mode 100644 src/dwarfparser/dwarf_cu.cpp delete mode 100644 src/dwarfparser/dwarf_file.cpp delete mode 100644 src/dwarfparser/dwarf_functions.cpp delete mode 100644 src/dwarfparser/dwarf_linenumbers.cpp delete mode 100644 src/dwarfparser/dwarf_locations.cpp delete mode 100644 src/dwarfparser/dwarf_resources.cpp delete mode 100644 src/dwarfparser/dwarf_types.cpp delete mode 100644 src/dwarfparser/dwarf_utils.cpp delete mode 100644 src/dwarfparser/dwarf_vars.cpp diff --git a/LICENSE-THIRD-PARTY b/LICENSE-THIRD-PARTY index e0d181cd8..01e939a2d 100644 --- a/LICENSE-THIRD-PARTY +++ b/LICENSE-THIRD-PARTY @@ -10,15 +10,13 @@ RetDec uses the following third-party libraries or other resources: 2) Elfio: http://elfio.sourceforge.net/ 3) Google Test: https://github.com/avast/googletest 4) Keystone Engine: http://www.keystone-engine.org/ -5) Libdwarf: https://www.prevanders.net/dwarf.html -6) Libelf: https://github.com/WolfgangSt/libelf -7) LLVM: https://llvm.org/ -8) OpenSSL: https://www.openssl.org/ -9) RapidJSON: https://github.com/Tencent/rapidjson -10) TinyXML-2: https://github.com/leethomason/tinyxml2 -11) whereami: https://github.com/gpakosz/whereami -12) yara: https://virustotal.github.io/yara/ -13) yaramod: https://github.com/avast/yaramod +5) LLVM: https://llvm.org/ +6) OpenSSL: https://www.openssl.org/ +7) RapidJSON: https://github.com/Tencent/rapidjson +8) TinyXML-2: https://github.com/leethomason/tinyxml2 +9) whereami: https://github.com/gpakosz/whereami +10) yara: https://virustotal.github.io/yara/ +11) yaramod: https://github.com/avast/yaramod These third-party libraries or other resources are licensed under the following licenses: @@ -472,1066 +470,7 @@ library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. =============================================================================== -5) Libdwarf -=============================================================================== - -The files: - libdwarf.h - dwarf.h - and all the .h and .c files in this implementation of - libdwarf are copyrighted according to the file - LIBDWARFCOPYRIGHT (which mentions the LGPL version 2.1). - Each file mentions the LGPL. - The full text of the LGPL 2.1 is provided in LGPL.txt - -The libdwarf documentation: - libdwarf2.1.mm - is based on material submitted to the UI PLSIG as proposed - interfaces for dwarf, but completely rewritten. - Copyright ownership is therefore SGI (but see the document for details) - and it seems clear that the intent was there was to be free - copying with no fees. - - libdwarf2p.1.mm - is documentation of a set of interfaces - (not part of the UI PLSIG proposals) - and the document was written from scratch at SGI. - Copyright ownership is therefore SGI (but see the document for details) - and it seems clear that the intent was there was to be free - copying with no fees. - -====== -Update January 31, 2015: -The SGI postal address and oss.sgi.com address -in the original copyright are no longer correct. -So the final 8 lines of the original copyright -have been deleted from the current copyright. - -====== original copyright example. - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2.1 of the GNU Lesser General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. - - Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, - Mountain View, CA 94043, or: - - http://www.sgi.com - - For further information regarding this notice, see: - - http://oss.sgi.com/projects/GenInfo/NoticeExplan - -17 March 2014:Updated to remove reference to dwarf.v2.mm. - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, 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.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 - -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! - -=============================================================================== -6) Libelf -=============================================================================== - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - 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 Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the 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 a program 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. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - 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, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -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 compile 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) 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. - - c) 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. - - d) 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 source code 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 to -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 Library 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 Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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! - -=============================================================================== -7) LLVM +5) LLVM =============================================================================== University of Illinois/NCSA @@ -1576,7 +515,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. =============================================================================== -8) OpenSSL +6) OpenSSL =============================================================================== LICENSE ISSUES @@ -1706,7 +645,7 @@ SOFTWARE. */ =============================================================================== -9) RapidJSON +7) RapidJSON =============================================================================== Tencent is pleased to support the open source community by making RapidJSON available. @@ -1766,7 +705,7 @@ The above copyright notice and this permission notice shall be included in all c 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. =============================================================================== -10) TinyXML-2 +8) TinyXML-2 =============================================================================== TinyXML-2 is released under the zlib license: @@ -1780,7 +719,7 @@ Permission is granted to anyone to use this software for any purpose, including 3. This notice may not be removed or altered from any source distribution. =============================================================================== -11) whereami +9) whereami =============================================================================== DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE @@ -1800,7 +739,7 @@ Permission is granted to anyone to use this software for any purpose, including 2. Montesqieu et camembert, vive la France, zut alors! =============================================================================== -12) YARA +10) YARA =============================================================================== Copyright (c) 2007-2016. The YARA Authors. All Rights Reserved. @@ -1831,7 +770,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== -13) yaramod +11) yaramod =============================================================================== The MIT License (MIT) diff --git a/README.md b/README.md index f4a46761e..14efccaf9 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ You can pass the following additional parameters to `cmake`: * `-DRETDEC_COMPILE_YARA=OFF` to disable YARA rules compilation at installation step (enabled by default). * `-DCMAKE_BUILD_TYPE=Debug` to build with debugging information, which is useful during development. By default, the project is built in the `Release` mode. This has no effect on Windows, but the same thing can be achieved by running `cmake --build .` with the `--config Debug` parameter. * `-DCMAKE_PROGRAM_PATH=` to use Perl at `` (probably useful only on Windows). -* `-D_LOCAL_DIR=` where `` is from `{CAPSTONE, GOOGLETEST, KEYSTONE, LIBDWARF, LLVM, YARA, YARAMOD}` (e.g. `-DCAPSTONE_LOCAL_DIR=`), to use the local repository clone at `` for RetDec dependency instead of downloading a fresh copy at build time. Multiple such options may be used at the same time. +* `-D_LOCAL_DIR=` where `` is from `{CAPSTONE, GOOGLETEST, KEYSTONE, LLVM, YARA, YARAMOD}` (e.g. `-DCAPSTONE_LOCAL_DIR=`), to use the local repository clone at `` for RetDec dependency instead of downloading a fresh copy at build time. Multiple such options may be used at the same time. * `-DRETDEC_ENABLE_=ON` to build only the specified component(s) (multiple such options can be used at once), and its (theirs) dependencies. By default, all the components are built. If at least one component is enabled via this mechanism, all the other components that were not explicitly enabled (and are not needed as dependencies of enabled components) are not built. See [cmake/options.cmake](https://github.com/avast/retdec/blob/master/cmake/options.cmake) for all the available component options. * `-DRETDEC_ENABLE_ALL=ON` can be used to (re-)enable all the components. * Alternatively, `-DRETDEC_ENABLE=` can be used instead of `-DRETDEC_ENABLE_=ON` (e.g. `-DRETDEC_ENABLE=fileformat,loader,ctypesparser` is equivalent to `-DRETDEC_ENABLE_FILEFORMAT=ON -DRETDEC_ENABLE_LOADER=ON -DRETDEC_ENABLE_CTYPESPARSER=ON`). @@ -301,7 +301,6 @@ This repository contains the following libraries: * `ctypes` - C++ library for representing C function data types. * `debugformat` - library for uniform representation of DWARF and PDB debugging information. * `demangler` - demangling library capable to handle names generated by the GCC/Clang, Microsoft Visual C++, and Borland C++ compilers. -* `dwarfparser` - library for high-level representation of DWARF debugging information. * `fileformat` - library for parsing and uniform representation of various object file formats. Currently supporting the following formats: COFF, ELF, Intel HEX, Mach-O, PE, raw data. * `llvm-support` - set of LLVM related utility functions. * `llvmir-emul` - LLVM IR emulation library used for unit testing. diff --git a/cmake/options.cmake b/cmake/options.cmake index 3ca2bd512..2d60d5069 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -26,7 +26,6 @@ option(RETDEC_ENABLE_CTYPESPARSER "" OFF) option(RETDEC_ENABLE_DEBUGFORMAT "" OFF) option(RETDEC_ENABLE_DEMANGLER "" OFF) option(RETDEC_ENABLE_DEMANGLERTOOL "" OFF) -option(RETDEC_ENABLE_DWARFPARSER "" OFF) option(RETDEC_ENABLE_FILEFORMAT "" OFF) option(RETDEC_ENABLE_FILEINFO "" OFF) option(RETDEC_ENABLE_GETSIG "" OFF) @@ -83,7 +82,6 @@ foreach(t ${RETDEC_ENABLE}) set_if_equal(${t} "debugformat" RETDEC_ENABLE_DEBUGFORMAT) set_if_equal(${t} "demangler" RETDEC_ENABLE_DEMANGLER) set_if_equal(${t} "demanglertool" RETDEC_ENABLE_DEMANGLERTOOL) - set_if_equal(${t} "dwarfparser" RETDEC_ENABLE_DWARFPARSER) set_if_equal(${t} "fileformat" RETDEC_ENABLE_FILEFORMAT) set_if_equal(${t} "fileinfo" RETDEC_ENABLE_FILEINFO) set_if_equal(${t} "getsig" RETDEC_ENABLE_GETSIG) @@ -130,7 +128,6 @@ if (RETDEC_ENABLE_AR_EXTRACTOR OR RETDEC_ENABLE_DEBUGFORMAT OR RETDEC_ENABLE_DEMANGLER OR RETDEC_ENABLE_DEMANGLERTOOL - OR RETDEC_ENABLE_DWARFPARSER OR RETDEC_ENABLE_FILEFORMAT OR RETDEC_ENABLE_FILEINFO OR RETDEC_ENABLE_GETSIG @@ -319,10 +316,6 @@ set_if_at_least_one_set(RETDEC_ENABLE_CTYPES RETDEC_ENABLE_ALL RETDEC_ENABLE_CTYPESPARSER) -set_if_at_least_one_set(RETDEC_ENABLE_DWARFPARSER - RETDEC_ENABLE_ALL - RETDEC_ENABLE_DEBUGFORMAT) - set_if_at_least_one_set(RETDEC_ENABLE_PDBPARSER RETDEC_ENABLE_CPDETECT RETDEC_ENABLE_DEBUGFORMAT) @@ -341,7 +334,6 @@ set_if_at_least_one_set(RETDEC_ENABLE_FILEFORMAT RETDEC_ENABLE_ALL RETDEC_ENABLE_BIN2LLVMIR RETDEC_ENABLE_CPDETECT - RETDEC_ENABLE_DWARFPARSER RETDEC_ENABLE_FILEINFO RETDEC_ENABLE_GETSIG RETDEC_ENABLE_LOADER @@ -397,7 +389,6 @@ set_if_at_least_one_set(RETDEC_ENABLE_UTILS RETDEC_ENABLE_CRYPTO RETDEC_ENABLE_CTYPES RETDEC_ENABLE_CTYPESPARSER - RETDEC_ENABLE_DWARFPARSER RETDEC_ENABLE_FILEFORMAT RETDEC_ENABLE_FILEINFO RETDEC_ENABLE_IDR2PAT @@ -494,10 +485,6 @@ set_if_at_least_one_set(RETDEC_ENABLE_KEYSTONE RETDEC_ENABLE_CAPSTONE2LLVMIRTOOL RETDEC_ENABLE_CAPSTONE2LLVMIR_TESTS) -set_if_at_least_one_set(RETDEC_ENABLE_LIBDWARF - RETDEC_ENABLE_CPDETECT - RETDEC_ENABLE_DWARFPARSER) - set_if_at_least_one_set(RETDEC_ENABLE_LLVM RETDEC_ENABLE_AR_EXTRACTOR RETDEC_ENABLE_BIN2LLVMIR @@ -507,7 +494,9 @@ set_if_at_least_one_set(RETDEC_ENABLE_LLVM RETDEC_ENABLE_LLVM_SUPPORT RETDEC_ENABLE_LLVMIR_EMUL RETDEC_ENABLE_LLVMIR2HLL - RETDEC_ENABLE_MACHO_EXTRACTOR) + RETDEC_ENABLE_MACHO_EXTRACTOR + RETDEC_ENABLE_CPDETECT + RETDEC_ENABLE_DEBUGFORMAT) set_if_at_least_one_set(RETDEC_ENABLE_OPENSLL RETDEC_ENABLE_CRYPTO) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index ebfc926e1..3336b84a8 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -7,7 +7,6 @@ cond_add_subdirectory(capstone RETDEC_ENABLE_CAPSTONE) cond_add_subdirectory(elfio RETDEC_ENABLE_ELFIO) cond_add_subdirectory(googletest RETDEC_ENABLE_GOOGLETEST) cond_add_subdirectory(keystone RETDEC_ENABLE_KEYSTONE) -cond_add_subdirectory(libdwarf RETDEC_ENABLE_LIBDWARF) cond_add_subdirectory(llvm RETDEC_ENABLE_LLVM) cond_add_subdirectory(openssl RETDEC_ENABLE_OPENSLL) cond_add_subdirectory(rapidjson RETDEC_ENABLE_RAPIDJSON) diff --git a/deps/libdwarf/CMakeLists.txt b/deps/libdwarf/CMakeLists.txt deleted file mode 100644 index a3a7b0685..000000000 --- a/deps/libdwarf/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -include(ExternalProject) - -if(CMAKE_C_COMPILER) - set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}") -endif() -if(CMAKE_CXX_COMPILER) - set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") -endif() - -set(LIBDWARF_INSTALL_DIR "${PROJECT_BINARY_DIR}/external/src/libdwarf-project-install") - -if(LIBDWARF_LOCAL_DIR) - message(STATUS "LibDwarf: using local LibDwarf directory.") - - ExternalProject_Add(libdwarf-project - DOWNLOAD_COMMAND "" - SOURCE_DIR "${LIBDWARF_LOCAL_DIR}" - CMAKE_ARGS - # This does not work on MSVC, but may be useful on Linux. - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=${LIBDWARF_INSTALL_DIR} - # Force the use of the same compiler as used to build the top-level - # project. Otherwise, the external project may pick up a different - # compiler, which may result in link errors. - "${CMAKE_C_COMPILER_OPTION}" - "${CMAKE_CXX_COMPILER_OPTION}" - # Disable the update step. - UPDATE_COMMAND "" - ) - force_configure_step(libdwarf-project) -else() - message(STATUS "LibDwarf: using remote LibDwarf revision.") - - ExternalProject_Add(libdwarf-project - URL https://github.com/avast/libdwarf/archive/85465d5e235cc2d2f90d04016d6aca1a452d0e73.zip - URL_HASH SHA256=2864aa7b46529778476190e90359669eb35799ad273233c4df2203bec7db0738 - DOWNLOAD_NAME libdwarf.zip - CMAKE_ARGS - # This does not work on MSVC, but may be useful on Linux. - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=${LIBDWARF_INSTALL_DIR} - # Force the use of the same compiler as used to build the top-level - # project. Otherwise, the external project may pick up a different - # compiler, which may result in link errors. - "${CMAKE_C_COMPILER_OPTION}" - "${CMAKE_CXX_COMPILER_OPTION}" - # Disable the update step. - UPDATE_COMMAND "" - LOG_DOWNLOAD ON - LOG_CONFIGURE ON - LOG_BUILD ON - ) -endif() - -check_if_variable_changed(LIBDWARF_LOCAL_DIR CHANGED) -if(CHANGED) - ExternalProject_Get_Property(libdwarf-project binary_dir) - message(STATUS "LibDwarf: path to LibDwarf directory changed -> cleaning CMake files in ${binary_dir}.") - clean_cmake_files(${binary_dir}) -endif() - -ExternalProject_Get_Property(libdwarf-project source_dir) -ExternalProject_Get_Property(libdwarf-project binary_dir) - -# Add libraries. -add_library(libdwarf INTERFACE) -add_dependencies(libdwarf libdwarf-project) - -target_include_directories(libdwarf SYSTEM INTERFACE ${source_dir}/libdwarf) - -if(MSVC) - target_link_libraries(libdwarf INTERFACE ${binary_dir}/libdwarf/libdwarf/$/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libdwarf.lib) - target_link_libraries(libdwarf INTERFACE ${binary_dir}/libelf/lib/$/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libelf.lib) -elseif(MSYS) - target_link_libraries(libdwarf INTERFACE ${LIBDWARF_INSTALL_DIR}/bin/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libdwarf${CMAKE_SHARED_LIBRARY_SUFFIX}) - target_link_libraries(libdwarf INTERFACE ${LIBDWARF_INSTALL_DIR}/bin/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libelf${CMAKE_SHARED_LIBRARY_SUFFIX}) -else() # Linux - target_link_libraries(libdwarf INTERFACE ${LIBDWARF_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libdwarf${CMAKE_SHARED_LIBRARY_SUFFIX}) - target_link_libraries(libdwarf INTERFACE ${LIBDWARF_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}retdec-libelf${CMAKE_SHARED_LIBRARY_SUFFIX}) -endif() - -if(MSVC) - install(DIRECTORY "${LIBDWARF_INSTALL_DIR}/bin" DESTINATION "${CMAKE_INSTALL_PREFIX}") -elseif(MSYS) - install(DIRECTORY "${LIBDWARF_INSTALL_DIR}/bin" DESTINATION "${CMAKE_INSTALL_PREFIX}") -else() # Linux - install(DIRECTORY "${LIBDWARF_INSTALL_DIR}/lib" DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() diff --git a/include/retdec/dwarfparser/dwarf_base.h b/include/retdec/dwarfparser/dwarf_base.h deleted file mode 100644 index fa1b8152d..000000000 --- a/include/retdec/dwarfparser/dwarf_base.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_base.h - * @brief Declaration of base classes used in dwarfparser. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_BASE_H -#define RETDEC_DWARFPARSER_DWARF_BASE_H - -#include -#include -#include -#include - -#include -#include - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; -class DwarfCU; - -// Locale forward declarations. -template -class DwarfBaseContainer; -class DwarfBaseElement; - -/** - * @class DwarfBaseContainer. - * @brief Base container class for all container objects used by dwarfparser. - */ -template -class DwarfBaseContainer -{ - // - // Type aliases - // - public: - using iterator = typename std::vector::iterator; - using const_iterator = typename std::vector::const_iterator; - - // - // Non-virtual functions. - // - public: - DwarfBaseContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr) : - m_res(0), - m_error(nullptr), - m_parentFile(file), - m_parentElem(elem) - { - - } - - std::size_t size() const { return m_data.size(); } - void push_back(T *n) { m_data.push_back(n); } - bool empty() const { return m_data.empty(); } - iterator begin() { return m_data.begin(); } - const_iterator begin() const { return m_data.begin(); } - iterator end() { return m_data.end(); } - const_iterator end() const { return m_data.end(); } - - DwarfBaseElement *getParentElem() const { return m_parentElem; } - DwarfFile *getParentFile() const { return m_parentFile; } - - // TODO: get element by DIE? - DwarfBaseElement *getElemByOffset(Dwarf_Off o); - - // - // Virtual functions. - // - public: - virtual ~DwarfBaseContainer() - { - for (iterator it=begin(); it!=end(); ++it) - delete (*it); - m_data.clear(); - } - - virtual void dump() const - { - for (const_iterator cit=begin(); cit!=end(); ++cit) - (*cit)->dump(); - } - - // - // Pure virtual functions. - // - public: - virtual T* loadAndGetDie(Dwarf_Die die, unsigned lvl) = 0; - - // - // Data. - // - protected: - std::vector m_data; ///< Object container. - - int m_res; ///< Global return value. - Dwarf_Error m_error; ///< Global error code. - - DwarfFile *m_parentFile; ///< Pointer to DWARF file representation. - DwarfBaseElement *m_parentElem; ///< Pointer to parent element, if nullptr then parent is DWARF file. - - public: - /** - * DIE offset to element mapping. - * One element may have multiple offsets -- multiple mappings. - * ==> *DO NOT* iterate through this container, use 'm_data'. - */ - std::map off2data; -}; - -/** - * @class DwarfBaseElement - * @brief Base element class for all objects used by dwarfparser. - */ -class DwarfBaseElement -{ - public: - /** - * @brief Types element - */ - enum type_t - { - CU, - FUNCTION, - LINE, - TYPE, - VAR - }; - - DwarfBaseElement(type_t type, DwarfBaseContainer *prnt, Dwarf_Off d); - virtual ~DwarfBaseElement() = default; - virtual void dump() const = 0; - - public: - virtual const std::string& getName() const {return name;} - - type_t getType() const {return m_type;} - DwarfBaseContainer *getPrntCont() const {return m_parent;} - DwarfFile *getParentFile() const {return getPrntCont()->getParentFile();} - DwarfCU *getCuParent() const {return m_cuParent;} - - Dwarf_Debug &getLibdwarfDebug() const; - void addOffset(Dwarf_Off o); - std::string getDwarfdump2OffsetString() const; - - public: - std::string name; - - protected: - type_t m_type; - DwarfBaseContainer *m_parent; ///< Pointer to parent container that contains this element. - DwarfCU *m_cuParent; ///< Pointer to parent CU element that contains this element. -}; - -/** - * @brief Get container's element with provided offset. - * @param o Offset. - * @return Element with offset. - */ -template -DwarfBaseElement* DwarfBaseContainer::getElemByOffset(Dwarf_Off o) -{ - auto it = off2data.find(o); - if (it != off2data.end()) - return it->second; - else - return nullptr; -} - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_cu.h b/include/retdec/dwarfparser/dwarf_cu.h deleted file mode 100644 index 9983b1959..000000000 --- a/include/retdec/dwarfparser/dwarf_cu.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_cu.h - * @brief Declaration of classes representing Compilation Units. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_CU_H -#define RETDEC_DWARFPARSER_DWARF_CU_H - -#include -#include - -#include "retdec/dwarfparser/dwarf_base.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; - -// Locale forward declarations. -class DwarfCU; -class DwarfCUContainer; - -/** - * @class DwarfCU - * @brief Compilation unit object. - */ -class DwarfCU : public DwarfBaseElement -{ - public: - DwarfCU(DwarfCUContainer *prnt, Dwarf_Off o); - virtual void dump() const override; - - std::size_t srcFilesCount(); - void addSrcFile(std::string f); - std::string *getSrcFile(unsigned idx); - int findSrcFile(std::string f, const std::string **ret); - bool IsLanguageC() const; - bool IsLanguageCpp() const; - - public: - std::string compDir; ///< Name of compilation directory. - std::string producer; ///< Name of compiler used to create CU. - Dwarf_Addr lowAddr; ///< Lowest address of active range, base for loclists. - Dwarf_Addr highAddr; ///< Highest address of active range. - Dwarf_Unsigned language; ///< A code indicating the source language. - - private: - std::list m_srcFiles; ///< List of source file of this compilation unit. -}; - -/** - * @class DwarfCUContainer - * @brief Compilation unit container. - */ -class DwarfCUContainer : public DwarfBaseContainer -{ - public: - DwarfCUContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr); - virtual DwarfCU *loadAndGetDie(Dwarf_Die cuDie, unsigned lvl) override; - virtual void dump() const override; -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_file.h b/include/retdec/dwarfparser/dwarf_file.h deleted file mode 100644 index d436e361d..000000000 --- a/include/retdec/dwarfparser/dwarf_file.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_file.h - * @brief Declarations of DwarfFile class which provides high-level access - * to DWARF debugging informations. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -/* - * TODO: - * - Multiple CUs -> CUs should own other info that are inside them. - * At the moment each object contains pointer to its CU. - * It would be better designed if CU elements would contain all the different - * containers (lines, functions, types, ...). - * Problem is that there would be many containers for each element type, and - * it is much easier for user of this library to have all functions, types, etc. - * in single container -- methods getFunctions(), etc. - * Possible solution would be to create new container when get*() method is called, - * this container would contain all element from all CU containers of the type. - * But I'm not sure that this is the best solution. - * - add some method that enables printing debug info in all classes. - * - class holding and managing active context, accessible from other classes. - * - DW_AT_abstract_origin problem -- associate object with original DIE. - * - void data type - is it the best solution ??? - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_FILE_H -#define RETDEC_DWARFPARSER_DWARF_FILE_H - -#include - -#include -#include - -#include "retdec/fileformat-libdwarf-interface/bin_interface.h" - -#include "retdec/dwarfparser/dwarf_cu.h" -#include "retdec/dwarfparser/dwarf_functions.h" -#include "retdec/dwarfparser/dwarf_linenumbers.h" -#include "retdec/dwarfparser/dwarf_locations.h" -#include "retdec/dwarfparser/dwarf_parserdefs.h" -#include "retdec/dwarfparser/dwarf_resources.h" -#include "retdec/dwarfparser/dwarf_types.h" -#include "retdec/dwarfparser/dwarf_utils.h" -#include "retdec/dwarfparser/dwarf_vars.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. - -// Locale forward declarations. -class DwarfFile; - -/** - * @class DwarfFile - * @brief Main class containing all DWARF information. - */ -class DwarfFile -{ - // - // Public methods. - // - public: - DwarfFile(std::string fileName, retdec::fileformat::FileFormat *fileParser = nullptr); - ~DwarfFile(); - bool hasDwarfInfo(); - - // - // Functions getting particular DWARF records. - // - public: - DwarfCUContainer *getCUs(); - DwarfLineContainer *getLines(); - DwarfFunctionContainer *getFunctions(); - DwarfTypeContainer *getTypes(); - DwarfVarContainer *getGlobalVars(); - Dwarf_Debug &getDwarfDebug(); - - // - // Private methods. - // - private: - bool loadFile(std::string fileName, retdec::fileformat::FileFormat *fileParser); - void loadFileCUs(); - void loadCUtree(Dwarf_Die die, DwarfBaseElement* parent, int lvl); - void loadDIE(Dwarf_Die die, DwarfBaseElement* &parent, int lvl); - void makeStructTypesUnique(); - - // - // Containers storing high-level representation of DWARF data. - // - private: - DwarfCUContainer m_CUs; ///< Compilation units. - DwarfLineContainer m_lines; ///< Line numbers. - DwarfFunctionContainer m_functions; ///< Functions. - DwarfTypeContainer m_types; ///< Data types. - DwarfVarContainer m_globalVars; ///< Global variables. - - // - // Some auxiliary variables. - // - private: - bool m_hasDwarf; ///< Loaded file contains some DWARF information. - int m_res; ///< Global return value. - Dwarf_Debug m_dbg; ///< Libdwarf structure representing DWARF file. - int m_fd; ///< File descriptor used in dwarf_init(). - Dwarf_Error m_error; ///< Global libdwarf error code. - - // - // Variables keep track of the context of DWARF tree. - // - private: - DwarfCU *m_activeCU; - - // - // Resources. - // - public: - void initMapping(eDefaultMap m); - DwarfResources resources; ///< Class representing resources. - - // - // These classes need to access DWARF context tree. - // - template friend class DwarfBaseContainer; - friend class DwarfCUContainer; - friend class DwarfLineContainer; - friend class DwarfFunctionContainer; - friend class DwarfVarContainer; - friend class DwarfTypeContainer; - friend class DwarfBaseElement; - friend class DwarfCU; - friend class DwarfArrayType; - friend class DwarfEnumType; - friend class DwarfStructType; - friend class DwarfLocationDesc; - friend class AttrProcessor; -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_functions.h b/include/retdec/dwarfparser/dwarf_functions.h deleted file mode 100644 index efd3747aa..000000000 --- a/include/retdec/dwarfparser/dwarf_functions.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_functions.h - * @brief Declaration of classes representing functions. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_FUNCTIONS_H -#define RETDEC_DWARFPARSER_DWARF_FUNCTIONS_H - -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_vars.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; - -// Locale forward declarations. -class DwarfFunction; -class DwarfFunctionContainer; - -/** - * @class DwarfFunction - * @brief Function object. - */ -class DwarfFunction : public DwarfVar -{ - public: - DwarfFunction(DwarfFunctionContainer *prnt, Dwarf_Off o, const std::string &n); - virtual ~DwarfFunction() override; - virtual void dump() const override; - - bool hasVars() const; - bool hasParams() const; - DwarfVarContainer *getVars(); - DwarfVarContainer *getParams(); - std::size_t getParamCount() const; - bool hasFrameBase() const; - DwarfLocationDesc::cLocType getFrameBase(std::string *n, Dwarf_Addr *a, Dwarf_Addr pc = 0); - - public: - std::string linkageName; ///< Mangled name, sometimes only this one is in DWARF, then use it as name as well. - Dwarf_Addr lowAddr; ///< Lowest address of active range. - Dwarf_Addr highAddr; ///< Highest address of active range. - Dwarf_Unsigned line; ///< Function declaration line number. - const std::string &file; ///< Source file name where function is declared. - DwarfLocationDesc *frameBase; ///< Frame base location descriptor. - bool isVariadic; ///< If true, function has variadic argument following arguments stored in m_params. - bool isDeclaration; ///< - bool isTemplateInstance; - bool isVariadicTemplateInstance; - bool isTemplateTemplateInstance; - - private: - DwarfVarContainer m_vars; ///< Container with local variables of this function. - DwarfVarContainer m_params; ///< Container with parameters of this function. -}; - -/** - * @class DwarfFunctionContainer - * @brief Function container. - */ -class DwarfFunctionContainer : public DwarfBaseContainer -{ - public: - DwarfFunctionContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr); - virtual void dump() const override; - - virtual DwarfFunction *loadAndGetDie(Dwarf_Die die, unsigned lvl) override; - DwarfFunction *getFunctionByName(std::string n); -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_linenumbers.h b/include/retdec/dwarfparser/dwarf_linenumbers.h deleted file mode 100644 index 8506d4b8e..000000000 --- a/include/retdec/dwarfparser/dwarf_linenumbers.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_linenumbers.h - * @brief Declaration of classes representing linenumbers. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_LINENUMBERS_H -#define RETDEC_DWARFPARSER_DWARF_LINENUMBERS_H - -#include -#include -#include - -#include "retdec/dwarfparser/dwarf_base.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; - -// Locale forward declarations. -class DwarfLine; -class DwarfLineContainer; - -/** - * @class DwarfLine - * @brief Line number object. - */ -class DwarfLine : public DwarfBaseElement -{ - public: - /** - * @brief Flags of line number. - */ - enum eFlags - { - EMPTY = 0, ///< Empty. - STAT_BEG = 1 << 1, ///< Line number entry marked as beginning a statment. - SEQ_END = 1 << 2, ///< Line number entry marked as ending a text sequence. - BASE_BLOCK_BEG = 1 << 3, ///< Line number entry marked as beginning a basic block. - PROLOGUE_END = 1 << 4, ///< Line number entry marked as end of prologue. - EPILOGUE_BEGIN = 1 << 5 ///< Line number entry marked as begin of epilogue. - }; - - public: - DwarfLine(DwarfLineContainer *prnt, const std::string &n); - virtual void dump() const override; - - virtual const std::string& getName() const override {return name;} - bool isStatmentBeg() const; - bool isSequenceEnd() const; - bool isBasicBlockBeg() const; - - public: - Dwarf_Unsigned lineNum; ///< Source statement line number. - Dwarf_Addr addr; ///< Address associated with line. - Dwarf_Unsigned col; ///< Column number at which statement represented by line begins. - int flags; ///< Line number record flags. - const std::string &name; ///< Name of source file where line occurs. -}; - -/** - * @class DwarfLineContainer - * @brief Line number container. - */ -class DwarfLineContainer : public DwarfBaseContainer -{ - public: - DwarfLineContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr); - virtual DwarfLine *loadAndGetDie(Dwarf_Die cu_die, unsigned lvl) override; - virtual void dump() const override; - - std::vector getAddrByLine(std::string file, Dwarf_Unsigned line); - DwarfLine *getLineByAddr(Dwarf_Addr addr); - - private: - void loadLine(Dwarf_Line line); - std::string *findSrcFile(std::string f); - - private: - std::list m_srcFiles; ///< List of all source file names used in lines. -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_locations.h b/include/retdec/dwarfparser/dwarf_locations.h deleted file mode 100644 index 045116696..000000000 --- a/include/retdec/dwarfparser/dwarf_locations.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_locations.h - * @brief Declaration of classes representing locations. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_LOCATIONS_H -#define RETDEC_DWARFPARSER_DWARF_LOCATIONS_H - -#include -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_resources.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFunction; - -// Locale forward declarations. -class DwarfLocationDesc; - -/** - * @class DwarfLocationDesc - * @brief Class represents location description used by DWARF. - */ -class DwarfLocationDesc -{ - public: - /** - * @brief Type of location. - */ - enum eLocType - { - REGISTER = 0, ///< Register. - ADDRESS = 1 << 1, ///< Address. - VALUE = 1 << 2, ///< Actual value of the object. - FAIL = 1 << 3 ///< Invalid. - }; - - /** - * @class cLocType. - * @brief Class representing location type. - */ - class cLocType - { - public: - cLocType(eLocType tt); - bool isRegister(); - bool isAddress(); - bool isValue(); - bool failed(); - private: - eLocType t; ///< Location type. - }; - - /** - * @brief Basic unit of location description. - */ - struct Atom - { - Dwarf_Small opcode; ///< Operation code. - Dwarf_Unsigned op1; ///< Operand #1. - Dwarf_Unsigned op2; ///< Operand #2. - Dwarf_Unsigned off; ///< Offset in locexpr used in OP_BRA. - }; - - /** - * @brief DWARF expression. - */ - class Expression - { - public: - Dwarf_Addr lowAddr; ///< Lowest address of active range. - Dwarf_Addr highAddr; ///< Highest address of active range. - std::vector atoms; ///< Vector of expression's atoms. - std::size_t count() const {return atoms.size();} - }; - - public: - DwarfLocationDesc(); - - cLocType computeLocation(std::string *n, Dwarf_Addr *a, Dwarf_Addr pc = 0, - Dwarf_Addr base = 0, bool hasBase = false); - - void addExpr(Expression e); - void setBaseFunc(DwarfFunction *f); - DwarfLocationDesc *getBaseLoc(); - void setParent(DwarfBaseElement *p); - DwarfCU *getCuParent(); - std::string getParentName(); - DwarfResources *getResources(); - std::size_t count() const; - bool isEmpty(); - bool isNormal() const; - bool isList(); - bool isOnStack(Dwarf_Signed *off, bool *deref, Dwarf_Addr pc = 0, int *regNum=nullptr); - void dump(); - - private: - cLocType evaluateExpression(Expression &expr, std::string *retN, Dwarf_Addr *retA, - Dwarf_Addr pc = 0, Dwarf_Addr base = 0, bool hasBase = false); - - private: - std::vector m_exprs; ///< Vector of expressions of this location. - DwarfFunction *m_baseFunc; ///< Pointer to base function containing frame base location. - DwarfBaseElement *m_parent; ///< Pointer to object which owns this location. -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_parserdefs.h b/include/retdec/dwarfparser/dwarf_parserdefs.h deleted file mode 100644 index 9044369eb..000000000 --- a/include/retdec/dwarfparser/dwarf_parserdefs.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_parserdefs.h - * @brief Definitions globally used in dwarfparser library. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_PARSERDEFS_H -#define RETDEC_DWARFPARSER_DWARF_PARSERDEFS_H - -#include -#include -#include -#include -#include - -#include -#include - -#include "retdec/utils/os.h" - -#ifdef OS_WINDOWS - #include -#endif - -/** - * These constants represents empty values of used data types. - */ -const std::string EMPTY_STR = ""; -const Dwarf_Unsigned EMPTY_UNSIGNED = std::numeric_limits::max(); -const Dwarf_Signed EMPTY_SIGNED = std::numeric_limits::max(); -const Dwarf_Addr EMPTY_ADDR = EMPTY_UNSIGNED; -const Dwarf_Off EMPTY_OFF = EMPTY_UNSIGNED; - -/** - * TODO: - * this is used to determine source section of DWARF info in some new - * libdwarf functions - * at the moment '.debug_info' is always used - * implement possible use of '.debug_types' as in dwarfdump2 - */ -const Dwarf_Bool is_info = true; - -/** - * - */ -const unsigned short BITS_IN_BYTE = 8; - -/** - * @brief Variants of default DWARF registers numbers mapping initialization. - */ -enum eDefaultMap -{ - MIPS, ///< - ARM, ///< - X86 ///< -}; - -/* - * Debug msg printing. - */ -//#define DWARF_PARSER_RECOVERY_DEBUG -#undef DWARF_PARSER_RECOVERY_DEBUG - -#ifndef OS_WINDOWS /* OS_WINDOWS */ - -const std::string DWARF_CYAN = "\33[22;36m"; -const std::string DWARF_RED = "\33[22;31m"; -const std::string DWARF_NOCOLOR = "\33[0m"; - -#ifdef DWARF_PARSER_RECOVERY_DEBUG /* DWARF_PARSER_RECOVERY_DEBUG */ - -#define DWARF_ERROR(X) \ - std::cout << DWARF_RED << "Dwarfparserl Error: " << X << " -> (" << __FILE__ << ":" << std::dec << __LINE__ << ")" << DWARF_NOCOLOR << std::endl; - -#define DWARF_WARNING(X) \ - std::cout << DWARF_CYAN << "Dwarfparserl Warning: " << X << " -> (" << __FILE__ << ":" << std::dec << __LINE__ << ")" << DWARF_NOCOLOR << std::endl; - -#endif /* DWARF_PARSER_RECOVERY_DEBUG */ - -#ifndef DWARF_PARSER_RECOVERY_DEBUG /* DWARF_PARSER_RECOVERY_DEBUG */ -#define DWARF_ERROR(X) {} -#define DWARF_WARNING(X) {} -#endif /* DWARF_PARSER_RECOVERY_DEBUG */ - -#else /* OS_WINDOWS */ - -#ifdef DWARF_PARSER_RECOVERY_DEBUG /* DWARF_PARSER_RECOVERY_DEBUG */ -#define DWARF_ERROR(X) \ - { \ - int wOldColorAttrs; \ - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; \ - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo); \ - wOldColorAttrs = csbiInfo.wAttributes; \ - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_DWARF_RED | FOREGROUND_INTENSITY); \ - std::cout << "Dwarfparserl Error: " << X << " -> (" << __FILE__ << ":" << std::dec << __LINE__ << ")" << std::endl; \ - SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), wOldColorAttrs);\ - } - -#define DWARF_WARNING(X) \ - { \ - int wOldColorAttrs; \ - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; \ - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo); \ - wOldColorAttrs = csbiInfo.wAttributes; \ - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_INTENSITY); \ - std::cout << "Dwarfparserl Warning: " << X << " -> (" << __FILE__ << ":" << std::dec << __LINE__ << ")" << std::endl; \ - SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), wOldColorAttrs); \ - } -#endif /* DWARF_PARSER_RECOVERY_DEBUG */ - -#ifndef DWARF_PARSER_RECOVERY_DEBUG /* DWARF_PARSER_RECOVERY_DEBUG */ -#define DWARF_ERROR(X) {} -#define DWARF_WARNING(X) {} -#endif /* DWARF_PARSER_RECOVERY_DEBUG */ - -#endif /* OS_WINDOWS */ - -#endif diff --git a/include/retdec/dwarfparser/dwarf_resources.h b/include/retdec/dwarfparser/dwarf_resources.h deleted file mode 100644 index fa1ce0cd3..000000000 --- a/include/retdec/dwarfparser/dwarf_resources.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_resources.h - * @brief Declaration of classes representing resources. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_RESOURCES_H -#define RETDEC_DWARFPARSER_DWARF_RESOURCES_H - -#include -#include - -#include "retdec/dwarfparser/dwarf_parserdefs.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. - -// Locale forward declarations. -class DwarfResources; - -/** - * @class DwarfResources - * @brief Provide access to local resources. - * Must be initialized before use. - * To initialize use initAccess() and initPcReg(). - */ -class DwarfResources -{ - public: - /** - * @brief Representation of real architecture register. - */ - struct RealReg - { - RealReg() : arrayNum(0) {} - RealReg(std::string s, unsigned n) : name(s), arrayNum(n) {} - std::string name; ///< Name of register array which contains this register. - unsigned arrayNum; ///< Index number of this register in register array. - }; - - public: - void initMappingDefault(eDefaultMap m = MIPS); - void dump(); - - Dwarf_Signed getReg(Dwarf_Half n); - Dwarf_Signed getReg(std::string name, Dwarf_Addr number); - Dwarf_Signed getAddr(Dwarf_Addr a); - Dwarf_Addr getPcReg(); - void setReg(Dwarf_Half reg, std::string *n, Dwarf_Addr *a); - - private: - std::map m_regMaps; ///< Mapping of DWARF register numbers to - ///< architecture registers. -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_types.h b/include/retdec/dwarfparser/dwarf_types.h deleted file mode 100644 index 2d389a564..000000000 --- a/include/retdec/dwarfparser/dwarf_types.h +++ /dev/null @@ -1,454 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_types.h - * @brief Declaration of classes representing data types. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_TYPES_H -#define RETDEC_DWARFPARSER_DWARF_TYPES_H - -#include -#include -#include - -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_locations.h" -#include "retdec/dwarfparser/dwarf_utils.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; -class DwarfVarContainer; - -// Locale forward declarations. -class DwarfType; -class DwarfArrayType; -class DwarfEnumType; -class DwarfStructType; -class DwarfUnionType; -class DwarfTypedefType; -class DwarfFunctionType; -class DwarfTypeContainer; - -class DwarfModifierType; -class DwarfConstType; -class DwarfPackedType; -class DwarfPointerType; -class DwarfReferenceType; -class DwarfRestrictType; -class DwarfRValReferenceType; -class DwarfSharedType; -class DwarfVolatileType; - -// Macros for type identification. -#define DEC_DWARF_TYPE_TID static const DwarfType::eDataType TID -#define DEF_DWARF_TYPE_TID(CL, ID) const DwarfType::eDataType CL::TID = ID - -/** - * @class DwarfType - * @brief Base data type, others are derived from it. - */ -class DwarfType : public DwarfBaseElement -{ - public: - /** - * @brief Types of data types. - */ - enum eDataType - { - BASE, ///< Basic data type. - // Composite types. - ARRAY, ///< Data type is an array. - ENUMERATION, ///< Data type is an enumeration. - FUNCTION, ///< Data type is a function. - STRUCTURE, ///< Data type is a structure. - TYPEDEF, ///< Data type is a typedef. - UNION, ///< Data type is an union. - CLASS, ///< Data type is a class. - // Modifier types. - CONSTANT, ///< C or C++ const qualified type. - PACKED, ///< Pascal or Ada packed type. - POINTER, ///< Pointer to an object of the type being modified. - REFERENCE, ///< C++ (lvalue) reference to an object ot the type being modified. - RESTRICT, ///< C restrict qualified type. - RVAL_REFERENCE, ///< C++ rvalue to an object ot the type being modified. - SHARED, ///< UPC shared qualified type. - VOLATILE ///< C or C++ volatile qualified type. - }; - - /** - * @brief Mapping of eDataType enum to strings. - * Entries must be in the same order as in eDataType. - */ - static const char * eDataTypeString[]; - - public: - DwarfType(DwarfTypeContainer *prnt, Dwarf_Off o); - - virtual void load(AttrProcessor &ap); - virtual void dump() const override; - virtual std::string toLLVMString() const; - virtual std::string toLLVMStringIdentified() const; - Dwarf_Unsigned getBitSize() const; - Dwarf_Unsigned getByteSize() const; - DwarfType *getUnderlyingType(); - std::string dumpNameAndOffset() const; - - // - // All data types are referenced as pointers to this base class. - // TODO: not sure about these, i might be dangerous to use strict T::TID. - // - template bool constructed_as() - { - return (dynamic_cast(this) != nullptr ? true : false); - } - template T* leaf_cast() - { - return dynamic_cast(this); - } - - public: - DEC_DWARF_TYPE_TID; - Dwarf_Unsigned bitSize; ///< Bit size of data type. - Dwarf_Unsigned encoding; ///< DWARF Encoding of base type (valid only for base types). - eDataType dataType; ///< Type of data type. -}; - -/** - * @class DwarfArrayType - * @brief Array data type. - */ -class DwarfArrayType : public DwarfType -{ - public: - using dimension_it = std::vector::iterator; - using const_dimension_it = std::vector::const_iterator; - - public: - DwarfArrayType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - void addDimension(Dwarf_Unsigned d); - void updateSize(); - std::size_t dimensionCount(); - - DEC_DWARF_TYPE_TID; - DwarfType *baseType; ///< Pointer to data type object of array elements. - std::vector dimensionBounds; ///< Array bounds. bound(int[3]) = 2. -}; - -/** - * @class DwarfEnumType - * @brief Enumeration data type. - */ -class DwarfEnumType : public DwarfType -{ - public: - /** - * @brief Structure representing single enumeration member. - */ - struct EnumMember - { - std::string name; ///< Name of member. - Dwarf_Signed constVal; ///< Constant value of member. - }; - - using member_t = std::vector ; - using member_const_it_t = member_t::const_iterator ; - - public: - DwarfEnumType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - void addMember(EnumMember m); - std::size_t memberCount(); - - DEC_DWARF_TYPE_TID; - DwarfType *baseType; ///< Pointer to data type of elements. C is not using it. - member_t members; ///< Vector of enumeration members. -}; - -/** - * @class DwarfStructType - * @brief Structure data type. - */ -class DwarfStructType : public DwarfType -{ - public: - /** - * @brief Structure representing single structure member. - */ - class StructMember - { - public: - StructMember() : - type(nullptr), location(nullptr), bitSize(EMPTY_UNSIGNED), bitOffset(EMPTY_UNSIGNED), access(DW_ACCESS_public) - {} - - void setAccess(Dwarf_Unsigned a) - { access = (a==DW_ACCESS_public || a==DW_ACCESS_protected || a==DW_ACCESS_private) ? a : DW_ACCESS_public; } - Dwarf_Unsigned getAccess() const - { return access; } - - std::string name; ///< Name of this member. - DwarfType *type; ///< Pointer to data type of this member. - DwarfLocationDesc* location; ///< Location of the member. - Dwarf_Unsigned bitSize; ///< Bit size of bit field. - Dwarf_Unsigned bitOffset; ///< Bit offset of bit field. - - private: - Dwarf_Unsigned access; ///< Member accessibility. - }; - - public: - DwarfStructType(DwarfTypeContainer *prnt, Dwarf_Off o); - ~DwarfStructType(); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - void addMember(StructMember m); - void addStaticMember(StructMember m); - std::size_t memberCount(); - - DEC_DWARF_TYPE_TID; - std::vector members; ///< Vector of structure members. - std::vector staticMembers; -}; - -/** - * @class DwarfStructType - * @brief Structure data type. - */ -class DwarfUnionType : public DwarfStructType -{ - public: - DwarfUnionType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfClassType - */ -class DwarfClassType : public DwarfStructType -{ - public: - /** - * @brief Class represents inheritance relationship. - */ - class InheritanceMember - { - public: - InheritanceMember(DwarfClassType *b, Dwarf_Unsigned a) : - base(b), - access((a==DW_ACCESS_public || a==DW_ACCESS_protected || a==DW_ACCESS_private) ? a : DW_ACCESS_public) - { - - } - - DwarfClassType *getBase() const { return base; } - Dwarf_Unsigned getAccess() const { return access; } - - private: - DwarfClassType *base; - Dwarf_Unsigned access; - }; - - public: - DwarfClassType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - DEC_DWARF_TYPE_TID; - - std::vector memberFunctions; - std::vector baseClasses; -}; - -/** - * @class DwarfTypedefType - * @brief Typedef data type. - */ -class DwarfTypedefType : public DwarfType -{ - public: - DwarfTypedefType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - - DEC_DWARF_TYPE_TID; - DwarfType *baseType; ///< Pointer to original data type od this typedef. -}; - -/** - * @class DwarfFunctionType - * @brief Function (subroutine) data type. - */ -class DwarfFunctionType : public DwarfType -{ - public: - DwarfFunctionType(DwarfTypeContainer *prnt, Dwarf_Off o); - ~DwarfFunctionType(); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - - bool hasParams(); - DwarfVarContainer *getParams(); - const DwarfVarContainer *getParams() const; - std::size_t getParamCount() const; - - DEC_DWARF_TYPE_TID; - DwarfType *type; ///< Data type of function. - DwarfFunction *func; ///< Real function of this type. This may be filled using name of the type. - ///< Name is usually not set, and this is not used at the moment. - bool isVariadic; ///< If true, function has variadic argument following arguments stored in m_params. - - private: - DwarfVarContainer *m_params; ///< Container with parameters of this function. -}; - -/** - * @class DwarfModifierType - * @brief Base class for all data type modifier classes. - */ -class DwarfModifierType : public DwarfType -{ - public: - DwarfModifierType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual void load(AttrProcessor &ap) override; - virtual void dump() const override; - virtual std::string toLLVMString() const override; - virtual std::string toLLVMStringIdentified() const override; - - DwarfType *baseType; ///< Pointer to data type this pointer is pointing to. -}; - -/** - * @class DwarfConstType - * @brief Constant data type modifier. - */ -class DwarfConstType : public DwarfModifierType -{ - public: - DwarfConstType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfPackedType - * @brief Packed data type modifier. - */ -class DwarfPackedType : public DwarfModifierType -{ - public: - DwarfPackedType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfPointerType - * @brief Pointer data type modifier. - */ -class DwarfPointerType : public DwarfModifierType -{ - public: - DwarfPointerType(DwarfTypeContainer *prnt, Dwarf_Off o); - virtual std::string toLLVMString() const override; - unsigned getPointerLevel(); - - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfReferenceType - * @brief Reference data type modifier. - */ -class DwarfReferenceType : public DwarfModifierType -{ - public: - DwarfReferenceType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfRestrictType - * @brief Restrict data type modifier. - */ -class DwarfRestrictType : public DwarfModifierType -{ - public: - DwarfRestrictType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfRValReferenceType - * @brief Rvalue reference data type modifier. - */ -class DwarfRValReferenceType : public DwarfModifierType -{ - public: - DwarfRValReferenceType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfSharedType - * @brief Shared data type modifier. - */ -class DwarfSharedType : public DwarfModifierType -{ - public: - DwarfSharedType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfVolatileType - * @brief Volatile data type modifier. - */ -class DwarfVolatileType : public DwarfModifierType -{ - public: - DwarfVolatileType(DwarfTypeContainer *prnt, Dwarf_Off o); - DEC_DWARF_TYPE_TID; -}; - -/** - * @class DwarfTypeContainer - * @brief Data type container. - */ -class DwarfTypeContainer : public DwarfBaseContainer -{ - public: - DwarfTypeContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr); - virtual void dump() const override; - - DwarfType *checkIfLoaded(Dwarf_Off off); - virtual DwarfType *loadAndGetDie(Dwarf_Die die, unsigned lvl) override; - - DwarfType *getTypeByName(std::string n); - DwarfType *getVoid(); - - int getDieFlags(Dwarf_Die die, unsigned lvl); - - private: - DwarfType m_void; ///< Void data type. - std::map m_typeCache; ///< Cache for fast type search based on die offset. -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_utils.h b/include/retdec/dwarfparser/dwarf_utils.h deleted file mode 100644 index f75697307..000000000 --- a/include/retdec/dwarfparser/dwarf_utils.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_utils.h - * @brief Declaration of utility functions and classes. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_UTILS_H -#define RETDEC_DWARFPARSER_DWARF_UTILS_H - -#include - -#include -#include - -namespace retdec { -namespace dwarfparser { - -class DwarfType; -class DwarfLocationDesc; - -// Extern forward declarations. - -// Locale forward declarations. -class AttrProcessor; - -/** - * Safe encapsulation of libdwarf functions that are getting - * data from attributes. - */ - Dwarf_Addr getAttrAddr(Dwarf_Attribute attr); - Dwarf_Unsigned getAttrNumb(Dwarf_Attribute attr); - std::string getAttrStr(Dwarf_Attribute attr); - Dwarf_Off getAttrRef(Dwarf_Attribute attr); - Dwarf_Off getAttrGlobalRef(Dwarf_Attribute attr); - Dwarf_Bool getAttrFlag(Dwarf_Attribute attr); - Dwarf_Block *getAttrBlock(Dwarf_Attribute attr); - Dwarf_Sig8 getAttrSig(Dwarf_Attribute attr); - void getAttrExprLoc(Dwarf_Attribute attr, Dwarf_Unsigned *exprlen, Dwarf_Ptr *ptr); - - std::string getDwarfError(Dwarf_Error &error); - - bool getDieFromOffset(Dwarf_Debug dbg, Dwarf_Off off, Dwarf_Die &die); - -/** - * @class AttrProcessor - * @brief Helper class providing access to DIE's attributes. - * Class is initialized with DIE which attributes will be processed. - */ -class AttrProcessor -{ - public: - AttrProcessor(Dwarf_Debug dbg, Dwarf_Die die, DwarfFile *parent); - - bool get(Dwarf_Half attrCode, std::string& ret); - bool get(Dwarf_Half attrCode, const std::string* &ret); - bool get(Dwarf_Half attrCode, Dwarf_Unsigned& ret); - bool get(Dwarf_Half attrCode, Dwarf_Signed& ret); - bool get(Dwarf_Half attrCode, Dwarf_Bool& ret); - bool get(Dwarf_Half attrCode, DwarfLocationDesc* &ret); - bool get(Dwarf_Half attrCode, DwarfType* &ret); - bool geti(Dwarf_Half attrCode, int& ret); - - Dwarf_Off getDieOff(); - - private: - Dwarf_Debug m_dbg; ///< Libdwarf structure representing DWARF file. - Dwarf_Die m_die; ///< Source DIE which atributes will be processed. - DwarfFile *m_parent; ///< Parent dwarfparser representation of DWARF file. - - int m_res; ///< Global return value. - Dwarf_Error m_error; ///< Global error code. -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/dwarfparser/dwarf_vars.h b/include/retdec/dwarfparser/dwarf_vars.h deleted file mode 100644 index 18308680a..000000000 --- a/include/retdec/dwarfparser/dwarf_vars.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file include/retdec/dwarfparser/dwarf_vars.h - * @brief Declaration of classes representing variables. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef RETDEC_DWARFPARSER_DWARF_VARS_H -#define RETDEC_DWARFPARSER_DWARF_VARS_H - -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_locations.h" -#include "retdec/dwarfparser/dwarf_types.h" - -namespace retdec { -namespace dwarfparser { - -// Extern forward declarations. -class DwarfFile; - -// Locale forward declarations. -class DwarfVar; -class DwarfVarContainer; - -/** - * @class DwarfVar - * @brief Variable object. - */ -class DwarfVar : public DwarfBaseElement -{ - public: - /** - * @brief Variable flags. - */ - enum eFlags - { - EMPTY = 0, ///< Empty. - CONSTANT = 1 << 1, ///< This is constant, not variable. - POINTER = 1 << 2, ///< Variable is a pointer. - RESTRICT = 1 << 3, ///< Variable is restrict. - VOLATILE = 1 << 4 ///< Variable is volatile. - }; - - public: - DwarfVar(DwarfVarContainer *prnt, Dwarf_Off off, DwarfBaseElement::type_t t = DwarfBaseElement::VAR); - virtual ~DwarfVar() override; - virtual void dump() const override; - - bool hasLocation(); - void mergeWith(DwarfVar *o); - DwarfLocationDesc::cLocType getLocation(std::string *n, Dwarf_Addr *a, Dwarf_Addr pc=0); - bool isOnStack(Dwarf_Signed *a, bool *deref, Dwarf_Addr pc = 0, int *regNum=nullptr); - - bool isConstant() const; - bool isPointer() const; - bool isRestrict() const; - bool isVolatile() const; - - public: - int flags; ///< Flags of variable. - DwarfType *type; ///< Data type of variable. - DwarfLocationDesc *location; ///< Location descriptor of variable. -}; - -/** - * @class DwarfVarContainer - * @brief Variable container. - */ -class DwarfVarContainer : public DwarfBaseContainer -{ - public: - DwarfVarContainer(DwarfFile *file, DwarfBaseElement *elem = nullptr); - virtual void dump() const override; - - virtual DwarfVar *loadAndGetDie(Dwarf_Die die, unsigned lvl) override; - DwarfVar *getVarByName(std::string n); - - DwarfVar *addParameter(DwarfVar *n); -}; - -} // namespace dwarfparser -} // namespace retdec - -#endif diff --git a/include/retdec/fileformat-libdwarf-interface/README b/include/retdec/fileformat-libdwarf-interface/README deleted file mode 100644 index a4bc0cc11..000000000 --- a/include/retdec/fileformat-libdwarf-interface/README +++ /dev/null @@ -1,11 +0,0 @@ -########################################## -# -# Makefile -# -########################################## - -# -# !!! THIS IS NOT USED, ONLY SOURCES ARE ADDED TO APPLICATION COMPILATION. -# !!! WHEN I TRIED TO CREATE .a FROM INTERFACE THE SAME CODE THAT WORKED -# !!! BEFORE CAUSED SEG FAULT. -# diff --git a/include/retdec/fileformat-libdwarf-interface/bin_interface.h b/include/retdec/fileformat-libdwarf-interface/bin_interface.h deleted file mode 100644 index e7c8dca19..000000000 --- a/include/retdec/fileformat-libdwarf-interface/bin_interface.h +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @file include/retdec/fileformat-libdwarf-interface/bin_interface.h - * @brief Definition of binary interface working with input files. - * Based on declarations of interface in libdwarf.h - * and definition of ELF interface in dwarf_elf_access.cpp. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#ifndef BININT_H_ -#define BININT_H_ - -#include -#include -#include -#include -#include - -#include -#include - -#include "retdec/fileformat/format_factory.h" -#include "retdec/fileformat/file_format/file_format.h" - -/** - * @class BinInt. - * @brief This class creates binary interface to access input files. - */ -class BinInt -{ - // - // Public class methods. - // - public: - /** - * @brief Initialize class and dwarf object access method structure. - * @param fileName Name of input file to load. - * @param fileParser Parser of input file (optional). - * @note Function which relocate a section is not used at the moment. - */ - BinInt(std::string fileName, retdec::fileformat::FileFormat *fileParser = nullptr) : - m_fileName(fileName), - m_fileParser(fileParser), - m_parserInsteadOfPath(m_fileParser && m_fileParser->isInValidState()), - m_success(true), - m_binInt(nullptr), - dwarf_binint_object_access_methods() - { - dwarf_binint_object_access_init(); - - struct Dwarf_Obj_Access_Methods_s p = { - dwarf_binint_object_access_get_section_info, - dwarf_binint_object_access_get_byte_order, - dwarf_binint_object_access_get_length_size, - dwarf_binint_object_access_get_pointer_size, - dwarf_binint_object_access_get_section_count, - dwarf_binint_object_access_load_section, - nullptr //dwarf_binint_object_relocate_a_section - }; - - dwarf_binint_object_access_methods = p; - } - - /** - * @brief Clean up input file object access interface. - */ - ~BinInt() - { - delete m_binInt; - } - - /** - * @brief Return input file binary interface. - * @return Input file binary interface. - */ - Dwarf_Obj_Access_Interface *getInt() - { - return m_binInt; - } - - /** - * @brief Tells caller if input file file was loaded successfully or not. - * @return True if success, false otherwise. - */ - bool success() - { - return m_success; - } - - // - // TODO: maybe relocate this to ctor. - // - private: - /** - * @brief Initialize input file binary interface. - */ - void dwarf_binint_object_access_init() - { - // Open input object file. - retdec::fileformat::FileFormat *objFile = nullptr; - if(m_parserInsteadOfPath) - { - objFile = m_fileParser; - } - else - { - m_newParserPtr = retdec::fileformat::createFileFormat(m_fileName); - if(m_newParserPtr) - { - objFile = m_newParserPtr.get(); - } - } - - // Alloc interface descriptor. - m_binInt = new Dwarf_Obj_Access_Interface; - if (!m_binInt || !objFile) - { - m_success = false; - return; - } - - // Initialize the interface struct. - m_binInt->object = objFile; - m_binInt->methods = &dwarf_binint_object_access_methods; - m_success = objFile->isInValidState(); - return; - } - - // - // Access functions as defined in libdwarf.h. - // - private: - /** - * @brief Get address, size, and name info about a section. - * @param obj_in Object file structure. - * @param section_index Section index. - * @param ret_scn Structure where section info will be placed. - * @param error A pointer to an integer in which an error code may be stored. - * @return Return code. - */ - static int dwarf_binint_object_access_get_section_info( - void* obj_in, - Dwarf_Half section_index, - Dwarf_Obj_Access_Section* ret_scn, - int* error) - { - auto *obj = static_cast(obj_in); - - const auto *sec = obj->getSection(section_index); - if (!sec) - { - *error = DW_DLE_MDE; - return DW_DLV_ERROR; - } - - ret_scn->size = sec->getSizeInFile(); - ret_scn->addr = sec->getAddress(); - ret_scn->name = sec->getNameAsCStr(); - ret_scn->link = 0; // TODO: meaningless? - - return DW_DLV_OK; - } - - /** - * @brief Find out if file is big-endian or little endian. - * @param obj_in Object file structure. - * @return Endianness of object. - */ - static Dwarf_Endianness dwarf_binint_object_access_get_byte_order( - void* obj_in) - { - auto *obj = static_cast(obj_in); - - if (obj->isLittleEndian()) - { - return DW_OBJECT_LSB; - } - else if (obj->isBigEndian()) - { - return DW_OBJECT_MSB; - } - else - { - // This may happen in input file (undefined) but there is no - // dwarflib option for it. - return DW_OBJECT_LSB; - } - } - - /** - * @brief Get the size of a length field in the underlying object file. - * @param obj_in Object file structure. - * @return Size of length. - * - * TODO: what is length size??? is it same as word length??? - */ - static Dwarf_Small dwarf_binint_object_access_get_length_size( - void* obj_in) - { - auto *obj = static_cast(obj_in); - return static_cast(obj->getBytesPerWord()); - } - - /** - * @brief Get the size of a pointer field in the underlying object file. - * @param obj_in Object file structure. - * @return Size of pointer. - */ - static Dwarf_Small dwarf_binint_object_access_get_pointer_size( - void* obj_in) - { - auto *obj = static_cast(obj_in); - return static_cast(obj->getBytesPerWord()); - } - - /** - * @brief Get the number of sections in the object file. - * @param obj_in Object file structure. - * @return Number of sections. - */ - static Dwarf_Unsigned dwarf_binint_object_access_get_section_count( - void * obj_in) - { - auto *obj = static_cast(obj_in); - return obj->getNumberOfSections(); - } - - /** - * @brief Get a pointer to an array of bytes that represent the section. - * @param obj_in Object file structure. - * @param section_index Index of section which data to get. - * @param section_data The address of a pointer where sec data will be placed. - * @param error Pointer to integer for returning libdwarf-defined error numbers. - * @return Return code. - */ - static int dwarf_binint_object_access_load_section( - void* obj_in, - Dwarf_Half section_index, - Dwarf_Small** section_data, - int* error) - { - std::map>::iterator fIt = BinInt::secBytes().find(section_index); - if (fIt != BinInt::secBytes().end()) - { - *section_data = fIt->second.data(); - return DW_DLV_OK; - } - else - { - auto *obj = static_cast(obj_in); - if (!obj || !section_data) - { - *error = DW_DLE_MDE; - return DW_DLV_ERROR; - } - - const auto *fSec = obj->getSection(section_index); - std::vector bytes; - if (!fSec || !fSec->getBytes(bytes)) - { - *error = DW_DLE_MDE; - return DW_DLV_ERROR; - } - - BinInt::secBytes()[section_index] = bytes; - - *section_data = BinInt::secBytes()[section_index].data(); - - if (*section_data == NULL) - { - *error = DW_DLE_MDE; - return DW_DLV_ERROR; - } - - return DW_DLV_OK; - } - } - - /** - * @brief Relocate a section. - * @param obj_in Object file structure. - * @param section_index Index of section to relocate. - * @param dbg Libdwarf representation of file. - * @param error Pointer to integer for returning libdwarf-defined error numbers. - * @return Return code. - */ - static int dwarf_binint_object_relocate_a_section( - void* obj_in, - Dwarf_Half section_index, - Dwarf_Debug dbg, - int* error) - { - return DW_DLV_OK; - } - - // - // When this module had both header and source file, we declared static variable - // secBytes here in header and defined it in source. - // However, it is easier to use this module when it is header only. - // The problem is that static member variables can not be defined in header files. - // Therefore, we hack it by using static member getter method which contains - // static local variable in its body. - // - // Matula: I have no idea why there is (must be?) a static member variable in the - // first place, but it seems to work, so be it. - // - private: - static std::map>& secBytes() - { - static std::map> secBytes; - return secBytes; - } - - // - // Class data. - // - private: - std::string m_fileName; - std::unique_ptr m_newParserPtr; - retdec::fileformat::FileFormat *m_fileParser; - bool m_parserInsteadOfPath; - bool m_success; - Dwarf_Obj_Access_Interface *m_binInt; - struct Dwarf_Obj_Access_Methods_s dwarf_binint_object_access_methods; -}; - -#endif diff --git a/include/retdec/fileformat-libdwarf-interface/dwarfdump.add b/include/retdec/fileformat-libdwarf-interface/dwarfdump.add deleted file mode 100644 index 7ba22e982..000000000 --- a/include/retdec/fileformat-libdwarf-interface/dwarfdump.add +++ /dev/null @@ -1,54 +0,0 @@ -# -# This file contains code that needs to be added to dwarfdump2 -# to enable inputs in our format. -# It needs to be modified manually because new versions might change -# original dawrfdump.cc and automatic patch may screw it up. -# - -// Add include. -// Simple or with more complex path -- depends on make settings. -// -#include "bin_interface.h" - -// Make sure input files will be further processed in main(). -// - -// replace - /* not a 64-bit obj either! */ - /* dwarfdump is quiet when not an object */ -// with - process_one_file(elf, file_name, archive, &config_file_data); -// or just always call process_one_file. - -// Add bin-interface to process_one_file(). -// - -// add - Dwarf_Handler errHand = 0; - Dwarf_Ptr errArg = 0; - - BinInt *binInt = new BinInt(file_name); - if (binInt->success()) - { - dres = dwarf_object_init(binInt->getInt(), - errHand, errArg, &dbg, &err); - - // Input file has no DWARF information. - if (dres == DW_DLV_NO_ENTRY) - { - cout <<"No DWARF information present in " << file_name < -#include -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_functions.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param type Type of the base element. - * @param prnt Pointer to parent container that contains this element. - * @param off Offset associated with this element in DWARF file - unique ID. - */ -DwarfBaseElement::DwarfBaseElement(type_t type, DwarfBaseContainer *prnt, Dwarf_Off off) : - m_type(type), - m_parent(prnt), - m_cuParent(m_parent->getParentFile()->m_activeCU) -{ - if (m_parent) - m_parent->off2data[off] = this; -} - -/** - * - */ -void DwarfBaseElement::addOffset(Dwarf_Off o) -{ - if (m_parent) - m_parent->off2data[o] = this; -} - -/** - * - */ -string DwarfBaseElement::getDwarfdump2OffsetString() const -{ - stringstream ret; - ret << "("; - ret << ")"; - return ret.str(); -} - -/** - * @brief Get libdwarf's debug file. - */ -Dwarf_Debug &DwarfBaseElement::getLibdwarfDebug() const -{ - return getParentFile()->getDwarfDebug(); -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_cu.cpp b/src/dwarfparser/dwarf_cu.cpp deleted file mode 100644 index 37bf1f618..000000000 --- a/src/dwarfparser/dwarf_cu.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_cu.cpp - * @brief Implementaion of classes representing Compilation Units. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include -#include - -#include "retdec/dwarfparser/dwarf_cu.h" -#include "retdec/dwarfparser/dwarf_file.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param file Pointer to dwarfparser representation of DWARF file which owns this container. - * @param elem Pointer to parent element that owns this container. - */ -DwarfCUContainer::DwarfCUContainer(DwarfFile *file, DwarfBaseElement *elem) : - DwarfBaseContainer(file, elem) -{ - -} - -/** - * @brief Get all data from compilation unit DIE. - * @param cuDie Compilation unit DIE. - * @param lvl Level (depth) of this die. - * @return Pointer to newly created CU object or nullptr if failed. - */ -DwarfCU *DwarfCUContainer::loadAndGetDie(Dwarf_Die cuDie, unsigned) -{ - // Get source files. - char **srcFiles; - Dwarf_Signed fileCnt; - m_res = dwarf_srcfiles(cuDie, &srcFiles, &fileCnt, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_WARNING("dwarf_srcfiles() in loadDie() failed.\n" - "Libdwarf error: " << getDwarfError(m_error)); - } - - AttrProcessor ap(m_parentFile->m_dbg, cuDie, m_parentFile); - - DwarfCU *newCU = new DwarfCU(this, ap.getDieOff()); - - // Copy source files to new CU. - if (m_res == DW_DLV_OK) - { - for (int i=0; iaddSrcFile(srcFiles[i]); - dwarf_dealloc(m_parentFile->m_dbg, srcFiles[i], DW_DLA_STRING); - } - - dwarf_dealloc(m_parentFile->m_dbg, srcFiles, DW_DLA_LIST); - } - - // Use special class to get attributes that we want. - ap.get(DW_AT_comp_dir, newCU->compDir); - ap.get(DW_AT_name, newCU->name); - ap.get(DW_AT_producer, newCU->producer); - ap.get(DW_AT_low_pc, newCU->lowAddr); - ap.get(DW_AT_high_pc, newCU->highAddr); - ap.get(DW_AT_language, newCU->language); - - // Add new CU to container and set as active. - m_data.push_back(newCU); - m_parentFile->m_activeCU = newCU; - - return newCU; -} - -/** - * @brief Print contents of this container. - */ -void DwarfCUContainer::dump() const -{ - cout << endl; - cout << "==================== CUs ====================" << endl; - - DwarfBaseContainer::dump(); - - cout << endl; -} - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfCU::DwarfCU(DwarfCUContainer *prnt, Dwarf_Off o) : - DwarfBaseElement(DwarfBaseElement::CU, reinterpret_cast*>(prnt), o), - lowAddr(0), - highAddr(0), - language(0) -{ - -} - -/** - * @brief Get number of source file of this compilation unit. - * @return Number of source files. - */ -std::size_t DwarfCU::srcFilesCount() -{ - return m_srcFiles.size(); -} - -/** - * @brief Add source file to compilation unit. - * @param f Name of source file. - */ -void DwarfCU::addSrcFile(string f) -{ - m_srcFiles.push_back(f); -} - -/** - * @brief Get source file by its index. - * @param idx Index of source file to get. - * @return Pointer to source file name or nullptr if index out of range. - */ -string *DwarfCU::getSrcFile(unsigned idx) -{ - if (idx < srcFilesCount()) - { - list::iterator srcFileIt = m_srcFiles.begin(); - advance(srcFileIt, idx); - return &(*srcFileIt); - } - else - { - DWARF_ERROR("getSrcFile(idx): index out of range."); - return nullptr; - } -} - -/** - * @brief This method finds record in list of source files with - * the same name as parameter and returns pointer to it. - * @param f Name of source file to find. - * @param ret Address of pointer where result will be saved. - * @return DW_DLV_OK if record was found, DW_DLV_NO_ENTRY if not. - */ -int DwarfCU::findSrcFile(string f, const string **ret) -{ - list::const_iterator srcFileIt = m_srcFiles.begin(); - while (srcFileIt != m_srcFiles.end()) - { - if (*srcFileIt == f) - { - *ret = &(*srcFileIt); - return DW_DLV_OK; - } - - ++srcFileIt; - } - - // If it gets here, no record was found. - return DW_DLV_NO_ENTRY; -} - -bool DwarfCU::IsLanguageC() const -{ - return - language == DW_LANG_C89 || - language == DW_LANG_C || - language == DW_LANG_C99; -} - -bool DwarfCU::IsLanguageCpp() const -{ - return - language == DW_LANG_C_plus_plus; -} - -/** - * @brief Print contents of this class. - */ -void DwarfCU::dump() const -{ - cout << "CU : " << name << endl; - cout << "CU DIR : " << compDir << endl; - cout << "CU lowpc : " << hex << lowAddr << endl; - cout << "CU highpc : " << hex << highAddr << endl; - - list::const_iterator srcFileIt = m_srcFiles.begin(); - while (srcFileIt != m_srcFiles.end()) - { - cout << "\t" << *(srcFileIt) << endl; - ++srcFileIt; - } - - cout << endl; -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_file.cpp b/src/dwarfparser/dwarf_file.cpp deleted file mode 100644 index 40f7cd705..000000000 --- a/src/dwarfparser/dwarf_file.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_file.cpp - * @brief Implementaion of DwarfFile class which provides high-level access - * to DWARF debugging informations. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include -#include - -#include "retdec/utils/os.h" -#include "retdec/dwarfparser/dwarf_file.h" - -#ifdef OS_WINDOWS - #include -#else - #include -#endif - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor -- create containers and load data from input file. - * @param fileName Name of file to open. - * @param fileParser Parser of input file (optional) - */ -DwarfFile::DwarfFile(string fileName, retdec::fileformat::FileFormat *fileParser) : - m_CUs(this), - m_lines(this), - m_functions(this), - m_types(this), - m_globalVars(this), - m_hasDwarf(false), - m_res(0), - m_dbg(nullptr), - m_fd(0), - m_error(nullptr), - m_activeCU(nullptr) -{ - loadFile(fileName, fileParser); -} - -/** - * @brief dctor -- destroy containers. - */ -DwarfFile::~DwarfFile() -{ - if (m_fd && m_dbg) - { - dwarf_finish(m_dbg, &m_error); -#ifdef OS_WINDOWS - _close(m_fd); -#else - close(m_fd); -#endif - } - else - { - dwarf_object_finish(m_dbg, &m_error); - } -} - -/** - * @brief Open file and get DWARF info. - * @param fileName Name of file to open. - * @param fileParser Parser of input file (optional) - * @return True if input file contains DWARF information, false otherwise. - * - * Binary interface is used to access input file at first. - * If it fails standard ELF interface provided by libdwarf is used. - */ -bool DwarfFile::loadFile(string fileName, retdec::fileformat::FileFormat *fileParser) -{ - Dwarf_Handler errHand = nullptr; - Dwarf_Ptr errArg = nullptr; - - // It is possible to load input file with our backend. - BinInt binInt(fileName, fileParser); - if (binInt.success()) - { - m_res = dwarf_object_init(binInt.getInt(), - errHand, errArg, &m_dbg, &m_error); - - // Input file has no DWARF information. - if (m_res == DW_DLV_NO_ENTRY) - { - DWARF_WARNING("File: \"" << fileName << "\" has no DWARF information."); - return false; - } - // Something went wrong. - else if (m_res != DW_DLV_OK) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return false; - } - - resources.initMappingDefault(); - - loadFileCUs(); - m_hasDwarf = true; - } - - // Our binary backend can not be used - // --> try to use ELF interface. - else - { - DWARF_WARNING("Using ELF interface."); - -#ifdef OS_WINDOWS - if ((m_fd = _open(fileName.c_str(), _O_RDONLY, 0)) < 0) -#else - if ((m_fd = open(fileName.c_str(), O_RDONLY, 0)) < 0) -#endif - { - DWARF_ERROR("File: \"" << fileName << "\" can not be opened."); - return false; - } - - m_res = dwarf_init(m_fd, DW_DLC_READ, errHand, errArg, &m_dbg, &m_error); - - if (m_res == DW_DLV_NO_ENTRY) - { - DWARF_WARNING("File: \"" << fileName << "\" has no DWARF information."); - return false; - } - else if(m_res != DW_DLV_OK) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return false; - } - - // Init register mapping by default values. - resources.initMappingDefault(); - - loadFileCUs(); - m_hasDwarf = true; - } - - makeStructTypesUnique(); - - return m_hasDwarf; -} - -/** - * Same-named structures may exist. We need to rename them -> make them unique, - * otherwise, string based (LLVM) type representation can not be used. - * Several same named structures would be generated and it would not be possible - * to distinguish their uses from one another. - */ -void DwarfFile::makeStructTypesUnique() -{ - std::map typeMap; - for (auto& t : m_types) - { - if (t->constructed_as()) - { - auto fIt = typeMap.find(t->name); - if (fIt == typeMap.end()) - { - typeMap[t->name] = 1; - } - else - { - t->name = t->name + "_" + std::to_string(fIt->second); - ++fIt->second; - } - } - } -} - -/** - * @brief Find out if input file contains DWARF information. - * @return True if input file contains DWARF information, false otherwise. - */ -bool DwarfFile::hasDwarfInfo() -{ - return m_hasDwarf; -} - -/** - * @brief Iterate over DWARF file's CUs. - */ -void DwarfFile::loadFileCUs() -{ - Dwarf_Unsigned cu_header_length = 0; - Dwarf_Half version_stamp = 0; - Dwarf_Unsigned abbrev_offset = 0; - Dwarf_Half address_size = 0; - Dwarf_Half offset_size = 0; - Dwarf_Half extension_size = 0; - Dwarf_Sig8 signature; - Dwarf_Unsigned typeoffset = 0; - Dwarf_Unsigned next_cu_header = 0; - - // Iterate over CU headers. - while (dwarf_next_cu_header_c( - m_dbg, - is_info, - &cu_header_length, - &version_stamp, - &abbrev_offset, - &address_size, - &offset_size, - &extension_size, - &signature, - &typeoffset, - &next_cu_header, - &m_error) == DW_DLV_OK) - { - Dwarf_Die cuDie = nullptr; - - // CU have single sibling - CU DIE. - // nullptr - descriptor of first die in CU. - m_res = dwarf_siblingof_b(m_dbg, nullptr, is_info, &cuDie, &m_error); - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return; - } - else if (m_res == DW_DLV_NO_ENTRY) - { - return; - } - - int lvl = 0; - loadCUtree(cuDie, nullptr, lvl); - - dwarf_dealloc(m_dbg, cuDie, DW_DLA_DIE); - } -} - -/** - * @brief Gets a CU DIE at first and recursively load all DIEs in tree. - * @param inDie Input die - * @param parent Parent element or nullptr. - * @param lvl Level (depth) of this die. - */ -void DwarfFile::loadCUtree(Dwarf_Die inDie, DwarfBaseElement* parent, int lvl) -{ - Dwarf_Die curDie = inDie; - DwarfBaseElement* siblingElement = parent; - - loadDIE(curDie, siblingElement, lvl); - - // Siblings and childs. - while (1) - { - // Get child. - Dwarf_Die child = nullptr; - m_res = dwarf_child(curDie, &child, &m_error); - - if(m_res == DW_DLV_ERROR) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return; - } - - // Has child -> recursion. - if(m_res == DW_DLV_OK) - { - loadCUtree(child, siblingElement, lvl+1); - } - - // No entry -> no child. - Dwarf_Die sib_die = nullptr; - m_res = dwarf_siblingof_b(m_dbg, curDie, is_info, &sib_die, &m_error); - - if(m_res == DW_DLV_ERROR) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return; - } - - // Done at this level. - if(m_res == DW_DLV_NO_ENTRY) - { - break; - } - - // res == DW_DLV_OK - if(curDie != inDie) - { - dwarf_dealloc(m_dbg, curDie, DW_DLA_DIE); - } - - curDie = sib_die; - siblingElement = parent; - loadDIE(curDie, siblingElement, lvl); - } -} - -/** - * @brief Get DIE and load all its contents to dwarfparser representation. - * @param die DIE to load. - * @param parent Input parent element. Output newly loaded element or nullptr. - * @param lvl Level (depth) of this die. - */ -void DwarfFile::loadDIE(Dwarf_Die die, DwarfBaseElement* &parent, int lvl) -{ - DwarfBaseElement* parentElement = parent; - parent = nullptr; - - // DIE name -- unused, but without it there is a SEG FAULT for some reason. - // - char *dieName = nullptr; - bool localname = false; - - m_res = dwarf_diename(die, &dieName, &m_error); - - if(m_res == DW_DLV_ERROR) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return; - } - if(m_res == DW_DLV_NO_ENTRY) - { - localname = true; - } - - // DIE TAG. - Dwarf_Half tag = 0; - if (dwarf_tag(die, &tag, &m_error) != DW_DLV_OK) - { - DWARF_ERROR("Libdwarf error: " << getDwarfError(m_error)); - return; - } - - AttrProcessor ap(m_dbg, die, this); - - // Decide what to do based on tag type. - switch (tag) - { - // - // Compilation unit. - // - case DW_TAG_compile_unit: - { - parent = m_CUs.loadAndGetDie(die, lvl); - m_lines.loadAndGetDie(die, lvl); - - break; - } - - // - // Subprogram name == DIE name. - // - case DW_TAG_subprogram: - { - DwarfFunction *tmp = m_functions.loadAndGetDie(die, lvl); - parent = tmp; - - DwarfClassType *activeClass = dynamic_cast(parentElement); - if (tmp && activeClass) - { - activeClass->memberFunctions.push_back(tmp); // TODO: nejak obojsmerne nastavit. - } - break; - } - - // - // Class inheritance. - // - case DW_TAG_inheritance: - { - DwarfType *type = nullptr; - Dwarf_Unsigned access; - - ap.get(DW_AT_type, type); - ap.get(DW_AT_accessibility, access); - - DwarfClassType *activeClass = dynamic_cast(parentElement); - DwarfClassType *base = dynamic_cast(type); - if (base && activeClass) - { - DwarfClassType::InheritanceMember inh(base, access); - activeClass->baseClasses.push_back(inh); - } - - break; - } - - // - // Send all type related DIEs to type class. - // - case DW_TAG_array_type: - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_const_type: - case DW_TAG_enumeration_type: // May be used as DW_TAG_subrange_type - case DW_TAG_file_type: - case DW_TAG_interface_type: - case DW_TAG_packed_type: - case DW_TAG_pointer_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_reference_type: - case DW_TAG_restrict_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_set_type: - case DW_TAG_shared_type: - case DW_TAG_string_type: - case DW_TAG_structure_type: - case DW_TAG_subroutine_type: - case DW_TAG_thrown_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_type: - case DW_TAG_volatile_type: - { - auto p = m_types.loadAndGetDie(die, lvl); - Dwarf_Die child = nullptr; - if (dwarf_child(die, &child, &m_error) == DW_DLV_OK) - { - parent = p; - } - break; - } - - // - // Belongs to active array. - // - case DW_TAG_subrange_type: - { - DwarfArrayType *activeArray = dynamic_cast(parentElement); - if (activeArray != nullptr) - { - Dwarf_Unsigned bound; - ap.get(DW_AT_upper_bound, bound); - activeArray->addDimension(bound); - } - break; - } - - // - // Belongs to active enumeration. - // - case DW_TAG_enumerator: - { - DwarfEnumType *activeEnum = dynamic_cast(parentElement); - if (activeEnum != nullptr) - { - DwarfEnumType::EnumMember m; - ap.get(DW_AT_name, m.name); - ap.get(DW_AT_const_value, m.constVal); - activeEnum->addMember(m); - } - break; - } - - // - // Belongs to active structure. - // - case DW_TAG_member: - { - DwarfStructType *activeStruct = dynamic_cast(parentElement); - if (activeStruct != nullptr) - { - DwarfStructType::StructMember m; - m.type = nullptr; - m.location = nullptr; - m.bitSize = EMPTY_UNSIGNED; - m.bitOffset = EMPTY_UNSIGNED; - ap.get(DW_AT_name, m.name); - ap.get(DW_AT_type, m.type); - ap.get(DW_AT_data_member_location, m.location); - ap.get(DW_AT_bit_size, m.bitSize); - ap.get(DW_AT_bit_offset, m.bitOffset); - - Dwarf_Bool isStatic; - ap.get(DW_AT_external, isStatic); - - Dwarf_Unsigned a; - ap.get(DW_AT_accessibility, a); - m.setAccess(a); - - if (m.location != nullptr) - { - m.location->setParent(activeStruct); - } - if (isStatic) - activeStruct->addStaticMember(m); - else - activeStruct->addMember(m); - } - break; - } - - // - // Variables and constants. - // - case DW_TAG_variable: - { - // Global variable. - if (dynamic_cast(parentElement)) //DwarfCU *activeCu - { - m_globalVars.loadAndGetDie(die, lvl); - } - // Variable belongs to some function. - else if (DwarfFunction *activeFunc = dynamic_cast(parentElement)) - { - activeFunc->getVars()->loadAndGetDie(die, lvl); - } - - break; - } - - // - // Function parameters -- belong to active function or function type. - // - case DW_TAG_formal_parameter: - { - DwarfFunction *activeFunc = dynamic_cast(parentElement); - if (activeFunc != nullptr && !activeFunc->isDeclaration) - { - activeFunc->getParams()->loadAndGetDie(die, lvl); - } - else - { - DwarfFunctionType *activeFuncType = dynamic_cast(parentElement); - if (activeFuncType != nullptr) - { - activeFuncType->getParams()->loadAndGetDie(die, lvl); - } - } - break; - } - - // - // Variadic parameters. - // - case DW_TAG_unspecified_parameters: - { - DwarfFunction *activeFunc = - dynamic_cast(parentElement); - if (activeFunc != nullptr) - { - activeFunc->isVariadic = true; - } - else - { - DwarfFunctionType *activeFuncType = - dynamic_cast(parentElement); - if (activeFuncType != nullptr) - { - activeFuncType->isVariadic = true; - } - } - break; - } - - // - // Block -- not processed at the moment, but we want to keep old parent - // so that DIEs on lower level connect with parents even if block DIEs - // in the middle are not processed. - // - case DW_TAG_catch_block: - case DW_TAG_common_block: - case DW_TAG_label: - case DW_TAG_lexical_block: - case DW_TAG_module: - case DW_TAG_namespace: - case DW_TAG_partial_unit: - case DW_TAG_try_block: - { - parent = parentElement; - break; - } - - // - // DW_TAG_template_type_parameter is in standard. - // - case DW_TAG_template_type_parameter: - { - DwarfFunction *activeFunc = dynamic_cast(parentElement); - if (activeFunc != nullptr && !activeFunc->isDeclaration) - { - activeFunc->isTemplateInstance = true; - } - break; - } - - // - // GNU extension for variadic templates. - // - case DW_TAG_GNU_template_parameter_pack: - case DW_TAG_GNU_formal_parameter_pack: - { - DwarfFunction *activeFunc = dynamic_cast(parentElement); - if (activeFunc != nullptr && !activeFunc->isDeclaration) - { - activeFunc->isVariadicTemplateInstance = true; - } - break; - } - - // - // GNU extension for template template arguments. - // - case DW_TAG_GNU_template_template_parameter: - { - DwarfFunction *activeFunc = dynamic_cast(parentElement); - if (activeFunc != nullptr && !activeFunc->isDeclaration) - { - activeFunc->isTemplateTemplateInstance = true; - } - break; - } - - // - // Unprocessed tags. - // - case DW_TAG_access_declaration: - case DW_TAG_common_inclusion: - case DW_TAG_condition: - case DW_TAG_constant: // in languages with true named constants - case DW_TAG_dwarf_procedure: - case DW_TAG_entry_point: - case DW_TAG_friend: - case DW_TAG_imported_declaration: - case DW_TAG_imported_module: - case DW_TAG_imported_unit: - case DW_TAG_inlined_subroutine: - case DW_TAG_namelist: - case DW_TAG_namelist_item: - case DW_TAG_template_alias: - case DW_TAG_template_value_parameter: - case DW_TAG_type_unit: - case DW_TAG_variant: - case DW_TAG_variant_part: - case DW_TAG_with_stmt: - default: - { - break; - } - } - - // Free DIE dieName. - if(!localname) - { - dwarf_dealloc(m_dbg, dieName, DW_DLA_STRING); - } -} - -/** - * @brief Get reference to Libdwarf representation. - * @return reference to Libdwarf representation. - */ -Dwarf_Debug &DwarfFile::getDwarfDebug() -{ - return m_dbg; -} - -/** - * @brief Get all compilation units. - * @return Compilation units. - */ -DwarfCUContainer *DwarfFile::getCUs() -{ - return &m_CUs; -} - -/** - * @brief Get lines information. - * @return Lines. - */ -DwarfLineContainer *DwarfFile::getLines() -{ - return &m_lines; -} - -/** - * @brief Get all functions. - * @return Functions. - */ -DwarfFunctionContainer *DwarfFile::getFunctions() -{ - return &m_functions; -} - -/** - * @brief Get all data types. - * @return Data types. - */ -DwarfTypeContainer *DwarfFile::getTypes() -{ - return &m_types; -} - -/** - * @brief Get all global variables. - * @return Global variables. - */ -DwarfVarContainer *DwarfFile::getGlobalVars() -{ - return &m_globalVars; -} - -/** - * @brief Init mapping of DWARF register numbers to names using - * default -- well known mapping for architectures. - * @param m Architecture which default mapping will be used. - * @note Use this method if mappingSecPresent() returns false -> input file - * doesn't contain section with DWARF register numbers mapping. - */ -void DwarfFile::initMapping(eDefaultMap m) -{ - resources.initMappingDefault(m); -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_functions.cpp b/src/dwarfparser/dwarf_functions.cpp deleted file mode 100644 index 91af605fb..000000000 --- a/src/dwarfparser/dwarf_functions.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_functions.cpp - * @brief Implementation of classes representing functions. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "retdec/dwarfparser/dwarf_base.h" -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_functions.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param file Pointer to dwarfparser representation of DWARF file which owns this container. - * @param elem Pointer to parent element that owns this container. - */ -DwarfFunctionContainer::DwarfFunctionContainer(DwarfFile *file, DwarfBaseElement *elem) : - DwarfBaseContainer(file, elem) -{ - -} - -/** - * @brief Get all data from function DIE. - * @param die Function DIE. - * @param lvl Level (depth) of this die. - * @return Pointer to newly created data type object or nullptr if failed. - */ -DwarfFunction *DwarfFunctionContainer::loadAndGetDie(Dwarf_Die die, unsigned) -{ - // Use special class to get attributes that we want. - AttrProcessor ap(m_parentFile->m_dbg, die, m_parentFile); - - DwarfFunction *f = nullptr; - - // If this has DW_AT_abstract_origin, then this is second part of some other declaration. - // Find first one and just actualize it. Otherwise create new function declaration. - // TODO: This expects that the first part without DW_AT_abstract_origin was already - // processed. I'm not sure if it is possible/common that second part is before first one. - Dwarf_Off ref = EMPTY_UNSIGNED; - ap.get(DW_AT_abstract_origin, ref); - - if (ref == EMPTY_UNSIGNED) - ap.get(DW_AT_specification, ref); - - if (ref != EMPTY_UNSIGNED) - { - f = static_cast( this->getElemByOffset(ref) ); - - if (f) - { - f->addOffset( ap.getDieOff() ); - } - } - else if ( (f = static_cast( this->getElemByOffset( ap.getDieOff() )) ) ) - { -// if (f) -// f->addOffset( ap.getDieOff() ); // adds the same offset for the second time? - - // This will probably get function info for the second time, but it is not big problem. - } - else - { - const string *fileName = nullptr; - ap.get(DW_AT_decl_file, fileName); - - f = new DwarfFunction(this, ap.getDieOff(), *fileName); - if (f != nullptr) - m_data.push_back(f); - } - - if (f == nullptr) - { - DWARF_ERROR("Function was not found/created."); - return nullptr; - } - - // We can not load directly to f->*, because if may overwrite already loaded values. - string name; - string linkName; - Dwarf_Addr low, high; - Dwarf_Unsigned line; - DwarfType *type; - DwarfLocationDesc *frame; - - ap.get(DW_AT_name, name); - - ap.get(DW_AT_linkage_name, linkName); - if (linkName.empty()) - ap.get(DW_AT_MIPS_linkage_name, linkName); - if (linkName.empty()) - ap.get(DW_AT_HP_linkage_name, linkName); - - ap.get(DW_AT_low_pc, low); - ap.get(DW_AT_high_pc, high); - ap.get(DW_AT_decl_line, line); - ap.get(DW_AT_type, type); - ap.get(DW_AT_frame_base, frame); - - if (name != EMPTY_STR) f->name = name; - if (linkName != EMPTY_STR) - { - f->linkageName = linkName; - if (f->name.empty()) - f->name = linkName; - } - if (low != EMPTY_ADDR) f->lowAddr = low; - if (high != EMPTY_ADDR) f->highAddr = high; - if (line != EMPTY_UNSIGNED) f->line = line; - if (type != nullptr) f->type = type; - else f->type = m_parentFile->getTypes()->getVoid(); - if (f->frameBase == nullptr && frame != nullptr) - { - f->frameBase = frame; - f->frameBase->setParent(f); - } - - // Offset from low address. - if (f->highAddr < f->lowAddr) - f->highAddr += f->lowAddr; - - // Set function as active. - // TODO: Functions with DW_AT_declaration attribute are skipped at the moment. - // For each such DIE there should be another one that defines function. - Dwarf_Bool isDeclr; - ap.get(DW_AT_declaration, isDeclr); - - if (!isDeclr) - f->isDeclaration = false; - - return f; -} - -/** - * @brief Print contents of this container. - */ -void DwarfFunctionContainer::dump() const -{ - cout << endl; - cout << "==================== Functions ====================" << endl; - - DwarfBaseContainer::dump(); - - cout << endl; -} - -/** - * @brief Get function by its name. - * @param n Name of function to get. - * @return Pointer to function object if found, nullptr otherwise. - */ -DwarfFunction *DwarfFunctionContainer::getFunctionByName(string n) -{ - for (iterator it=begin(); it!=end(); ++it) - { - if ((*it)->name == n) - return (*it); - } - - return nullptr; -} - -/** - * @brief ctor -- create local containers. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - * @param n Reference to source file name where function is declared. - */ -DwarfFunction::DwarfFunction(DwarfFunctionContainer *prnt, Dwarf_Off o, const string &n) : - DwarfVar(reinterpret_cast(prnt), o, DwarfBaseElement::FUNCTION), - lowAddr(0), - highAddr(0), - line(0), - file(n), - frameBase(nullptr), - isVariadic(false), - isDeclaration(true), - isTemplateInstance(false), - isVariadicTemplateInstance(false), - isTemplateTemplateInstance(false), - m_vars(getParentFile(), this), - m_params(getParentFile(), this) -{ - -} - -/** - * @brief dctor -- destroy local containers. - */ -DwarfFunction::~DwarfFunction() -{ - delete frameBase; -} - -/** - * @brief Print contents of this class. - */ -void DwarfFunction::dump() const -{ - cout << "Function: \"" << name << "\" " << getDwarfdump2OffsetString() << endl; - cout << "\tLink name : " << linkageName << endl; - cout << "\tType : " << type->name << endl; - cout << "\tLine : " << dec << line << endl; - cout << "\tAddr. range : " << hex << lowAddr - << " - " << highAddr << endl; - cout << "\tSrc. file : " << file << endl; - cout << endl; - - cout << "\tParams cnt. : " << dec << m_params.size() << endl; - DwarfVarContainer::const_iterator iter = m_params.begin(); - while (iter != m_params.end()) - { - cout << "\t "; - (*iter)->dump(); - ++iter; - } - if (isVariadic) - cout << "\t ... variadic argument" << endl; - cout << endl; - - cout << "\tVars cnt. : " << dec << m_vars.size() << endl; - iter = m_vars.begin(); - while (iter != m_vars.end()) - { - cout << "\t "; - (*iter)->dump(); - ++iter; - } - - cout << endl; -} - -/** - * @brief Test if function has local variables. - * @return True if function has local variables, false otherwise. - */ -bool DwarfFunction::hasVars() const -{ - return (m_vars.size() != 0); -} - -/** - * @brief Test if function has parameters. - * @return True if function has parameters, false otherwise. - */ -bool DwarfFunction::hasParams() const -{ - return (m_params.size() != 0); -} - -/** - * @brief Get local variables. - * @return Pointer to container of local variables. - */ -DwarfVarContainer *DwarfFunction::getVars() -{ - return &m_vars; -} - -/** - * @brief Get parameters. - * @return Pointer to container of parameters. - */ -DwarfVarContainer *DwarfFunction::getParams() -{ - return &m_params; -} - -/** - * @brief Get number of function's parameters. - * @return Number of functions parameters. - */ -std::size_t DwarfFunction::getParamCount() const -{ - return m_params.size(); -} - -/** - * @brief Find out if this function has frame base. - * @return True if function has frame base, false otherwise. - */ -bool DwarfFunction::hasFrameBase() const -{ - return (frameBase != nullptr); -} - -/** - * @brief Compute and return value of function's frame base. - * @param n Pointer to string that will be filled by method. - * If location is address this is a name of address space. - * If location is register this is a name of register array. - * @param a Pointer to value that will be filled by method. - * If location is address this is an address in address space. - * If location is register this is a number in register array. - * @param pc Program counter value. - * @return Type of location - address or register. - * @note Frame base should be always address. - */ -DwarfLocationDesc::cLocType DwarfFunction::getFrameBase(string *n, Dwarf_Addr *a, Dwarf_Addr pc) -{ - if (frameBase) - return (frameBase->computeLocation(n, a, pc)); - else - return DwarfLocationDesc::FAIL; -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_linenumbers.cpp b/src/dwarfparser/dwarf_linenumbers.cpp deleted file mode 100644 index 5188a04a4..000000000 --- a/src/dwarfparser/dwarf_linenumbers.cpp +++ /dev/null @@ -1,347 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_linenumbers.cpp - * @brief Implementation of classes representing linenumbers. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include -#include -#include - -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_linenumbers.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param file Pointer to dwarfparser representation of DWARF file which owns this container. - * @param elem Pointer to parent element that owns this container. - */ -DwarfLineContainer::DwarfLineContainer(DwarfFile *file, DwarfBaseElement *elem) : - DwarfBaseContainer(file, elem) -{ - m_srcFiles.push_back(EMPTY_STR); -} - -/** - * @brief Get line number information from compilation unit DIE. - * @param cu_die Compilation unit DIE. - * @param lvl Level (depth) of this die. - * @return Loaded line element pointer or nullptr if some problem. - */ -DwarfLine *DwarfLineContainer::loadAndGetDie(Dwarf_Die cu_die, unsigned) -{ - // Get all lines to buffer. - Dwarf_Signed lineCnt = 0; - Dwarf_Line *lineBuf = nullptr; - - m_res = dwarf_srclines(cu_die, &lineBuf, &lineCnt, &m_error); - - if (m_res == DW_DLV_NO_ENTRY) - { - return nullptr; - } - else if (m_res != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return nullptr; - } - - // Iterate through lines and load each one of them. - for (int i=0; im_dbg, lineBuf, lineCnt); - return nullptr; -} - -/** - * @brief Process one line number record. - * @param line Line to process. - */ -void DwarfLineContainer::loadLine(Dwarf_Line line) -{ - // Address associated with line. - Dwarf_Addr addr = 0; - m_res = dwarf_lineaddr(line, &addr, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - if (m_res == DW_DLV_NO_ENTRY) - { - addr = EMPTY_ADDR; - } - - // Source statement line number. - Dwarf_Unsigned lineno; - m_res = dwarf_lineno(line, &lineno, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - if (m_res == DW_DLV_NO_ENTRY) - { - lineno = EMPTY_UNSIGNED; - } - - // Column number at which statement represented by line begins. - Dwarf_Unsigned column; - m_res = dwarf_lineoff_b(line, &column, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - if (m_res == DW_DLV_NO_ENTRY) - { - column = EMPTY_UNSIGNED; - } - - // Name of src file where line occurs. - char *s = nullptr; - string f; - m_res = dwarf_linesrc(line, &s, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - - if (m_res == DW_DLV_NO_ENTRY || s==nullptr) - f = EMPTY_STR; - else - f = s; - - dwarf_dealloc(m_parentFile->m_dbg, s, DW_DLA_STRING); - - // Is line marked as beginning of the statement? - Dwarf_Bool statBeg; - m_res = dwarf_linebeginstatement(line, &statBeg, &m_error); - - if (m_res != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - - // Is line marked as ending a text sequence? - Dwarf_Bool seqEnd; - m_res = dwarf_lineendsequence(line, &seqEnd, &m_error); - - if (m_res != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - - // Is line marked as not beginning basic block? - Dwarf_Bool basicBlockBeg; - m_res = dwarf_lineblock(line, &basicBlockBeg, &m_error); - - if (m_res != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - - Dwarf_Bool prologueEnd, epilogueBegin; - Dwarf_Unsigned isa, discriminator; - m_res = dwarf_prologue_end_etc(line, &prologueEnd, &epilogueBegin, - &isa, &discriminator, &m_error); - - if (m_res != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return; - } - - // Create line record. - DwarfLine *l = new DwarfLine(this, *findSrcFile(f)); - - l->lineNum = lineno; - l->addr = addr; - l->col = column; - - if (statBeg) l->flags += DwarfLine::STAT_BEG; - if (seqEnd) l->flags += DwarfLine::SEQ_END; - if (basicBlockBeg) l->flags += DwarfLine::BASE_BLOCK_BEG; - if (prologueEnd) l->flags += DwarfLine::PROLOGUE_END; - if (epilogueBegin) l->flags += DwarfLine::EPILOGUE_BEGIN; - - m_data.push_back(l); -} - -/** - * @brief Find source file name and return pointer to it. - * If specified name is not in list yet, add it. - * @param f Source file name to find. - * @return Pointer to file name in list. - */ -string *DwarfLineContainer::findSrcFile(string f) -{ - list::iterator srcFilesIter = m_srcFiles.begin(); - while (srcFilesIter != m_srcFiles.end()) - { - if (*srcFilesIter == f) - { - return &(*srcFilesIter); - } - - ++srcFilesIter; - } - - // If it gets here, no record was found. - m_srcFiles.push_back(f); - return &(m_srcFiles.back()); -} - -/** - * @brief Gets all addresses associated with particular line. - * @param file Name of source file where line occurs. - * @param line Source statement line number. - * @return Vector of addresses. - */ -vector DwarfLineContainer::getAddrByLine(string file, Dwarf_Unsigned line) -{ - vector ret; - - for (iterator it=begin(); it!=end(); ++it) - { - if (((*it)->name == file) && - ((*it)->lineNum == line)) - { - ret.push_back((*it)->addr); - } - } - - return ret; -} - -/** - * @brief Gets line associated with particular addresses. - * @return Dwarfparser representation of line. - */ -DwarfLine *DwarfLineContainer::getLineByAddr(Dwarf_Addr addr) -{ - for (iterator it=begin(); it!=end(); ++it) - { - if ((*it)->addr == addr) - return (*it); - } - - return nullptr; -} - -/** - * @brief Prints content of line number container. - * @note Debugging purposes. - */ -void DwarfLineContainer::dump() const -{ - cout << endl; - cout << "==================== Lines ====================" << endl; - - // Is empty? - if (m_data.empty()) - { - cout << "NO line number information." << endl; - return; - } - - // Header. - cout << setw(10) << right << "Line num"; - cout << setw(12) << right << "Address"; - cout << setw(10) << right << "Column"; - cout << setw(8) << right << "Marks"; - cout << " " << "Filename" << endl; - - // Lines. - DwarfBaseContainer::dump(); - - // Explanation of marks meaning. - cout << endl << "Marks meaning:" << endl; - cout << "\tB - Line is marked as beginning of the statement." << endl; - cout << "\tE - Line is marked as ending a text sequence." << endl; - cout << "\tK - Line is marked as not beginning basic block." << endl; - cout << endl; -} - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param n Reference to bame of source file where line occurs. - * @note There is no DIE offset for lines, this value is set to zero. - */ -DwarfLine::DwarfLine(DwarfLineContainer *prnt, const string &n) : - DwarfBaseElement(DwarfBaseElement::LINE, reinterpret_cast*>(prnt), 0), - lineNum(0), - addr(0), - col(0), - flags(EMPTY), - name(n) -{ - -} - -/** - * @brief Print contents of this class. - */ -void DwarfLine::dump() const -{ - string marks = " "; - if (isStatmentBeg()) - marks[0] = 'B'; - if (isSequenceEnd()) - marks[1] = 'E'; - if (isBasicBlockBeg()) - marks[2] = 'K'; - - cout << setw(10) << right << dec << lineNum; - cout << setw(12) << right << hex << addr; - cout << setw(10) << right << dec << col; - cout << setw(8) << right << marks; - cout << " " << name << endl; -} - -/** - * @brief Test if line is beginning a statment. - * @return True if line is beginning a statment, false otherwise. - */ -bool DwarfLine::isStatmentBeg() const -{ - return (flags & STAT_BEG); -} - -/** - * @brief Test if line is ending a text sequence. - * @return True if line is ending a text sequence, false otherwise. - */ -bool DwarfLine::isSequenceEnd() const -{ - return (flags & SEQ_END); -} - -/** - * @brief Test if line is beginning a basic block. - * @return True if line is beginning a basic block, false otherwise. - */ -bool DwarfLine::isBasicBlockBeg() const -{ - return (flags & BASE_BLOCK_BEG); // TODO - reverse ? -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_locations.cpp b/src/dwarfparser/dwarf_locations.cpp deleted file mode 100644 index f23b7e675..000000000 --- a/src/dwarfparser/dwarf_locations.cpp +++ /dev/null @@ -1,1064 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_locations.cpp - * @brief Implementaion of classes representing locations. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include -#include - -#include -#include - -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_locations.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param tt Location type. - */ -DwarfLocationDesc::cLocType::cLocType(eLocType tt) : - t(tt) -{ - -} - -/** - * @brief Test if location is register. - * @return True if register, flase otherwise. - */ -bool DwarfLocationDesc::cLocType::isRegister() -{ - return (t == REGISTER) ? (true) : (false); -} - -/** - * @brief Test if location is address. - * @return True if address, false otherwise. - */ -bool DwarfLocationDesc::cLocType::isAddress() -{ - return (t == ADDRESS) ? (true) : (false); -} - -/** - * @brief Test if location is a value of the object. - * @return True if value, false otherwise. - */ -bool DwarfLocationDesc::cLocType::isValue() -{ - return (t == VALUE) ? (true) : (false); -} - -/** - * @brief Test if location type is invalid. - * @return True if invalid, false otherwise. - */ -bool DwarfLocationDesc::cLocType::failed() -{ - return (t == FAIL) ? (true) : (false); -} - -/** - * @brief ctor. - */ -DwarfLocationDesc::DwarfLocationDesc() : - m_baseFunc(nullptr), - m_parent(nullptr) -{ - -} - -/** - * @brief Add expression to location descriptor. - * @param e Expression to add. - */ -void DwarfLocationDesc::addExpr(Expression e) -{ - m_exprs.push_back(e); -} - -/** - * @brief Get resource access object. - * @return Pointer to resource access object. - */ -DwarfResources *DwarfLocationDesc::getResources() -{ - return &(m_parent->getParentFile()->resources); -} - -/** - * @brief Set base function of this location. - * @param f Pointer to base function. - */ -void DwarfLocationDesc::setBaseFunc(DwarfFunction *f) -{ - m_baseFunc = f; -} - -/** - * @brief Get frame base location. - * @return Frame base. - */ -DwarfLocationDesc *DwarfLocationDesc::getBaseLoc() -{ - return (m_baseFunc->frameBase); -} - -/** - * @brief Set parent of this location. - * @param p Parent. - */ -void DwarfLocationDesc::setParent(DwarfBaseElement *p) -{ - m_parent = p; -} - -/** - * @brief Set compilation unit for this location. - */ -DwarfCU *DwarfLocationDesc::getCuParent() -{ - if (m_parent != nullptr) - return (m_parent->getCuParent()); - else - return nullptr; -} - -/** - * @brief Get name of parent object. - * @return Parent name. - */ -string DwarfLocationDesc::getParentName() -{ - if (DwarfFunction *f = dynamic_cast (m_parent)) - return f->name; - else if (DwarfVar *v = dynamic_cast (m_parent)) - return v->name; - else - return ""; - -} - -/** - * @brief Get number of expressions of this location descriptor. - * @return Number of expressions. - */ -std::size_t DwarfLocationDesc::count() const -{ - return m_exprs.size(); -} - -/** - * @brief Location description is empty if id does not have any expression records. - * @return True if empty, false otherwise. - */ -bool DwarfLocationDesc::isEmpty() -{ - return (count() == 0); -} - -/** - * @brief Location description is normal if it has only one expression record. - * @return True if normal, false otherwise. - */ -bool DwarfLocationDesc::isNormal() const -{ - return (count() == 1); -} - -/** - * @brief Location description is list if it has multiple expression records. - * @return True if list, false otherwise. - */ -bool DwarfLocationDesc::isList() -{ - return (count() > 1); -} - -/** - * @brief If variable is on stack, get its offset from stack pointer; - * @param off Pointer to offset that will be filled by method. - * If variable is not on stack it will be set to zero. - * @param deref Pointer to boolean value that will be filled by method. - * If true then on address counted using returned offset is an - * address of variable data. - * If false then there are actual data on counted address. - * If variable is not on stack it will be set to false. - * @param pc Actual program counter. - * @param regNum Pointer to number of register where the offset is, filled by method. - * -1 if on stack. This is used in case of DW_OP_bregX. - * @return True if variable on stack, false otherwise. - */ -bool DwarfLocationDesc::isOnStack(Dwarf_Signed *off, bool *deref, Dwarf_Addr pc, int *regNum) -{ - Expression *e = nullptr; - - // - // Only one expression. - // - if (isNormal() && getCuParent()) - { - Expression &ex = m_exprs.front(); - - // Expression range is unlimited -> get expression. - if (ex.lowAddr==0 && ex.highAddr==numeric_limits::max()) - e = &(ex); - - // CUs lowpc is base for expression's range. - Dwarf_Addr low = ex.lowAddr + getCuParent()->lowAddr; - Dwarf_Addr high = ex.highAddr + getCuParent()->highAddr; - - if ((pc >= low) && - (pc < high)) - { - e = &(ex); - } - } - // - // Expression list -- determine correct one based on program counter address. - // - else if (isList() && getCuParent()) - { - vector::iterator iter; - - for (iter=m_exprs.begin(); iter!=m_exprs.end(); ++iter) - { - // Expression range is unlimited -> get expression. - // This should not happen in expression list, but check anyway. - if ((*iter).lowAddr==0 && (*iter).highAddr==numeric_limits::max()) - e = &(*iter); - - // CUs lowpc is base for location list ranges. - Dwarf_Addr low = (*iter).lowAddr + getCuParent()->lowAddr; - Dwarf_Addr high = (*iter).highAddr + getCuParent()->highAddr; - - if ((pc >= low) && - (pc < high)) - { - e = &(*iter); - } - } - } - // - // Should not happen. - // - else - { - DWARF_ERROR("Invalid type of location description in isOnStack() method."); - } - - // - // Expression have only one atom -- DW_OP_fbreg, - // or two atoms -- DW_OP_fbreg, DW_OP_deref. - // - if (e!=nullptr && e->atoms.size() == 1) - { - Atom &a = e->atoms.front(); - - if (a.opcode == DW_OP_fbreg) - { - *off = a.op1; - *deref = false; - if (regNum) *regNum = -1; - return true; - } - - if (a.opcode >= DW_OP_breg0 && a.opcode <= DW_OP_breg31) - { - *off = a.op1; - *deref = false; - if (regNum) *regNum = a.opcode - DW_OP_breg0; - return true; - } - } - else if (e!=nullptr && e->atoms.size() == 2) - { - Atom &a0 = e->atoms[0]; - Atom &a1 = e->atoms[1]; - - if (a0.opcode == DW_OP_fbreg && a1.opcode == DW_OP_deref) - { - *off = a0.op1; - *deref = true; - if (regNum) *regNum = -1; - return true; - } - } - - *off = 0; - *deref = false; - if (regNum) *regNum = -1; - return false; -} - -/** - * @brief Print contents of location descriptor class. - */ -void DwarfLocationDesc::dump() -{ - for (unsigned i=0; i (" << a.op1 << ") (" << a.op2 << ")" << endl; - } - cout << endl; - } -} - -/** - * @brief Compute value of location descriptor. - * @param n Pointer to string that will be filled by method. - * If location is address this is a name of address space. - * If location is register this is a name of register array. - * @param a Pointer to value that will be filled by method. - * If location is address this is an address in address space. - * If location is register this is a number in register array. - * @param pc Program counter value. - * @param base Base address. - * @param hasBase @c true if it has a base address; @c false otherwise. - * @return Type of location - address or register. - */ -DwarfLocationDesc::cLocType DwarfLocationDesc::computeLocation(string *n, - Dwarf_Addr *a, Dwarf_Addr pc, Dwarf_Addr base, bool hasBase) -{ - n->clear(); - - // - // Only one expression -- check that program counter is in this expression's range. - // - if (isNormal() && getCuParent()) - { - Expression &e = m_exprs.front(); - - // Expression range is unlimited -> evaluate. - if (e.lowAddr==0 && e.highAddr==numeric_limits::max()) - return (evaluateExpression(e, n, a, pc, base, hasBase)); - - // We have got program counter, check if it is in range of the expression. - // CUs lowpc is base for expression's range. - Dwarf_Addr low = e.lowAddr + getCuParent()->lowAddr; - Dwarf_Addr high = e.highAddr + getCuParent()->highAddr; - - if ((pc >= low) && - (pc < high)) - { - return (evaluateExpression(e, n, a, pc, base, hasBase)); - } - } - - // - // There are multiple expressions. - // Find correct one based on program counter address. - // - else if (isList() && getCuParent()) - { - vector::iterator iter; - - for (iter=m_exprs.begin(); iter!=m_exprs.end(); ++iter) - { - // Expression range is unlimited -> evaluate. - // This should not happen in expression list, but check anyway. - if ((*iter).lowAddr==0 && (*iter).highAddr==numeric_limits::max()) - return (evaluateExpression((*iter), n, a, pc, base, hasBase)); - - // CUs lowpc is base for location list ranges. - Dwarf_Addr low = (*iter).lowAddr + getCuParent()->lowAddr; - Dwarf_Addr high = (*iter).highAddr + getCuParent()->highAddr; - - if ((pc >= low) && - (pc < high)) - { - return (evaluateExpression((*iter), n, a, pc, base, hasBase)); - } - } - - // TODO - Temporary disabled, create some flag/define that will control warning printing. - //string warMsg = "Program counter not in range of frame base."; - //dwarfapi_warning(warMsg.c_str()); - } - - // - // Should not happen. - // - else - { - DWARF_ERROR("Invalid type of location description in computeLocation() method: " << count()); - } - - return cLocType(FAIL); -} - -/** - * @brief Evaluate DWARF expression. - * @param expr Reference to expression to evaluate. - * @param retN Pointer to string that will be filled by method. - * If location is address this is a name of address space. - * If location is register this is a name of register array. - * If location is actual value this is nullptr. - * @param retA Pointer to value that will be filled by method. - * If location is address this is an address in address space. - * If location is register this is a number in register array. - * If location is actual value this is a the value. - * @param pc Program counter value. - * @param base Base address. - * @param hasBase @c true if it has a base address; @c false otherwise. - * @return Type of variable location - address or register. - * - * - * According to DWARF specification: - * http://www.dwarfstd.org/doc/040408.1.html - * Warning - some opcodes like DW_OP_const1_type, DW_OP_regval, ... - * (the green ones in web page) are not processed -- there is no support - * in libdwarf for them. - * - * TODO - Dwarf_Addr alebo Dwarf_Signed -- moze to byt zaporne? - * - Asi ano -- nemusi to byt len adresa. - */ -DwarfLocationDesc::cLocType -DwarfLocationDesc::evaluateExpression(Expression &expr, string *retN, - Dwarf_Addr *retA, Dwarf_Addr pc, Dwarf_Addr base, bool hasBase) -{ - - // - // There must be at least one atom. - // - if (expr.count() < 1) - { - DWARF_WARNING("There are no atoms in DWARF expression."); - return cLocType(FAIL); - } - - // - // Register Location Descriptions. - // - // TODO - right now it works only if there is only one atom determining register - // but there might be multiple atoms, for example if Composite Location Descriptions - // are used. - // - - if ((expr.atoms[0].opcode >= DW_OP_reg0) && - (expr.atoms[0].opcode <= DW_OP_reg31)) - { - if (hasBase) - { - // Evaluation with base is supported only with address location - return cLocType(FAIL); - } - // Special case for long/double registers composed from two registers. - // They do not have to be one after another. - if (expr.count() == 4) - { - // There must be exact sequence of OP codes, and second register. - if (expr.atoms[1].opcode != DW_OP_piece || expr.atoms[1].op1 != 4) return cLocType(FAIL); - if (!(expr.atoms[2].opcode >= DW_OP_reg0 && expr.atoms[2].opcode <= DW_OP_reg31)) return cLocType(FAIL); - if (expr.atoms[3].opcode != DW_OP_piece || expr.atoms[3].op1 != 4) return cLocType(FAIL); - - // TODO - only the first register is returned at the moment. - Dwarf_Half regNum = expr.atoms[0].opcode - DW_OP_reg0; - getResources()->setReg(regNum, retN, retA); - return cLocType(REGISTER); - } - - // One atom check -- TODO: remove after implementing - if (expr.count() > 1) - { - // "There are multiple atoms in DWARF expression. - return cLocType(FAIL); - } - - Dwarf_Half regNum = expr.atoms[0].opcode - DW_OP_reg0; - getResources()->setReg(regNum, retN, retA); - - return cLocType(REGISTER); - } - else if (expr.atoms[0].opcode == DW_OP_regx) - { - if (hasBase) - { - // Evaluation with base is supported only with address location - return cLocType(FAIL); - } - // Special case for double registers composed from two float registers. - if (expr.count() == 4) - { - // There must be exact sequence of OP codes, and second register - // must folow the first one. - Dwarf_Half firstReg = expr.atoms[0].op1; - if (expr.atoms[1].opcode != DW_OP_piece || expr.atoms[1].op1 != 4) return cLocType(FAIL); - if (expr.atoms[2].opcode != DW_OP_regx || expr.atoms[2].op1 != unsigned(firstReg+1)) return cLocType(FAIL); - if (expr.atoms[3].opcode != DW_OP_piece || expr.atoms[3].op1 != 4) return cLocType(FAIL); - - getResources()->setReg(expr.atoms[0].op1 + expr.atoms[2].op1, retN, retA); - return cLocType(REGISTER); - } - - // One atom check -- TODO: remove after implementing - if (expr.count() > 1) - { - // There are multiple atoms in DWARF expression. - return cLocType(FAIL); - } - - getResources()->setReg(expr.atoms[0].op1, retN, retA); - return cLocType(REGISTER); - } - - // - // Address Location Descriptions. - // - // Use stack machine to evaluate. - // Iterate through all atoms, perform operations on stack and value at - // the top is the result. - // - - stack mystack; - - if (hasBase) - { - mystack.push(base); - } - - vector::iterator iter; - for (iter=expr.atoms.begin(); iter!=expr.atoms.end(); ++iter) - { - Atom &a = (*iter); - - switch(a.opcode) - { - // - // Literal Encodings. - // Push a value onto the DWARF stack. - // - - // Literals. - case DW_OP_lit0: - case DW_OP_lit1: - case DW_OP_lit2: - case DW_OP_lit3: - case DW_OP_lit4: - case DW_OP_lit5: - case DW_OP_lit6: - case DW_OP_lit7: - case DW_OP_lit8: - case DW_OP_lit9: - case DW_OP_lit10: - case DW_OP_lit11: - case DW_OP_lit12: - case DW_OP_lit13: - case DW_OP_lit14: - case DW_OP_lit15: - case DW_OP_lit16: - case DW_OP_lit17: - case DW_OP_lit18: - case DW_OP_lit19: - case DW_OP_lit20: - case DW_OP_lit21: - case DW_OP_lit22: - case DW_OP_lit23: - case DW_OP_lit24: - case DW_OP_lit25: - case DW_OP_lit26: - case DW_OP_lit27: - case DW_OP_lit28: - case DW_OP_lit29: - case DW_OP_lit30: - case DW_OP_lit31: - mystack.push(a.opcode - DW_OP_lit0); - break; - - // First operand pushed to stack. - // Signed and unsigned together. - case DW_OP_addr: - case DW_OP_const1u: - case DW_OP_const1s: - case DW_OP_const2u: - case DW_OP_const2s: - case DW_OP_const4u: - case DW_OP_const4s: - case DW_OP_const8u: - case DW_OP_const8s: - case DW_OP_constu: - case DW_OP_consts: - mystack.push(a.op1); - break; - - // - // Register Based Addressing. - // Pushed value is result of adding the contents of a register - // with a given signed offset. - // - - // Frame base plus signed first operand. - case DW_OP_fbreg: - { - string name; - Dwarf_Addr fbase; - - Dwarf_Addr pcReg = pc; - DwarfLocationDesc::cLocType ret = getBaseLoc()->computeLocation(&name, &fbase, pcReg); - - if (ret.isAddress()) - { - mystack.push(fbase + Dwarf_Signed(a.op1)); - } - else if (ret.isRegister()) - { - return cLocType(FAIL); - } - else - { - // PC may be outside of frame base range. - return cLocType(FAIL); - } - - break; - } - - // Content of register (address) plus signed first operand. - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - { - return cLocType(FAIL); - } - - // - case DW_OP_bregx: - { - return cLocType(FAIL); - } - - // - // Stack Operations. - // Operations manipulate the DWARF stack. - // - - // Duplicates the value at the top of the stack. - case DW_OP_dup: - if (mystack.empty()) - { - return cLocType(FAIL); - } - mystack.push(mystack.top()); - break; - - // Pops the value at the top of the stack - case DW_OP_drop: - if (mystack.empty()) - { - return cLocType(FAIL); - } - mystack.pop(); - break; - - // Entry with specified index is copied at the top. - case DW_OP_pick: - { - Dwarf_Unsigned idx = a.op1; - stack t; - - if (mystack.size() < (idx + 1)) - { - return cLocType(FAIL); - } - - for (unsigned i=0; igetAddr(adr)); - break; - } - - // - case DW_OP_deref_size: - { - // TODO - break; - } - - // - case DW_OP_xderef: - { - // TODO - break; - } - - // - case DW_OP_xderef_size: - { - // TODO - break; - } - - // - case DW_OP_push_object_address: - { - // TODO - break; - } - - // - case DW_OP_form_tls_address: - { - // TODO - break; - } - - // - case DW_OP_call_frame_cfa: - { - // TODO - DWARF_ERROR("DW_OP_call_frame_cfa."); - return cLocType(FAIL); - } - - // - // Arithmetic and Logical Operations. - // The arithmetic operations perform addressing arithmetic, that is, - // unsigned arithmetic that wraps on an address-sized boundary. - // - - // Operates on top entry. - case DW_OP_abs: - case DW_OP_neg: - case DW_OP_not: - case DW_OP_plus_uconst: - { - if (mystack.empty()) - { - return cLocType(FAIL); - } - Dwarf_Signed top = mystack.top(); - mystack.pop(); - - switch(a.opcode) - { - // Replace top with it's absolute value. - case DW_OP_abs: mystack.push(abs(top)); - break; - - // Negate top. - case DW_OP_neg: mystack.push(-top); - break; - - // Bitwise complement of the top. - case DW_OP_not: mystack.push(~top); - break; - - // Top value plus unsigned first operand. - case DW_OP_plus_uconst: mystack.push(top + a.op1); - break; - - // Should not happen. - default: - DWARF_ERROR("Should not happen."); - return cLocType(FAIL); - } - - break; - } - - // Operates on top two entries. - case DW_OP_and: - case DW_OP_div: - case DW_OP_minus: - case DW_OP_mod: - case DW_OP_mul: - case DW_OP_or: - case DW_OP_plus: - case DW_OP_shl: - case DW_OP_shr: - case DW_OP_shra: - case DW_OP_xor: - { - if (mystack.size() < 2) - { - return cLocType(FAIL); - } - Dwarf_Signed e1 = mystack.top(); - mystack.pop(); - Dwarf_Signed e2 = mystack.top(); - mystack.pop(); - - switch(a.opcode) - { - // Bitwise and on top 2 values. - case DW_OP_and: mystack.push(e1 & e2); - break; - - // Second div first from top (signed division). - case DW_OP_div: mystack.push(e2 / e1); - break; - - // Second minus first from top. - case DW_OP_minus: mystack.push(e2 - e1); - break; - - // Second modulo first from top. - case DW_OP_mod: mystack.push(e2 % e1); - break; - - // Second times first from top. - case DW_OP_mul: mystack.push(e2 * e1); - break; - - // Bitwise or of top 2 entries. - case DW_OP_or: mystack.push(e2 | e1); - break; - - // Adds together top two entries. - case DW_OP_plus: mystack.push(e2 + e1); - break; - - // Shift second entry to left by first entry. - case DW_OP_shl: mystack.push(e2 << e1); - break; - - // Shift second entry to right by first entry. - case DW_OP_shr: mystack.push(e2 >> e1); - break; - - // Shift second entry arithmetically to right by first entry. - case DW_OP_shra: mystack.push(e2 >> e1); - break; - - // Bitwise XOR on top two entries. - case DW_OP_xor: mystack.push(e2 ^ e1); - break; - - // Should not happen. - default: - DWARF_ERROR("Should not happen."); - return cLocType(FAIL); - } - - break; - } - - // - // Control Flow Operations. - // TODO - not implemented at all right now. - // - case DW_OP_le: - case DW_OP_ge: - case DW_OP_eq: - case DW_OP_lt: - case DW_OP_gt: - case DW_OP_ne: - case DW_OP_skip: - case DW_OP_bra: - case DW_OP_call2: - case DW_OP_call4: - case DW_OP_call_ref: - { - break; - } - - // - // Implicit Location Descriptions. - // - - case DW_OP_implicit_value: - { - // TODO - break; - } - - // - // Composite Location Descriptions. - // TODO - not implemented at all right now. - // - - case DW_OP_piece: - case DW_OP_bit_piece: - { - break; - } - - // - // Special Operations. - // - - // This has no effect. - case DW_OP_nop: - break; - - // - // Object does not exist in memory but its value is known and it is at the top - // of the DWARF expression stack. - // DWARF expression represents actual value of the object, rather then its location. - // DW_OP_stack_alue operation terminates the expression. - // - case DW_OP_stack_value: - if (mystack.empty()) - { - return cLocType(FAIL); - } - retN = nullptr; - *retA = mystack.top(); - return cLocType(VALUE); - break; - - // - // Invalid or unrecognized operations. - // - default: - { - const char *opName; - if (dwarf_get_OP_name(a.opcode, &opName) == DW_DLV_OK) - { - DWARF_ERROR("Invalid or unrecognized expression operation: " << string(opName)); - } - else - { - DWARF_ERROR("Invalid or unrecognized expression operation: "); - } - - return cLocType(FAIL); - break; - } - - } // switch - } // for - - if (mystack.empty()) - { - return cLocType(FAIL); - } - else - { - *retA = mystack.top(); - return cLocType(ADDRESS); - } -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_resources.cpp b/src/dwarfparser/dwarf_resources.cpp deleted file mode 100644 index 7de112f5b..000000000 --- a/src/dwarfparser/dwarf_resources.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_resources.cpp - * @brief Implementation of classes representing resources. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "retdec/dwarfparser/dwarf_resources.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief Print contents of this class. - */ -void DwarfResources::dump() -{ - cout << endl; - cout << "==================== Resources ====================" << endl; - cout << endl; - - cout << "Register mapping:" << endl; - const char *s0 = "Idx"; - const char *s1 = "Dwarf num."; - const char *s2 = "Array num."; - const char *s3 = "Name"; - printf("\t%4s %10s %10s %-30s\n", s0, s1, s2, s3); - - unsigned idx = 0; - map::iterator mIter; - for(mIter=m_regMaps.begin(); mIter!=m_regMaps.end(); ++mIter) - { - printf("\t%4d %10d %10d %-30s\n", - idx, - (*mIter).first, - (*mIter).second.arrayNum, - (*mIter).second.name.c_str() - ); - idx++; - } - - cout << endl; -} - -/** - * @brief Gets DWARF register number and returns its content. - * @param n DWARF register number. - * @return value of the given register. - */ -Dwarf_Signed DwarfResources::getReg(Dwarf_Half n) -{ - (void) n; - return EMPTY_SIGNED; -} - -/** - * @brief Gets name of register array and number in register array and returns content of that register. - * @param name is a name of register array. - * @param number is a number in register array. - * @return value of the given register. - */ -Dwarf_Signed DwarfResources::getReg(std::string name, Dwarf_Addr number) -{ - (void) name; - (void) number; - return EMPTY_SIGNED; -} - -/** - * @brief Gets address and returns its content. - * @param a Address to get. - * @return Value on the given address. - * @note It use only one (always the first) address name space at the moment. - */ -Dwarf_Signed DwarfResources::getAddr(Dwarf_Addr a) -{ - (void) a; - return EMPTY_SIGNED; -} - -/** - * @brief Gets content of program counter register. - * @return Value of program counter. - */ -Dwarf_Addr DwarfResources::getPcReg() -{ - return EMPTY_SIGNED; -} - -/** - * @brief Gets DWARF register number and sets name of register array and - * its index number used in architecture. - * @param reg Register number used by DWARF. - * @param n Name of register array in architecture to set. - * @param a Index number of register in register array to set. - */ -void DwarfResources::setReg(Dwarf_Half reg, string *n, Dwarf_Addr *a) -{ - map::iterator iter; - iter = m_regMaps.find(reg); - - if (iter == m_regMaps.end()) - { - DWARF_ERROR("DwarfResources::setReg(): DWARF register num is not mapped to a register."); - } - else - { - RealReg rr = (*iter).second; - *n = rr.name; - *a = rr.arrayNum; - } -} - -/** - * @brief Init mapping of DWARF register numbers to names using - * default -- well known mapping for architectures. - * @param m Architecture which default mapping will be used. - */ -void DwarfResources::initMappingDefault(eDefaultMap m) -{ - - switch (m) - { - - // - // Mapping is the same as the one generated by compiler. - // MIPS-32. - // - case MIPS: - { - unsigned i = 0; - string general = "gpregs"; - for (unsigned j=0; j<32; j++, i++) - m_regMaps[i] = RealReg(general, j); - - // Mapping same as in files from compiler. - // But according to tests, fpu registers begin on number 32. - // Single precision. - string fpu_s = "fpuregs_s"; - for (unsigned j=0; j<32; j++, i++) - m_regMaps[i] = RealReg(fpu_s, j); - - // Double precision - on MIPS 32. - string fpu_d = "fpuregs_d"; - i = 32; - for (unsigned j=0; j<16; j++, i=i+2) - { - m_regMaps[i+i+1] = RealReg(fpu_d, i-32); - } - - break; - } - - // - // Only first 16 general registers are mapped. - // Name of register array was taken from ARM semantics specification (resource_name record). - // - case ARM: - { - unsigned i; - string general = "regs"; - for (i=0; i<16; i++) - m_regMaps[i] = RealReg(general, i); - - m_regMaps[128] = RealReg("spsr", 0); - - break; - } - - // - // Only 8 general registers (32-bit) are mapped. - // Name of register array was taken from x86 semantics specification (resource_name record). - // - case X86: - { - - unsigned i; - string general = "gp32"; - for (i=0; i<8; i++) - m_regMaps[i] = RealReg(general, i); - - break; - } - - // - // Default. - // - default: - { - DWARF_ERROR("DwarfResources::initMappingDefault: unrecognized type of default mapping used."); - initMappingDefault(MIPS); - break; - } - } -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_types.cpp b/src/dwarfparser/dwarf_types.cpp deleted file mode 100644 index 74996edfe..000000000 --- a/src/dwarfparser/dwarf_types.cpp +++ /dev/null @@ -1,1460 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_types.cpp - * @brief Implementaion of classes representing data types. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include -#include -#include - -#include -#include - -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_types.h" -#include "retdec/dwarfparser/dwarf_vars.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/* - * ============================================================================= - * DwarfTypeContainer - * ============================================================================= - */ - -/** - * @brief ctor. - * @param file Pointer to dwarfparser representation of DWARF file which owns this container. - * @param elem Pointer to parent element that owns this container. - */ -DwarfTypeContainer::DwarfTypeContainer(DwarfFile *file, DwarfBaseElement *elem) : - DwarfBaseContainer(file, elem), - m_void(this, 0) -{ - m_void.name = "void"; - m_void.bitSize = 0; - m_void.dataType = DwarfType::BASE; -} - -/** - * @brief Test if provided DIE was already loaded. - * @param off DIE offset to test. - * @return Pointer to object that was created from die or nullptr if not loaded yet. - */ -DwarfType *DwarfTypeContainer::checkIfLoaded(Dwarf_Off off) -{ - map::iterator fIt; - fIt = m_typeCache.find(off); - if (fIt == m_typeCache.end()) - return nullptr; - else - return (fIt->second); -} - -/** - * @brief Get all data from data type DIE and return newly created object. - * @param die Data type unit DIE. - * @param lvl Level (depth) of this die. - * @return Pointer to newly created data type object or nullptr if failed. - */ -DwarfType *DwarfTypeContainer::loadAndGetDie(Dwarf_Die die, unsigned) -{ - DwarfType *newType = nullptr; - - AttrProcessor ap(m_parentFile->m_dbg, die, m_parentFile); - Dwarf_Off off = ap.getDieOff(); - - // Disabled, if is too slow, it is better to just create another type. - // Die was already loaded. - if ((newType = checkIfLoaded(off)) != nullptr) - { - return newType; - } - - // Get DIE tag. - Dwarf_Half tag = 0; - if (dwarf_tag(die, &tag, &m_error) != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return nullptr; - } - - // - // Do not try to find declarations for unprocessed types. - // - switch (tag) - { - case DW_TAG_file_type: - case DW_TAG_interface_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_string_type: - case DW_TAG_thrown_type: - case DW_TAG_unspecified_type: - return nullptr; - break; - - default: - // continue for all other types. - break; - } - - // - // If this DIE have DW_AT_specification, then it inherits from some other DIE with DW_AT_declaration. - // TODO: This expects that DW_AT_declaration will be before DW_AT_specification, otherwise it wont be - // discovered (searching in already processed DIEs). - // It also expects that each DW_AT_declaration is specified only once -- original DIE offset will be - // replaced by the current one, so it wont be possible to find it again. - // Even if we did not do this, it would not be easy to inherit twice -- original DIE could not be - // directly completed by entries in this one, because other inheritance probably could have other entries. - // There would need to be some deep copy mechanism -- copy original to new object and complete it. - // - Dwarf_Off ref = EMPTY_UNSIGNED; - ap.get(DW_AT_specification, ref); - - // This is indeed a specification DIE. - bool found = false; - if (ref != EMPTY_UNSIGNED) - { - newType = static_cast( this->getElemByOffset(ref) ); - - if (newType != nullptr) - { - found = true; - newType->addOffset( ap.getDieOff() ); - } - } - - // This is not a specification DIE, or declaration was not found. - if (newType == nullptr) - { - // Decide what to do based on tag type. - switch (tag) - { - // - // Base type. - // - case DW_TAG_base_type: newType = new DwarfType(this, off); break; - - // - // Composite types. - // - case DW_TAG_array_type: newType = new DwarfArrayType(this, off); break; - case DW_TAG_enumeration_type: newType = new DwarfEnumType(this, off); break; - case DW_TAG_structure_type: newType = new DwarfStructType(this, off); break; - case DW_TAG_union_type: newType = new DwarfUnionType(this, off); break; - case DW_TAG_subroutine_type: newType = new DwarfFunctionType(this, off); break; - case DW_TAG_typedef: newType = new DwarfTypedefType(this, off); break; - case DW_TAG_class_type: newType = new DwarfClassType(this, off); break; - - // - // Modifier types. - // - case DW_TAG_const_type: newType = new DwarfConstType(this, off); break; - case DW_TAG_packed_type: newType = new DwarfPackedType(this, off); break; - case DW_TAG_pointer_type: newType = new DwarfPointerType(this, off); break; - case DW_TAG_reference_type: newType = new DwarfReferenceType(this, off); break; - case DW_TAG_restrict_type: newType = new DwarfRestrictType(this, off); break; - case DW_TAG_rvalue_reference_type: newType = new DwarfRValReferenceType(this, off); break; - case DW_TAG_shared_type: newType = new DwarfSharedType(this, off); break; - case DW_TAG_volatile_type: newType = new DwarfVolatileType(this, off); break; - - // - // Unprocessed tags. - // - case DW_TAG_file_type: - case DW_TAG_interface_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_string_type: - case DW_TAG_thrown_type: - case DW_TAG_unspecified_type: - default: - delete newType; - return nullptr; - } - } - - static std::map inProgress; - auto fIt = inProgress.find(off); - if (fIt != inProgress.end()) - { - auto* ret = fIt->second; - inProgress.erase(off); - delete newType; - return ret; - } - else - { - inProgress[off] = newType; - } - - // Load and save new type. - newType->load(ap); - - inProgress.erase(off); - - if (!found) - m_data.push_back(newType); - - // Add to cache. - m_typeCache[off] = newType; - - return newType; -} - -/** - * @brief Print contents of this container. - */ -void DwarfTypeContainer::dump() const -{ - cout << endl; - cout << "==================== Types ====================" << endl; - - if (m_data.empty()) - { - cout << "NO base type information." << endl; - return; - } - - DwarfBaseContainer::dump(); - cout << endl; -} - -/** - * @brief Get data type by its name. - * @param n Name of data type to get. - * @return Pointer to data type object if found, nullptr otherwise. - */ -DwarfType *DwarfTypeContainer::getTypeByName(string n) -{ - for (iterator it=begin(); it!=end(); ++it) - { - if ((*it)->name == n) - { - return (*it); - } - } - - return nullptr; -} - -/** - * @brief Get void data type. - * @return Pointer to void data type. - */ -DwarfType *DwarfTypeContainer::getVoid() -{ - return &m_void; -} - -/** - * @brief Load provided DIE as data type and return its flags. - * @param die Data type unit DIE. - * @param lvl Level (depth) of this die. - * @return Flags of loaded data type. - * - * TODO: toto sa mi nepaci, naco to je, neda sa to lepsie? - */ -int DwarfTypeContainer::getDieFlags(Dwarf_Die die, unsigned lvl) -{ - loadAndGetDie(die, lvl); - - int flags = 0; - int f = 0; - - // Get DIE tag. - Dwarf_Half tag = 0; - if (dwarf_tag(die, &tag, &m_error) != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return DwarfVar::EMPTY; - } - - AttrProcessor ap(m_parentFile->m_dbg, die, m_parentFile); - - // Decide what to do based on tag type. - switch (tag) - { - case DW_TAG_const_type: - flags += DwarfVar::CONSTANT; - ap.geti(DW_AT_type, f); - break; - - case DW_TAG_pointer_type: - flags += DwarfVar::POINTER; - ap.geti(DW_AT_type, f); - break; - - case DW_TAG_restrict_type: - flags += DwarfVar::RESTRICT; - ap.geti(DW_AT_type, f); - break; - - case DW_TAG_volatile_type: - flags += DwarfVar::VOLATILE; - ap.geti(DW_AT_type, f); - break; - - default: - - break; - } - - flags += f; - return flags; -} - -/* - * ============================================================================= - * DwarfType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfType, DwarfType::BASE); - -const char * DwarfType::eDataTypeString[] = -{ - "BASE TYPE", - "ARRAY", - "ENUMERATION", - "FUNCTION", - "STRUCTURE", - "TYPEDEF", - "UNION", - "CLASS", - "CONSTANT", - "PACKED", - "POINTER", - "REFERENCE", - "RESTRICT", - "RVAL_REFERENCE", - "SHARED", - "VOLATILE" -}; - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfType::DwarfType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfBaseElement(DwarfBaseElement::TYPE, reinterpret_cast*>(prnt), o), - bitSize(EMPTY_UNSIGNED), - encoding(EMPTY_UNSIGNED), - dataType(BASE) -{ - -} - -/** - * @brief Load base attributes -- name and bitsize. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfType::load(AttrProcessor &ap) -{ - string n; - Dwarf_Unsigned e; - - ap.get(DW_AT_name, n); - ap.get(DW_AT_encoding, e); - if (n != EMPTY_STR) name = n; - if (e != EMPTY_UNSIGNED) encoding = e; - - Dwarf_Unsigned bitSz = EMPTY_UNSIGNED; - ap.get(DW_AT_bit_size, bitSz); - if (bitSz == EMPTY_UNSIGNED) - { - ap.get(DW_AT_byte_size, bitSz); - if (bitSz != EMPTY_UNSIGNED) - { - bitSz *= BITS_IN_BYTE; - } - } - - if (bitSz != EMPTY_UNSIGNED) bitSize = bitSz; -} - -/** - * @brief Print contents of this class. - */ -void DwarfType::dump() const -{ - cout << dumpNameAndOffset() << endl; - cout << "\t" << eDataTypeString[dataType] << endl; - - if (bitSize != EMPTY_UNSIGNED) - cout << "\tBit size : " << bitSize << " (" << getByteSize() << " bytes)" << endl; - else - cout << "\tBit size : NOT_SET" << endl; - cout << "\tLLVM IR : " << toLLVMString() << endl; - - cout << endl; -} - -/** - * @brief Dump name of type and offset of DIE it comes from. - * @return Name and offset of type. - */ -string DwarfType::dumpNameAndOffset() const -{ - stringstream ss; - if (name.empty()) - ss << ""; - else - ss << name; - ss << "\t" << getDwarfdump2OffsetString(); - - return ss.str(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfType::toLLVMString() const -{ - stringstream ret; - - // - // Void. - // - if (name == "void") - return "void"; - - // - // Check. - // - if ((dataType != BASE) || - (encoding == EMPTY_UNSIGNED)) - { - return ""; - } - - // - // Boolean. - // - if (encoding == DW_ATE_boolean) - { - ret << "i1"; - } - - // - // Integer and char. - // - if (encoding == DW_ATE_signed || - encoding == DW_ATE_signed_char || - encoding == DW_ATE_unsigned || - encoding == DW_ATE_unsigned_char || - encoding == DW_ATE_signed_fixed || - encoding == DW_ATE_unsigned_fixed) - { - ret << "i" << getBitSize(); - } - - // - // Floating point. - // - if (encoding == DW_ATE_complex_float || - encoding == DW_ATE_float || - encoding == DW_ATE_imaginary_float || - encoding == DW_ATE_decimal_float) - { - switch (getBitSize()) - { - case 16: ret << "half"; break; - case 32: ret << "float"; break; - case 64: ret << "double"; break; - case 128: ret << "fp128"; break; - case 80: ret << "x86_fp80"; break; - default: ret << "double"; break; - } - } - - // - // Not processed at the moment. - // - if (encoding == DW_ATE_address || - encoding == DW_ATE_packed_decimal || - encoding == DW_ATE_numeric_string || - encoding == DW_ATE_edited || - //encoding == DW_ATE_UTF || // Defined in DWARF specification, missing in libdwarf. - encoding == DW_ATE_lo_user || - encoding == DW_ATE_hi_user) - { - return ""; - } - - return ret.str(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * If possible then use type identifier instead of full definition. - * @return String representing this type. - */ -string DwarfType::toLLVMStringIdentified() const -{ - return toLLVMString(); -} - -/** - * @brief Get bit size of data type. - * @return Bit size of data type. - */ -Dwarf_Unsigned DwarfType::getBitSize() const -{ - return bitSize; -} - -/** - * @brief Get byte size of data type. - * @return Byte size of data type. - */ -Dwarf_Unsigned DwarfType::getByteSize() const -{ - if (bitSize == EMPTY_UNSIGNED) - return EMPTY_UNSIGNED; - - if (bitSize % BITS_IN_BYTE != 0) - DWARF_WARNING("Bitsize: \"" << bitSize << "\" modulo bits in byte: \"" << BITS_IN_BYTE << "\" is not zero."); - - return (bitSize / BITS_IN_BYTE); -} - -/** - * @brief Returns underlying type behind this type. - * Underlying is the first non-modifier data type. - * Non-modifier data types return themselves. - * @return Pointer to underlying type. - */ -DwarfType *DwarfType::getUnderlyingType() -{ - DwarfType *res = this; - DwarfModifierType *tmp = nullptr; - - while ((tmp = dynamic_cast(res))) - { - res = tmp->baseType; - } - - return res; -} - -/* - * ============================================================================= - * DwarfArrayType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfArrayType, DwarfType::ARRAY); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfArrayType::DwarfArrayType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfType(prnt, o), - baseType(nullptr) -{ - dataType = DwarfType::ARRAY; -} - -/** - * @brief Load array specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfArrayType::load(AttrProcessor &ap) -{ - this->DwarfType::load(ap); - - DwarfType *t = nullptr; - ap.get(DW_AT_type, t); - if (t != nullptr && (baseType == nullptr || t != getParentFile()->getTypes()->getVoid())) baseType = t; - - bitSize = 0; - - if (baseType == nullptr) - { - DWARF_ERROR("DwarfArrayType::load -- no base type of array."); - assert(baseType != nullptr); - } -} - -/** - * @brief Print contents of this class. - */ -void DwarfArrayType::dump() const -{ - this->DwarfType::dump(); - - cout << "\tBase. type : " << baseType->dumpNameAndOffset() << endl; - cout << "\tDimensions : " << dimensionBounds.size() << endl; - for (std::size_t i=0; itoLLVMStringIdentified(); - - for (std::size_t i=0; ibitSize; - - bitSize = sz; -} - -/** - * @brief Get number of array dimensions. - * @return Number of array dimensions. - */ -std::size_t DwarfArrayType::dimensionCount() -{ - return dimensionBounds.size(); -} - -/* - * ============================================================================= - * DwarfEnumType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfEnumType, DwarfType::ENUMERATION); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfEnumType::DwarfEnumType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfType(prnt, o), - baseType(nullptr) -{ - dataType = DwarfType::ENUMERATION; -} - -/** - * @brief Load enumeration specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfEnumType::load(AttrProcessor &ap) -{ - this->DwarfType::load(ap); - - DwarfType *t = nullptr; - ap.get(DW_AT_type, t); - if (t != nullptr && (baseType == nullptr || t != getParentFile()->getTypes()->getVoid())) baseType = t; - - if (baseType == nullptr) - { - DWARF_ERROR("DwarfEnumType::load -- no base type of enumeration."); - assert(baseType != nullptr); - } -} - -/** - * @brief Print contents of this class. - */ -void DwarfEnumType::dump() const -{ - this->DwarfType::dump(); - - cout << "\tBase. type : " << baseType->dumpNameAndOffset() << endl; - cout << "\tEnumerators : " << members.size() << endl; - for (std::size_t i=0; iDwarfType::load(ap); - - static unsigned anonCntr = 0; - if (name.empty()) - { - name = "anon_struct_" + std::to_string(anonCntr++); - } -} - -/** - * @brief Print contents of this class. - */ -void DwarfStructType::dump() const -{ - this->DwarfType::dump(); - - cout << "\tMembers : " << members.size() << endl; - for (std::size_t i=0; igetDwarfdump2OffsetString() - << ", access : " << out - << endl; - } - cout << endl; -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfStructType::toLLVMString() const -{ - bool first = true; - stringstream ret; - - if (!name.empty()) - ret << "%" << name << " = type "; - ret << "{"; - - vector::const_iterator iter; - for (iter=members.begin(); iter != members.end(); ++iter) - { - if (!first) - ret << ","; - else - first = false; - - ret << " " << (*iter).type->toLLVMStringIdentified(); - } - - if (members.empty()) - { - ret << "i32"; - } - - ret << " }"; - return ret.str(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * If possible then use type identifier instead of full definition. - * @return String representing this type. - */ -string DwarfStructType::toLLVMStringIdentified() const -{ - return ( "%" + name ); -} - -/** - * @brief Add structure member. - * @param m Member to add. - */ -void DwarfStructType::addMember(StructMember m) -{ - members.push_back(m); -} - -/** - * @brief Add static structure member. - * @param m Member to add. - */ -void DwarfStructType::addStaticMember(StructMember m) -{ - staticMembers.push_back(m); -} - -/** - * @brief Get number of structure members. - * @return Number of structure members. - */ -std::size_t DwarfStructType::memberCount() -{ - return members.size(); -} - -/* - * ============================================================================= - * DwarfUnionType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfUnionType, DwarfType::UNION); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfUnionType::DwarfUnionType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfStructType(prnt, o) -{ - dataType = DwarfType::UNION; -} - -/* - * ============================================================================= - * DwarfClassType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfClassType, DwarfType::CLASS); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfClassType::DwarfClassType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfStructType(prnt, o) -{ - dataType = DwarfType::CLASS; -} - -/** - * @brief Load class specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfClassType::load(AttrProcessor &ap) -{ - this->DwarfStructType::load(ap); -} - -/** - * @brief Print contents of this class. - */ -void DwarfClassType::dump() const -{ - this->DwarfStructType::dump(); - - cout << "\tFunction Members : " << memberFunctions.size() << endl; - for (std::size_t i=0; iname - << memberFunctions[i]->getDwarfdump2OffsetString() << endl; - } - cout << endl; - - cout << "\tBase Classes : " << baseClasses.size() << endl; - for (std::size_t i=0; iname - << baseClasses[i].getBase()->getDwarfdump2OffsetString() - << ", access : " << out << endl; - } - cout << endl; -} - -/* - * ============================================================================= - * DwarfTypedefType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfTypedefType, DwarfType::TYPEDEF); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfTypedefType::DwarfTypedefType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfType(prnt, o), - baseType(nullptr) -{ - dataType = DwarfType::TYPEDEF; -} - -/** - * @brief Load typedef specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfTypedefType::load(AttrProcessor &ap) -{ - this->DwarfType::load(ap); - - DwarfType *t = nullptr; - ap.get(DW_AT_type, t); - if (t != nullptr && (baseType == nullptr || t != getParentFile()->getTypes()->getVoid())) baseType = t; - - bitSize = baseType->bitSize; - - if (baseType == nullptr) - { - DWARF_ERROR("DwarfTypedefType::load -- no base type of typedef."); - assert(baseType != nullptr); - } - - if (baseType->name.empty()) - { - baseType->name = name; - } -} - -/** - * @brief Print contents of this class. - */ -void DwarfTypedefType::dump() const -{ - this->DwarfType::dump(); - - cout << "\tOrig. type : " << baseType->dumpNameAndOffset() << endl; - cout << endl; -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfTypedefType::toLLVMString() const -{ - return baseType->toLLVMString(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * If possible then use type identifier instead of full definition. - * @return String representing this type. - */ -string DwarfTypedefType::toLLVMStringIdentified() const -{ - return baseType->toLLVMStringIdentified(); -} - -/* - * ============================================================================= - * DwarfFunctionType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfFunctionType, DwarfType::FUNCTION); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfFunctionType::DwarfFunctionType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfType(prnt, o), - type(nullptr), - func(nullptr), - isVariadic(false) -{ - dataType = DwarfType::FUNCTION; - m_params = new DwarfVarContainer(getParentFile(), this); -} - -/** - * @brief dctor. - */ -DwarfFunctionType::~DwarfFunctionType() -{ - delete m_params; -} - -/** - * @brief Load pointer specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfFunctionType::load(AttrProcessor &ap) -{ - this->DwarfType::load(ap); - - DwarfType *t = nullptr; - ap.get(DW_AT_type, t); // type returned by subroutine, if entry not found, it is set to void. - if (t != nullptr && (type == nullptr || t != getParentFile()->getTypes()->getVoid())) type = t; - - if (type == nullptr) - { - DWARF_ERROR("DwarfFunctionType::load -- no return type of function."); - assert(type != nullptr); - } - - // - // If types of the arguments necessary, then this entry owns next - // argument description entries -> "m_parentFile->m_activeFunc = nullptr" - // in "DwarfTypeContainer::loadAndGet" ??? - // So all next DW_TAG_formal_parameter DIEs will be associated with this - // function type. - // -} - -/** - * @brief Print contents of this class. - */ -void DwarfFunctionType::dump() const -{ - this->DwarfType::dump(); - - if (func) - cout << "\tReal func. : " << func->name << endl; - else - cout << "\tReal func. : UNKNOWN" << endl; - cout << "\tParams cnt.: " << dec << getParamCount() << endl; - DwarfVarContainer::iterator iter = m_params->begin(); - while (iter != m_params->end()) - { - cout << "\t "; - (*iter)->dump(); - ++iter; - } - if (isVariadic) - cout << "\t ... variadic argument" << endl; - cout << endl; -} - -/** - * @brief Convert function type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfFunctionType::toLLVMString() const -{ - static std::set inProgress; - if (inProgress.count(this)) - { - inProgress.erase(this); - return "i32"; - } - else - { - inProgress.insert(this); - } - - bool first = true; - stringstream ret; - - ret << type->toLLVMStringIdentified(); - ret << " ("; - DwarfVarContainer::iterator iter; - for (iter=m_params->begin(); iter!=m_params->end(); ++iter) - { - if (!first) - ret << ", "; - else - first = false; - - ret << (*iter)->type->toLLVMStringIdentified(); - } - ret << ")"; - - inProgress.erase(this); - return ret.str(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * If possible then use type identifier instead of full definition. - * @return String representing this type. - */ -string DwarfFunctionType::toLLVMStringIdentified() const -{ - return toLLVMString(); -} - -/** - * @brief Test if function has parameters. - * @return True if function has parameters, false otherwise. - */ -bool DwarfFunctionType::hasParams() -{ - return (m_params->size() != 0); -} - -/** - * @brief Get function's parameters. - * @return Pointer to container of parameters. - */ -DwarfVarContainer *DwarfFunctionType::getParams() -{ - return m_params; -} - -/** - * @brief Get function's parameters. - * @return Pointer to constant container of parameters. - */ -const DwarfVarContainer *DwarfFunctionType::getParams() const -{ - return m_params; -} - -/** - * @brief Get number of function's parameters. - * @return Number of functions parameters. - */ -std::size_t DwarfFunctionType::getParamCount() const -{ - return m_params->size(); -} - -/* - * ============================================================================= - * DwarfModifierType - * ============================================================================= - */ - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfModifierType::DwarfModifierType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfType(prnt, o), - baseType(nullptr) -{ - -} - -/** - * @brief Load modifier specific attributes. - * @param ap Reference to helper class providing access to attributes. - */ -void DwarfModifierType::load(AttrProcessor &ap) -{ - this->DwarfType::load(ap); - - DwarfType *t = nullptr; - ap.get(DW_AT_type, t); // type returned by subroutine, if entry not found, it is set to void. - if (t != nullptr && (baseType == nullptr || t != getParentFile()->getTypes()->getVoid())) baseType = t; -} - -/** - * @brief Print contents of this class. - */ -void DwarfModifierType::dump() const -{ - this->DwarfType::dump(); - - cout << "\tModifier of : " << baseType->dumpNameAndOffset() << endl; - cout << endl; -} - -/** - * @brief Convert modifier type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfModifierType::toLLVMString() const -{ - return baseType->toLLVMStringIdentified(); -} - -/** - * @brief Convert type to string that represents it in LLVM IR. - * If possible then use type identifier instead of full definition. - * @return String representing this type. - */ -string DwarfModifierType::toLLVMStringIdentified() const -{ - return toLLVMString(); -} - -/* - * ============================================================================= - * DwarfConstType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfConstType, DwarfType::CONSTANT); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfConstType::DwarfConstType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::CONSTANT; -} - -/* - * ============================================================================= - * DwarfPackedType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfPackedType, DwarfType::PACKED); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfPackedType::DwarfPackedType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::PACKED; -} - -/* - * ============================================================================= - * DwarfPointerType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfPointerType, DwarfType::POINTER); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfPointerType::DwarfPointerType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::POINTER; -} - -/** - * @brief Convert pointer type to string that represents it in LLVM IR. - * @return String representing this type. - */ -string DwarfPointerType::toLLVMString() const -{ - return baseType->toLLVMStringIdentified() + "*"; -} - -/** - * @brief Returns pointer level -- count of pointers type between this - * pointer (including) and underlying type. - * Underlying is first non-pointer data type. - * @return Pointer level. - */ -unsigned DwarfPointerType::getPointerLevel() -{ - unsigned res = 1; - DwarfType *temp = nullptr; - - temp = baseType; - while (temp->constructed_as()) - { - temp = temp->leaf_cast()->baseType; - res++; - } - - return res; -} - -/* - * ============================================================================= - * DwarfReferenceType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfReferenceType, DwarfType::REFERENCE); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfReferenceType::DwarfReferenceType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::REFERENCE; -} - -/* - * ============================================================================= - * DwarfRestrictType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfRestrictType, DwarfType::RESTRICT); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfRestrictType::DwarfRestrictType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::RESTRICT; -} - -/* - * ============================================================================= - * DwarfRValReferenceType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfRValReferenceType, DwarfType::RVAL_REFERENCE); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfRValReferenceType::DwarfRValReferenceType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::RVAL_REFERENCE; -} - -/* - * ============================================================================= - * DwarfSharedType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfSharedType, DwarfType::SHARED); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfSharedType::DwarfSharedType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::SHARED; -} - -/* - * ============================================================================= - * DwarfVolatileType - * ============================================================================= - */ - -DEF_DWARF_TYPE_TID(DwarfVolatileType, DwarfType::VOLATILE); - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param o Original libdwarf DIE offset. - */ -DwarfVolatileType::DwarfVolatileType(DwarfTypeContainer *prnt, Dwarf_Off o) : - DwarfModifierType(prnt, o) -{ - dataType = DwarfType::VOLATILE; -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_utils.cpp b/src/dwarfparser/dwarf_utils.cpp deleted file mode 100644 index 99f3154a7..000000000 --- a/src/dwarfparser/dwarf_utils.cpp +++ /dev/null @@ -1,856 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_utils.cpp - * @brief Implementation of utility functions and classes. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_utils.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -// -// Taken from dwarfdump2/print_die.cpp -// -static int get_form_values(Dwarf_Attribute attrib, Dwarf_Half & theform, Dwarf_Half & directform) -{ - Dwarf_Error err = nullptr; - int res = dwarf_whatform(attrib, &theform, &err); - dwarf_whatform_direct(attrib, &directform, &err); - return res; -} - -// -// Taken from dwarfdump2/print_die.cpp -// -/* -* This is a slightly simplistic rendering of the FORM -* issue, it is not precise. However it is really only -* here so we can detect and report an error (producing -* incorrect DWARF) by a particular compiler (a quite unusual error, -* noticed in April 2010). -* So this simplistic form suffices. See the libdwarf get_loclist_n() -* function source for the precise test. -*/ -static bool is_location_form(int form) -{ - if(form == DW_FORM_block1 || - form == DW_FORM_block2 || - form == DW_FORM_block4 || - form == DW_FORM_block || - form == DW_FORM_data4 || - form == DW_FORM_data8 || - form == DW_FORM_sec_offset) { - return true; - } - return false; -} - -/** - * @brief Get address from attribute. - * @param attr Address class attribute. - * @return Address represented by the attribute. - */ -Dwarf_Addr getAttrAddr(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - Dwarf_Addr retVal = 0; - - if (dwarf_formaddr(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return EMPTY_ADDR; - } -} - -/** - * @brief Get value of the attribute. - * @param attr Constant class attribute. - * @return Value of the attrinute. - */ -Dwarf_Unsigned getAttrNumb(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Unsigned uRetVal = 0; - if (dwarf_formudata(attr, &uRetVal, &error) == DW_DLV_OK) - { - return uRetVal; - } - - Dwarf_Signed sRetVal = 0; - if (dwarf_formsdata(attr, &sRetVal, &error) == DW_DLV_OK) - { - return sRetVal; - } - - DWARF_ERROR(getDwarfError(error)); - return EMPTY_UNSIGNED; -} - -/** - * @brief Get string from the attribute. - * @param attr String class attribute. - * @return String containing the value of the attribute. - */ -string getAttrStr(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - char *name = nullptr; - if (dwarf_formstring(attr, &name, &error) == DW_DLV_OK) - { - return string(name); - } - else - { - DWARF_ERROR(getDwarfError(error)); - return EMPTY_STR; - } -} - -/** - * @brief Get reference from the attribute. - * @param attr Reference class attribute. - * @return Offset represented by the attribute. - */ -Dwarf_Off getAttrRef(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Off retVal; - if (dwarf_formref(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return EMPTY_OFF; - } -} - -/** - * @brief Get global reference from the attribute. - * @param attr Reference or other section-references class - * attribute. - * @return Global offset represented by the attribute. - */ -Dwarf_Off getAttrGlobalRef(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Off retVal; - if (dwarf_global_formref(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return EMPTY_OFF; - } -} - -/** - * @brief Get flag from the attribute. - * @param attr Attribute. - * @return True if attribute has a non-zero value, else false. - */ -Dwarf_Bool getAttrFlag(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Bool retVal; - if (dwarf_formflag(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return false; - } -} - -/** - * @brief Get block from the attribute. - * @param attr Block class attribute. - * @return Pointer to block structure represented by the attribute, - */ -Dwarf_Block *getAttrBlock(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Block *retVal = nullptr; - if (dwarf_formblock(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return nullptr; - } -} - -/** - * @brief Get 8 byte signature from the attribute. - * @param attr Attribute of DW_FORM_ref_sig8 form. - * @return 8 byte signature represented by the attribute. - */ -Dwarf_Sig8 getAttrSig(Dwarf_Attribute attr) -{ - Dwarf_Error error = nullptr; - - Dwarf_Sig8 retVal; - if (dwarf_formsig8(attr, &retVal, &error) == DW_DLV_OK) - { - return retVal; - } - else - { - DWARF_ERROR(getDwarfError(error)); - return Dwarf_Sig8(); - } -} - -/** - * @brief Gets length of the location expression and pointer to - * the bytes of the location expression from the attribute. - * @param attr Attribute of DW_FORM_exprloc form. - * @param exprlen Pointer to location expression length to set. - * @param ptr Pointer to location expression pointer to set. - */ -void getAttrExprLoc(Dwarf_Attribute attr, Dwarf_Unsigned *exprlen, - Dwarf_Ptr *ptr) -{ - Dwarf_Error error = nullptr; - - if (dwarf_formexprloc(attr, exprlen, ptr, &error) != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(error)); - // non-recoverable -- exit(1) ??? - } -} - -/** - * @brief Gets libdwarf error message to provided error code. - * @param error Error code. - * @return Error message as strings. - */ -string getDwarfError(Dwarf_Error &error) -{ - return string(dwarf_errmsg(error)); -} - -/** - * @brief Gets DIE from provided offset. - * @param dbg Debug file. - * @param off Offset. - * @param die Found die. - * @return True if success, false otherwise. - */ -bool getDieFromOffset(Dwarf_Debug dbg, Dwarf_Off off, Dwarf_Die &die) -{ - bool is_info = true; - Dwarf_Error error; - int res = dwarf_offdie_b(dbg, off, is_info, &die, &error); - - if (res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(error)); - return false; - } - - if (res == DW_DLV_NO_ENTRY) - { - return false; - } - - return true; -} - -/** - * @brief ctor -- initialize class with DIE which attributes will be processed. - * @param dbg Libdwarf structure representing DWARF file. - * @param die Source DIE which atributes will be processed. - * @param parent Parent dwarfparser representation of DWARF file. - */ -AttrProcessor::AttrProcessor(Dwarf_Debug dbg, Dwarf_Die die, DwarfFile *parent) : - m_dbg(dbg), - m_die(die), - m_parent(parent), - m_res(DW_DLV_OK), - m_error(nullptr) -{ - -} - -/** - * @brief Get offset of source DIE. - * @return DIE offset. - */ -Dwarf_Off AttrProcessor::getDieOff() -{ - Dwarf_Off offset; - if (dwarf_dieoffset(m_die, &offset, &m_error) != DW_DLV_OK) - { - DWARF_ERROR(getDwarfError(m_error)); - return EMPTY_OFF; - } - - return offset; -} - -/** - * @brief Get attribute value from source DIE and return it in. - * @param attrCode Attribute code to get. - * @param ret Pointer to return value which will be filled with result. - * Caller must provide pointer to expected data type. - * @return True if specified attribute was found, false otherwise. - * @note - * AttrCodes in switch are not in alphabetical order, - * codes are grouped based on mechanism of getting attr values. - * But codes inside one group should by ordered alphabetically, - * so if you are adding some, place it in correct place here and - * in getEmpty() method as well. - * - * TODO: because it may be called at already initialized member of some object, it - * will rewrite (getEmpty) this member if attr not found for the second time: - * DW_AT_abstract_origin in functions, DW_AT_specification in types, ... - * It would be better to refactorize all work with this function, all ret must by initialized - * to empty value before call and there will be no getEmpty() function, if attr not found, - * ret wont be changed -- default empty value if not processed yet, previous value if already - * found and processed. - */ - -bool AttrProcessor::get(Dwarf_Half attrCode, std::string& ret) -{ - ret = EMPTY_STR; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_comp_dir: - case DW_AT_linkage_name: - case DW_AT_MIPS_linkage_name: - case DW_AT_HP_linkage_name: - case DW_AT_name: - case DW_AT_producer: - { - ret = getAttrStr(attr); - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, const std::string* &ret) -{ - ret = &EMPTY_STR; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_decl_file: - { - Dwarf_Unsigned fileNum = getAttrNumb(attr); - DwarfCU *lastCU = m_parent->m_activeCU; - - if(lastCU && - (fileNum > 0) && - (lastCU->srcFilesCount() > (fileNum-1))) - { - ret = lastCU->getSrcFile(fileNum-1); - } - else - { - r = false; - } - - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, Dwarf_Signed& ret) -{ - ret = EMPTY_SIGNED; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_const_value: // !!! block, constant, string - { - ret = getAttrNumb(attr); - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, Dwarf_Unsigned& ret) -{ - ret = EMPTY_UNSIGNED; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_low_pc: - { - ret = getAttrAddr(attr); - break; - } - case DW_AT_high_pc: - { - Dwarf_Half theform; - dwarf_whatform(attr,&theform,&m_error); - - if (theform == DW_FORM_addr) - ret = getAttrAddr(attr); // address class - else - ret = getAttrNumb(attr); // constant class - offset from low - - break; - } - case DW_AT_abstract_origin: - case DW_AT_sibling: - case DW_AT_specification: - { - ret = getAttrGlobalRef(attr); - break; - } - case DW_AT_ordering: - case DW_AT_byte_size: // !!! constant, exprloc, reference - case DW_AT_bit_offset: // !!! constant, exprloc, reference - case DW_AT_bit_size: // !!! constant, exprloc, reference - case DW_AT_language: - case DW_AT_discr_value: - case DW_AT_visibility: - case DW_AT_const_value: // !!! block, constant, string - case DW_AT_inline: - case DW_AT_upper_bound: // !!! constant, exprloc, reference - case DW_AT_accessibility: - case DW_AT_address_class: - case DW_AT_calling_convention: - case DW_AT_decl_column: - //case DW_AT_decl_file: // !!! implemented below - case DW_AT_decl_line: - case DW_AT_encoding: - case DW_AT_identifier_case: - case DW_AT_virtuality: - case DW_AT_call_column: - case DW_AT_call_file: - case DW_AT_call_line: - case DW_AT_binary_scale: - case DW_AT_decimal_scale: - case DW_AT_decimal_sign: - case DW_AT_digit_count: - case DW_AT_endianity: - case DW_AT_data_bit_offset: - { - ret = getAttrNumb(attr); - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, Dwarf_Bool& ret) -{ - ret = false; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_is_optional: - case DW_AT_prototyped: - case DW_AT_artificial: - case DW_AT_declaration: - case DW_AT_external: - case DW_AT_variable_parameter: - case DW_AT_use_UTF8: - case DW_AT_mutable: - case DW_AT_threads_scaled: - case DW_AT_explicit: - case DW_AT_elemental: - case DW_AT_pure: - case DW_AT_recursive: - case DW_AT_main_subprogram: - case DW_AT_const_expr: - case DW_AT_enum_class: - { - ret = getAttrFlag(attr); - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, DwarfLocationDesc* &ret) -{ - ret = nullptr; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_location: - case DW_AT_data_member_location: - case DW_AT_frame_base: - { - ret = new DwarfLocationDesc(); - - Dwarf_Half theform = 0; - Dwarf_Half directform = 0; - get_form_values(attr, theform, directform); - - // Location form - original form working on ARM, MIPS. - if (is_location_form(theform)) - { - Dwarf_Locdesc **locs; // list of location descriptions - Dwarf_Signed cnt; // number of list records - - m_res = dwarf_loclist_n(attr, &locs, &cnt, &m_error); - if (m_res != DW_DLV_OK) - { - delete ret; - ret = nullptr; - return false; - } - - // List of expressions. - for (int i=0; ild_lopc; - e.highAddr = locs[i]->ld_hipc; - - // List of atoms in one expression. - for (int j=0; jld_cents;j++) - { - Dwarf_Loc *atom = &(locs[i]->ld_s[j]); - - DwarfLocationDesc::Atom a; - - a.opcode = atom->lr_atom; - a.op1 = atom->lr_number; - a.op2 = atom->lr_number2; - a.off = atom->lr_offset; - - e.atoms.push_back(a); - } - - ret->addExpr(e); - - dwarf_dealloc(m_dbg, locs[i]->ld_s, DW_DLA_LOC_BLOCK); - dwarf_dealloc(m_dbg, locs[i], DW_DLA_LOCDESC); - } - - dwarf_dealloc(m_dbg, locs, DW_DLA_LIST); - } - - // Expression location - occured on x86. - else if (theform == DW_FORM_exprloc) - { - // Get expression location pointer. - Dwarf_Unsigned retExprLen; // Length of location expression. - Dwarf_Ptr blockPtr = nullptr; // Pointer to location expression. - m_res = dwarf_formexprloc(attr, &retExprLen, &blockPtr, &m_error); - - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR("dwarf_formexprloc() error."); - } - - delete ret; - ret = nullptr; - return false; - } - - // Get address size. - Dwarf_Half addrSize = 0; - m_res = dwarf_get_die_address_size(m_die, &addrSize, &m_error); - - if (m_res != DW_DLV_OK) - { - delete ret; - ret = nullptr; - return false; - } - - // Get list of location descriptors -- only one location expression. - Dwarf_Locdesc *loc = nullptr; - Dwarf_Signed cnt; - - m_res = dwarf_loclist_from_expr_a(m_dbg, - blockPtr, - retExprLen, - addrSize, - &loc, - &cnt, // should be set to 1. - &m_error); - if (m_res != DW_DLV_OK) { - delete ret; - ret = nullptr; - return false; - } - - // Copy single location to higher representation. - DwarfLocationDesc::Expression e; - e.lowAddr = loc->ld_lopc; - e.highAddr = loc->ld_hipc; - // List of atoms in one expression. - for (int j=0; jld_cents;j++) - { - Dwarf_Loc *atom = &(loc->ld_s[j]); - DwarfLocationDesc::Atom a; - - a.opcode = atom->lr_atom; - a.op1 = atom->lr_number; - a.op2 = atom->lr_number2; - a.off = atom->lr_offset; - - e.atoms.push_back(a); - } - ret->addExpr(e); - - dwarf_dealloc(m_dbg, loc->ld_s, DW_DLA_LOC_BLOCK); - dwarf_dealloc(m_dbg, loc, DW_DLA_LOCDESC); - } - - // - else if (theform == DW_FORM_data1 || - theform == DW_FORM_data2 || - theform == DW_FORM_data4 || - theform == DW_FORM_data8) - { - // TODO: dwarf-cpp-test: DW_AT_data_member_location: - // tu by to chcelo vratit konstantu a nie location, - // data member su vacsinou aj tak hodnoty a nie vyrazy. - // - //Dwarf_Unsigned *num = (Dwarf_Unsigned*) ret - //*num = getAttrNumb(attr) - break; - } - - // Bad attribute form. - else - { - DWARF_ERROR("Attribute form error: " << hex << attrCode << " : " << theform); - delete ret; - ret = nullptr; - return false; - } - - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::get(Dwarf_Half attrCode, DwarfType* &ret) -{ - ret = m_parent->getTypes()->getVoid(); - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_type: - { - Dwarf_Off typeRef = getAttrGlobalRef(attr); - Dwarf_Die typeDie; - - m_res = dwarf_offdie_b(m_dbg, typeRef, is_info, &typeDie, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - if (m_res == DW_DLV_NO_ENTRY) - { - return false; - } - - ret = m_parent->getTypes()->loadAndGetDie(typeDie, 0); - if (ret == nullptr) - { - ret = m_parent->getTypes()->getVoid(); - return false; - } - - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -bool AttrProcessor::geti(Dwarf_Half attrCode, int& ret) -{ - ret = 0; - - Dwarf_Attribute attr; - m_res = dwarf_attr(m_die, attrCode, &attr, &m_error); - if (m_res != DW_DLV_OK) - { - if (m_res == DW_DLV_ERROR) - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - bool r = true; - switch (attrCode) - { - case DW_AT_type: - { - Dwarf_Off typeRef = getAttrGlobalRef(attr); - Dwarf_Die typeDie; - - m_res = dwarf_offdie_b(m_dbg, typeRef, is_info, &typeDie, &m_error); - - if (m_res == DW_DLV_ERROR) - { - DWARF_ERROR(getDwarfError(m_error)); - return false; - } - - if (m_res == DW_DLV_NO_ENTRY) - { - return false; - } - - ret = m_parent->getTypes()->getDieFlags(typeDie, 0); - break; - } - default: - { - r = false; - } - } - - dwarf_dealloc(m_dbg, attr, DW_DLA_ATTR); - return r; -} - -} // namespace dwarfparser -} // namespace retdec diff --git a/src/dwarfparser/dwarf_vars.cpp b/src/dwarfparser/dwarf_vars.cpp deleted file mode 100644 index 5ee453a27..000000000 --- a/src/dwarfparser/dwarf_vars.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @file src/dwarfparser/dwarf_vars.cpp - * @brief Implementataion of classes representing variables. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include -#include - -#include "retdec/dwarfparser/dwarf_file.h" -#include "retdec/dwarfparser/dwarf_functions.h" -#include "retdec/dwarfparser/dwarf_vars.h" - -using namespace std; - -namespace retdec { -namespace dwarfparser { - -/** - * @brief ctor. - * @param file Pointer to dwarfparser representation of DWARF file which owns this container. - * @param elem Pointer to parent element that owns this container. - */ -DwarfVarContainer::DwarfVarContainer(DwarfFile *file, DwarfBaseElement *elem) : - DwarfBaseContainer(file, elem) -{ - -} - -/** - * @brief Print contents of this container. - */ -void DwarfVarContainer::dump() const -{ - cout << endl; - cout << "==================== Variables ====================" << endl; - - // Is Empty? - if (m_data.empty()) - { - cout << "NO variable information." << endl; - return; - } - - // Header. - cout << setw(30) << left << "Variable name"; - cout << setw(25) << left << "Variable type name"; - cout << setw(20) << left << "Flags" << endl; - - // Variables. - DwarfBaseContainer::dump(); - - cout << endl; -} - -/** - * @brief Get all data from function DIE. - * @param die Function DIE. - * @param lvl Level (depth) of this die. - * @return Pointer to variable object if found, nullptr otherwise. - */ -DwarfVar *DwarfVarContainer::loadAndGetDie(Dwarf_Die die, unsigned) -{ - // Use special class to get attributes that we want. - AttrProcessor ap(m_parentFile->m_dbg, die, m_parentFile); - - // TODO: Variables with DW_AT_declaration attribute are skipped at the moment. - // These DIEs do not contain DW_AT_location attribute. - // For each such DIE there should be another one that defines variable and - // contains location. - Dwarf_Bool isDeclr; - ap.get(DW_AT_declaration, isDeclr); - if (isDeclr) - return nullptr; - - // TODO: Variables with DW_AT_abstract_origin are skipped at them moment. - // They are inline instances of inline subprograms. - // They mess-up subprogram parameters. - Dwarf_Off ref = EMPTY_UNSIGNED; - ap.get(DW_AT_abstract_origin, ref); - if (ref != EMPTY_UNSIGNED) - return nullptr; - - DwarfVar *v = new DwarfVar(this, ap.getDieOff()); - - ap.get(DW_AT_name, v->name); - ap.get(DW_AT_type, v->type); - ap.geti(DW_AT_type, v->flags); - - ap.get(DW_AT_location, v->location); - if (v->location) - { - v->location->setParent(v); - if (m_parentElem != nullptr) - { - if (dynamic_cast(m_parentElem)) - { - // no frame base - } - else if (DwarfFunction *f = dynamic_cast(m_parentElem)) - { - v->location->setBaseFunc(f); - } - else - { - DWARF_WARNING("loadDie(): Unable to set frame base for variable: \"" << v->name << "\"."); - } - } - } - - Dwarf_Half tag = 0; - dwarf_tag(die, &tag, &m_error); - - if (tag == DW_TAG_variable) - { - m_data.push_back(v); - return v; - } - else if (tag == DW_TAG_formal_parameter) - { - return addParameter(v); - } - else - { - DWARF_ERROR("Unexpected tag."); - return nullptr; - } -} - -/** - * @brief Get variable by its name. - * @param n Name of variable to get. - * @return Pointer to variable object if found, nullptr otherwise. - */ -DwarfVar *DwarfVarContainer::getVarByName(string n) -{ - for (iterator it=begin(); it!=end(); ++it) - { - if ((*it)->name == n) - { - return (*it); - } - } - - return nullptr; -} - -/** - * @brief Add parameter co container. Check if it has unique name. - * @param n Parameter to add. - * @return Added parameter or existing one. - * - * TODO: podla mena to nie je 100%, v jednom DIE nemusi byt meno nastavene. - * V jednom samplu sa dali unikatne prepojit podla DW_AT_decl_file + DW_AT_decl_line. - * neviem ale ci je toto nastaven vzdy, ideal by bolo kontextove nacitanie, ktore by vedelo - * ku ktorej funkcii parameter partri, ktory v poradi je a ak by na tom indexe uz nieco - * existovalo tak by sa to len aktualizovalo a nevytvaralo nove. - */ -DwarfVar *DwarfVarContainer::addParameter(DwarfVar *n) -{ - if (n == nullptr) - return n; - - for (iterator it=begin(); it!=end(); ++it) - { - // not empty -> params for DW_TAG_subroutine_type do not have names, - // this may cause some other problems. - // - if (!n->name.empty() && (*it)->name == n->name) - { - (*it)->mergeWith(n); - delete n; - return (*it); - } - } - - m_data.push_back(n); - return n; -} - -/** - * @brief ctor. - * @param prnt Pointer to parent container owning this element. - * @param off Offset associated with this element in DWARF file - unique ID. - * @param t Type of DwarfBaseElement object. - */ -DwarfVar::DwarfVar(DwarfVarContainer *prnt, Dwarf_Off off, - DwarfBaseElement::type_t t) : - DwarfBaseElement(t, reinterpret_cast*>(prnt), off), - flags(EMPTY), - type(nullptr), - location(nullptr) -{ - -} - -/** - * @brief dctor. - */ -DwarfVar::~DwarfVar() -{ - delete location; -} - -/** - * @brief Print contents of this class. - */ -void DwarfVar::dump() const -{ - string f; - if (isConstant()) - f += " Const. "; - if (isPointer()) - f += " Ptr. "; - if (isRestrict()) - f += " Rest. "; - if (isVolatile()) - f += " Volat. "; - - cout << setw(30) << left << name; - cout << setw(25) << left << type->name; - cout << setw(20) << left << f; - cout << getDwarfdump2OffsetString() << endl; -} - -/** - * @brief Merge this variable with the provided one. - * Members that are not set in this are set from other. - * @param o Other variable. - */ -void DwarfVar::mergeWith(DwarfVar *o) -{ - if (name.empty()) name = o->name; - if (flags == EMPTY) flags = o->flags; - if (type == nullptr) type = o->type; - if (location == nullptr) { location = o->location; o->location = nullptr; } -} - -/** - * @brief Some variables may not have locations. - * @return True if this variable has location, false otherwise. - */ -bool DwarfVar::hasLocation() -{ - return (location != nullptr); -} - -/** - * @brief Compute location of variable. - * @param n Pointer to string that will be filled by method. - * If variable location is address this is a name of address space. - * If variable location is register this is a name of register array. - * @param a Pointer to value that will be filled by method. - * If variable location is address this is an address in address space. - * If variable location is register this is a number in register array. - * @param pc Program counter value. Does not need to be specified if resources was - * initialized. - * @return Type of variable location - address or register. - */ -DwarfLocationDesc::cLocType DwarfVar::getLocation(string *n, Dwarf_Addr *a, Dwarf_Addr pc) -{ - if (location) - return (location->computeLocation(n, a, pc)); - else - return DwarfLocationDesc::FAIL; -} - -/** - * @brief If variable is on stack, get its offset from stack pointer; - * @param a Pointer to offset that will be filled by method. - * If variable is not on stack it will be set to zero. - * @param deref Pointer to boolean value that will be filled by method. - * If true then on address counted using returned offset is an - * address of variable data. - * If false then there are actual data on counted address. - * If variable is not on stack it will be set to false. - * @param pc Actual program counter. - * @param regNum Register number. - * @return True if variable on stack, false otherwise. - */ -bool DwarfVar::isOnStack(Dwarf_Signed *a, bool *deref, Dwarf_Addr pc, int *regNum) -{ - if (location) - return location->isOnStack(a, deref, pc, regNum); - else - return false; -} - -/** - * @brief Test if variable is a constant. - * @return True if variable is a constant, false otherwise. - */ -bool DwarfVar::isConstant() const -{ - return (flags & CONSTANT); -} - -/** - * @brief Test if variable is a pointer. - * @return True if variable is a pointer, false otherwise. - */ -bool DwarfVar::isPointer() const -{ - return (flags & POINTER); -} - -/** - * @brief Test if variable is restrict. - * @return True if variable is restrict, false otherwise. - */ -bool DwarfVar::isRestrict() const -{ - return (flags & RESTRICT); -} - -/** - * @brief Test if variable is volatile. - * @return True if variable is volatile, false otherwise. - */ -bool DwarfVar::isVolatile() const -{ - return (flags & VOLATILE); -} - -} // namespace dwarfparser -} // namespace retdec