Compare commits
51 Commits
v1.0.1-alp
...
qt5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b58f315c98 | ||
|
|
7687c2b7d2 | ||
|
|
0abbce6f4e | ||
|
|
8ffdf657ec | ||
|
|
2232a76033 | ||
|
|
d6af9c1555 | ||
|
|
d7acc8cd4d | ||
|
|
a5f1d17e83 | ||
|
|
29efcd5be1 | ||
|
|
4656db9484 | ||
|
|
b33d7239e5 | ||
|
|
e1f0c084f8 | ||
|
|
e2a6b25345 | ||
|
|
f210ed78c2 | ||
|
|
ccc8cc526b | ||
|
|
cd6797499f | ||
|
|
b60903306f | ||
|
|
1df7cb3be4 | ||
|
|
a7265f06b0 | ||
|
|
58532f4402 | ||
|
|
7d986ef661 | ||
|
|
7f4197acc1 | ||
|
|
e71c8051c3 | ||
|
|
73cf949e25 | ||
|
|
b2be1cf2da | ||
|
|
94e3016a5b | ||
|
|
145a50369e | ||
|
|
d77927c608 | ||
|
|
3bb72987a6 | ||
|
|
c782892db4 | ||
|
|
a944ea5da8 | ||
|
|
d1738ea630 | ||
|
|
5f39236ba2 | ||
|
|
ede09ddae3 | ||
|
|
34b1f4f4fe | ||
|
|
d6249916e1 | ||
|
|
9cd3226536 | ||
|
|
3f217e83da | ||
|
|
652cfb67c3 | ||
|
|
c0e9ba2fb3 | ||
|
|
5963f5fd4d | ||
|
|
12ee08f87e | ||
|
|
5c85c92d1a | ||
|
|
b509d0fcf0 | ||
|
|
bb007ddefc | ||
|
|
9129d48429 | ||
|
|
d105182051 | ||
|
|
157a968372 | ||
|
|
bae2a582f1 | ||
|
|
19191876e2 | ||
|
|
fcfe3c1f4b |
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
* text=auto
|
||||||
|
*.c text
|
||||||
|
*.cpp text
|
||||||
|
*.ui text
|
||||||
|
*.qrc text
|
||||||
|
*.h text
|
||||||
5
3rd_party/libdisasm/libdis.h
vendored
5
3rd_party/libdisasm/libdis.h
vendored
@ -317,7 +317,10 @@ struct x86_op_t{
|
|||||||
case op_offset:
|
case op_offset:
|
||||||
return data.offset;
|
return data.offset;
|
||||||
case op_relative_far:
|
case op_relative_far:
|
||||||
return (int32_t) data.relative_far;
|
if (data.relative_far & 0x8000)
|
||||||
|
return (data.relative_far & 0xFFFF) | 0xFFFF0000;
|
||||||
|
else
|
||||||
|
return (int32_t)data.relative_far;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
PROJECT(dcc_original)
|
PROJECT(dcc_original)
|
||||||
cmake_minimum_required(VERSION 2.8.9)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
find_package(Qt5Core)
|
find_package(Qt5Core)
|
||||||
@ -7,15 +7,15 @@ find_package(Qt5Core)
|
|||||||
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
||||||
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
|
||||||
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE -DNOMINMAX)
|
||||||
ADD_DEFINITIONS(/W4)
|
ADD_DEFINITIONS(/W4)
|
||||||
ELSE()
|
ELSE()
|
||||||
#-D_GLIBCXX_DEBUG
|
#-D_GLIBCXX_DEBUG
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} " ) #--coverage
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} " ) #--coverage
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
||||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
||||||
include(cotire)
|
include(cotire)
|
||||||
@ -26,17 +26,12 @@ enable_testing()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
find_package(LLVM REQUIRED CONFIG)
|
|
||||||
llvm_map_components_to_libnames(REQ_LLVM_LIBRARIES native mc support tablegen)
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
3rd_party/libdisasm
|
3rd_party/libdisasm
|
||||||
include
|
include
|
||||||
include/idioms
|
include/idioms
|
||||||
common
|
common
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
${LLVM_INCLUDE_DIRS}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -95,6 +90,7 @@ set(dcc_HEADERS
|
|||||||
include/bundle.h
|
include/bundle.h
|
||||||
include/BinaryImage.h
|
include/BinaryImage.h
|
||||||
include/DccFrontend.h
|
include/DccFrontend.h
|
||||||
|
include/Enums.h
|
||||||
include/dcc.h
|
include/dcc.h
|
||||||
include/disassem.h
|
include/disassem.h
|
||||||
include/dosdcc.h
|
include/dosdcc.h
|
||||||
@ -135,8 +131,10 @@ qt5_use_modules(dcc_lib Core)
|
|||||||
|
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||||
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
||||||
TARGET_LINK_LIBRARIES(dcc_original dcc_lib dcc_hash disasm_s ${REQ_LLVM_LIBRARIES} LLVMSupport)
|
TARGET_LINK_LIBRARIES(dcc_original dcc_lib dcc_hash disasm_s)
|
||||||
qt5_use_modules(dcc_original Core)
|
qt5_use_modules(dcc_original Core)
|
||||||
|
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD 11)
|
||||||
|
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||||
#ADD_SUBDIRECTORY(gui)
|
#ADD_SUBDIRECTORY(gui)
|
||||||
if(dcc_build_tests)
|
if(dcc_build_tests)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
|
|||||||
339
LICENSE
Normal file
339
LICENSE
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 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.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, 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 software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, 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 redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
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 give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
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 Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
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 Program, 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 Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) 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; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, 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 executable. 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.
|
||||||
|
|
||||||
|
If distribution of executable or 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 counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||||
|
|
||||||
|
5. 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 Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program 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.
|
||||||
|
|
||||||
|
7. 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 Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program 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.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the 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 Program
|
||||||
|
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 Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, 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
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), 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 Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; 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.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
@ -6,6 +6,8 @@ To reflect those fixes, I've edited the original readme a bit.
|
|||||||
dcc Distribution
|
dcc Distribution
|
||||||
================
|
================
|
||||||
|
|
||||||
|
[](https://gitter.im/nemerle/dcc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
The code provided in this distribution is (C) by their authors:
|
The code provided in this distribution is (C) by their authors:
|
||||||
- Cristina Cifuentes (most of dcc code)
|
- Cristina Cifuentes (most of dcc code)
|
||||||
- Mike van Emmerik (signatures and prototype code)
|
- Mike van Emmerik (signatures and prototype code)
|
||||||
|
|||||||
@ -5,18 +5,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define SYMLEN 16 /* Number of chars in the symbol name, incl null */
|
#define SYMLEN 16 /* Number of chars in the symbol name, incl null */
|
||||||
#define PATLEN 23 /* Number of bytes in the pattern part */
|
#define PATLEN 23 /* Number of bytes in the pattern part */
|
||||||
|
|
||||||
struct HASHENTRY
|
struct HASHENTRY
|
||||||
{
|
{
|
||||||
char name[SYMLEN]; /* The symbol name */
|
char name[SYMLEN]; /* The symbol name */
|
||||||
uint8_t pat [PATLEN]; /* The pattern */
|
uint8_t pat [PATLEN]; /* The pattern */
|
||||||
uint16_t offset; /* Offset (needed temporarily) */
|
uint16_t offset; /* Offset (needed temporarily) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatternCollector {
|
struct PatternCollector {
|
||||||
uint8_t buf[100], bufSave[7]; /* Temp buffer for reading the file */
|
uint8_t buf[100], bufSave[7]; /* Temp buffer for reading the file */
|
||||||
uint16_t readShort(FILE *f)
|
uint16_t readShort(FILE *f)
|
||||||
{
|
{
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
#include "PatternCollector.h"
|
#include "PatternCollector.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -38,9 +39,6 @@ static bool *visited; /* Array of bools: whether visited */
|
|||||||
static bool *deleted; /* Array of bools: whether deleted */
|
static bool *deleted; /* Array of bools: whether deleted */
|
||||||
|
|
||||||
/* Private prototypes */
|
/* Private prototypes */
|
||||||
static void initGraph(void);
|
|
||||||
static void addToGraph(int e, int v1, int v2);
|
|
||||||
static bool isCycle(void);
|
|
||||||
static void duplicateKeys(int v1, int v2);
|
static void duplicateKeys(int v1, int v2);
|
||||||
|
|
||||||
void PerfectHash::setHashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
|
void PerfectHash::setHashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
|
||||||
@ -157,7 +155,7 @@ void PerfectHash::map(PatternCollector *collector)
|
|||||||
}
|
}
|
||||||
addToGraph(numEdges++, f1, f2);
|
addToGraph(numEdges++, f1, f2);
|
||||||
}
|
}
|
||||||
if (cycle || (cycle = isCycle())) /* OK - is there a cycle? */
|
if (cycle or (cycle = isCycle())) /* OK - is there a cycle? */
|
||||||
{
|
{
|
||||||
printf("Iteration %d\n", ++c);
|
printf("Iteration %d\n", ++c);
|
||||||
}
|
}
|
||||||
@ -314,7 +312,7 @@ bool PerfectHash::isCycle(void)
|
|||||||
}
|
}
|
||||||
for (v=1; v <= NumVert; v++)
|
for (v=1; v <= NumVert; v++)
|
||||||
{
|
{
|
||||||
if (!visited[v])
|
if (not visited[v])
|
||||||
{
|
{
|
||||||
if (DFS(-32767, v))
|
if (DFS(-32767, v))
|
||||||
{
|
{
|
||||||
@ -335,7 +333,7 @@ void PerfectHash::traverse(int u)
|
|||||||
while (e)
|
while (e)
|
||||||
{
|
{
|
||||||
w = graphNode[NumEntry+e]-1;
|
w = graphNode[NumEntry+e]-1;
|
||||||
if (!visited[w])
|
if (not visited[w])
|
||||||
{
|
{
|
||||||
g[w] = (abs(e)-1 - g[u]) % NumEntry;
|
g[w] = (abs(e)-1 - g[u]) % NumEntry;
|
||||||
if (g[w] < 0) g[w] += NumEntry; /* Keep these positive */
|
if (g[w] < 0) g[w] += NumEntry; /* Keep these positive */
|
||||||
@ -359,7 +357,7 @@ void PerfectHash::assign(void)
|
|||||||
|
|
||||||
for (v=0; v < NumVert; v++)
|
for (v=0; v < NumVert; v++)
|
||||||
{
|
{
|
||||||
if (!visited[v])
|
if (not visited[v])
|
||||||
{
|
{
|
||||||
g[v] = 0;
|
g[v] = 0;
|
||||||
traverse(v);
|
traverse(v);
|
||||||
@ -415,7 +413,7 @@ duplicateKeys(int v1, int v2)
|
|||||||
u += T1[keys[j] - SetMin];
|
u += T1[keys[j] - SetMin];
|
||||||
}
|
}
|
||||||
u %= NumVert;
|
u %= NumVert;
|
||||||
if ((u != v1) && (u != v2)) continue;
|
if ((u != v1) and (u != v2)) continue;
|
||||||
|
|
||||||
v = 0;
|
v = 0;
|
||||||
for (j=0; j < EntryLen; j++)
|
for (j=0; j < EntryLen; j++)
|
||||||
@ -425,7 +423,7 @@ duplicateKeys(int v1, int v2)
|
|||||||
}
|
}
|
||||||
v %= NumVert;
|
v %= NumVert;
|
||||||
|
|
||||||
if ((v == v2) || (v == v1))
|
if ((v == v2) or (v == v1))
|
||||||
{
|
{
|
||||||
printf("Entry #%d key: ", i+1);
|
printf("Entry #%d key: ", i+1);
|
||||||
for (j=0; j < EntryLen; j++) printf("%02X ", keys[j]);
|
for (j=0; j < EntryLen; j++) printf("%02X ", keys[j]);
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/** Perfect hashing function library. Contains functions to generate perfect
|
/** Perfect hashing function library. Contains functions to generate perfect
|
||||||
hashing functions */
|
hashing functions */
|
||||||
|
|||||||
@ -3,8 +3,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
#include <llvm/ADT/ilist_node.h>
|
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@ -27,7 +25,7 @@ struct TYPEADR_TYPE
|
|||||||
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
|
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
struct BB : public llvm::ilist_node<BB>
|
struct BB
|
||||||
{
|
{
|
||||||
friend struct Function;
|
friend struct Function;
|
||||||
private:
|
private:
|
||||||
@ -59,10 +57,10 @@ public:
|
|||||||
ICODE &front();
|
ICODE &front();
|
||||||
ICODE &back();
|
ICODE &back();
|
||||||
size_t size();
|
size_t size();
|
||||||
uint8_t nodeType; /* Type of node */
|
uint8_t nodeType; /* Type of node */
|
||||||
eDFS traversed; /* last traversal id is held here traversed yet? */
|
eDFS traversed; /* last traversal id is held here traversed yet? */
|
||||||
int numHlIcodes; /* No. of high-level icodes */
|
int numHlIcodes; /* No. of high-level icodes */
|
||||||
uint32_t flg; /* BB flags */
|
uint32_t flg; /* BB flags */
|
||||||
|
|
||||||
/* In edges and out edges */
|
/* In edges and out edges */
|
||||||
std::vector<BB *> inEdges; // does not own held pointers
|
std::vector<BB *> inEdges; // does not own held pointers
|
||||||
@ -80,10 +78,10 @@ public:
|
|||||||
interval *correspInt; //!< Corresponding interval in derived graph Gi-1
|
interval *correspInt; //!< Corresponding interval in derived graph Gi-1
|
||||||
// For live register analysis
|
// For live register analysis
|
||||||
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
|
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
|
||||||
LivenessSet liveUse; /* LiveUse(b) */
|
LivenessSet liveUse; /* LiveUse(b) */
|
||||||
LivenessSet def; /* Def(b) */
|
LivenessSet def; /* Def(b) */
|
||||||
LivenessSet liveIn; /* LiveIn(b) */
|
LivenessSet liveIn; /* LiveIn(b) */
|
||||||
LivenessSet liveOut; /* LiveOut(b) */
|
LivenessSet liveOut; /* LiveOut(b) */
|
||||||
|
|
||||||
/* For structuring analysis */
|
/* For structuring analysis */
|
||||||
int dfsFirstNum; /* DFS #: first visit of node */
|
int dfsFirstNum; /* DFS #: first visit of node */
|
||||||
@ -111,7 +109,7 @@ public:
|
|||||||
///
|
///
|
||||||
const Function *getParent() const { return Parent; }
|
const Function *getParent() const { return Parent; }
|
||||||
Function *getParent() { return Parent; }
|
Function *getParent() { return Parent; }
|
||||||
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
void writeBB(QTextStream & ostr, int lev, Function *pProc, int *numLoc);
|
||||||
BB * rmJMP(int marker, BB *pBB);
|
BB * rmJMP(int marker, BB *pBB);
|
||||||
void genDU1();
|
void genDU1();
|
||||||
void findBBExps(LOCAL_ID &locals, Function *f);
|
void findBBExps(LOCAL_ID &locals, Function *f);
|
||||||
|
|||||||
@ -3,21 +3,21 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
struct PROG /* Loaded program image parameters */
|
struct PROG /* Loaded program image parameters */
|
||||||
{
|
{
|
||||||
int16_t initCS;
|
uint16_t initCS=0;
|
||||||
int16_t initIP; /* These are initial load values */
|
uint16_t initIP=0; /* These are initial load values */
|
||||||
int16_t initSS; /* Probably not of great interest */
|
uint16_t initSS=0; /* Probably not of great interest */
|
||||||
uint16_t initSP;
|
uint16_t initSP=0;
|
||||||
bool fCOM; /* Flag set if COM program (else EXE)*/
|
bool fCOM=false; /* Flag set if COM program (else EXE)*/
|
||||||
int cReloc; /* No. of relocation table entries */
|
int cReloc=0; /* No. of relocation table entries */
|
||||||
std::vector<uint32_t> relocTable; /* Ptr. to relocation table */
|
std::vector<uint32_t> relocTable; /* Ptr. to relocation table */
|
||||||
uint8_t * map; /* Memory bitmap ptr */
|
uint8_t * map=nullptr; /* Memory bitmap ptr */
|
||||||
int cProcs; /* Number of procedures so far */
|
int cProcs=0; /* Number of procedures so far */
|
||||||
int offMain; /* The offset of the main() proc */
|
int offMain=0; /* The offset of the main() proc */
|
||||||
uint16_t segMain; /* The segment of the main() proc */
|
uint16_t segMain=0; /* The segment of the main() proc */
|
||||||
bool bSigs; /* True if signatures loaded */
|
bool bSigs=false; /* True if signatures loaded */
|
||||||
int cbImage; /* Length of image in bytes */
|
int cbImage=0; /* Length of image in bytes */
|
||||||
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
uint8_t * Imagez=nullptr; /* Allocated by loader to hold entire program image */
|
||||||
int addressingMode;
|
int addressingMode=0;
|
||||||
public:
|
public:
|
||||||
const uint8_t *image() const {return Imagez;}
|
const uint8_t *image() const {return Imagez;}
|
||||||
void displayLoadInfo();
|
void displayLoadInfo();
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
struct CConv {
|
struct CConv {
|
||||||
enum Type {
|
enum Type {
|
||||||
UNKNOWN=0,
|
eUnknown=0,
|
||||||
C,
|
eCdecl,
|
||||||
PASCAL
|
ePascal
|
||||||
};
|
};
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
||||||
virtual void writeComments(std::ostream &)=0;
|
virtual void writeComments(QTextStream &)=0;
|
||||||
static CConv * create(Type v);
|
static CConv * create(Type v);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -16,16 +18,16 @@ protected:
|
|||||||
|
|
||||||
struct C_CallingConvention : public CConv {
|
struct C_CallingConvention : public CConv {
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
||||||
};
|
};
|
||||||
struct Pascal_CallingConvention : public CConv {
|
struct Pascal_CallingConvention : public CConv {
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
};
|
};
|
||||||
struct Unknown_CallingConvention : public CConv {
|
struct Unknown_CallingConvention : public CConv {
|
||||||
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -90,16 +90,16 @@ enum eLLFlags
|
|||||||
/* Types of icodes */
|
/* Types of icodes */
|
||||||
enum icodeType
|
enum icodeType
|
||||||
{
|
{
|
||||||
NOT_SCANNED = 0, // not even scanned yet
|
NOT_SCANNED_ICODE = 0, // not even scanned yet
|
||||||
LOW_LEVEL, // low-level icode
|
LOW_LEVEL_ICODE, // low-level icode
|
||||||
HIGH_LEVEL // high-level icode
|
HIGH_LEVEL_ICODE // high-level icode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* LOW_LEVEL icode opcodes */
|
/* LOW_LEVEL icode opcodes */
|
||||||
enum llIcode
|
enum llIcode
|
||||||
{
|
{
|
||||||
//iINVALID,
|
iINVALID=-1,
|
||||||
iCBW, /* 0 */
|
iCBW, /* 0 */
|
||||||
iAAA,
|
iAAA,
|
||||||
iAAD,
|
iAAD,
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
//#include <llvm/ADT/ilist_node.h>
|
|
||||||
#include <bitset>
|
|
||||||
#include <map>
|
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "locident.h"
|
#include "locident.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
#include "CallConvention.h"
|
#include "CallConvention.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
/* PROCEDURE NODE */
|
/* PROCEDURE NODE */
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
struct Expr;
|
struct Expr;
|
||||||
@ -19,29 +23,6 @@ struct PROG;
|
|||||||
|
|
||||||
struct Function;
|
struct Function;
|
||||||
|
|
||||||
namespace llvm
|
|
||||||
{
|
|
||||||
// Traits for intrusive list of basic blocks...
|
|
||||||
template<>
|
|
||||||
struct ilist_traits<BB> : public ilist_default_traits<BB>
|
|
||||||
{
|
|
||||||
|
|
||||||
// createSentinel is used to get hold of the node that marks the end of the
|
|
||||||
// list... (same trick used here as in ilist_traits<Instruction>)
|
|
||||||
BB *createSentinel() const {
|
|
||||||
return static_cast<BB*>(&Sentinel);
|
|
||||||
}
|
|
||||||
static void destroySentinel(BB*) {}
|
|
||||||
|
|
||||||
BB *provideInitialHead() const { return createSentinel(); }
|
|
||||||
BB *ensureHead(BB*) const { return createSentinel(); }
|
|
||||||
static void noteHead(BB*, BB*) {}
|
|
||||||
|
|
||||||
//static ValueSymbolTable *getSymTab(Function *ItemParent);
|
|
||||||
private:
|
|
||||||
mutable ilist_half_node<BB> Sentinel;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/* Procedure FLAGS */
|
/* Procedure FLAGS */
|
||||||
enum PROC_FLAGS
|
enum PROC_FLAGS
|
||||||
{
|
{
|
||||||
@ -107,9 +88,9 @@ public:
|
|||||||
}
|
}
|
||||||
void push_back(BB *v) { m_listBB.push_back(v);}
|
void push_back(BB *v) { m_listBB.push_back(v);}
|
||||||
};
|
};
|
||||||
struct Function : public llvm::ilist_node<Function>
|
struct Function
|
||||||
{
|
{
|
||||||
typedef llvm::iplist<BB> BasicBlockListType;
|
typedef std::list<BB *> BasicBlockListType;
|
||||||
// BasicBlock iterators...
|
// BasicBlock iterators...
|
||||||
typedef BasicBlockListType::iterator iterator;
|
typedef BasicBlockListType::iterator iterator;
|
||||||
typedef BasicBlockListType::const_iterator const_iterator;
|
typedef BasicBlockListType::const_iterator const_iterator;
|
||||||
@ -119,15 +100,15 @@ protected:
|
|||||||
hasCase(false),liveAnal(0)
|
hasCase(false),liveAnal(0)
|
||||||
{
|
{
|
||||||
type = new FunctionType;
|
type = new FunctionType;
|
||||||
callingConv(CConv::UNKNOWN);
|
callingConv(CConv::eUnknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionType * type;
|
FunctionType * type;
|
||||||
CConv * m_call_conv;
|
CConv * m_call_conv;
|
||||||
uint32_t procEntry; /* label number */
|
uint32_t procEntry; /* label number */
|
||||||
std::string name; /* Meaningful name for this proc */
|
QString name; /* Meaningful name for this proc */
|
||||||
STATE state; /* Entry state */
|
STATE state; /* Entry state */
|
||||||
int depth; /* Depth at which we found it - for printing */
|
int depth; /* Depth at which we found it - for printing */
|
||||||
uint32_t flg; /* Combination of Icode & Proc flags */
|
uint32_t flg; /* Combination of Icode & Proc flags */
|
||||||
int16_t cbParam; /* Probable no. of bytes of parameters */
|
int16_t cbParam; /* Probable no. of bytes of parameters */
|
||||||
@ -153,7 +134,7 @@ public:
|
|||||||
delete type;
|
delete type;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
|
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const QString &nm="",void */*module*/=0)
|
||||||
{
|
{
|
||||||
Function *r=new Function(ty);
|
Function *r=new Function(ty);
|
||||||
r->name = nm;
|
r->name = nm;
|
||||||
@ -185,14 +166,14 @@ public:
|
|||||||
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void freeCFG();
|
void freeCFG();
|
||||||
void codeGen(std::ostream &fs);
|
void codeGen(QIODevice & fs);
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
void structIfs();
|
void structIfs();
|
||||||
void structLoops(derSeq *derivedG);
|
void structLoops(derSeq *derivedG);
|
||||||
void buildCFG(Disassembler &ds);
|
void buildCFG(Disassembler &ds);
|
||||||
void controlFlowAnalysis();
|
void controlFlowAnalysis();
|
||||||
void newRegArg(iICODE picode, iICODE ticode);
|
void newRegArg(iICODE picode, iICODE ticode);
|
||||||
void writeProcComments(std::ostream &ostr);
|
void writeProcComments(QTextStream & ostr);
|
||||||
|
|
||||||
void displayCFG();
|
void displayCFG();
|
||||||
void displayStats();
|
void displayStats();
|
||||||
@ -200,7 +181,7 @@ public:
|
|||||||
|
|
||||||
void preprocessReturnDU(LivenessSet &_liveOut);
|
void preprocessReturnDU(LivenessSet &_liveOut);
|
||||||
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
||||||
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
QString writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
||||||
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
||||||
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
||||||
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
||||||
@ -233,26 +214,12 @@ protected:
|
|||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
bool findDerivedSeq(derSeq &derivedGi);
|
bool findDerivedSeq(derSeq &derivedGi);
|
||||||
bool nextOrderGraph(derSeq &derivedGi);
|
bool nextOrderGraph(derSeq &derivedGi);
|
||||||
};
|
void addOutEdgesForConditionalJump(BB* pBB, int next_ip, LLInst *ll);
|
||||||
namespace llvm {
|
|
||||||
template<> struct ilist_traits<typename ::Function>
|
|
||||||
: public ilist_default_traits<typename ::Function> {
|
|
||||||
|
|
||||||
// createSentinel is used to get hold of the node that marks the end of the
|
|
||||||
// list... (same trick used here as in ilist_traits<Instruction>)
|
|
||||||
typename ::Function *createSentinel() const {
|
|
||||||
return static_cast<typename ::Function*>(&Sentinel);
|
|
||||||
}
|
|
||||||
static void destroySentinel(typename ::Function*) {}
|
|
||||||
|
|
||||||
typename ::Function *provideInitialHead() const { return createSentinel(); }
|
|
||||||
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
|
|
||||||
static void noteHead(typename ::Function*, typename ::Function*) {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable ilist_node<typename ::Function> Sentinel;
|
bool decodeIndirectJMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
|
bool decodeIndirectJMP2(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
};
|
};
|
||||||
}
|
typedef std::list<Function> FunctionListType;
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
|
||||||
typedef FunctionListType lFunction;
|
typedef FunctionListType lFunction;
|
||||||
typedef lFunction::iterator ilFunction;
|
typedef lFunction::iterator ilFunction;
|
||||||
|
|||||||
@ -5,11 +5,15 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/range/iterator_range.hpp>
|
|
||||||
#include "Enums.h"
|
|
||||||
static const int operandSize=20;
|
static const int operandSize=20;
|
||||||
/* The following definitions and types define the Conditional Expression
|
/* The following definitions and types define the Conditional Expression
|
||||||
* attributed syntax tree, as defined by the following EBNF:
|
* attributed syntax tree, as defined by the following EBNF:
|
||||||
@ -54,7 +58,7 @@ public:
|
|||||||
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
||||||
virtual ~Expr() {}
|
virtual ~Expr() {}
|
||||||
public:
|
public:
|
||||||
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
|
virtual QString walkCondExpr (Function * pProc, int* numLoc) const=0;
|
||||||
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
|
||||||
@ -96,10 +100,12 @@ struct UnaryOperator : public Expr
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
virtual QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual hlType expType(Function *pproc) const;
|
||||||
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
|
private:
|
||||||
|
QString wrapUnary(Function *pProc, int *numLoc, QChar op) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinaryOperator : public Expr
|
struct BinaryOperator : public Expr
|
||||||
@ -120,7 +126,7 @@ struct BinaryOperator : public Expr
|
|||||||
}
|
}
|
||||||
~BinaryOperator()
|
~BinaryOperator()
|
||||||
{
|
{
|
||||||
assert(m_lhs!=m_rhs || m_lhs==nullptr);
|
assert(m_lhs!=m_rhs or m_lhs==nullptr);
|
||||||
delete m_lhs;
|
delete m_lhs;
|
||||||
delete m_rhs;
|
delete m_rhs;
|
||||||
m_lhs=m_rhs=nullptr;
|
m_lhs=m_rhs=nullptr;
|
||||||
@ -184,7 +190,7 @@ struct BinaryOperator : public Expr
|
|||||||
condOp op() const { return m_op;}
|
condOp op() const { return m_op;}
|
||||||
/* Changes the boolean conditional operator at the root of this expression */
|
/* Changes the boolean conditional operator at the root of this expression */
|
||||||
void op(condOp o) { m_op=o;}
|
void op(condOp o) { m_op=o;}
|
||||||
std::string walkCondExpr (Function * pProc, int* numLoc) const;
|
QString walkCondExpr(Function * pProc, int* numLoc) const;
|
||||||
public:
|
public:
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
@ -211,13 +217,10 @@ struct AstIdent : public UnaryOperator
|
|||||||
virtual int hlTypeSize(Function *pproc) const;
|
virtual int hlTypeSize(Function *pproc) const;
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual hlType expType(Function *pproc) const;
|
||||||
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
|
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
|
||||||
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
virtual QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
protected:
|
|
||||||
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
struct GlobalVariable : public AstIdent
|
struct GlobalVariable : public AstIdent
|
||||||
{
|
{
|
||||||
@ -228,7 +231,7 @@ struct GlobalVariable : public AstIdent
|
|||||||
return new GlobalVariable(*this);
|
return new GlobalVariable(*this);
|
||||||
}
|
}
|
||||||
GlobalVariable(int16_t segValue, int16_t off);
|
GlobalVariable(int16_t segValue, int16_t off);
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -242,7 +245,7 @@ struct GlobalVariableIdx : public AstIdent
|
|||||||
return new GlobalVariableIdx(*this);
|
return new GlobalVariableIdx(*this);
|
||||||
}
|
}
|
||||||
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
|
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -264,9 +267,9 @@ struct Constant : public AstIdent
|
|||||||
{
|
{
|
||||||
return new Constant(*this);
|
return new Constant(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const { return TYPE_CONST; }
|
||||||
};
|
};
|
||||||
struct FuncNode : public AstIdent
|
struct FuncNode : public AstIdent
|
||||||
{
|
{
|
||||||
@ -284,7 +287,7 @@ struct FuncNode : public AstIdent
|
|||||||
{
|
{
|
||||||
return new FuncNode(*this);
|
return new FuncNode(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -310,7 +313,7 @@ struct RegisterNode : public AstIdent
|
|||||||
{
|
{
|
||||||
return new RegisterNode(*this);
|
return new RegisterNode(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *) const;
|
int hlTypeSize(Function *) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
|
|||||||
@ -7,8 +7,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <QtCore/QString>
|
||||||
struct strTable : std::vector<std::string>
|
#include <QtCore/QIODevice>
|
||||||
|
|
||||||
|
struct strTable : std::vector<QString>
|
||||||
{
|
{
|
||||||
/* Returns the next available index into the table */
|
/* Returns the next available index into the table */
|
||||||
size_t nextIdx() {return size();}
|
size_t nextIdx() {return size();}
|
||||||
@ -20,9 +22,9 @@ struct bundle
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void appendCode(const char *format, ...);
|
void appendCode(const char *format, ...);
|
||||||
void appendCode(const std::string &s);
|
void appendCode(const QString &s);
|
||||||
void appendDecl(const char *format, ...);
|
void appendDecl(const char *format, ...);
|
||||||
void appendDecl(const std::string &);
|
void appendDecl(const QString &);
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
decl.clear();
|
decl.clear();
|
||||||
@ -37,6 +39,6 @@ extern bundle cCode;
|
|||||||
#define lineSize 360 /* 3 lines in the mean time */
|
#define lineSize 360 /* 3 lines in the mean time */
|
||||||
|
|
||||||
//void newBundle (bundle *procCode);
|
//void newBundle (bundle *procCode);
|
||||||
void writeBundle (std::ostream &ios, bundle procCode);
|
void writeBundle (QIODevice & ios, bundle procCode);
|
||||||
void freeBundle (bundle *procCode);
|
void freeBundle (bundle *procCode);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
//TODO: Remove boolT
|
//TODO: Remove boolT
|
||||||
|
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
@ -29,24 +28,25 @@ extern bundle cCode; /* Output C procedure's declaration and code */
|
|||||||
|
|
||||||
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
|
|
||||||
typedef struct { /* Command line option flags */
|
/** Command line option flags */
|
||||||
unsigned verbose : 1;
|
struct OPTION
|
||||||
unsigned VeryVerbose : 1;
|
{
|
||||||
unsigned asm1 : 1; /* Early disassembly listing */
|
bool verbose;
|
||||||
unsigned asm2 : 1; /* Disassembly listing after restruct */
|
bool VeryVerbose;
|
||||||
unsigned Map : 1;
|
bool asm1; /* Early disassembly listing */
|
||||||
unsigned Stats : 1;
|
bool asm2; /* Disassembly listing after restruct */
|
||||||
unsigned Interact : 1; /* Interactive mode */
|
bool Map;
|
||||||
unsigned Calls : 1; /* Follow register indirect calls */
|
bool Stats;
|
||||||
|
bool Interact; /* Interactive mode */
|
||||||
|
bool Calls; /* Follow register indirect calls */
|
||||||
QString filename; /* The input filename */
|
QString filename; /* The input filename */
|
||||||
} OPTION;
|
uint32_t CustomEntryPoint;
|
||||||
|
};
|
||||||
|
|
||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory map states */
|
/* Memory map states */
|
||||||
enum eAreaType
|
enum eAreaType
|
||||||
{
|
{
|
||||||
@ -87,20 +87,18 @@ void interactDis(Function *, int initIC); /* disassem.c */
|
|||||||
bool JmpInst(llIcode opcode); /* idioms.c */
|
bool JmpInst(llIcode opcode); /* idioms.c */
|
||||||
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */
|
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */
|
||||||
|
|
||||||
void SetupLibCheck(void); /* chklib.c */
|
bool SetupLibCheck(void); /* chklib.c */
|
||||||
void CleanupLibCheck(void); /* chklib.c */
|
void CleanupLibCheck(void); /* chklib.c */
|
||||||
bool LibCheck(Function &p); /* chklib.c */
|
bool LibCheck(Function &p); /* chklib.c */
|
||||||
|
|
||||||
|
|
||||||
/* Exported functions from hlicode.c */
|
/* Exported functions from hlicode.c */
|
||||||
const char *writeJcond(const HLTYPE &, Function *, int *);
|
QString writeJcond(const HLTYPE &, Function *, int *);
|
||||||
const char *writeJcondInv (HLTYPE, Function *, int *);
|
QString writeJcondInv(HLTYPE, Function *, int *);
|
||||||
|
|
||||||
|
|
||||||
/* Exported funcions from locident.c */
|
/* Exported funcions from locident.c */
|
||||||
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
||||||
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
||||||
eReg otherLongRegi(eReg, int, LOCAL_ID *);
|
|
||||||
|
|
||||||
|
|
||||||
extern const char *indentStr(int level);
|
extern const char *indentStr(int level);
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
|
|
||||||
class IXmlTarget;
|
class IXmlTarget;
|
||||||
|
|
||||||
|
|||||||
@ -5,17 +5,22 @@
|
|||||||
***************************************************************************
|
***************************************************************************
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "bundle.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "bundle.h"
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
struct LLInst;
|
struct LLInst;
|
||||||
|
struct Function;
|
||||||
struct Disassembler
|
struct Disassembler
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int pass;
|
int pass;
|
||||||
int g_lab;
|
int g_lab;
|
||||||
//bundle &cCode;
|
//bundle &cCode;
|
||||||
std::ofstream m_fp;
|
QIODevice *m_disassembly_target;
|
||||||
|
QTextStream m_fp;
|
||||||
std::vector<std::string> m_decls;
|
std::vector<std::string> m_decls;
|
||||||
std::vector<std::string> m_code;
|
std::vector<std::string> m_code;
|
||||||
|
|
||||||
|
|||||||
155
include/icode.h
155
include/icode.h
@ -3,6 +3,16 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "BinaryImage.h"
|
||||||
|
#include "libdis.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
||||||
|
#include "CallConvention.h"
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -10,15 +20,6 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
#include <llvm/ADT/ilist_node.h>
|
|
||||||
#include <llvm/MC/MCInst.h>
|
|
||||||
#include <llvm/IR/Instruction.h>
|
|
||||||
#include <boost/range/iterator_range.hpp>
|
|
||||||
#include "libdis.h"
|
|
||||||
#include "Enums.h"
|
|
||||||
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
|
||||||
#include "CallConvention.h"
|
|
||||||
|
|
||||||
//enum condId;
|
//enum condId;
|
||||||
|
|
||||||
@ -58,12 +59,7 @@ public:
|
|||||||
}
|
}
|
||||||
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
|
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
|
||||||
{
|
{
|
||||||
// enable ADL (not necessary in our case, but good practice)
|
std::swap(first.registers, second.registers);
|
||||||
using std::swap;
|
|
||||||
|
|
||||||
// by swapping the members of two classes,
|
|
||||||
// the two classes are effectively swapped
|
|
||||||
swap(first.registers, second.registers);
|
|
||||||
}
|
}
|
||||||
LivenessSet &operator|=(const LivenessSet &other)
|
LivenessSet &operator|=(const LivenessSet &other)
|
||||||
{
|
{
|
||||||
@ -141,8 +137,8 @@ struct UnaryOperator;
|
|||||||
struct HlTypeSupport
|
struct HlTypeSupport
|
||||||
{
|
{
|
||||||
//hlIcode opcode; /* hlIcode opcode */
|
//hlIcode opcode; /* hlIcode opcode */
|
||||||
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
||||||
virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
|
virtual QString writeOut(Function *pProc, int *numLoc) const=0;
|
||||||
protected:
|
protected:
|
||||||
Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
|
Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
|
||||||
};
|
};
|
||||||
@ -157,37 +153,37 @@ struct CallType : public HlTypeSupport
|
|||||||
void placeStkArg(Expr *exp, int pos);
|
void placeStkArg(Expr *exp, int pos);
|
||||||
virtual Expr * toAst();
|
virtual Expr * toAst();
|
||||||
public:
|
public:
|
||||||
bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/)
|
bool removeRegFromLong(eReg /*regi*/, LOCAL_ID * /*locId*/)
|
||||||
{
|
{
|
||||||
printf("CallType : removeRegFromLong not supproted");
|
printf("CallType : removeRegFromLong not supproted\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct AssignType : public HlTypeSupport
|
struct AssignType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
/* for HLI_ASSIGN */
|
/* for HLI_ASSIGN */
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
Expr *m_lhs;
|
Expr * m_lhs;
|
||||||
Expr *rhs;
|
Expr * m_rhs;
|
||||||
AssignType() {}
|
AssignType() {}
|
||||||
Expr *lhs() const {return m_lhs;}
|
Expr *lhs() const {return m_lhs;}
|
||||||
void lhs(Expr *l);
|
void lhs(Expr *l);
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct ExpType : public HlTypeSupport
|
struct ExpType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
||||||
Expr *v;
|
Expr * v;
|
||||||
ExpType() : v(0) {}
|
ExpType() : v(nullptr) {}
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
||||||
{
|
{
|
||||||
v=performLongRemoval(regi,locId,v);
|
v=performLongRemoval(regi,locId,v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HLTYPE
|
struct HLTYPE
|
||||||
@ -241,7 +237,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
std::string write1HlIcode(Function *pProc, int *numLoc) const;
|
QString write1HlIcode(Function *pProc, int *numLoc) const;
|
||||||
void setAsgn(Expr *lhs, Expr *rhs);
|
void setAsgn(Expr *lhs, Expr *rhs);
|
||||||
} ;
|
} ;
|
||||||
/* LOW_LEVEL icode operand record */
|
/* LOW_LEVEL icode operand record */
|
||||||
@ -275,12 +271,12 @@ struct LLOperand
|
|||||||
}
|
}
|
||||||
bool operator==(const LLOperand &with) const
|
bool operator==(const LLOperand &with) const
|
||||||
{
|
{
|
||||||
return (seg==with.seg) &&
|
return (seg==with.seg) and
|
||||||
(segOver==with.segOver) &&
|
(segOver==with.segOver) and
|
||||||
(segValue==with.segValue) &&
|
(segValue==with.segValue) and
|
||||||
(regi == with.regi) &&
|
(regi == with.regi) and
|
||||||
(off == with.off) &&
|
(off == with.off) and
|
||||||
(opz==with.opz) &&
|
(opz==with.opz) and
|
||||||
(proc.proc==with.proc.proc);
|
(proc.proc==with.proc.proc);
|
||||||
}
|
}
|
||||||
int64_t getImm2() const {return opz;}
|
int64_t getImm2() const {return opz;}
|
||||||
@ -314,9 +310,10 @@ struct LLOperand
|
|||||||
bool compound() const {return is_compound;} // dx:ax pair
|
bool compound() const {return is_compound;} // dx:ax pair
|
||||||
size_t byteWidth() const { assert(width<=4); return width;}
|
size_t byteWidth() const { assert(width<=4); return width;}
|
||||||
};
|
};
|
||||||
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
|
struct LLInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
llIcode m_opcode; // Low level opcode identifier
|
||||||
uint32_t flg; /* icode flags */
|
uint32_t flg; /* icode flags */
|
||||||
LLOperand m_src; /* source operand */
|
LLOperand m_src; /* source operand */
|
||||||
public:
|
public:
|
||||||
@ -328,22 +325,25 @@ public:
|
|||||||
int caseEntry;
|
int caseEntry;
|
||||||
std::vector<uint32_t> caseTbl2;
|
std::vector<uint32_t> caseTbl2;
|
||||||
int hllLabNum; /* label # for hll codegen */
|
int hllLabNum; /* label # for hll codegen */
|
||||||
bool conditionalJump()
|
|
||||||
{
|
llIcode getOpcode() const { return m_opcode;}
|
||||||
return (getOpcode() >= iJB) && (getOpcode() < iJCXZ);
|
void setOpcode(uint32_t op) { m_opcode=(llIcode)op; }
|
||||||
}
|
bool conditionalJump()
|
||||||
bool testFlags(uint32_t x) const { return (flg & x)!=0;}
|
{
|
||||||
void setFlags(uint32_t flag) {flg |= flag;}
|
return (getOpcode() >= iJB) and (getOpcode() < iJCXZ);
|
||||||
void clrFlags(uint32_t flag)
|
}
|
||||||
{
|
bool testFlags(uint32_t x) const { return (flg & x)!=0;}
|
||||||
if(getOpcode()==iMOD)
|
void setFlags(uint32_t flag) {flg |= flag;}
|
||||||
{
|
void clrFlags(uint32_t flag)
|
||||||
assert(false);
|
{
|
||||||
}
|
if(getOpcode()==iMOD)
|
||||||
flg &= ~flag;
|
{
|
||||||
}
|
assert(false);
|
||||||
uint32_t getFlag() const {return flg;}
|
}
|
||||||
uint32_t GetLlLabel() const { return label;}
|
flg &= ~flag;
|
||||||
|
}
|
||||||
|
uint32_t getFlag() const {return flg;}
|
||||||
|
uint32_t GetLlLabel() const { return label;}
|
||||||
|
|
||||||
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
|
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
|
||||||
|
|
||||||
@ -366,11 +366,11 @@ public:
|
|||||||
}
|
}
|
||||||
bool match(llIcode op,eReg dest,eReg src_reg)
|
bool match(llIcode op,eReg dest,eReg src_reg)
|
||||||
{
|
{
|
||||||
return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
|
return (getOpcode()==op) and (m_dst.regi==dest) and (m_src.regi==src_reg);
|
||||||
}
|
}
|
||||||
bool match(eReg dest,eReg src_reg)
|
bool match(eReg dest,eReg src_reg)
|
||||||
{
|
{
|
||||||
return (m_dst.regi==dest)&&(m_src.regi==src_reg);
|
return (m_dst.regi==dest) and (m_src.regi==src_reg);
|
||||||
}
|
}
|
||||||
bool match(eReg dest)
|
bool match(eReg dest)
|
||||||
{
|
{
|
||||||
@ -400,11 +400,11 @@ public:
|
|||||||
}
|
}
|
||||||
void emitGotoLabel(int indLevel);
|
void emitGotoLabel(int indLevel);
|
||||||
void findJumpTargets(CIcodeRec &_pc);
|
void findJumpTargets(CIcodeRec &_pc);
|
||||||
void writeIntComment(std::ostringstream &s);
|
void writeIntComment(QTextStream & s);
|
||||||
void dis1Line(int loc_ip, int pass);
|
void dis1Line(int loc_ip, int pass);
|
||||||
std::ostringstream &strSrc(std::ostringstream &os,bool skip_comma=false);
|
QTextStream & strSrc(QTextStream & os, bool skip_comma=false);
|
||||||
|
|
||||||
void flops(std::ostringstream &out);
|
void flops(QTextStream & out);
|
||||||
bool isJmpInst();
|
bool isJmpInst();
|
||||||
HLTYPE createCall();
|
HLTYPE createCall();
|
||||||
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
||||||
@ -460,17 +460,17 @@ public:
|
|||||||
template<int TYPE>
|
template<int TYPE>
|
||||||
struct TypeFilter
|
struct TypeFilter
|
||||||
{
|
{
|
||||||
bool operator()(ICODE *ic) {return ic->type==HIGH_LEVEL;}
|
bool operator()(ICODE *ic) {return ic->type==TYPE;}
|
||||||
bool operator()(ICODE &ic) {return ic.type==HIGH_LEVEL;}
|
bool operator()(ICODE &ic) {return ic.type==TYPE;}
|
||||||
};
|
};
|
||||||
template<int TYPE>
|
template<int TYPE>
|
||||||
struct TypeAndValidFilter
|
struct TypeAndValidFilter
|
||||||
{
|
{
|
||||||
bool operator()(ICODE *ic) {return (ic->type==HIGH_LEVEL)&&(ic->valid());}
|
bool operator()(ICODE *ic) {return (ic->type==TYPE) and (ic->valid());}
|
||||||
bool operator()(ICODE &ic) {return (ic.type==HIGH_LEVEL)&&ic.valid();}
|
bool operator()(ICODE &ic) {return (ic.type==TYPE) and ic.valid();}
|
||||||
};
|
};
|
||||||
static TypeFilter<HIGH_LEVEL> select_high_level;
|
static TypeFilter<HIGH_LEVEL_ICODE> select_high_level;
|
||||||
static TypeAndValidFilter<HIGH_LEVEL> select_valid_high_level;
|
static TypeAndValidFilter<HIGH_LEVEL_ICODE> select_valid_high_level;
|
||||||
/* Def/Use of registers and stack variables */
|
/* Def/Use of registers and stack variables */
|
||||||
struct DU_ICODE
|
struct DU_ICODE
|
||||||
{
|
{
|
||||||
@ -506,7 +506,7 @@ public:
|
|||||||
if(iter==uses.end())
|
if(iter==uses.end())
|
||||||
return;
|
return;
|
||||||
uses.erase(iter);
|
uses.erase(iter);
|
||||||
assert("Same user more then once!" && uses.end()==std::find(uses.begin(),uses.end(),us));
|
assert("Same user more then once!" and uses.end()==std::find(uses.begin(),uses.end(),us));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -544,8 +544,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
icodeType type; /* Icode type */
|
icodeType type; /* Icode type */
|
||||||
DU_ICODE du; /* Def/use regs/vars */
|
DU_ICODE du; /* Def/use regs/vars */
|
||||||
DU1 du1; /* du chain 1 */
|
DU1 du1; /* du chain 1 */
|
||||||
int loc_ip; // used by CICodeRec to number ICODEs
|
int loc_ip; // used by CICodeRec to number ICODEs
|
||||||
|
|
||||||
LLInst * ll() { return &m_ll;}
|
LLInst * ll() { return &m_ll;}
|
||||||
@ -572,7 +572,7 @@ public:
|
|||||||
// set this icode to be an assign
|
// set this icode to be an assign
|
||||||
void setAsgn(Expr *lhs, Expr *rhs)
|
void setAsgn(Expr *lhs, Expr *rhs)
|
||||||
{
|
{
|
||||||
type=HIGH_LEVEL;
|
type=HIGH_LEVEL_ICODE;
|
||||||
hlU()->setAsgn(lhs,rhs);
|
hlU()->setAsgn(lhs,rhs);
|
||||||
}
|
}
|
||||||
void setUnary(hlIcode op, Expr *_exp);
|
void setUnary(hlIcode op, Expr *_exp);
|
||||||
@ -589,7 +589,7 @@ public:
|
|||||||
{
|
{
|
||||||
return hlU()->call.newStkArg(exp,opcode,pproc);
|
return hlU()->call.newStkArg(exp,opcode,pproc);
|
||||||
}
|
}
|
||||||
ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0)
|
ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED_ICODE),loc_ip(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@ -600,24 +600,23 @@ public:
|
|||||||
};
|
};
|
||||||
/** Map n low level instructions to m high level instructions
|
/** Map n low level instructions to m high level instructions
|
||||||
*/
|
*/
|
||||||
struct MappingLLtoML
|
//struct MappingLLtoML
|
||||||
{
|
//{
|
||||||
typedef llvm::iplist<llvm::Instruction> InstListType;
|
// typedef boost::iterator_range<iICODE> rSourceRange;
|
||||||
typedef boost::iterator_range<iICODE> rSourceRange;
|
// typedef boost::iterator_range<InstListType::iterator> rTargetRange;
|
||||||
typedef boost::iterator_range<InstListType::iterator> rTargetRange;
|
// rSourceRange m_low_level;
|
||||||
rSourceRange m_low_level;
|
// rTargetRange m_middle_level;
|
||||||
rTargetRange m_middle_level;
|
//};
|
||||||
};
|
|
||||||
// This is the icode array object.
|
// This is the icode array object.
|
||||||
class CIcodeRec : public std::list<ICODE>
|
class CIcodeRec : public std::list<ICODE>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CIcodeRec(); // Constructor
|
CIcodeRec(); // Constructor
|
||||||
|
|
||||||
ICODE * addIcode(ICODE *pIcode);
|
ICODE * addIcode(ICODE *pIcode);
|
||||||
void SetInBB(rCODE &rang, BB* pnewBB);
|
void SetInBB(rCODE &rang, BB* pnewBB);
|
||||||
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
||||||
iterator labelSrch(uint32_t target);
|
iterator labelSrch(uint32_t target);
|
||||||
ICODE * GetIcode(size_t ip);
|
ICODE * GetIcode(size_t ip);
|
||||||
bool alreadyDecoded(uint32_t target);
|
bool alreadyDecoded(uint32_t target);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,14 +6,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "machine_x86.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "types.h"
|
|
||||||
#include "Enums.h"
|
|
||||||
#include "machine_x86.h"
|
|
||||||
|
|
||||||
/* Type definition */
|
/* Type definition */
|
||||||
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
||||||
@ -25,7 +28,7 @@ struct LLInst;
|
|||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
struct IDX_ARRAY : public std::vector<iICODE>
|
struct IDX_ARRAY : public std::vector<iICODE>
|
||||||
{
|
{
|
||||||
bool inList(iICODE idx)
|
bool inList(iICODE idx) const
|
||||||
{
|
{
|
||||||
return std::find(begin(),end(),idx)!=end();
|
return std::find(begin(),end(),idx)!=end();
|
||||||
}
|
}
|
||||||
@ -93,23 +96,22 @@ protected:
|
|||||||
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
|
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
|
||||||
public:
|
public:
|
||||||
hlType type; /* Probable type */
|
hlType type; /* Probable type */
|
||||||
bool illegal; /* Boolean: not a valid field any more */
|
|
||||||
//std::vector<iICODE> idx;
|
|
||||||
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
|
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
|
||||||
frameType loc; /* Frame location */
|
frameType loc; /* Frame location */
|
||||||
|
bool illegal; /* Boolean: not a valid field any more */
|
||||||
bool hasMacro; /* Identifier requires a macro */
|
bool hasMacro; /* Identifier requires a macro */
|
||||||
char macro[10]; /* Macro for this identifier */
|
char macro[10]; /* Macro for this identifier */
|
||||||
std::string name; /* Identifier's name */
|
QString name; /* Identifier's name */
|
||||||
union ID_UNION { /* Different types of identifiers */
|
union ID_UNION { /* Different types of identifiers */
|
||||||
friend struct ID;
|
friend struct ID;
|
||||||
protected:
|
protected:
|
||||||
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
||||||
public:
|
public:
|
||||||
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
|
eReg regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */
|
||||||
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
|
struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
|
||||||
uint8_t regOff; /* register offset (if any) */
|
uint8_t regOff; /* register offset (if any) */
|
||||||
int off; /* offset from BP */
|
int off; /* offset from BP */
|
||||||
} bwId;
|
} bwId;
|
||||||
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
|
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
|
||||||
LONGGLB_TYPE longGlb;
|
LONGGLB_TYPE longGlb;
|
||||||
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
||||||
@ -118,27 +120,30 @@ public:
|
|||||||
} longKte;
|
} longKte;
|
||||||
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
||||||
} id;
|
} id;
|
||||||
LONGID_TYPE & longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
|
||||||
const LONGID_TYPE & longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
LONGID_TYPE & longId() {assert(isLong() and loc==REG_FRAME); return m_longId;}
|
||||||
LONG_STKID_TYPE & longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
const LONGID_TYPE & longId() const {assert(isLong() and loc==REG_FRAME); return m_longId;}
|
||||||
const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
LONG_STKID_TYPE & longStkId() {assert(isLong() and loc==STK_FRAME); return id.longStkId;}
|
||||||
|
const LONG_STKID_TYPE & longStkId() const {assert(isLong() and loc==STK_FRAME); return id.longStkId;}
|
||||||
ID();
|
ID();
|
||||||
ID(hlType t, frameType f);
|
ID(hlType t, frameType f);
|
||||||
ID(hlType t, const LONGID_TYPE &s);
|
ID(hlType t, const LONGID_TYPE &s);
|
||||||
ID(hlType t, const LONG_STKID_TYPE &s);
|
ID(hlType t, const LONG_STKID_TYPE &s);
|
||||||
ID(hlType t, const LONGGLB_TYPE &s);
|
ID(hlType t, const LONGGLB_TYPE &s);
|
||||||
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
bool isSigned() const { return (type==TYPE_BYTE_SIGN) or (type==TYPE_WORD_SIGN) or (type==TYPE_LONG_SIGN);}
|
||||||
uint16_t typeBitsize() const
|
uint16_t typeBitsize() const
|
||||||
{
|
{
|
||||||
return TypeContainer::typeSize(type)*8;
|
return TypeContainer::typeSize(type)*8;
|
||||||
}
|
}
|
||||||
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
|
bool isLong() const { return (type==TYPE_LONG_UNSIGN) or (type==TYPE_LONG_SIGN); }
|
||||||
void setLocalName(int i)
|
void setLocalName(int i)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf (buf, "loc%d", i);
|
sprintf (buf, "loc%d", i);
|
||||||
name=buf;
|
name=buf;
|
||||||
}
|
}
|
||||||
|
bool isLongRegisterPair() const { return (loc == REG_FRAME) and isLong();}
|
||||||
|
eReg getPairedRegister(eReg first) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LOCAL_ID
|
struct LOCAL_ID
|
||||||
@ -164,12 +169,13 @@ public:
|
|||||||
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
||||||
void newIdent(hlType t, frameType f);
|
void newIdent(hlType t, frameType f);
|
||||||
void flagByteWordId(int off);
|
void flagByteWordId(int off);
|
||||||
void propLongId(uint8_t regL, uint8_t regH, const char *name);
|
void propLongId(uint8_t regL, uint8_t regH, const QString & name);
|
||||||
size_t csym() const {return id_arr.size();}
|
size_t csym() const {return id_arr.size();}
|
||||||
void newRegArg(iICODE picode, iICODE ticode) const;
|
void newRegArg(ICODE & picode, ICODE & ticode) const;
|
||||||
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
void processTargetIcode(ICODE & picode, int &numHlIcodes, ICODE & ticode, bool isLong) const;
|
||||||
void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
|
void forwardSubs(Expr *lhs, Expr *rhs, ICODE & picode, ICODE & ticode, int &numHlIcodes) const;
|
||||||
AstIdent *createId(const ID *retVal, iICODE ix_);
|
AstIdent *createId(const ID *retVal, iICODE ix_);
|
||||||
|
eReg getPairedRegisterAt(int idx,eReg first) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
struct LivenessSet;
|
struct LivenessSet;
|
||||||
/* Machine registers */
|
/* Machine registers */
|
||||||
enum eReg
|
enum eReg
|
||||||
@ -60,13 +62,13 @@ class Machine_X86 : public SourceMachine
|
|||||||
public:
|
public:
|
||||||
Machine_X86();
|
Machine_X86();
|
||||||
virtual ~Machine_X86() {}
|
virtual ~Machine_X86() {}
|
||||||
static const std::string ®Name(eReg r);
|
static const QString & regName(eReg r);
|
||||||
static const std::string &opcodeName(unsigned r);
|
static const QString & opcodeName(unsigned r);
|
||||||
static const std::string &floatOpName(unsigned r);
|
static const QString & floatOpName(unsigned r);
|
||||||
bool physicalReg(eReg r);
|
bool physicalReg(eReg r);
|
||||||
/* Writes the registers that are set in the bitvector */
|
/* Writes the registers that are set in the bitvector */
|
||||||
//TODO: move this into Machine_X86 ?
|
//TODO: move this into Machine_X86 ?
|
||||||
static void writeRegVector (std::ostream &ostr,const LivenessSet ®i);
|
static void writeRegVector (QTextStream & ostr, const LivenessSet ®i);
|
||||||
static eReg subRegH(eReg reg);
|
static eReg subRegH(eReg reg);
|
||||||
static eReg subRegL(eReg reg);
|
static eReg subRegL(eReg reg);
|
||||||
static bool isMemOff(eReg r);
|
static bool isMemOff(eReg r);
|
||||||
|
|||||||
3
include/msvc_fixes.h
Normal file
3
include/msvc_fixes.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <iso646.h>
|
||||||
|
#endif
|
||||||
@ -3,7 +3,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
#include <boost/icl/interval.hpp>
|
#include <boost/icl/interval.hpp>
|
||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/split_interval_map.hpp>
|
#include <boost/icl/split_interval_map.hpp>
|
||||||
@ -23,52 +22,53 @@ class IProject
|
|||||||
};
|
};
|
||||||
class Project : public IProject
|
class Project : public IProject
|
||||||
{
|
{
|
||||||
static Project *s_instance;
|
static Project *s_instance;
|
||||||
QString m_fname;
|
QString m_fname;
|
||||||
QString m_project_name;
|
QString m_project_name;
|
||||||
QString m_output_path;
|
QString m_output_path;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
typedef std::list<Function> FunctionListType;
|
||||||
typedef FunctionListType lFunction;
|
typedef FunctionListType lFunction;
|
||||||
typedef FunctionListType::iterator ilFunction;
|
typedef FunctionListType::iterator ilFunction;
|
||||||
SYMTAB symtab; /* Global symbol table */
|
|
||||||
|
|
||||||
FunctionListType pProcList;
|
SYMTAB symtab; /* Global symbol table */
|
||||||
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
FunctionListType pProcList;
|
||||||
PROG prog; /* Loaded program image parameters */
|
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
||||||
// no copies
|
PROG prog; /* Loaded program image parameters */
|
||||||
Project(const Project&) = delete;
|
// no copies
|
||||||
const Project &operator=(const Project & l) =delete;
|
Project(const Project&) = delete;
|
||||||
// only moves
|
const Project & operator=(const Project & l) =delete;
|
||||||
Project(); // default constructor,
|
// only moves
|
||||||
|
Project(); // default constructor,
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void create(const QString &a);
|
void create(const QString &a);
|
||||||
bool load();
|
bool load();
|
||||||
const QString &output_path() const {return m_output_path;}
|
const QString & output_path() const {return m_output_path;}
|
||||||
const QString &project_name() const {return m_project_name;}
|
const QString & project_name() const {return m_project_name;}
|
||||||
const QString &binary_path() const {return m_fname;}
|
const QString & binary_path() const {return m_fname;}
|
||||||
QString output_name(const char *ext);
|
QString output_name(const char *ext);
|
||||||
ilFunction funcIter(Function *to_find);
|
ilFunction funcIter(Function *to_find);
|
||||||
ilFunction findByEntry(uint32_t entry);
|
ilFunction findByEntry(uint32_t entry);
|
||||||
ilFunction createFunction(FunctionType *f,const std::string &name);
|
ilFunction createFunction(FunctionType *f, const QString & name);
|
||||||
bool valid(ilFunction iter);
|
bool valid(ilFunction iter);
|
||||||
|
|
||||||
int getSymIdxByAdd(uint32_t adr);
|
int getSymIdxByAddr(uint32_t adr);
|
||||||
bool validSymIdx(size_t idx);
|
bool validSymIdx(size_t idx);
|
||||||
size_t symbolSize(size_t idx);
|
size_t symbolSize(size_t idx);
|
||||||
hlType symbolType(size_t idx);
|
hlType symbolType(size_t idx);
|
||||||
const std::string &symbolName(size_t idx);
|
const QString & symbolName(size_t idx);
|
||||||
const SYM &getSymByIdx(size_t idx) const;
|
const SYM & getSymByIdx(size_t idx) const;
|
||||||
|
|
||||||
static Project *get();
|
static Project * get();
|
||||||
PROG * binary() {return &prog;}
|
PROG * binary() {return &prog;}
|
||||||
SourceMachine *machine();
|
SourceMachine *machine();
|
||||||
|
|
||||||
const FunctionListType &functions() const { return pProcList; }
|
const FunctionListType &functions() const { return pProcList; }
|
||||||
|
FunctionListType &functions() { return pProcList; }
|
||||||
protected:
|
protected:
|
||||||
void initialize();
|
void initialize();
|
||||||
void writeGlobSymTable();
|
void writeGlobSymTable();
|
||||||
};
|
};
|
||||||
//extern Project g_proj;
|
//extern Project g_proj;
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
struct STATE
|
struct STATE
|
||||||
{
|
{
|
||||||
uint32_t IP; /* Offset into Image */
|
uint32_t IP; /* Offset into Image */
|
||||||
int16_t r[INDEX_BX_SI]; /* Value of segs and AX */
|
uint16_t r[INDEX_BX_SI]; /* Value of segs and AX */
|
||||||
bool f[INDEX_BX_SI]; /* True if r[.] has a value */
|
bool f[INDEX_BX_SI]; /* True if r[.] has a value */
|
||||||
struct
|
struct
|
||||||
{ /* For case stmt indexed reg */
|
{ /* For case stmt indexed reg */
|
||||||
|
|||||||
@ -3,10 +3,13 @@
|
|||||||
* (C) Mike van Emmerik
|
* (C) Mike van Emmerik
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <string>
|
||||||
|
#include <stdint.h>
|
||||||
struct Expr;
|
struct Expr;
|
||||||
struct AstIdent;
|
struct AstIdent;
|
||||||
struct TypeContainer;
|
struct TypeContainer;
|
||||||
@ -15,7 +18,7 @@ struct TypeContainer;
|
|||||||
/* * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * */
|
||||||
struct SymbolCommon
|
struct SymbolCommon
|
||||||
{
|
{
|
||||||
std::string name; /* New name for this variable/symbol/argument */
|
QString name; /* New name for this variable/symbol/argument */
|
||||||
int size; /* Size/maximum size */
|
int size; /* Size/maximum size */
|
||||||
hlType type; /* probable type */
|
hlType type; /* probable type */
|
||||||
eDuVal duVal; /* DEF, USE, VAL */
|
eDuVal duVal; /* DEF, USE, VAL */
|
||||||
@ -36,12 +39,12 @@ struct SYM : public SymbolCommon
|
|||||||
struct STKSYM : public SymbolCommon
|
struct STKSYM : public SymbolCommon
|
||||||
{
|
{
|
||||||
typedef int16_t tLabel;
|
typedef int16_t tLabel;
|
||||||
Expr *actual=0; /* Expression tree of actual parameter */
|
Expr * actual=0; /* Expression tree of actual parameter */
|
||||||
AstIdent *regs=0; /* For register arguments only */
|
AstIdent * regs=0; /* For register arguments only */
|
||||||
tLabel label=0; /* Immediate off from BP (+:args, -:params) */
|
tLabel label=0; /* Immediate off from BP (+:args, -:params) */
|
||||||
uint8_t regOff=0; /* Offset is a register (e.g. SI, DI) */
|
uint8_t regOff=0; /* Offset is a register (e.g. SI, DI) */
|
||||||
bool hasMacro=false; /* This type needs a macro */
|
bool hasMacro=false; /* This type needs a macro */
|
||||||
std::string macro; /* Macro name */
|
QString macro; /* Macro name */
|
||||||
bool invalid=false; /* Boolean: invalid entry in formal arg list*/
|
bool invalid=false; /* Boolean: invalid entry in formal arg list*/
|
||||||
void setArgName(int i)
|
void setArgName(int i)
|
||||||
{
|
{
|
||||||
@ -91,7 +94,7 @@ struct SYMTABLE
|
|||||||
{
|
{
|
||||||
// does not yse pSymName, to ease finding by symOff/symProc combo
|
// does not yse pSymName, to ease finding by symOff/symProc combo
|
||||||
// in map<SYMTABLE,X>
|
// in map<SYMTABLE,X>
|
||||||
return (symOff==other.symOff) && symProc==(other.symProc);
|
return (symOff==other.symOff) and symProc==(other.symProc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,6 +107,6 @@ constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be la
|
|||||||
|
|
||||||
void createSymTables(void);
|
void createSymTables(void);
|
||||||
void destroySymTables(void);
|
void destroySymTables(void);
|
||||||
bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
bool readVal (QTextStream & symName, uint32_t symOff, Function *symProc);
|
||||||
void selectTable(tableType); /* Select a particular table */
|
void selectTable(tableType); /* Select a particular table */
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,13 @@
|
|||||||
***************************************************************************
|
***************************************************************************
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "Enums.h"
|
#include <stdlib.h>
|
||||||
|
|
||||||
/**** Common definitions and macros ****/
|
/**** Common definitions and macros ****/
|
||||||
#define MAX 0x7FFFFFFF
|
#define MAX 0x7FFFFFFF
|
||||||
|
|
||||||
@ -25,7 +29,7 @@
|
|||||||
// Macro reads a LH word from the image regardless of host convention
|
// Macro reads a LH word from the image regardless of host convention
|
||||||
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
|
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
|
||||||
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
||||||
#define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
|
#define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
|
||||||
|
|
||||||
|
|
||||||
/* Macro reads a LH word from the image regardless of host convention */
|
/* Macro reads a LH word from the image regardless of host convention */
|
||||||
@ -64,12 +68,22 @@ struct eDuVal
|
|||||||
use = x&USE;
|
use = x&USE;
|
||||||
val = x&VAL;
|
val = x&VAL;
|
||||||
}
|
}
|
||||||
bool isUSE_VAL() {return use&&val;} //Use and Val
|
bool isUSE_VAL() {return use and val;} //Use and Val
|
||||||
};
|
};
|
||||||
static constexpr const char * hlTypes[13] = {
|
static constexpr const char * hlTypes[13] = {
|
||||||
"", "char", "unsigned char", "int", "unsigned int",
|
"",
|
||||||
"long", "unsigned long", "record", "int *", "char *",
|
"char",
|
||||||
"", "float", "double"
|
"unsigned char",
|
||||||
|
"int",
|
||||||
|
"unsigned int",
|
||||||
|
"long",
|
||||||
|
"unsigned long",
|
||||||
|
"record",
|
||||||
|
"int *",
|
||||||
|
"char *",
|
||||||
|
"",
|
||||||
|
"float",
|
||||||
|
"double"
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeContainer
|
struct TypeContainer
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
|
#include "BasicBlock.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "Procedure.h"
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/range/rbegin.hpp>
|
#include <boost/range/rbegin.hpp>
|
||||||
#include <boost/range/rend.hpp>
|
#include <boost/range/rend.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
#include "Procedure.h"
|
|
||||||
#include "dcc.h"
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
@ -139,7 +144,8 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
if(loopType == eNodeHeaderType::NO_TYPE)
|
if(loopType == eNodeHeaderType::NO_TYPE)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
ICODE* picode;
|
ICODE* picode;
|
||||||
switch (loopType)
|
switch (loopType)
|
||||||
{
|
{
|
||||||
@ -165,7 +171,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
|
picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
string e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
QString e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
||||||
}
|
}
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -182,27 +188,28 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
picode = &latch->back();
|
picode = &latch->back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
stats.numHLIcode += 1;
|
stats.numHLIcode += 1;
|
||||||
indLevel++;
|
indLevel++;
|
||||||
return picode;
|
return picode;
|
||||||
}
|
}
|
||||||
bool BB::isEndOfPath(int latch_node_idx) const
|
bool BB::isEndOfPath(int latch_node_idx) const
|
||||||
{
|
{
|
||||||
return nodeType == RETURN_NODE || nodeType == TERMINATE_NODE ||
|
return nodeType == RETURN_NODE or nodeType == TERMINATE_NODE or
|
||||||
nodeType == NOWHERE_NODE || (dfsLastNum == latch_node_idx);
|
nodeType == NOWHERE_NODE or dfsLastNum == latch_node_idx;
|
||||||
}
|
}
|
||||||
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
||||||
{
|
{
|
||||||
int follow; /* ifFollow */
|
int follow; /* ifFollow */
|
||||||
BB * succ, *latch; /* Successor and latching node */
|
BB * succ, *latch; /* Successor and latching node */
|
||||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||||
std::string l; /* Pointer to HLI_JCOND expression */
|
QString l; /* Pointer to HLI_JCOND expression */
|
||||||
bool emptyThen, /* THEN clause is empty */
|
bool emptyThen, /* THEN clause is empty */
|
||||||
repCond; /* Repeat condition for while() */
|
repCond; /* Repeat condition for while() */
|
||||||
|
|
||||||
/* Check if this basic block should be analysed */
|
/* Check if this basic block should be analysed */
|
||||||
if ((_ifFollow != UN_INIT) && (this == pProc->m_dfsLast[_ifFollow]))
|
if ((_ifFollow != UN_INIT) and (this == pProc->m_dfsLast[_ifFollow]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wasTraversedAtLevel(DFS_ALPHA))
|
if (wasTraversedAtLevel(DFS_ALPHA))
|
||||||
@ -217,9 +224,11 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
/* Write the code for this basic block */
|
/* Write the code for this basic block */
|
||||||
if (repCond == false)
|
if (repCond == false)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
writeBB(ostr,indLevel, pProc, numLoc);
|
writeBB(ostr,indLevel, pProc, numLoc);
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for end of path */
|
/* Check for end of path */
|
||||||
@ -250,7 +259,8 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
indLevel--;
|
indLevel--;
|
||||||
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
/* Check if there is need to repeat other statements involved
|
/* Check if there is need to repeat other statements involved
|
||||||
* in while condition, then, emit the loop trailer */
|
* in while condition, then, emit the loop trailer */
|
||||||
if (repCond)
|
if (repCond)
|
||||||
@ -258,13 +268,14 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
writeBB(ostr,indLevel+1, pProc, numLoc);
|
writeBB(ostr,indLevel+1, pProc, numLoc);
|
||||||
}
|
}
|
||||||
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
}
|
}
|
||||||
else if (loopType == eNodeHeaderType::ENDLESS_TYPE)
|
else if (loopType == eNodeHeaderType::ENDLESS_TYPE)
|
||||||
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
||||||
else if (loopType == eNodeHeaderType::REPEAT_TYPE)
|
else if (loopType == eNodeHeaderType::REPEAT_TYPE)
|
||||||
{
|
{
|
||||||
string e = "//*failed*//";
|
QString e = "//*failed*//";
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
{
|
{
|
||||||
reportError (REPEAT_FAIL);
|
reportError (REPEAT_FAIL);
|
||||||
@ -273,7 +284,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
{
|
{
|
||||||
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
}
|
}
|
||||||
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
|
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),qPrintable(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recurse on the loop follow */
|
/* Recurse on the loop follow */
|
||||||
@ -305,13 +316,13 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
if (succ->dfsLastNum != follow) /* THEN part */
|
if (succ->dfsLastNum != follow) /* THEN part */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
||||||
}
|
}
|
||||||
else /* empty THEN part => negate ELSE part */
|
else /* empty THEN part => negate ELSE part */
|
||||||
{
|
{
|
||||||
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
||||||
emptyThen = true;
|
emptyThen = true;
|
||||||
}
|
}
|
||||||
@ -331,7 +342,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
}
|
}
|
||||||
/* else (empty ELSE part) */
|
/* else (empty ELSE part) */
|
||||||
}
|
}
|
||||||
else if (! emptyThen) /* already visited => emit label */
|
else if (not emptyThen) /* already visited => emit label */
|
||||||
{
|
{
|
||||||
cCode.appendCode( "%s}\n%selse {\n",
|
cCode.appendCode( "%s}\n%selse {\n",
|
||||||
indentStr(indLevel-1), indentStr(indLevel - 1));
|
indentStr(indLevel-1), indentStr(indLevel - 1));
|
||||||
@ -347,7 +358,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
else /* no follow => if..then..else */
|
else /* no follow => if..then..else */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
@ -370,7 +381,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
* Args: pBB: pointer to the current basic block.
|
* Args: pBB: pointer to the current basic block.
|
||||||
* Icode: pointer to the array of icodes for current procedure.
|
* Icode: pointer to the array of icodes for current procedure.
|
||||||
* lev: indentation level - used for formatting. */
|
* lev: indentation level - used for formatting. */
|
||||||
void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
void BB::writeBB(QTextStream &ostr,int lev, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
/* Save the index into the code table in case there is a later goto
|
/* Save the index into the code table in case there is a later goto
|
||||||
* into this instruction (first instruction of the BB) */
|
* into this instruction (first instruction of the BB) */
|
||||||
@ -380,10 +391,10 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
|
|
||||||
for(ICODE &pHli : instructions)
|
for(ICODE &pHli : instructions)
|
||||||
{
|
{
|
||||||
if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here.
|
if ((pHli.type == HIGH_LEVEL_ICODE) and ( pHli.valid() )) //TODO: use filtering range here.
|
||||||
{
|
{
|
||||||
std::string line = pHli.hl()->write1HlIcode(pProc, numLoc);
|
QString line = pHli.hl()->write1HlIcode(pProc, numLoc);
|
||||||
if (!line.empty())
|
if (not line.isEmpty())
|
||||||
{
|
{
|
||||||
ostr<<indentStr(lev)<<line;
|
ostr<<indentStr(lev)<<line;
|
||||||
stats.numHLIcode++;
|
stats.numHLIcode++;
|
||||||
|
|||||||
@ -1,36 +1,37 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "CallConvention.h"
|
#include "CallConvention.h"
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
CConv *CConv::create(Type v)
|
CConv *CConv::create(Type v)
|
||||||
{
|
{
|
||||||
static C_CallingConvention *c_call = nullptr;
|
static C_CallingConvention *c_call = nullptr;
|
||||||
static Pascal_CallingConvention *p_call = nullptr;
|
static Pascal_CallingConvention *p_call = nullptr;
|
||||||
static Unknown_CallingConvention *u_call= nullptr;
|
static Unknown_CallingConvention *u_call= nullptr;
|
||||||
if(!c_call)
|
if(nullptr==c_call)
|
||||||
c_call = new C_CallingConvention;
|
c_call = new C_CallingConvention;
|
||||||
if(!p_call)
|
if(nullptr==p_call)
|
||||||
p_call = new Pascal_CallingConvention;
|
p_call = new Pascal_CallingConvention;
|
||||||
if(!u_call)
|
if(nullptr==u_call)
|
||||||
u_call = new Unknown_CallingConvention;
|
u_call = new Unknown_CallingConvention;
|
||||||
switch(v) {
|
switch(v) {
|
||||||
case UNKNOWN: return u_call;
|
case eUnknown: return u_call;
|
||||||
case C: return c_call;
|
case eCdecl: return c_call;
|
||||||
case PASCAL: return p_call;
|
case ePascal: return p_call;
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C_CallingConvention::writeComments(std::ostream &ostr)
|
void C_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * C calling convention.\n";
|
ostr << " * C calling convention.\n";
|
||||||
}
|
}
|
||||||
void Pascal_CallingConvention::writeComments(std::ostream &ostr)
|
void Pascal_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * Pascal calling convention.\n";
|
ostr << " * Pascal calling convention.\n";
|
||||||
}
|
}
|
||||||
void Unknown_CallingConvention::writeComments(std::ostream &ostr)
|
void Unknown_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * Unknown calling convention.\n";
|
ostr << " * Unknown calling convention.\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "DccFrontend.h"
|
#include "DccFrontend.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "disassem.h"
|
#include "disassem.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
|
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ void PROG::displayLoadInfo(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("File type is %s\n", (fCOM)?"COM":"EXE");
|
printf("File type is %s\n", (fCOM)?"COM":"EXE");
|
||||||
if (! fCOM) {
|
if (not fCOM) {
|
||||||
printf("Signature = %02X%02X\n", header.sigLo, header.sigHi);
|
printf("Signature = %02X%02X\n", header.sigLo, header.sigHi);
|
||||||
printf("File size %% 512 = %04X\n", LH(&header.lastPageSize));
|
printf("File size %% 512 = %04X\n", LH(&header.lastPageSize));
|
||||||
printf("File size / 512 = %04X pages\n", LH(&header.numPages));
|
printf("File size / 512 = %04X pages\n", LH(&header.numPages));
|
||||||
@ -73,11 +74,11 @@ void PROG::displayLoadInfo(void)
|
|||||||
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
|
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
|
||||||
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
|
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
|
||||||
}
|
}
|
||||||
printf("Load image size = %04" PRIiPTR "\n", cbImage - sizeof(PSP));
|
printf("Load image size = %08lX\n", cbImage - sizeof(PSP));
|
||||||
printf("Initial SS:SP = %04X:%04X\n", initSS, initSP);
|
printf("Initial SS:SP = %04X:%04X\n", initSS, initSP);
|
||||||
printf("Initial CS:IP = %04X:%04X\n", initCS, initIP);
|
printf("Initial CS:IP = %04X:%04X\n", initCS, initIP);
|
||||||
|
|
||||||
if (option.VeryVerbose && cReloc)
|
if (option.VeryVerbose and cReloc)
|
||||||
{
|
{
|
||||||
printf("\nRelocation Table\n");
|
printf("\nRelocation Table\n");
|
||||||
for (i = 0; i < cReloc; i++)
|
for (i = 0; i < cReloc; i++)
|
||||||
@ -123,20 +124,20 @@ static void displayMemMap(void)
|
|||||||
fill(ip, b1);
|
fill(ip, b1);
|
||||||
printf("%06X %s\n", ip, b1);
|
printf("%06X %s\n", ip, b1);
|
||||||
ip += 16;
|
ip += 16;
|
||||||
for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
|
for (i = 3, c = b1[1]; i < 32 and c == b1[i]; i += 2)
|
||||||
; /* Check if all same */
|
; /* Check if all same */
|
||||||
if (i > 32)
|
if (i > 32)
|
||||||
{
|
{
|
||||||
fill(ip, b2); /* Skip until next two are not same */
|
fill(ip, b2); /* Skip until next two are not same */
|
||||||
fill(ip+16, b3);
|
fill(ip+16, b3);
|
||||||
if (! (strcmp(b1, b2) || strcmp(b1, b3)))
|
if (not (strcmp(b1, b2) || strcmp(b1, b3)))
|
||||||
{
|
{
|
||||||
printf(" :\n");
|
printf(" :\n");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ip += 16;
|
ip += 16;
|
||||||
fill(ip+16, b1);
|
fill(ip+16, b1);
|
||||||
} while (! strcmp(b1, b2));
|
} while (0==strcmp(b1, b2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +207,7 @@ struct ComLoader : public DosLoader {
|
|||||||
fp.seek(0);
|
fp.seek(0);
|
||||||
char sig[2];
|
char sig[2];
|
||||||
if(2==fp.read(sig,2)) {
|
if(2==fp.read(sig,2)) {
|
||||||
return not (sig[0] == 0x4D && sig[1] == 0x5A);
|
return not (sig[0] == 0x4D and sig[1] == 0x5A);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -227,8 +228,7 @@ struct ComLoader : public DosLoader {
|
|||||||
prog.initSP = 0xFFFE;
|
prog.initSP = 0xFFFE;
|
||||||
prog.cReloc = 0;
|
prog.cReloc = 0;
|
||||||
|
|
||||||
prepareImage(prog,cb,fp);
|
prepareImage(prog, cb, fp);
|
||||||
|
|
||||||
|
|
||||||
/* Set up memory map */
|
/* Set up memory map */
|
||||||
cb = (prog.cbImage + 3) / 4;
|
cb = (prog.cbImage + 3) / 4;
|
||||||
@ -237,6 +237,120 @@ struct ComLoader : public DosLoader {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#if 0
|
||||||
|
struct RomLoader {
|
||||||
|
bool canLoad(QFile &fp) {
|
||||||
|
fp.seek(0xFFF0);
|
||||||
|
uint8_t sig[1];
|
||||||
|
if(fp.read((char *)sig,1) == 1)
|
||||||
|
{
|
||||||
|
return (sig[0] == 0xEA);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool load(PROG &prog,QFile &fp) {
|
||||||
|
printf("Loading ROM...\n");
|
||||||
|
fp.seek(0);
|
||||||
|
/* ROM file
|
||||||
|
* In this case the load module size is just the file length
|
||||||
|
*/
|
||||||
|
auto cb = fp.size();
|
||||||
|
|
||||||
|
fp.seek(cb - 0x10);
|
||||||
|
uint8_t buf[5];
|
||||||
|
printf("Going to get CS/IP...\n");
|
||||||
|
if(fp.read((char *)buf, 5) != 5)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp.seek(0);
|
||||||
|
|
||||||
|
/* ROM File, Hard to say where it is suppose to start, so try to trust the
|
||||||
|
*/
|
||||||
|
prog.initIP = (buf[2] << 8) | buf[1];
|
||||||
|
//prog.initCS = 0;
|
||||||
|
prog.initCS = (buf[4] << 8) | buf[3];
|
||||||
|
|
||||||
|
prog.initSS = 0;
|
||||||
|
prog.initSP = 0xFFFE;
|
||||||
|
|
||||||
|
prog.cReloc = 0;
|
||||||
|
|
||||||
|
prepareImage(prog, cb, fp);
|
||||||
|
|
||||||
|
/* Set up memory map */
|
||||||
|
cb = (prog.cbImage + 3) / 4;
|
||||||
|
prog.map = (uint8_t *)malloc(cb);
|
||||||
|
memset(prog.map, BM_UNKNOWN, (size_t)cb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void prepareImage(PROG &prog, size_t sz, QFile &fp)
|
||||||
|
{
|
||||||
|
int32_t start = 0x100000 - sz;
|
||||||
|
/* Allocate a block of memory for the program. */
|
||||||
|
prog.cbImage = 1 * 1024 * 1024; /* Allocate the whole 1MB memory */
|
||||||
|
//prog.cbImage = 64 * 1024; /* Allocate the whole 1MB memory */
|
||||||
|
prog.Imagez = new uint8_t [prog.cbImage];
|
||||||
|
|
||||||
|
if (fp.read((char *)prog.Imagez + start, sz) != sz)
|
||||||
|
//if (fp.read((char *)prog.Imagez, sz) != sz)
|
||||||
|
{
|
||||||
|
fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
struct RomLoader {
|
||||||
|
bool canLoad(QFile &fp) {
|
||||||
|
fp.seek(0xFFF0);
|
||||||
|
uint8_t sig[1];
|
||||||
|
if(fp.read((char *)sig,1) == 1)
|
||||||
|
{
|
||||||
|
return (sig[0] == 0xEA);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool load(PROG &prog,QFile &fp) {
|
||||||
|
fp.seek(0);
|
||||||
|
/* COM file
|
||||||
|
* In this case the load module size is just the file length
|
||||||
|
*/
|
||||||
|
auto cb = fp.size();
|
||||||
|
|
||||||
|
/* COM programs start off with an ORG 100H (to leave room for a PSP)
|
||||||
|
* This is also the implied start address so if we load the image
|
||||||
|
* at offset 100H addresses should all line up properly again.
|
||||||
|
*/
|
||||||
|
prog.initCS = 0;
|
||||||
|
prog.initIP = 0x000;
|
||||||
|
prog.initSS = 0;
|
||||||
|
prog.initSP = 0xFFFE;
|
||||||
|
prog.cReloc = 0;
|
||||||
|
|
||||||
|
prepareImage(prog, cb, fp);
|
||||||
|
|
||||||
|
/* Set up memory map */
|
||||||
|
cb = (prog.cbImage + 3) / 4;
|
||||||
|
prog.map = (uint8_t *)malloc(cb);
|
||||||
|
memset(prog.map, BM_UNKNOWN, (size_t)cb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void prepareImage(PROG &prog, size_t sz, QFile &fp)
|
||||||
|
{
|
||||||
|
/* Allocate a block of memory for the program. */
|
||||||
|
prog.cbImage = sz;
|
||||||
|
prog.Imagez = new uint8_t[prog.cbImage];
|
||||||
|
|
||||||
|
if (sz != fp.read((char *)prog.Imagez, sz))
|
||||||
|
fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
struct ExeLoader : public DosLoader {
|
struct ExeLoader : public DosLoader {
|
||||||
bool canLoad(QFile &fp) {
|
bool canLoad(QFile &fp) {
|
||||||
if(fp.size()<sizeof(header))
|
if(fp.size()<sizeof(header))
|
||||||
@ -244,7 +358,7 @@ struct ExeLoader : public DosLoader {
|
|||||||
MZHeader tmp_header;
|
MZHeader tmp_header;
|
||||||
fp.seek(0);
|
fp.seek(0);
|
||||||
fp.read((char *)&tmp_header, sizeof(header));
|
fp.read((char *)&tmp_header, sizeof(header));
|
||||||
if(not (tmp_header.sigLo == 0x4D && tmp_header.sigHi == 0x5A))
|
if(not (tmp_header.sigLo == 0x4D and tmp_header.sigHi == 0x5A))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* This is a typical DOS kludge! */
|
/* This is a typical DOS kludge! */
|
||||||
@ -331,7 +445,7 @@ bool Project::load()
|
|||||||
const char *fname = binary_path().toLocal8Bit().data();
|
const char *fname = binary_path().toLocal8Bit().data();
|
||||||
QFile finfo(binary_path());
|
QFile finfo(binary_path());
|
||||||
/* Open the input file */
|
/* Open the input file */
|
||||||
if(!finfo.open(QFile::ReadOnly)) {
|
if(not finfo.open(QFile::ReadOnly)) {
|
||||||
fatalError(CANNOT_OPEN, fname);
|
fatalError(CANNOT_OPEN, fname);
|
||||||
}
|
}
|
||||||
/* Read in first 2 bytes to check EXE signature */
|
/* Read in first 2 bytes to check EXE signature */
|
||||||
@ -339,8 +453,16 @@ bool Project::load()
|
|||||||
{
|
{
|
||||||
fatalError(CANNOT_READ, fname);
|
fatalError(CANNOT_READ, fname);
|
||||||
}
|
}
|
||||||
|
RomLoader rom_loader;
|
||||||
ComLoader com_loader;
|
ComLoader com_loader;
|
||||||
ExeLoader exe_loader;
|
ExeLoader exe_loader;
|
||||||
|
if(rom_loader.canLoad(finfo)) {
|
||||||
|
/* We have no relacation and code should be on 64K only,
|
||||||
|
* So let's consider it as a COM file
|
||||||
|
*/
|
||||||
|
prog.fCOM = true;
|
||||||
|
return rom_loader.load(prog,finfo);
|
||||||
|
}
|
||||||
if(exe_loader.canLoad(finfo)) {
|
if(exe_loader.canLoad(finfo)) {
|
||||||
prog.fCOM = false;
|
prog.fCOM = false;
|
||||||
return exe_loader.load(prog,finfo);
|
return exe_loader.load(prog,finfo);
|
||||||
@ -371,7 +493,7 @@ void DccFrontend::parse(Project &proj)
|
|||||||
/* Check for special settings of initial state, based on idioms of the
|
/* Check for special settings of initial state, based on idioms of the
|
||||||
startup code */
|
startup code */
|
||||||
state.checkStartup();
|
state.checkStartup();
|
||||||
Function *start_proc;
|
ilFunction start_proc;
|
||||||
/* Make a struct for the initial procedure */
|
/* Make a struct for the initial procedure */
|
||||||
if (prog.offMain != -1)
|
if (prog.offMain != -1)
|
||||||
{
|
{
|
||||||
@ -402,7 +524,7 @@ void DccFrontend::parse(Project &proj)
|
|||||||
|
|
||||||
/* This proc needs to be called to set things up for LibCheck(), which
|
/* This proc needs to be called to set things up for LibCheck(), which
|
||||||
checks a proc to see if it is a know C (etc) library */
|
checks a proc to see if it is a know C (etc) library */
|
||||||
SetupLibCheck();
|
prog.bSigs = SetupLibCheck();
|
||||||
//BUG: proj and g_proj are 'live' at this point !
|
//BUG: proj and g_proj are 'live' at this point !
|
||||||
|
|
||||||
/* Recursively build entire procedure list */
|
/* Recursively build entire procedure list */
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
|
||||||
//FunctionType *Function::getFunctionType() const
|
//FunctionType *Function::getFunctionType() const
|
||||||
//{
|
//{
|
||||||
// return &m_type;
|
// return &m_type;
|
||||||
@ -15,7 +18,7 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
for (uint32_t i = start; i < finish; i += 2)
|
for (uint32_t i = start; i < finish; i += 2)
|
||||||
{
|
{
|
||||||
uint32_t target = cs + LH(&prg->image()[i]);
|
uint32_t target = cs + LH(&prg->image()[i]);
|
||||||
if (target < finish && target >= start)
|
if (target < finish and target >= start)
|
||||||
finish = target;
|
finish = target;
|
||||||
else if (target >= (uint32_t)prg->cbImage)
|
else if (target >= (uint32_t)prg->cbImage)
|
||||||
finish = i;
|
finish = i;
|
||||||
@ -25,7 +28,7 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
{
|
{
|
||||||
uint32_t target = cs + LH(&prg->image()[i]);
|
uint32_t target = cs + LH(&prg->image()[i]);
|
||||||
/* Be wary of 00 00 as code - it's probably data */
|
/* Be wary of 00 00 as code - it's probably data */
|
||||||
if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode))
|
if (not (prg->image()[target] or prg->image()[target+1]) or scan(target, _Icode))
|
||||||
finish = i;
|
finish = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "ast.h"
|
||||||
|
#include "bundle.h"
|
||||||
|
#include "machine_x86.h"
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
|
||||||
//#include <boost/range/algorithm.hpp>
|
//#include <boost/range/algorithm.hpp>
|
||||||
//#include <boost/assign.hpp>
|
//#include <boost/assign.hpp>
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "ast.h"
|
|
||||||
#include "bundle.h"
|
|
||||||
|
|
||||||
#include "machine_x86.h"
|
|
||||||
#include "project.h"
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
||||||
@ -41,7 +42,7 @@ RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
|||||||
// ident.type(REGISTER);
|
// ident.type(REGISTER);
|
||||||
// hlType type_sel;
|
// hlType type_sel;
|
||||||
// regType reg_type;
|
// regType reg_type;
|
||||||
// if ((icodeFlg & B) || (icodeFlg & SRC_B))
|
// if ((icodeFlg & B) or (icodeFlg & SRC_B))
|
||||||
// {
|
// {
|
||||||
// type_sel = TYPE_BYTE_SIGN;
|
// type_sel = TYPE_BYTE_SIGN;
|
||||||
// reg_type = BYTE_REG;
|
// reg_type = BYTE_REG;
|
||||||
@ -55,42 +56,42 @@ RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
|||||||
// regiType = reg_type;
|
// regiType = reg_type;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
QString RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
std::ostringstream codeOut;
|
QString codeOut;
|
||||||
|
|
||||||
std::ostringstream o;
|
QString o;
|
||||||
assert(&pProc->localId==m_syms);
|
assert(&pProc->localId==m_syms);
|
||||||
ID *id = &pProc->localId.id_arr[regiIdx];
|
ID *id = &pProc->localId.id_arr[regiIdx];
|
||||||
if (id->name[0] == '\0') /* no name */
|
if (id->name[0] == '\0') /* no name */
|
||||||
{
|
{
|
||||||
id->setLocalName(++(*numLoc));
|
id->setLocalName(++(*numLoc));
|
||||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
codeOut += QString("%1 %2; ").arg(TypeContainer::typeName(id->type)).arg(id->name);
|
||||||
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
|
codeOut += QString("/* %1 */\n").arg(Machine_X86::regName(id->id.regi));
|
||||||
}
|
}
|
||||||
if (id->hasMacro)
|
if (id->hasMacro)
|
||||||
o << id->macro << "("<<id->name<<")";
|
o += QString("%1(%2)").arg(id->macro).arg(id->name);
|
||||||
else
|
else
|
||||||
o << id->name;
|
o += id->name;
|
||||||
|
|
||||||
cCode.appendDecl(codeOut.str());
|
cCode.appendDecl(codeOut);
|
||||||
return o.str();
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegisterNode::hlTypeSize(Function *) const
|
int RegisterNode::hlTypeSize(Function *) const
|
||||||
{
|
{
|
||||||
if (regiType == BYTE_REG)
|
if (regiType == BYTE_REG)
|
||||||
return (1);
|
return 1;
|
||||||
else
|
else
|
||||||
return (2);
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlType RegisterNode::expType(Function *pproc) const
|
hlType RegisterNode::expType(Function *pproc) const
|
||||||
{
|
{
|
||||||
if (regiType == BYTE_REG)
|
if (regiType == BYTE_REG)
|
||||||
return (TYPE_BYTE_SIGN);
|
return TYPE_BYTE_SIGN;
|
||||||
else
|
else
|
||||||
return (TYPE_WORD_SIGN);
|
return TYPE_WORD_SIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
||||||
|
|||||||
276
src/ast.cpp
276
src/ast.cpp
@ -4,34 +4,41 @@
|
|||||||
* Date: September 1993
|
* Date: September 1993
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
|
#include "ast.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "bundle.h"
|
||||||
|
#include "machine_x86.h"
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
|
#include <boost/range/algorithm.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <boost/range.hpp>
|
|
||||||
#include <boost/range/adaptors.hpp>
|
|
||||||
#include <boost/range/algorithm.hpp>
|
|
||||||
#include <boost/assign.hpp>
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "ast.h"
|
|
||||||
#include "bundle.h"
|
|
||||||
#include "machine_x86.h"
|
|
||||||
#include "project.h"
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
|
|
||||||
extern int strSize (const uint8_t *, char);
|
extern int strSize (const uint8_t *, char);
|
||||||
extern char *cChar(uint8_t c);
|
extern char *cChar(uint8_t c);
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
// Conditional operator symbols in C. Index by condOp enumeration type
|
// Conditional operator symbols in C. Index by condOp enumeration type
|
||||||
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
|
constexpr const char * condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
|
||||||
" & ", " | ", " ^ ", " ~ ",
|
" & ", " | ", " ^ ", " ~ ",
|
||||||
" + ", " - ", " * ", " / ",
|
" + ", " - ", " * ", " / ",
|
||||||
" >> ", " << ", " % ", " && ", " || " };
|
" >> ", " << ", " % ", " && ", " || " };
|
||||||
|
/* Size of hl types */
|
||||||
|
constexpr const int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
|
||||||
|
|
||||||
/* Local expression stack */
|
/* Local expression stack */
|
||||||
//typedef struct _EXP_STK {
|
//typedef struct _EXP_STK {
|
||||||
@ -40,13 +47,13 @@ static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ",
|
|||||||
//} EXP_STK; - for local expression stack
|
//} EXP_STK; - for local expression stack
|
||||||
|
|
||||||
/* Returns the integer i in C hexadecimal format */
|
/* Returns the integer i in C hexadecimal format */
|
||||||
static const char *hexStr (uint16_t i)
|
const char *hexStr (uint16_t i)
|
||||||
{
|
{
|
||||||
static char buf[10];
|
static char buf[10];
|
||||||
sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
|
sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
|
||||||
return (buf);
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Sets the du record for registers according to the du flag */
|
/* Sets the du record for registers according to the du flag */
|
||||||
void ICODE::setRegDU (eReg regi, operDu du_in)
|
void ICODE::setRegDU (eReg regi, operDu du_in)
|
||||||
@ -121,7 +128,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
|
|||||||
valid = true;
|
valid = true;
|
||||||
ident.idType = GLOB_VAR;
|
ident.idType = GLOB_VAR;
|
||||||
adr = opAdr(segValue, off);
|
adr = opAdr(segValue, off);
|
||||||
auto i=Project::get()->getSymIdxByAdd(adr);
|
auto i=Project::get()->getSymIdxByAddr(adr);
|
||||||
if ( not Project::get()->validSymIdx(i) )
|
if ( not Project::get()->validSymIdx(i) )
|
||||||
{
|
{
|
||||||
printf ("Error, glob var not found in symtab\n");
|
printf ("Error, glob var not found in symtab\n");
|
||||||
@ -130,10 +137,10 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
|
|||||||
globIdx = i;
|
globIdx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
string GlobalVariable::walkCondExpr(Function *, int *) const
|
QString GlobalVariable::walkCondExpr(Function *, int *) const
|
||||||
{
|
{
|
||||||
if(valid)
|
if(valid)
|
||||||
return Project::get()->symtab[globIdx].name;
|
return Project::get()->symbolName(globIdx);
|
||||||
return "INVALID GlobalVariable";
|
return "INVALID GlobalVariable";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +153,7 @@ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
|
|||||||
for (i = 0; i < localId->csym(); i++)
|
for (i = 0; i < localId->csym(); i++)
|
||||||
{
|
{
|
||||||
const ID &lID(localId->id_arr[i]);
|
const ID &lID(localId->id_arr[i]);
|
||||||
if ((lID.id.bwId.off == off) && (lID.id.bwId.regOff == 0))
|
if ((lID.id.bwId.off == off) and (lID.id.bwId.regOff == 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == localId->csym())
|
if (i == localId->csym())
|
||||||
@ -181,19 +188,17 @@ GlobalVariableIdx::GlobalVariableIdx (int16_t segValue, int16_t off, uint8_t reg
|
|||||||
for (i = 0; i < locSym->csym(); i++)
|
for (i = 0; i < locSym->csym(); i++)
|
||||||
{
|
{
|
||||||
const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb);
|
const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb);
|
||||||
if ((lID.seg == segValue) && (lID.off == off) && (lID.regi == regi))
|
if ((lID.seg == segValue) and (lID.off == off) and (lID.regi == regi))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == locSym->csym())
|
if (i == locSym->csym())
|
||||||
printf ("Error, indexed-glob var not found in local id table\n");
|
printf ("Error, indexed-glob var not found in local id table\n");
|
||||||
idxGlbIdx = i;
|
idxGlbIdx = i;
|
||||||
}
|
}
|
||||||
string GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
|
QString GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
|
||||||
{
|
{
|
||||||
ostringstream o;
|
|
||||||
auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
|
auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
|
||||||
o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]";
|
return QString("%1[%2]").arg((bwGlb->seg << 4) + bwGlb->off).arg(Machine_X86::regName(bwGlb->regi));
|
||||||
return o.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,7 +226,7 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
|
|||||||
{
|
{
|
||||||
AstIdent *newExp;
|
AstIdent *newExp;
|
||||||
/* Check for long constant and save it as a constant expression */
|
/* Check for long constant and save it as a constant expression */
|
||||||
if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */
|
if ((sd == SRC) and pIcode->ll()->testFlags(I)) /* constant */
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
if (f == HIGH_FIRST)
|
if (f == HIGH_FIRST)
|
||||||
@ -258,18 +263,18 @@ AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off)
|
|||||||
* TYPE_WORD_SIGN */
|
* TYPE_WORD_SIGN */
|
||||||
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
AstIdent *newExp=nullptr;
|
AstIdent *newExp=nullptr;
|
||||||
switch(retVal->type)
|
switch(retVal->type)
|
||||||
{
|
{
|
||||||
case TYPE_LONG_SIGN:
|
case TYPE_LONG_SIGN:
|
||||||
{
|
{
|
||||||
newExp = new AstIdent();
|
newExp = new AstIdent();
|
||||||
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
int idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
||||||
newExp->ident.idType = LONG_VAR;
|
newExp->ident.idType = LONG_VAR;
|
||||||
newExp->ident.idNode.longIdx = idx;
|
newExp->ident.idNode.longIdx = idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TYPE_WORD_UNSIGN:
|
||||||
case TYPE_WORD_SIGN:
|
case TYPE_WORD_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
||||||
break;
|
break;
|
||||||
@ -296,8 +301,8 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
|
|
||||||
const LLOperand &pm(*ll_insn.get(sd));
|
const LLOperand &pm(*ll_insn.get(sd));
|
||||||
|
|
||||||
if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or
|
if ( ((sd == DST) and ll_insn.testFlags(IM_DST)) or
|
||||||
((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
|
((sd == SRC) and ll_insn.testFlags(IM_SRC)) or
|
||||||
(sd == LHS_OP)) /* for MUL lhs */
|
(sd == LHS_OP)) /* for MUL lhs */
|
||||||
{ /* implicit dx:ax */
|
{ /* implicit dx:ax */
|
||||||
idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_);
|
idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_);
|
||||||
@ -306,13 +311,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
duIcode.setRegDU (rAX, du);
|
duIcode.setRegDU (rAX, du);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST))
|
else if ((sd == DST) and ll_insn.testFlags(IM_TMP_DST))
|
||||||
{ /* implicit tmp */
|
{ /* implicit tmp */
|
||||||
newExp = new RegisterNode(LLOperand(rTMP,2), &pProc->localId);
|
newExp = new RegisterNode(LLOperand(rTMP,2), &pProc->localId);
|
||||||
duIcode.setRegDU(rTMP, (operDu)eUSE);
|
duIcode.setRegDU(rTMP, (operDu)eUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */
|
else if ((sd == SRC) and ll_insn.testFlags(I)) /* constant */
|
||||||
newExp = new Constant(ll_insn.src().getImm2(), 2);
|
newExp = new Constant(ll_insn.src().getImm2(), 2);
|
||||||
else if (pm.regi == rUNDEF) /* global variable */
|
else if (pm.regi == rUNDEF) /* global variable */
|
||||||
newExp = new GlobalVariable(pm.segValue, pm.off);
|
newExp = new GlobalVariable(pm.segValue, pm.off);
|
||||||
@ -325,14 +330,14 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
|
|
||||||
else if (pm.off) /* offset */
|
else if (pm.off) /* offset */
|
||||||
{ // TODO: this is ABI specific, should be actually based on Function calling conv
|
{ // TODO: this is ABI specific, should be actually based on Function calling conv
|
||||||
if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */
|
if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) /* idx on bp */
|
||||||
{
|
{
|
||||||
if (pm.off >= 0) /* argument */
|
if (pm.off >= 0) /* argument */
|
||||||
newExp = AstIdent::Param (pm.off, &pProc->args);
|
newExp = AstIdent::Param (pm.off, &pProc->args);
|
||||||
else /* local variable */
|
else /* local variable */
|
||||||
newExp = AstIdent::Loc (pm.off, &pProc->localId);
|
newExp = AstIdent::Loc (pm.off, &pProc->localId);
|
||||||
}
|
}
|
||||||
else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */
|
else if ((pm.seg == rDS) and (pm.regi == INDEX_BX)) /* bx */
|
||||||
{
|
{
|
||||||
if (pm.off > 0) /* global variable */
|
if (pm.off > 0) /* global variable */
|
||||||
newExp = new GlobalVariableIdx(pm.segValue, pm.off, rBX,&pProc->localId);
|
newExp = new GlobalVariableIdx(pm.segValue, pm.off, rBX,&pProc->localId);
|
||||||
@ -344,10 +349,9 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
|
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
|
||||||
/**** check long ops, indexed global var *****/
|
/**** check long ops, indexed global var *****/
|
||||||
}
|
}
|
||||||
|
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
|
||||||
else /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */
|
|
||||||
{
|
{
|
||||||
if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */
|
if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */
|
||||||
{
|
{
|
||||||
eReg selected;
|
eReg selected;
|
||||||
switch (pm.regi) {
|
switch (pm.regi) {
|
||||||
@ -367,7 +371,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
else
|
else
|
||||||
newExp = AstIdent::Other (pm.seg, pm.regi, 0);
|
newExp = AstIdent::Other (pm.seg, pm.regi, 0);
|
||||||
}
|
}
|
||||||
return (newExp);
|
return newExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -376,32 +380,29 @@ condId LLInst::idType(opLoc sd) const
|
|||||||
{
|
{
|
||||||
const LLOperand &pm((sd == SRC) ? src() : m_dst);
|
const LLOperand &pm((sd == SRC) ? src() : m_dst);
|
||||||
|
|
||||||
if ((sd == SRC) && testFlags(I))
|
if ((sd == SRC) and testFlags(I))
|
||||||
return (CONSTANT);
|
return CONSTANT;
|
||||||
else if (pm.regi == 0)
|
else if (pm.regi == 0)
|
||||||
return (GLOB_VAR);
|
return GLOB_VAR;
|
||||||
else if ( pm.isReg() )
|
else if ( pm.isReg() )
|
||||||
return (REGISTER);
|
return REGISTER;
|
||||||
else if ((pm.seg == rSS) && (pm.regi == INDEX_BP))
|
else if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) // TODO: this assumes BP-based function frames !
|
||||||
{
|
{
|
||||||
//TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
|
//TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
|
||||||
if (pm.off >= 0)
|
if (pm.off >= 0)
|
||||||
return (PARAM);
|
return PARAM;
|
||||||
else
|
return LOCAL_VAR;
|
||||||
return (LOCAL_VAR);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (OTHER);
|
return OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Size of hl types */
|
|
||||||
int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
|
|
||||||
|
|
||||||
int Expr::hlTypeSize(Function * pproc) const
|
int Expr::hlTypeSize(Function * pproc) const
|
||||||
{
|
{
|
||||||
if (this == nullptr)
|
if (this == nullptr)
|
||||||
return (2); /* for TYPE_UNKNOWN */
|
return 2; /* for TYPE_UNKNOWN */
|
||||||
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
|
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
|
||||||
return 2; // CC: is this correct?
|
return 2; // CC: is this correct?
|
||||||
}
|
}
|
||||||
@ -436,11 +437,11 @@ int AstIdent::hlTypeSize(Function *pproc) const
|
|||||||
case PARAM:
|
case PARAM:
|
||||||
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
||||||
case STRING:
|
case STRING:
|
||||||
return (2);
|
return 2;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
return (4);
|
return 4;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
return (2);
|
return 2;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return -1;
|
return -1;
|
||||||
@ -523,42 +524,40 @@ Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the string located in image, formatted in C format. */
|
/* Returns the string located in image, formatted in C format. */
|
||||||
static std::string getString (int offset)
|
static QString getString (int offset)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ostringstream o;
|
QString o;
|
||||||
int strLen, i;
|
int strLen, i;
|
||||||
|
|
||||||
strLen = strSize (&prog.image()[offset], '\0');
|
strLen = strSize (&prog.image()[offset], '\0');
|
||||||
o << '"';
|
o += '"';
|
||||||
for (i = 0; i < strLen; i++)
|
for (i = 0; i < strLen; i++)
|
||||||
o<<cChar(prog.image()[offset+i]);
|
o += cChar(prog.image()[offset+i]);
|
||||||
o << "\"\0";
|
o += "\"\0";
|
||||||
return (o.str());
|
return o;
|
||||||
}
|
}
|
||||||
string BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
QString BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
||||||
{
|
{
|
||||||
std::ostringstream outStr;
|
|
||||||
outStr << "(";
|
|
||||||
if(m_op!=NOT)
|
|
||||||
{
|
|
||||||
outStr << lhs()->walkCondExpr(pProc, numLoc);
|
|
||||||
}
|
|
||||||
assert(rhs());
|
assert(rhs());
|
||||||
outStr << condOpSym[m_op];
|
|
||||||
outStr << rhs()->walkCondExpr(pProc, numLoc);
|
return QString("(%1%2%3)")
|
||||||
outStr << ")";
|
.arg((m_op!=NOT) ? lhs()->walkCondExpr(pProc, numLoc) : "")
|
||||||
return outStr.str();
|
.arg(condOpSym[m_op])
|
||||||
|
.arg(rhs()->walkCondExpr(pProc, numLoc));
|
||||||
}
|
}
|
||||||
string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
QString AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
int16_t off; /* temporal - for OTHER */
|
int16_t off; /* temporal - for OTHER */
|
||||||
ID* id; /* Pointer to local identifier table */
|
ID* id; /* Pointer to local identifier table */
|
||||||
BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */
|
BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */
|
||||||
STKSYM * psym; /* Pointer to argument in the stack */
|
STKSYM * psym; /* Pointer to argument in the stack */
|
||||||
std::ostringstream outStr,codeOut;
|
QString codeContents;
|
||||||
|
QString collectedContents;
|
||||||
|
|
||||||
|
QTextStream codeOut(&codeContents);
|
||||||
|
QTextStream o(&collectedContents);
|
||||||
|
|
||||||
std::ostringstream o;
|
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
@ -587,7 +586,7 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
||||||
Machine_X86::regName(id->longId().l()) << " */\n";
|
Machine_X86::regName(id->longId().l()) << " */\n";
|
||||||
o << id->name;
|
o << id->name;
|
||||||
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name.c_str());
|
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name);
|
||||||
}
|
}
|
||||||
else /* GLB_FRAME */
|
else /* GLB_FRAME */
|
||||||
{
|
{
|
||||||
@ -595,6 +594,10 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
||||||
else if (id->id.longGlb.regi == rBX)
|
else if (id->id.longGlb.regi == rBX)
|
||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
||||||
|
else {
|
||||||
|
qCritical() << "AstIdent::walkCondExpr unhandled LONG_VAR in GLB_FRAME";
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
@ -613,79 +616,60 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
|
|
||||||
|
|
||||||
} /* eos */
|
} /* eos */
|
||||||
outStr << o.str();
|
cCode.appendDecl(codeContents);
|
||||||
cCode.appendDecl(codeOut.str());
|
return collectedContents;
|
||||||
return outStr.str();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
string UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
QString UnaryOperator::wrapUnary(Function *pProc, int *numLoc,QChar op) const
|
||||||
{
|
{
|
||||||
std::ostringstream outStr;
|
QString outStr = op;
|
||||||
bool needBracket=true;
|
QString inner = unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
|
if (unaryExp->m_type == IDENTIFIER)
|
||||||
|
outStr += inner;
|
||||||
|
else
|
||||||
|
outStr += "("+inner+')';
|
||||||
|
return outStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
|
{
|
||||||
|
QString outStr;
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
outStr+=wrapUnary(pProc,numLoc,'!');
|
||||||
{
|
|
||||||
needBracket = false;
|
|
||||||
outStr << "!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
outStr << "! (";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
outStr+=wrapUnary(pProc,numLoc,'&');
|
||||||
{
|
|
||||||
needBracket = false;
|
|
||||||
outStr << "&";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
outStr << "&(";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
outStr << "*";
|
outStr+=wrapUnary(pProc,numLoc,'*');
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
|
||||||
needBracket = false;
|
|
||||||
else
|
|
||||||
outStr << "(";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_INC:
|
case POST_INC:
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc) << "++";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_DEC:
|
case POST_DEC:
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc) << "--";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_INC:
|
case PRE_INC:
|
||||||
outStr << "++"<< unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_DEC:
|
case PRE_DEC:
|
||||||
outStr << "--"<< unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return outStr.str();
|
return outStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walks the conditional expression tree and returns the result on a string */
|
/* Walks the conditional expression tree and returns the result on a string */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Changes the boolean conditional operator at the root of this expression */
|
/* Changes the boolean conditional operator at the root of this expression */
|
||||||
void BinaryOperator::changeBoolOp (condOp newOp)
|
void BinaryOperator::changeBoolOp (condOp newOp)
|
||||||
{
|
{
|
||||||
@ -816,9 +800,8 @@ Expr *BinaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
|||||||
Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
||||||
{
|
{
|
||||||
if (ident.idNode.longIdx == longIdx)
|
if (ident.idNode.longIdx == longIdx)
|
||||||
{
|
|
||||||
return _expr;
|
return _expr;
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,10 +817,10 @@ Expr *BinaryOperator::clone() const
|
|||||||
|
|
||||||
Expr *BinaryOperator::inverse() const
|
Expr *BinaryOperator::inverse() const
|
||||||
{
|
{
|
||||||
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
|
constexpr static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
|
||||||
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
|
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
|
||||||
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
|
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
|
||||||
DUMMY, DBL_OR, DBL_AND};
|
DUMMY, DBL_OR, DBL_AND};
|
||||||
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
||||||
switch (m_op)
|
switch (m_op)
|
||||||
{
|
{
|
||||||
@ -866,37 +849,19 @@ Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
|
|||||||
{
|
{
|
||||||
eReg otherRegi; /* high or low part of long register */
|
eReg otherRegi; /* high or low part of long register */
|
||||||
|
|
||||||
if (ident.idType == LONG_VAR)
|
if (ident.idType != LONG_VAR)
|
||||||
{
|
return this;
|
||||||
otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId);
|
otherRegi = locId->getPairedRegisterAt(ident.idNode.longIdx,regi);
|
||||||
delete this;
|
bool long_was_signed = locId->id_arr[ident.idNode.longIdx].isSigned();
|
||||||
return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG,locId);
|
delete this;
|
||||||
}
|
return new RegisterNode(locId->newByteWordReg(long_was_signed ? TYPE_WORD_SIGN : TYPE_WORD_UNSIGN,otherRegi),WORD_REG,locId);
|
||||||
return this;
|
|
||||||
}
|
|
||||||
eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|
||||||
{
|
|
||||||
ID *id = &locTbl->id_arr[idx];
|
|
||||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
|
||||||
{
|
|
||||||
if (id->longId().h() == regi)
|
|
||||||
return (id->longId().l());
|
|
||||||
else if (id->longId().l() == regi)
|
|
||||||
return (id->longId().h());
|
|
||||||
}
|
|
||||||
return rUNDEF; // Cristina: please check this!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Constant::walkCondExpr(Function *, int *) const
|
||||||
string Constant::walkCondExpr(Function *, int *) const
|
|
||||||
{
|
{
|
||||||
ostringstream o;
|
|
||||||
if (kte.kte < 1000)
|
if (kte.kte < 1000)
|
||||||
o << kte.kte;
|
return QString::number(kte.kte);
|
||||||
else
|
return "0x" + QString::number(kte.kte,16);
|
||||||
o << "0x"<<std::hex << kte.kte;
|
|
||||||
return o.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Constant::hlTypeSize(Function *) const
|
int Constant::hlTypeSize(Function *) const
|
||||||
@ -904,12 +869,7 @@ int Constant::hlTypeSize(Function *) const
|
|||||||
return kte.size;
|
return kte.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlType Constant::expType(Function *pproc) const
|
QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
|
||||||
return TYPE_CONST;
|
|
||||||
}
|
|
||||||
|
|
||||||
string FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
|
||||||
{
|
{
|
||||||
return pProc->writeCall(call.proc,*call.args, numLoc);
|
return pProc->writeCall(call.proc,*call.args, numLoc);
|
||||||
}
|
}
|
||||||
|
|||||||
136
src/backend.cpp
136
src/backend.cpp
@ -4,12 +4,20 @@
|
|||||||
* Purpose: Back-end module. Generates C code for each procedure.
|
* Purpose: Back-end module. Generates C code for each procedure.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <QDir>
|
#include "dcc.h"
|
||||||
#include <QFile>
|
#include "msvc_fixes.h"
|
||||||
|
#include "disassem.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -17,15 +25,13 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "dcc.h"
|
|
||||||
#include "disassem.h"
|
|
||||||
#include "project.h"
|
|
||||||
#include "CallGraph.h"
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
bundle cCode; /* Procedure declaration and code */
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
bundle cCode; /* Procedure declaration and code */
|
||||||
|
|
||||||
/* Returns a unique index to the next label */
|
/* Returns a unique index to the next label */
|
||||||
int getNextLabel()
|
int getNextLabel()
|
||||||
{
|
{
|
||||||
@ -37,14 +43,14 @@ int getNextLabel()
|
|||||||
/* displays statistics on the subroutine */
|
/* displays statistics on the subroutine */
|
||||||
void Function::displayStats ()
|
void Function::displayStats ()
|
||||||
{
|
{
|
||||||
printf("\nStatistics - Subroutine %s\n", name.c_str());
|
qDebug() << "\nStatistics - Subroutine" << name;
|
||||||
printf ("Number of Icode instructions:\n");
|
qDebug() << "Number of Icode instructions:";
|
||||||
printf (" Low-level : %4d\n", stats.numLLIcode);
|
qDebug() << " Low-level :" << stats.numLLIcode;
|
||||||
if (! (flg & PROC_ASM))
|
if (not (flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
printf (" High-level: %4d\n", stats.numHLIcode);
|
qDebug() << " High-level:"<<stats.numHLIcode;
|
||||||
printf (" Percentage reduction: %2.2f%%\n", 100.0 - (stats.numHLIcode *
|
qDebug() << QString(" Percentage reduction: %1%%").arg(100.0 - (stats.numHLIcode *
|
||||||
100.0) / stats.numLLIcode);
|
100.0) / stats.numLLIcode,4,'f',2,QChar('0'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +108,7 @@ char *cChar (uint8_t c)
|
|||||||
* Note: to get to the value of the variable:
|
* Note: to get to the value of the variable:
|
||||||
* com file: prog.Image[operand]
|
* com file: prog.Image[operand]
|
||||||
* exe file: prog.Image[operand+0x100] */
|
* exe file: prog.Image[operand+0x100] */
|
||||||
static void printGlobVar (std::ostream &ostr,SYM * psym)
|
static void printGlobVar (QTextStream &ostr,SYM * psym)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
@ -125,10 +131,10 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ostringstream strContents;
|
QString strContents;
|
||||||
for (j=0; j < psym->size; j++)
|
for (j=0; j < psym->size; j++)
|
||||||
strContents << cChar(prog.image()[relocOp + j]);
|
strContents += cChar(prog.image()[relocOp + j]);
|
||||||
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
|
ostr << "char\t*"<<psym->name<<" = \""<<strContents<<"\";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +145,8 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
|
|||||||
* initialization. */
|
* initialization. */
|
||||||
void Project::writeGlobSymTable()
|
void Project::writeGlobSymTable()
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString contents;
|
||||||
|
QTextStream ostr(&contents);
|
||||||
|
|
||||||
if (symtab.empty())
|
if (symtab.empty())
|
||||||
return;
|
return;
|
||||||
@ -147,13 +154,13 @@ void Project::writeGlobSymTable()
|
|||||||
for (SYM &sym : symtab)
|
for (SYM &sym : symtab)
|
||||||
{
|
{
|
||||||
if (sym.duVal.isUSE_VAL()) /* first used */
|
if (sym.duVal.isUSE_VAL()) /* first used */
|
||||||
printGlobVar (ostr,&sym);
|
printGlobVar (ostr,&sym);
|
||||||
else { /* first defined */
|
else { /* first defined */
|
||||||
switch (sym.size) {
|
switch (sym.size) {
|
||||||
case 1: ostr<<"uint8_t\t"; break;
|
case 1: ostr<<"uint8_t\t"; break;
|
||||||
case 2: ostr<<"int\t"; break;
|
case 2: ostr<<"int16_t\t"; break;
|
||||||
case 4: if (sym.type == TYPE_PTR)
|
case 4: if (sym.type == TYPE_PTR)
|
||||||
ostr<<"int\t*";
|
ostr<<"int32_t\t*";
|
||||||
else
|
else
|
||||||
ostr<<"char\t*";
|
ostr<<"char\t*";
|
||||||
break;
|
break;
|
||||||
@ -163,13 +170,14 @@ void Project::writeGlobSymTable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ostr<< "\n";
|
ostr<< "\n";
|
||||||
cCode.appendDecl( ostr.str() );
|
ostr.flush();
|
||||||
|
cCode.appendDecl( contents );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the header information and global variables to the output C file
|
/* Writes the header information and global variables to the output C file
|
||||||
* fp. */
|
* fp. */
|
||||||
static void writeHeader (std::ostream &_ios, const std::string &fileName)
|
static void writeHeader (QIODevice &_ios, const std::string &fileName)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
/* Write header information */
|
/* Write header information */
|
||||||
@ -206,10 +214,11 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
|||||||
|
|
||||||
/* Writes the procedure's declaration (including arguments), local variables,
|
/* Writes the procedure's declaration (including arguments), local variables,
|
||||||
* and invokes the procedure that writes the code of the given record *hli */
|
* and invokes the procedure that writes the code of the given record *hli */
|
||||||
void Function::codeGen (std::ostream &fs)
|
void Function::codeGen (QIODevice &fs)
|
||||||
{
|
{
|
||||||
int numLoc;
|
int numLoc;
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
//STKFRAME * args; /* Procedure arguments */
|
//STKFRAME * args; /* Procedure arguments */
|
||||||
//char buf[200], /* Procedure's definition */
|
//char buf[200], /* Procedure's definition */
|
||||||
// arg[30]; /* One argument */
|
// arg[30]; /* One argument */
|
||||||
@ -218,30 +227,27 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
/* Write procedure/function header */
|
/* Write procedure/function header */
|
||||||
cCode.init();
|
cCode.init();
|
||||||
if (flg & PROC_IS_FUNC) /* Function */
|
if (flg & PROC_IS_FUNC) /* Function */
|
||||||
ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
|
ostr << QString("\n%1 %2 (").arg(TypeContainer::typeName(retVal.type)).arg(name);
|
||||||
else /* Procedure */
|
else /* Procedure */
|
||||||
ostr<< "\nvoid "<<name<<" (";
|
ostr << "\nvoid "+name+" (";
|
||||||
|
|
||||||
/* Write arguments */
|
/* Write arguments */
|
||||||
struct validArg
|
struct validArg
|
||||||
{
|
{
|
||||||
bool operator()(STKSYM &s) { return s.invalid==false;}
|
bool operator()(STKSYM &s) { return s.invalid==false;}
|
||||||
};
|
};
|
||||||
auto valid_args = args | filtered(validArg());
|
QStringList parts;
|
||||||
int count_valid = std::distance(valid_args.begin(),valid_args.end());
|
for (STKSYM &arg : (args | filtered(validArg())))
|
||||||
for (STKSYM &arg : valid_args)
|
|
||||||
{
|
{
|
||||||
ostr<<hlTypes[arg.type]<<" "<<arg.name;
|
parts << QString("%1 %2").arg(hlTypes[arg.type]).arg(arg.name);
|
||||||
if(--count_valid!=0)
|
|
||||||
ostr<<", ";
|
|
||||||
}
|
}
|
||||||
ostr<<")\n";
|
ostr << parts.join(", ")+")\n";
|
||||||
|
|
||||||
/* Write comments */
|
/* Write comments */
|
||||||
writeProcComments( ostr );
|
writeProcComments( ostr );
|
||||||
|
|
||||||
/* Write local variables */
|
/* Write local variables */
|
||||||
if (! (flg & PROC_ASM))
|
if (not (flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
numLoc = 0;
|
numLoc = 0;
|
||||||
for (ID &refId : localId )
|
for (ID &refId : localId )
|
||||||
@ -252,8 +258,8 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
if (refId.loc == REG_FRAME)
|
if (refId.loc == REG_FRAME)
|
||||||
{
|
{
|
||||||
/* Register variables are assigned to a local variable */
|
/* Register variables are assigned to a local variable */
|
||||||
if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
|
if (((flg & SI_REGVAR) and (refId.id.regi == rSI)) or
|
||||||
((flg & DI_REGVAR) && (refId.id.regi == rDI)))
|
((flg & DI_REGVAR) and (refId.id.regi == rDI)))
|
||||||
{
|
{
|
||||||
refId.setLocalName(++numLoc);
|
refId.setLocalName(++numLoc);
|
||||||
ostr << "int "<<refId.name<<";\n";
|
ostr << "int "<<refId.name<<";\n";
|
||||||
@ -269,7 +275,9 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs<<ostr.str();
|
ostr.flush();
|
||||||
|
fs.write(ostr_contents.toLatin1());
|
||||||
|
|
||||||
/* Write procedure's code */
|
/* Write procedure's code */
|
||||||
if (flg & PROC_ASM) /* generate assembler */
|
if (flg & PROC_ASM) /* generate assembler */
|
||||||
{
|
{
|
||||||
@ -286,36 +294,41 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
freeBundle (&cCode);
|
freeBundle (&cCode);
|
||||||
|
|
||||||
/* Write Live register analysis information */
|
/* Write Live register analysis information */
|
||||||
if (option.verbose)
|
if (option.verbose) {
|
||||||
|
QString debug_contents;
|
||||||
|
QTextStream debug_stream(&debug_contents);
|
||||||
for (size_t i = 0; i < numBBs; i++)
|
for (size_t i = 0; i < numBBs; i++)
|
||||||
{
|
{
|
||||||
pBB = m_dfsLast[i];
|
pBB = m_dfsLast[i];
|
||||||
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
||||||
cout << "BB "<<i<<"\n";
|
debug_stream << "BB "<<i<<"\n";
|
||||||
cout << " Start = "<<pBB->begin()->loc_ip;
|
debug_stream << " Start = "<<pBB->begin()->loc_ip;
|
||||||
cout << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
|
debug_stream << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
|
||||||
cout << " LiveUse = ";
|
debug_stream << " LiveUse = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveUse);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveUse);
|
||||||
cout << "\n Def = ";
|
debug_stream << "\n Def = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->def);
|
Machine_X86::writeRegVector(debug_stream,pBB->def);
|
||||||
cout << "\n LiveOut = ";
|
debug_stream << "\n LiveOut = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveOut);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveOut);
|
||||||
cout << "\n LiveIn = ";
|
debug_stream << "\n LiveIn = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveIn);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveIn);
|
||||||
cout <<"\n\n";
|
debug_stream <<"\n\n";
|
||||||
}
|
}
|
||||||
|
debug_stream.flush();
|
||||||
|
qDebug() << debug_contents.toLatin1();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Recursive procedure. Displays the procedure's code in depth-first order
|
/* Recursive procedure. Displays the procedure's code in depth-first order
|
||||||
* of the call graph. */
|
* of the call graph. */
|
||||||
static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
static void backBackEnd (CALL_GRAPH * pcallGraph, QIODevice &_ios)
|
||||||
{
|
{
|
||||||
|
|
||||||
// IFace.Yield(); /* This is a good place to yield to other apps */
|
// IFace.Yield(); /* This is a good place to yield to other apps */
|
||||||
|
|
||||||
/* Check if this procedure has been processed already */
|
/* Check if this procedure has been processed already */
|
||||||
if ((pcallGraph->proc->flg & PROC_OUTPUT) ||
|
if ((pcallGraph->proc->flg & PROC_OUTPUT) or
|
||||||
(pcallGraph->proc->flg & PROC_ISLIB))
|
(pcallGraph->proc->flg & PROC_ISLIB))
|
||||||
return;
|
return;
|
||||||
pcallGraph->proc->flg |= PROC_OUTPUT;
|
pcallGraph->proc->flg |= PROC_OUTPUT;
|
||||||
@ -334,7 +347,7 @@ static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
|||||||
/* Generate statistics */
|
/* Generate statistics */
|
||||||
if (option.Stats)
|
if (option.Stats)
|
||||||
pcallGraph->proc->displayStats ();
|
pcallGraph->proc->displayStats ();
|
||||||
if (! (pcallGraph->proc->flg & PROC_ASM))
|
if (not (pcallGraph->proc->flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
stats.totalLL += stats.numLLIcode;
|
stats.totalLL += stats.numLLIcode;
|
||||||
stats.totalHL += stats.numHLIcode;
|
stats.totalHL += stats.numHLIcode;
|
||||||
@ -345,16 +358,15 @@ static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
|||||||
/* Invokes the necessary routines to produce code one procedure at a time. */
|
/* Invokes the necessary routines to produce code one procedure at a time. */
|
||||||
void BackEnd(CALL_GRAPH * pcallGraph)
|
void BackEnd(CALL_GRAPH * pcallGraph)
|
||||||
{
|
{
|
||||||
std::ofstream fs; /* Output C file */
|
|
||||||
|
|
||||||
/* Get output file name */
|
/* Get output file name */
|
||||||
QString outNam(Project::get()->output_name("b")); /* b for beta */
|
QString outNam(Project::get()->output_name("b")); /* b for beta */
|
||||||
|
QFile fs(outNam); /* Output C file */
|
||||||
|
|
||||||
/* Open output file */
|
/* Open output file */
|
||||||
fs.open(outNam.toStdString());
|
if(not fs.open(QFile::WriteOnly|QFile::Text))
|
||||||
if(!fs.is_open())
|
|
||||||
fatalError (CANNOT_OPEN, outNam.toStdString().c_str());
|
fatalError (CANNOT_OPEN, outNam.toStdString().c_str());
|
||||||
std::cout<<"dcc: Writing C beta file "<<outNam.toStdString()<<"\n";
|
|
||||||
|
qDebug()<<"dcc: Writing C beta file"<<outNam;
|
||||||
|
|
||||||
/* Header information */
|
/* Header information */
|
||||||
writeHeader (fs, option.filename.toStdString());
|
writeHeader (fs, option.filename.toStdString());
|
||||||
@ -368,7 +380,7 @@ void BackEnd(CALL_GRAPH * pcallGraph)
|
|||||||
|
|
||||||
/* Close output file */
|
/* Close output file */
|
||||||
fs.close();
|
fs.close();
|
||||||
std::cout << "dcc: Finished writing C beta file\n";
|
qDebug() << "dcc: Finished writing C beta file";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <QtCore/QIODevice>
|
||||||
#define deltaProcLines 20
|
#define deltaProcLines 20
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -21,26 +21,26 @@ using namespace std;
|
|||||||
* tab is removed and replaced by this label */
|
* tab is removed and replaced by this label */
|
||||||
void strTable::addLabelBundle (int idx, int label)
|
void strTable::addLabelBundle (int idx, int label)
|
||||||
{
|
{
|
||||||
char s[16];
|
QString &processedLine(at(idx));
|
||||||
sprintf (s, "l%d: ", label);
|
QString s = QString("l%1: ").arg(label);
|
||||||
if(at(idx).size()<4)
|
if(processedLine.size()<4)
|
||||||
at(idx)=s;
|
processedLine = s;
|
||||||
else
|
else
|
||||||
at(idx) = string(s)+at(idx).substr(4);
|
processedLine = s+processedLine.mid(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the contents of the string table on the file fp. */
|
/* Writes the contents of the string table on the file fp. */
|
||||||
static void writeStrTab (std::ostream &ios, strTable &strTab)
|
static void writeStrTab (QIODevice &ios, strTable &strTab)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < strTab.size(); i++)
|
for (size_t i = 0; i < strTab.size(); i++)
|
||||||
ios << strTab[i];
|
ios.write(strTab[i].toLatin1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the contents of the bundle (procedure code and declaration) to
|
/* Writes the contents of the bundle (procedure code and declaration) to
|
||||||
* a file. */
|
* a file. */
|
||||||
void writeBundle (std::ostream &ios, bundle procCode)
|
void writeBundle (QIODevice &ios, bundle procCode)
|
||||||
{
|
{
|
||||||
writeStrTab (ios, procCode.decl);
|
writeStrTab (ios, procCode.decl);
|
||||||
writeStrTab (ios, procCode.code);
|
writeStrTab (ios, procCode.code);
|
||||||
@ -70,7 +70,7 @@ void bundle::appendCode(const char *format,...)
|
|||||||
code.push_back(buf);
|
code.push_back(buf);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
void bundle::appendCode(const std::string &s)
|
void bundle::appendCode(const QString & s)
|
||||||
{
|
{
|
||||||
code.push_back(s);
|
code.push_back(s);
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ void bundle::appendDecl(const char *format,...)
|
|||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bundle::appendDecl(const std::string &v)
|
void bundle::appendDecl(const QString &v)
|
||||||
{
|
{
|
||||||
decl.push_back(v);
|
decl.push_back(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,15 +6,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
#include "dcc_interface.h"
|
#include "dcc_interface.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
PerfectHash g_pattern_hasher;
|
PerfectHash g_pattern_hasher;
|
||||||
#define NIL -1 /* Used like NULL, but 0 is valid */
|
#define NIL -1 /* Used like NULL, but 0 is valid */
|
||||||
|
|
||||||
@ -49,7 +53,7 @@ int numVert; /* Number of vertices in the graph (also size of g[]
|
|||||||
unsigned PatLen; /* Size of the keys (pattern length) */
|
unsigned PatLen; /* Size of the keys (pattern length) */
|
||||||
unsigned SymLen; /* Max size of the symbols, including null */
|
unsigned SymLen; /* Max size of the symbols, including null */
|
||||||
static FILE *g_file; /* File being read */
|
static FILE *g_file; /* File being read */
|
||||||
static char sSigName[100]; /* Full path name of .sig file */
|
static QString sSigName; /* Full path name of .sig file */
|
||||||
|
|
||||||
static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
|
static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
|
||||||
static uint16_t *g; /* g[] */
|
static uint16_t *g; /* g[] */
|
||||||
@ -294,9 +298,8 @@ static uint8_t pattMsChkstk[] =
|
|||||||
|
|
||||||
|
|
||||||
/* This procedure is called to initialise the library check code */
|
/* This procedure is called to initialise the library check code */
|
||||||
void SetupLibCheck(void)
|
bool SetupLibCheck(void)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
|
||||||
uint16_t w, len;
|
uint16_t w, len;
|
||||||
int i;
|
int i;
|
||||||
IDcc *dcc = IDcc::get();
|
IDcc *dcc = IDcc::get();
|
||||||
@ -304,13 +307,12 @@ void SetupLibCheck(void)
|
|||||||
if ((g_file = fopen(qPrintable(fpath), "rb")) == nullptr)
|
if ((g_file = fopen(qPrintable(fpath), "rb")) == nullptr)
|
||||||
{
|
{
|
||||||
printf("Warning: cannot open signature file %s\n", qPrintable(fpath));
|
printf("Warning: cannot open signature file %s\n", qPrintable(fpath));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
readProtoFile();
|
readProtoFile();
|
||||||
|
|
||||||
|
|
||||||
prog.bSigs = false; /* False unless everything goes right */
|
|
||||||
/* Read the parameters */
|
/* Read the parameters */
|
||||||
grab(4, g_file);
|
grab(4, g_file);
|
||||||
if (memcmp("dccs", buf, 4) != 0)
|
if (memcmp("dccs", buf, 4) != 0)
|
||||||
@ -322,11 +324,10 @@ void SetupLibCheck(void)
|
|||||||
numVert = readFileShort(g_file);
|
numVert = readFileShort(g_file);
|
||||||
PatLen = readFileShort(g_file);
|
PatLen = readFileShort(g_file);
|
||||||
SymLen = readFileShort(g_file);
|
SymLen = readFileShort(g_file);
|
||||||
if ((PatLen != PATLEN) || (SymLen != SYMLEN))
|
if ((PatLen != PATLEN) or (SymLen != SYMLEN))
|
||||||
{
|
{
|
||||||
printf("Sorry! Compiled for sym and pattern lengths of %d and %d\n",
|
printf("Sorry! Compiled for sym and pattern lengths of %d and %d\n", SYMLEN, PATLEN);
|
||||||
SYMLEN, PATLEN);
|
return false;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
||||||
@ -353,7 +354,7 @@ void SetupLibCheck(void)
|
|||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
return false;
|
||||||
}
|
}
|
||||||
readFileSection(T1base, len, g_file);
|
readFileSection(T1base, len, g_file);
|
||||||
|
|
||||||
@ -361,13 +362,13 @@ void SetupLibCheck(void)
|
|||||||
if (memcmp("T2", buf, 2) != 0)
|
if (memcmp("T2", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'T2'\n");
|
printf("Expected 'T2'\n");
|
||||||
exit(3);
|
return false;
|
||||||
}
|
}
|
||||||
w = readFileShort(g_file);
|
w = readFileShort(g_file);
|
||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
return false;
|
||||||
}
|
}
|
||||||
readFileSection(T2base, len, g_file);
|
readFileSection(T2base, len, g_file);
|
||||||
|
|
||||||
@ -376,14 +377,14 @@ void SetupLibCheck(void)
|
|||||||
if (memcmp("gg", buf, 2) != 0)
|
if (memcmp("gg", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'gg'\n");
|
printf("Expected 'gg'\n");
|
||||||
exit(3);
|
return false;
|
||||||
}
|
}
|
||||||
len = (uint16_t)(numVert * sizeof(uint16_t));
|
len = (uint16_t)(numVert * sizeof(uint16_t));
|
||||||
w = readFileShort(g_file);
|
w = readFileShort(g_file);
|
||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
return false;
|
||||||
}
|
}
|
||||||
readFileSection(g, len, g_file);
|
readFileSection(g, len, g_file);
|
||||||
|
|
||||||
@ -394,19 +395,19 @@ void SetupLibCheck(void)
|
|||||||
if ( nullptr == ht)
|
if ( nullptr == ht)
|
||||||
{
|
{
|
||||||
printf("Could not allocate hash table\n");
|
printf("Could not allocate hash table\n");
|
||||||
exit(1);
|
return false;
|
||||||
}
|
}
|
||||||
grab(2, g_file);
|
grab(2, g_file);
|
||||||
if (memcmp("ht", buf, 2) != 0)
|
if (memcmp("ht", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'ht'\n");
|
printf("Expected 'ht'\n");
|
||||||
exit(3);
|
return false;
|
||||||
}
|
}
|
||||||
w = readFileShort(g_file);
|
w = readFileShort(g_file);
|
||||||
if (w != numKeys * (SymLen + PatLen + sizeof(uint16_t)))
|
if (w != numKeys * (SymLen + PatLen + sizeof(uint16_t)))
|
||||||
{
|
{
|
||||||
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
||||||
exit(6);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -415,11 +416,11 @@ void SetupLibCheck(void)
|
|||||||
if (fread(&ht[i], 1, SymLen + PatLen, g_file) != SymLen + PatLen)
|
if (fread(&ht[i], 1, SymLen + PatLen, g_file) != SymLen + PatLen)
|
||||||
{
|
{
|
||||||
printf("Could not read signature\n");
|
printf("Could not read signature\n");
|
||||||
exit(11);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(g_file);
|
fclose(g_file);
|
||||||
prog.bSigs = true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -466,17 +467,17 @@ bool LibCheck(Function & pProc)
|
|||||||
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
||||||
{
|
{
|
||||||
/* We have a match. Save the name, if not already set */
|
/* We have a match. Save the name, if not already set */
|
||||||
if (pProc.name.empty() ) /* Don't overwrite existing name */
|
if (pProc.name.isEmpty() ) /* Don't overwrite existing name */
|
||||||
{
|
{
|
||||||
/* Give proc the new name */
|
/* Give proc the new name */
|
||||||
pProc.name = ht[h].htSym;
|
pProc.name = ht[h].htSym;
|
||||||
}
|
}
|
||||||
/* But is it a real library function? */
|
/* But is it a real library function? */
|
||||||
i = NIL;
|
i = NIL;
|
||||||
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
|
if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL)
|
||||||
{
|
{
|
||||||
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
||||||
pProc.callingConv(CConv::C);
|
pProc.callingConv(CConv::eCdecl);
|
||||||
if (i != NIL)
|
if (i != NIL)
|
||||||
{
|
{
|
||||||
/* Allocate space for the arg struct, and copy the hlType to
|
/* Allocate space for the arg struct, and copy the hlType to
|
||||||
@ -502,12 +503,14 @@ bool LibCheck(Function & pProc)
|
|||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
pProc.liveOut.setReg(rAL);
|
pProc.liveOut.setReg(rAL);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_STR:
|
||||||
case TYPE_PTR:
|
case TYPE_PTR:
|
||||||
fprintf(stderr,"Warning assuming Large memory model\n");
|
fprintf(stderr,"Warning assuming Large memory model\n");
|
||||||
pProc.liveOut.setReg(rAX).addReg(rDS);
|
pProc.liveOut.setReg(rAX).addReg(rDS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Unknown retval type %d for %s in LibCheck\n",pProc.retVal.type,pProc.name.c_str());
|
qCritical() << QString("Unknown retval type %1 for %2 in LibCheck")
|
||||||
|
.arg(pProc.retVal.type).arg(pProc.name);
|
||||||
/*** other types are not considered yet ***/
|
/*** other types are not considered yet ***/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +534,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.args.numArgs = 0; /* With no args */
|
pProc.args.numArgs = 0; /* With no args */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool)((pProc.flg & PROC_ISLIB) != 0);
|
return pProc.isLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -545,8 +548,7 @@ void grab(int n, FILE *_file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
uint16_t readFileShort(FILE *f)
|
||||||
readFileShort(FILE *f)
|
|
||||||
{
|
{
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
|
|
||||||
@ -603,7 +605,7 @@ static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pa
|
|||||||
for (j=0; j < iPatLen; j++)
|
for (j=0; j < iPatLen; j++)
|
||||||
{
|
{
|
||||||
/* j is the index of the uint8_t being considered in the pattern. */
|
/* j is the index of the uint8_t being considered in the pattern. */
|
||||||
if ((*pSrc != pattern[j]) && (pattern[j] != WILD))
|
if ((*pSrc != pattern[j]) and (pattern[j] != WILD))
|
||||||
{
|
{
|
||||||
/* A definite mismatch */
|
/* A definite mismatch */
|
||||||
break; /* Break to outer loop */
|
break; /* Break to outer loop */
|
||||||
@ -828,16 +830,12 @@ void STATE::checkStartup()
|
|||||||
|
|
||||||
gotVendor:
|
gotVendor:
|
||||||
|
|
||||||
strcat(sSigName, "dcc");
|
sSigName = QString("dcc%1%2%3.sig")
|
||||||
temp[1] = '\0';
|
.arg(QChar(chVendor)) /* Add vendor */
|
||||||
temp[0] = chVendor;
|
.arg(QChar(chVersion)) /* Add version */
|
||||||
strcat(sSigName, temp); /* Add vendor */
|
.arg(QChar(chModel)) /* Add model */
|
||||||
temp[0] = chVersion;
|
;
|
||||||
strcat(sSigName, temp); /* Add version */
|
printf("Signature file: %s\n", qPrintable(sSigName));
|
||||||
temp[0] = chModel;
|
|
||||||
strcat(sSigName, temp); /* Add model */
|
|
||||||
strcat(sSigName, ".sig"); /* Add extension */
|
|
||||||
printf("Signature file: %s\n", sSigName);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <QTextStream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#define intSize 40
|
#define intSize 40
|
||||||
|
|
||||||
@ -148,7 +151,7 @@ static const char *intOthers[] = {
|
|||||||
|
|
||||||
/* Writes the description of the current interrupt. Appends it to the
|
/* Writes the description of the current interrupt. Appends it to the
|
||||||
* string s. */
|
* string s. */
|
||||||
void LLInst::writeIntComment (std::ostringstream &s)
|
void LLInst::writeIntComment (QTextStream &s)
|
||||||
{
|
{
|
||||||
uint32_t src_immed=src().getImm2();
|
uint32_t src_immed=src().getImm2();
|
||||||
s<<"\t/* ";
|
s<<"\t/* ";
|
||||||
@ -156,7 +159,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
{
|
{
|
||||||
s <<int21h[m_dst.off];
|
s <<int21h[m_dst.off];
|
||||||
}
|
}
|
||||||
else if (src_immed > 0x1F && src_immed < 0x2F)
|
else if (src_immed > 0x1F and src_immed < 0x2F)
|
||||||
{
|
{
|
||||||
s <<intOthers[src_immed - 0x20];
|
s <<intOthers[src_immed - 0x20];
|
||||||
}
|
}
|
||||||
@ -186,12 +189,15 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
//, &cCode.decl
|
//, &cCode.decl
|
||||||
void Function::writeProcComments()
|
void Function::writeProcComments()
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString dest_str;
|
||||||
writeProcComments(ostr);
|
{
|
||||||
cCode.appendDecl(ostr.str());
|
QTextStream ostr(&dest_str);
|
||||||
|
writeProcComments(ostr);
|
||||||
|
}
|
||||||
|
cCode.appendDecl(dest_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::writeProcComments(std::ostream &ostr)
|
void Function::writeProcComments(QTextStream &ostr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
ID *id; /* Pointer to register argument identifier */
|
ID *id; /* Pointer to register argument identifier */
|
||||||
|
|||||||
306
src/control.cpp
306
src/control.cpp
@ -2,33 +2,34 @@
|
|||||||
* Description : Performs control flow analysis on the CFG
|
* Description : Performs control flow analysis on the CFG
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <boost/range/algorithm.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <list>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
//typedef struct list {
|
#include <boost/range/algorithm.hpp>
|
||||||
// int nodeIdx;
|
#include <cassert>
|
||||||
// struct list *next;
|
#include <cstdio>
|
||||||
//} nodeList;
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace {
|
||||||
typedef std::list<int> nodeList; /* dfsLast index to the node */
|
typedef std::list<int> nodeList; /* dfsLast index to the node */
|
||||||
|
|
||||||
#define ancestor(a,b) ((a->dfsLastNum < b->dfsLastNum) && (a->dfsFirstNum < b->dfsFirstNum))
|
|
||||||
/* there is a path on the DFST from a to b if the a was first visited in a
|
/* there is a path on the DFST from a to b if the a was first visited in a
|
||||||
* dfs, and a was later visited than b when doing the last visit of each
|
* dfs, and a was later visited than b when doing the last visit of each
|
||||||
* node. */
|
* node. */
|
||||||
|
bool inline ancestor(BB *a,BB *b)
|
||||||
|
{
|
||||||
|
return (a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks if the edge (p,s) is a back edge. If node s was visited first
|
/** Checks if the edge (p,s) is a back edge. If node s was visited first
|
||||||
* during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
|
* during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
|
||||||
* then it is a backedge.
|
* then it is a backedge.
|
||||||
* Also incrementes the number of backedges entries to the header node. */
|
* Also incrementes the number of backedges entries to the header node. */
|
||||||
static bool isBackEdge (BB * p,BB * s)
|
bool isBackEdge (BB * p,BB * s)
|
||||||
{
|
{
|
||||||
if (p->dfsFirstNum >= s->dfsFirstNum)
|
if (p->dfsFirstNum >= s->dfsFirstNum)
|
||||||
{
|
{
|
||||||
@ -39,16 +40,16 @@ static bool isBackEdge (BB * p,BB * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finds the common dominator of the current immediate dominator
|
/** Finds the common dominator of the current immediate dominator
|
||||||
* currImmDom and its predecessor's immediate dominator predImmDom */
|
* currImmDom and its predecessor's immediate dominator predImmDom */
|
||||||
static int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
||||||
{
|
{
|
||||||
if (currImmDom == NO_DOM)
|
if (currImmDom == NO_DOM)
|
||||||
return (predImmDom);
|
return (predImmDom);
|
||||||
if (predImmDom == NO_DOM) /* predecessor is the root */
|
if (predImmDom == NO_DOM) /* predecessor is the root */
|
||||||
return (currImmDom);
|
return (currImmDom);
|
||||||
|
|
||||||
while ((currImmDom != NO_DOM) && (predImmDom != NO_DOM) &&
|
while ((currImmDom != NO_DOM) and (predImmDom != NO_DOM) and
|
||||||
(currImmDom != predImmDom))
|
(currImmDom != predImmDom))
|
||||||
{
|
{
|
||||||
if (currImmDom < predImmDom)
|
if (currImmDom < predImmDom)
|
||||||
@ -58,70 +59,47 @@ static int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
|||||||
}
|
}
|
||||||
return (currImmDom);
|
return (currImmDom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finds the immediate dominator of each node in the graph pProc->cfg.
|
|
||||||
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
|
|
||||||
* immediate dominators only.
|
|
||||||
* Note: graph should be reducible */
|
|
||||||
void Function::findImmedDom ()
|
|
||||||
{
|
|
||||||
BB * currNode;
|
|
||||||
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
|
|
||||||
{
|
|
||||||
currNode = m_dfsLast[currIdx];
|
|
||||||
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
|
||||||
continue;
|
|
||||||
for (BB * inedge : currNode->inEdges)
|
|
||||||
{
|
|
||||||
size_t predIdx = inedge->dfsLastNum;
|
|
||||||
if (predIdx < currIdx)
|
|
||||||
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Inserts the node n to the list l. */
|
|
||||||
static void insertList (nodeList &l, int n)
|
|
||||||
{
|
|
||||||
l.push_back(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether or not the node n (dfsLast numbering of a basic block)
|
/* Returns whether or not the node n (dfsLast numbering of a basic block)
|
||||||
* is on the list l. */
|
* is on the list l. */
|
||||||
static bool inList (const nodeList &l, int n)
|
bool inList (const nodeList &l, int n)
|
||||||
{
|
{
|
||||||
return std::find(l.begin(),l.end(),n)!=l.end();
|
return std::find(l.begin(),l.end(),n)!=l.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Frees space allocated by the list l. */
|
|
||||||
static void freeList (nodeList &l)
|
|
||||||
{
|
|
||||||
l.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether the node n belongs to the queue list q. */
|
/* Returns whether the node n belongs to the queue list q. */
|
||||||
static bool inInt(BB * n, queue &q)
|
bool inInt(BB * n, queue &q)
|
||||||
{
|
{
|
||||||
return std::find(q.begin(),q.end(),n)!=q.end();
|
return std::find(q.begin(),q.end(),n)!=q.end();
|
||||||
}
|
}
|
||||||
|
/** Recursive procedure to find nodes that belong to the interval (ie. nodes
|
||||||
|
* from G1). */
|
||||||
|
void findNodesInInt (queue &intNodes, int level, interval *Ii)
|
||||||
|
{
|
||||||
|
if (level == 1)
|
||||||
|
{
|
||||||
|
for(BB *en : Ii->nodes)
|
||||||
|
{
|
||||||
|
appendQueue(intNodes,en);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(BB *en : Ii->nodes)
|
||||||
|
{
|
||||||
|
findNodesInInt(intNodes,level-1,en->correspInt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Finds the follow of the endless loop headed at node head (if any).
|
/* Finds the follow of the endless loop headed at node head (if any).
|
||||||
* The follow node is the closest node to the loop. */
|
* The follow node is the closest node to the loop. */
|
||||||
static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
||||||
{
|
{
|
||||||
head->loopFollow = MAX;
|
head->loopFollow = MAX;
|
||||||
for( int loop_node : loopNodes)
|
for( int loop_node : loopNodes)
|
||||||
{
|
{
|
||||||
for (TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
|
for (const TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
|
||||||
{
|
{
|
||||||
int succ = typeaddr.BBptr->dfsLastNum;
|
int succ = typeaddr.BBptr->dfsLastNum;
|
||||||
if ((! inList(loopNodes, succ)) && (succ < head->loopFollow))
|
if ((not inList(loopNodes, succ)) and (succ < head->loopFollow))
|
||||||
head->loopFollow = succ;
|
head->loopFollow = succ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +109,7 @@ static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
|||||||
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
||||||
/* Flags nodes that belong to the loop determined by (latchNode, head) and
|
/* Flags nodes that belong to the loop determined by (latchNode, head) and
|
||||||
* determines the type of loop. */
|
* determines the type of loop. */
|
||||||
static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
|
void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
|
||||||
{
|
{
|
||||||
int i, headDfsNum, intNodeType;
|
int i, headDfsNum, intNodeType;
|
||||||
nodeList loopNodes;
|
nodeList loopNodes;
|
||||||
@ -142,30 +120,30 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
/* Flag nodes in loop headed by head (except header node) */
|
/* Flag nodes in loop headed by head (except header node) */
|
||||||
headDfsNum = head->dfsLastNum;
|
headDfsNum = head->dfsLastNum;
|
||||||
head->loopHead = headDfsNum;
|
head->loopHead = headDfsNum;
|
||||||
insertList (loopNodes, headDfsNum);
|
loopNodes.push_back(headDfsNum);
|
||||||
for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
|
for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
|
||||||
{
|
{
|
||||||
if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */
|
if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
immedDom = pProc->m_dfsLast[i]->immedDom;
|
immedDom = pProc->m_dfsLast[i]->immedDom;
|
||||||
if (inList (loopNodes, immedDom) && inInt(pProc->m_dfsLast[i], intNodes))
|
if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes))
|
||||||
{
|
{
|
||||||
insertList (loopNodes, i);
|
loopNodes.push_back(i);
|
||||||
if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
|
if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
|
||||||
pProc->m_dfsLast[i]->loopHead = headDfsNum;
|
pProc->m_dfsLast[i]->loopHead = headDfsNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
latchNode->loopHead = headDfsNum;
|
latchNode->loopHead = headDfsNum;
|
||||||
if (latchNode != head)
|
if (latchNode != head)
|
||||||
insertList (loopNodes, latchNode->dfsLastNum);
|
loopNodes.push_back(latchNode->dfsLastNum);
|
||||||
|
|
||||||
/* Determine type of loop and follow node */
|
/* Determine type of loop and follow node */
|
||||||
intNodeType = head->nodeType;
|
intNodeType = head->nodeType;
|
||||||
if (latchNode->nodeType == TWO_BRANCH)
|
if (latchNode->nodeType == TWO_BRANCH)
|
||||||
if ((intNodeType == TWO_BRANCH) || (latchNode == head))
|
if ((intNodeType == TWO_BRANCH) or (latchNode == head))
|
||||||
if ((latchNode == head) ||
|
if ((latchNode == head) or
|
||||||
(inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
|
(inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) and
|
||||||
inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
|
inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
|
||||||
{
|
{
|
||||||
head->loopType = eNodeHeaderType::REPEAT_TYPE;
|
head->loopType = eNodeHeaderType::REPEAT_TYPE;
|
||||||
@ -219,7 +197,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if couldn't find it, then it is a strangely formed
|
/* Check if couldn't find it, then it is a strangely formed
|
||||||
* loop, so it is safer to consider it an endless loop */
|
* loop, so it is safer to consider it an endless loop */
|
||||||
if (pbb->dfsLastNum <= head->dfsLastNum)
|
if (pbb->dfsLastNum <= head->dfsLastNum)
|
||||||
{
|
{
|
||||||
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
||||||
@ -238,32 +216,79 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
findEndlessFollow (pProc, loopNodes, head);
|
findEndlessFollow (pProc, loopNodes, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
freeList(loopNodes);
|
loopNodes.clear();
|
||||||
}
|
}
|
||||||
|
/** \returns whether the BB indexed by s is a successor of the BB indexed by \arg h
|
||||||
//static void findNodesInInt (queue **intNodes, int level, interval *Ii)
|
* \note that h is a case node.
|
||||||
/* Recursive procedure to find nodes that belong to the interval (ie. nodes
|
*/
|
||||||
* from G1). */
|
bool successor (int s, int h, Function * pProc)
|
||||||
static void findNodesInInt (queue &intNodes, int level, interval *Ii)
|
|
||||||
{
|
{
|
||||||
if (level == 1)
|
BB * header = pProc->m_dfsLast[h];
|
||||||
|
auto iter = std::find_if(header->edges.begin(),
|
||||||
|
header->edges.end(),
|
||||||
|
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
||||||
|
return iter!=header->edges.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Recursive procedure to tag nodes that belong to the case described by
|
||||||
|
* the list l, head and tail (dfsLast index to first and exit node of the
|
||||||
|
* case). */
|
||||||
|
void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
||||||
|
{
|
||||||
|
int current; /* index to current node */
|
||||||
|
|
||||||
|
pBB->traversed = DFS_CASE;
|
||||||
|
current = pBB->dfsLastNum;
|
||||||
|
if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom)))
|
||||||
{
|
{
|
||||||
for(BB *en : Ii->nodes)
|
l.push_back(current);
|
||||||
|
pBB->caseHead = head;
|
||||||
|
for(TYPEADR_TYPE &edge : pBB->edges)
|
||||||
{
|
{
|
||||||
appendQueue(intNodes,en);
|
if (edge.BBptr->traversed != DFS_CASE)
|
||||||
|
tagNodesInCase (edge.BBptr, l, head, tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
/** Flags all nodes in the list l as having follow node f, and deletes all
|
||||||
|
* nodes from the list. */
|
||||||
|
void flagNodes (nodeList &l, int f, Function * pProc)
|
||||||
|
{
|
||||||
|
for(int idx : l)
|
||||||
{
|
{
|
||||||
for(BB *en : Ii->nodes)
|
pProc->m_dfsLast[idx]->ifFollow = f;
|
||||||
|
}
|
||||||
|
l.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end of anonymouse namespace
|
||||||
|
|
||||||
|
/** Finds the immediate dominator of each node in the graph pProc->cfg.
|
||||||
|
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
|
||||||
|
* immediate dominators only.
|
||||||
|
* Note: graph should be reducible */
|
||||||
|
void Function::findImmedDom ()
|
||||||
|
{
|
||||||
|
BB * currNode;
|
||||||
|
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
|
||||||
|
{
|
||||||
|
currNode = m_dfsLast[currIdx];
|
||||||
|
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
||||||
|
continue;
|
||||||
|
for (BB * inedge : currNode->inEdges)
|
||||||
{
|
{
|
||||||
findNodesInInt(intNodes,level-1,en->correspInt);
|
size_t predIdx = inedge->dfsLastNum;
|
||||||
|
if (predIdx < currIdx)
|
||||||
|
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Algorithm for structuring loops */
|
/** Algorithm for structuring loops */
|
||||||
void Function::structLoops(derSeq *derivedG)
|
void Function::structLoops(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
interval *Ii;
|
interval *Ii;
|
||||||
@ -279,8 +304,7 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
for(auto & elem : *derivedG)
|
for(auto & elem : *derivedG)
|
||||||
{
|
{
|
||||||
level++;
|
level++;
|
||||||
Ii = elem.Ii;
|
for (Ii = elem.Ii; Ii!=nullptr; Ii = Ii->next) /* for all intervals Ii of Gi */
|
||||||
while (Ii) /* for all intervals Ii of Gi */
|
|
||||||
{
|
{
|
||||||
latchNode = nullptr;
|
latchNode = nullptr;
|
||||||
intNodes.clear();
|
intNodes.clear();
|
||||||
@ -299,9 +323,9 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
for (size_t i = 0; i < intHead->inEdges.size(); i++)
|
for (size_t i = 0; i < intHead->inEdges.size(); i++)
|
||||||
{
|
{
|
||||||
pred = intHead->inEdges[i];
|
pred = intHead->inEdges[i];
|
||||||
if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
|
if (inInt(pred, intNodes) and isBackEdge(pred, intHead))
|
||||||
{
|
{
|
||||||
if (! latchNode)
|
if (nullptr == latchNode)
|
||||||
latchNode = pred;
|
latchNode = pred;
|
||||||
else if (pred->dfsLastNum > latchNode->dfsLastNum)
|
else if (pred->dfsLastNum > latchNode->dfsLastNum)
|
||||||
latchNode = pred;
|
latchNode = pred;
|
||||||
@ -314,7 +338,7 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
/* Check latching node is at the same nesting level of case
|
/* Check latching node is at the same nesting level of case
|
||||||
* statements (if any) and that the node doesn't belong to
|
* statements (if any) and that the node doesn't belong to
|
||||||
* another loop. */
|
* another loop. */
|
||||||
if ((latchNode->caseHead == intHead->caseHead) &&
|
if ((latchNode->caseHead == intHead->caseHead) and
|
||||||
(latchNode->loopHead == NO_NODE))
|
(latchNode->loopHead == NO_NODE))
|
||||||
{
|
{
|
||||||
intHead->latchNode = latchNode->dfsLastNum;
|
intHead->latchNode = latchNode->dfsLastNum;
|
||||||
@ -322,45 +346,6 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
latchNode->flg |= IS_LATCH_NODE;
|
latchNode->flg |= IS_LATCH_NODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next interval */
|
|
||||||
Ii = Ii->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next derived sequence */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether the BB indexed by s is a successor of the BB indexed by
|
|
||||||
* h. Note that h is a case node. */
|
|
||||||
static bool successor (int s, int h, Function * pProc)
|
|
||||||
{
|
|
||||||
BB * header = pProc->m_dfsLast[h];
|
|
||||||
auto iter = std::find_if(header->edges.begin(),
|
|
||||||
header->edges.end(),
|
|
||||||
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
|
||||||
return iter!=header->edges.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Recursive procedure to tag nodes that belong to the case described by
|
|
||||||
* the list l, head and tail (dfsLast index to first and exit node of the
|
|
||||||
* case). */
|
|
||||||
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
|
||||||
{
|
|
||||||
int current; /* index to current node */
|
|
||||||
|
|
||||||
pBB->traversed = DFS_CASE;
|
|
||||||
current = pBB->dfsLastNum;
|
|
||||||
if ((current != tail) && (pBB->nodeType != MULTI_BRANCH) && (inList (l, pBB->immedDom)))
|
|
||||||
{
|
|
||||||
insertList (l, current);
|
|
||||||
pBB->caseHead = head;
|
|
||||||
for(TYPEADR_TYPE &edge : pBB->edges)
|
|
||||||
{
|
|
||||||
if (edge.BBptr->traversed != DFS_CASE)
|
|
||||||
tagNodesInCase (edge.BBptr, l, head, tail);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,12 +370,10 @@ void Function::structCases()
|
|||||||
* the current header node, and is not a successor. */
|
* the current header node, and is not a successor. */
|
||||||
for (size_t j = i + 2; j < numBBs; j++)
|
for (size_t j = i + 2; j < numBBs; j++)
|
||||||
{
|
{
|
||||||
if ((!successor(j, i, this)) && (m_dfsLast[j]->immedDom == i))
|
if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i))
|
||||||
{
|
{
|
||||||
if (exitNode == NO_NODE)
|
if (exitNode == NO_NODE)
|
||||||
{
|
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
|
||||||
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
}
|
||||||
@ -399,7 +382,7 @@ void Function::structCases()
|
|||||||
|
|
||||||
/* Tag nodes that belong to the case by recording the
|
/* Tag nodes that belong to the case by recording the
|
||||||
* header field with caseHeader. */
|
* header field with caseHeader. */
|
||||||
insertList (caseNodes, i);
|
caseNodes.push_back(i);
|
||||||
m_dfsLast[i]->caseHead = i;
|
m_dfsLast[i]->caseHead = i;
|
||||||
for(TYPEADR_TYPE &pb : caseHeader->edges)
|
for(TYPEADR_TYPE &pb : caseHeader->edges)
|
||||||
{
|
{
|
||||||
@ -412,20 +395,6 @@ void Function::structCases()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Flags all nodes in the list l as having follow node f, and deletes all
|
|
||||||
* nodes from the list. */
|
|
||||||
static void flagNodes (nodeList &l, int f, Function * pProc)
|
|
||||||
{
|
|
||||||
nodeList::iterator p;
|
|
||||||
for(int idx : l)
|
|
||||||
{
|
|
||||||
pProc->m_dfsLast[idx]->ifFollow = f;
|
|
||||||
}
|
|
||||||
l.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Structures if statements */
|
/* Structures if statements */
|
||||||
void Function::structIfs ()
|
void Function::structIfs ()
|
||||||
{
|
{
|
||||||
@ -437,7 +406,7 @@ void Function::structIfs ()
|
|||||||
unresolved /* List of unresolved if nodes */
|
unresolved /* List of unresolved if nodes */
|
||||||
;
|
;
|
||||||
BB * currNode, /* Pointer to current node */
|
BB * currNode, /* Pointer to current node */
|
||||||
* pbb;
|
* pbb;
|
||||||
|
|
||||||
/* Linear scan of nodes in reverse dfsLast order */
|
/* Linear scan of nodes in reverse dfsLast order */
|
||||||
for (curr = numBBs - 1; curr >= 0; curr--)
|
for (curr = numBBs - 1; curr >= 0; curr--)
|
||||||
@ -446,7 +415,7 @@ void Function::structIfs ()
|
|||||||
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((currNode->nodeType == TWO_BRANCH) && (!currNode->back().ll()->testFlags(JX_LOOP)))
|
if ((currNode->nodeType == TWO_BRANCH) and (not currNode->back().ll()->testFlags(JX_LOOP)))
|
||||||
{
|
{
|
||||||
followInEdges = 0;
|
followInEdges = 0;
|
||||||
follow = 0;
|
follow = 0;
|
||||||
@ -456,7 +425,7 @@ void Function::structIfs ()
|
|||||||
{
|
{
|
||||||
if (m_dfsLast[desc]->immedDom == curr)
|
if (m_dfsLast[desc]->immedDom == curr)
|
||||||
{
|
{
|
||||||
insertList (domDesc, desc);
|
domDesc.push_back(desc);
|
||||||
pbb = m_dfsLast[desc];
|
pbb = m_dfsLast[desc];
|
||||||
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
||||||
{
|
{
|
||||||
@ -468,16 +437,16 @@ void Function::structIfs ()
|
|||||||
|
|
||||||
/* Determine follow according to number of descendants
|
/* Determine follow according to number of descendants
|
||||||
* immediately dominated by this node */
|
* immediately dominated by this node */
|
||||||
if ((follow != 0) && (followInEdges > 1))
|
if ((follow != 0) and (followInEdges > 1))
|
||||||
{
|
{
|
||||||
currNode->ifFollow = follow;
|
currNode->ifFollow = follow;
|
||||||
if (!unresolved.empty())
|
if (not unresolved.empty())
|
||||||
flagNodes (unresolved, follow, this);
|
flagNodes (unresolved, follow, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
insertList (unresolved, curr);
|
unresolved.push_back(curr);
|
||||||
}
|
}
|
||||||
freeList (domDesc);
|
domDesc.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
|
bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
|
||||||
@ -617,33 +586,33 @@ void Function::compoundCond()
|
|||||||
|
|
||||||
change = true; //assume change
|
change = true; //assume change
|
||||||
|
|
||||||
/* Check (X || Y) case */
|
/* Check (X or Y) case */
|
||||||
if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) &&
|
if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and
|
||||||
(thenBB->inEdges.size() == 1) && (thenBB->edges[ELSE].BBptr == elseBB))
|
(thenBB->inEdges.size() == 1) and (thenBB->edges[ELSE].BBptr == elseBB))
|
||||||
{
|
{
|
||||||
if(Case_X_or_Y(pbb, thenBB, elseBB))
|
if(Case_X_or_Y(pbb, thenBB, elseBB))
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (!X && Y) case */
|
/* Check (not X and Y) case */
|
||||||
else if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) &&
|
else if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and
|
||||||
(thenBB->inEdges.size() == 1) && (thenBB->edges[THEN].BBptr == elseBB))
|
(thenBB->inEdges.size() == 1) and (thenBB->edges[THEN].BBptr == elseBB))
|
||||||
{
|
{
|
||||||
if(Case_notX_and_Y(pbb, thenBB, elseBB))
|
if(Case_notX_and_Y(pbb, thenBB, elseBB))
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (X && Y) case */
|
/* Check (X and Y) case */
|
||||||
else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) &&
|
else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and
|
||||||
(elseBB->inEdges.size()==1) && (elseBB->edges[THEN].BBptr == thenBB))
|
(elseBB->inEdges.size()==1) and (elseBB->edges[THEN].BBptr == thenBB))
|
||||||
{
|
{
|
||||||
if(Case_X_and_Y(pbb, thenBB, elseBB ))
|
if(Case_X_and_Y(pbb, thenBB, elseBB ))
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (!X || Y) case */
|
/* Check (not X or Y) case */
|
||||||
else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) &&
|
else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and
|
||||||
(elseBB->inEdges.size() == 1) && (elseBB->edges[ELSE].BBptr == thenBB))
|
(elseBB->inEdges.size() == 1) and (elseBB->edges[ELSE].BBptr == thenBB))
|
||||||
{
|
{
|
||||||
if(Case_notX_or_Y(pbb, thenBB, elseBB ))
|
if(Case_notX_or_Y(pbb, thenBB, elseBB ))
|
||||||
--i;
|
--i;
|
||||||
@ -654,8 +623,7 @@ void Function::compoundCond()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Structuring algorithm to find the structures of the graph pProc->cfg */
|
||||||
/* Structuring algorithm to find the structures of the graph pProc->cfg */
|
|
||||||
void Function::structure(derSeq *derivedG)
|
void Function::structure(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
/* Find immediate dominators of the graph */
|
/* Find immediate dominators of the graph */
|
||||||
|
|||||||
352
src/dataflow.cpp
352
src/dataflow.cpp
@ -4,20 +4,27 @@
|
|||||||
* Purpose: Data flow analysis module.
|
* Purpose: Data flow analysis module.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
#include <boost/range/algorithm.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <boost/range.hpp>
|
|
||||||
#include <boost/range/adaptors.hpp>
|
|
||||||
#include <boost/range/algorithm.hpp>
|
|
||||||
#include <boost/assign.hpp>
|
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "project.h"
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
|
using namespace std;
|
||||||
|
namespace
|
||||||
|
{
|
||||||
struct ExpStack
|
struct ExpStack
|
||||||
{
|
{
|
||||||
Function *func;
|
Function *func;
|
||||||
@ -28,7 +35,7 @@ struct ExpStack
|
|||||||
void push(Expr *);
|
void push(Expr *);
|
||||||
Expr * pop();
|
Expr * pop();
|
||||||
Expr * top() const {
|
Expr * top() const {
|
||||||
if(!expStk.empty())
|
if(not expStk.empty())
|
||||||
return expStk.back();
|
return expStk.back();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -45,6 +52,57 @@ struct ExpStack
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
ExpStack g_exp_stk;
|
||||||
|
/** Returns a string with the source operand of Icode */
|
||||||
|
Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
||||||
|
{
|
||||||
|
const LLOperand * src_op = ll_insn.get(SRC);
|
||||||
|
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
|
||||||
|
{
|
||||||
|
//if (ll_insn.testFlags(B))
|
||||||
|
return new Constant(src_op->getImm2(), src_op->byteWidth());
|
||||||
|
}
|
||||||
|
// otherwise
|
||||||
|
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the destination operand */
|
||||||
|
Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
||||||
|
{
|
||||||
|
Expr *n;
|
||||||
|
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
|
||||||
|
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
|
||||||
|
void forwardSubsLong (int longIdx, Expr *_exp, ICODE &picode, ICODE &ticode, int *numHlIcodes)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
if (_exp == nullptr) /* In case expression popped is NULL */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Insert on rhs of ticode, if possible */
|
||||||
|
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_rhs, longIdx);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
picode.invalidate();
|
||||||
|
(*numHlIcodes)--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to insert it on lhs of ticode*/
|
||||||
|
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_lhs, longIdx);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
picode.invalidate();
|
||||||
|
(*numHlIcodes)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of anonymous namespace
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Expression stack functions
|
* Expression stack functions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@ -88,8 +146,6 @@ bool ExpStack::empty()
|
|||||||
return expStk.empty();
|
return expStk.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
ExpStack g_exp_stk;
|
|
||||||
|
|
||||||
/* Returns the index of the local variable or parameter at offset off, if it
|
/* Returns the index of the local variable or parameter at offset off, if it
|
||||||
* is in the stack frame provided. */
|
* is in the stack frame provided. */
|
||||||
@ -100,28 +156,6 @@ size_t STKFRAME::getLocVar(int off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns a string with the source operand of Icode */
|
|
||||||
static Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
|
||||||
{
|
|
||||||
const LLOperand * src_op = ll_insn.get(SRC);
|
|
||||||
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
|
|
||||||
{
|
|
||||||
//if (ll_insn.testFlags(B))
|
|
||||||
return new Constant(src_op->getImm2(), src_op->byteWidth());
|
|
||||||
}
|
|
||||||
// otherwise
|
|
||||||
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns the destination operand */
|
|
||||||
static Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
|
||||||
{
|
|
||||||
Expr *n;
|
|
||||||
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
|
|
||||||
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
|
|
||||||
return (n);
|
|
||||||
}
|
|
||||||
/* Eliminates all condition codes and generates new hlIcode instructions */
|
/* Eliminates all condition codes and generates new hlIcode instructions */
|
||||||
void Function::elimCondCodes ()
|
void Function::elimCondCodes ()
|
||||||
{
|
{
|
||||||
@ -145,7 +179,7 @@ void Function::elimCondCodes ()
|
|||||||
{
|
{
|
||||||
llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
|
llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
|
||||||
use = useAt->ll()->flagDU.u;
|
use = useAt->ll()->flagDU.u;
|
||||||
if ((useAt->type != LOW_LEVEL) || ( ! useAt->valid() ) || ( 0 == use ))
|
if ((useAt->type != LOW_LEVEL_ICODE) or ( not useAt->valid() ) or ( 0 == use ))
|
||||||
continue;
|
continue;
|
||||||
/* Find definition within the same basic block */
|
/* Find definition within the same basic block */
|
||||||
defAt=useAt;
|
defAt=useAt;
|
||||||
@ -158,7 +192,7 @@ void Function::elimCondCodes ()
|
|||||||
continue;
|
continue;
|
||||||
notSup = false;
|
notSup = false;
|
||||||
LLOperand *dest_ll = defIcode.ll()->get(DST);
|
LLOperand *dest_ll = defIcode.ll()->get(DST);
|
||||||
if ((useAtOp >= iJB) && (useAtOp <= iJNS))
|
if ((useAtOp >= iJB) and (useAtOp <= iJNS))
|
||||||
{
|
{
|
||||||
iICODE befDefAt = (++riICODE(defAt)).base();
|
iICODE befDefAt = (++riICODE(defAt)).base();
|
||||||
switch (defIcode.ll()->getOpcode())
|
switch (defIcode.ll()->getOpcode())
|
||||||
@ -194,7 +228,7 @@ void Function::elimCondCodes ()
|
|||||||
reportError (JX_NOT_DEF, defIcode.ll()->getOpcode());
|
reportError (JX_NOT_DEF, defIcode.ll()->getOpcode());
|
||||||
flg |= PROC_ASM; /* generate asm */
|
flg |= PROC_ASM; /* generate asm */
|
||||||
}
|
}
|
||||||
if (! notSup)
|
if (not notSup)
|
||||||
{
|
{
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
assert(rhs);
|
assert(rhs);
|
||||||
@ -219,14 +253,14 @@ void Function::elimCondCodes ()
|
|||||||
{
|
{
|
||||||
ICODE &a(*defAt);
|
ICODE &a(*defAt);
|
||||||
ICODE &b(*useAt);
|
ICODE &b(*useAt);
|
||||||
reportError (NOT_DEF_USE,a.ll()->getOpcode(),b.ll()->getOpcode());
|
reportError (NOT_DEF_USE,a.ll()->label,a.ll()->getOpcode(),b.ll()->getOpcode());
|
||||||
flg |= PROC_ASM; /* generate asm */
|
flg |= PROC_ASM; /* generate asm */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for extended basic block */
|
/* Check for extended basic block */
|
||||||
if ((pBB->size() == 1) &&(useAtOp >= iJB) && (useAtOp <= iJNS))
|
if ((pBB->size() == 1) and(useAtOp >= iJB) and (useAtOp <= iJNS))
|
||||||
{
|
{
|
||||||
ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */
|
ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */
|
||||||
if (_prev.hl()->opcode == HLI_JCOND)
|
if (_prev.hl()->opcode == HLI_JCOND)
|
||||||
@ -268,7 +302,7 @@ void Function::genLiveKtes ()
|
|||||||
continue; // skip invalid BBs
|
continue; // skip invalid BBs
|
||||||
for(ICODE &insn : *pbb)
|
for(ICODE &insn : *pbb)
|
||||||
{
|
{
|
||||||
if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
|
if ((insn.type == HIGH_LEVEL_ICODE) and ( insn.valid() ))
|
||||||
{
|
{
|
||||||
liveUse |= (insn.du.use - def);
|
liveUse |= (insn.du.use - def);
|
||||||
def |= insn.du.def;
|
def |= insn.du.def;
|
||||||
@ -342,7 +376,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
pcallee = ticode.hl()->call.proc;
|
pcallee = ticode.hl()->call.proc;
|
||||||
|
|
||||||
/* user/runtime routine */
|
/* user/runtime routine */
|
||||||
if (! (pcallee->flg & PROC_ISLIB))
|
if (not (pcallee->flg & PROC_ISLIB))
|
||||||
{
|
{
|
||||||
if (pcallee->liveAnal == false) /* hasn't been processed */
|
if (pcallee->liveAnal == false) /* hasn't been processed */
|
||||||
pcallee->dataFlow (pbb->liveOut);
|
pcallee->dataFlow (pbb->liveOut);
|
||||||
@ -350,7 +384,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
}
|
}
|
||||||
else /* library routine */
|
else /* library routine */
|
||||||
{
|
{
|
||||||
if ( (pcallee->flg & PROC_IS_FUNC) && /* returns a value */
|
if ( (pcallee->flg & PROC_IS_FUNC) and /* returns a value */
|
||||||
(pcallee->liveOut & pbb->edges[0].BBptr->liveIn).any()
|
(pcallee->liveOut & pbb->edges[0].BBptr->liveIn).any()
|
||||||
)
|
)
|
||||||
pbb->liveOut = pcallee->liveOut;
|
pbb->liveOut = pcallee->liveOut;
|
||||||
@ -358,10 +392,11 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
pbb->liveOut.reset();
|
pbb->liveOut.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((! (pcallee->flg & PROC_ISLIB)) || ( pbb->liveOut.any() ))
|
if ((not (pcallee->flg & PROC_ISLIB)) or ( pbb->liveOut.any() ))
|
||||||
{
|
{
|
||||||
switch (pcallee->retVal.type) {
|
switch (pcallee->retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN:
|
||||||
|
case TYPE_LONG_UNSIGN:
|
||||||
ticode.du1.setDef(rAX).addDef(rDX);
|
ticode.du1.setDef(rAX).addDef(rDX);
|
||||||
//TODO: use Calling convention to properly set regs here
|
//TODO: use Calling convention to properly set regs here
|
||||||
break;
|
break;
|
||||||
@ -385,7 +420,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def));
|
pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def));
|
||||||
|
|
||||||
/* Check if live sets have been modified */
|
/* Check if live sets have been modified */
|
||||||
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
|
if ((prevLiveIn != pbb->liveIn) or (prevLiveOut != pbb->liveOut))
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,9 +447,9 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
* register */
|
* register */
|
||||||
bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
||||||
{
|
{
|
||||||
if ((regi == rDI) && (flg & DI_REGVAR))
|
if ((regi == rDI) and (flg & DI_REGVAR))
|
||||||
return true;
|
return true;
|
||||||
if ((regi == rSI) && (flg & SI_REGVAR))
|
if ((regi == rSI) and (flg & SI_REGVAR))
|
||||||
return true;
|
return true;
|
||||||
if (distance(start_at,end())>1) /* several instructions */
|
if (distance(start_at,end())>1) /* several instructions */
|
||||||
{
|
{
|
||||||
@ -457,7 +492,7 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
|||||||
* on optimized code. */
|
* on optimized code. */
|
||||||
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
||||||
{
|
{
|
||||||
if (!((picode.hl()->opcode == HLI_CALL) && (picode.hl()->call.proc->flg & PROC_IS_FUNC)))
|
if (not ((picode.hl()->opcode == HLI_CALL) and (picode.hl()->call.proc->flg & PROC_IS_FUNC)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BB *tbb = this->edges[0].BBptr;
|
BB *tbb = this->edges[0].BBptr;
|
||||||
@ -475,7 +510,7 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
|||||||
/* if not used in this basic block, check if the
|
/* if not used in this basic block, check if the
|
||||||
* register is live out, if so, make it the last
|
* register is live out, if so, make it the last
|
||||||
* definition of this register */
|
* definition of this register */
|
||||||
if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi))
|
if ( picode.du1.used(defRegIdx) and tbb->liveOut.testRegAndSubregs(regi))
|
||||||
picode.du.lastDefRegi.addReg(regi);
|
picode.du.lastDefRegi.addReg(regi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,11 +523,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
|||||||
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
||||||
{
|
{
|
||||||
if (picode->valid() and not picode->du1.used(defRegIdx) and
|
if (picode->valid() and not picode->du1.used(defRegIdx) and
|
||||||
(not picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
(not picode->du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
(not ((picode->hl()->opcode == HLI_CALL) &&
|
(not ((picode->hl()->opcode == HLI_CALL) and
|
||||||
(picode->hl()->call.proc->flg & PROC_ISLIB))))
|
(picode->hl()->call.proc->flg & PROC_ISLIB))))
|
||||||
{
|
{
|
||||||
if (! (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */
|
if (not (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */
|
||||||
{
|
{
|
||||||
bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
|
bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
|
||||||
if (res == true)
|
if (res == true)
|
||||||
@ -540,7 +575,7 @@ void BB::genDU1()
|
|||||||
defRegIdx++;
|
defRegIdx++;
|
||||||
|
|
||||||
/* Check if all defined registers have been processed */
|
/* Check if all defined registers have been processed */
|
||||||
if ((defRegIdx >= picode->du1.getNumRegsDef()) || (defRegIdx == MAX_REGS_DEF))
|
if ((defRegIdx >= picode->du1.getNumRegsDef()) or (defRegIdx == MAX_REGS_DEF))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,7 +593,7 @@ void Function::genDU1 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
|
||||||
void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, ICODE &picode, ICODE &ticode, int &numHlIcodes) const
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
UnaryOperator *lhs_unary;
|
UnaryOperator *lhs_unary;
|
||||||
@ -574,64 +609,37 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Insert on rhs of ticode, if possible */
|
/* Insert on rhs of ticode, if possible */
|
||||||
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try to insert it on lhs of ticode*/
|
/* Try to insert it on lhs of ticode*/
|
||||||
RegisterNode *op = dynamic_cast<RegisterNode *>(ticode->hlU()->asgn.m_lhs);
|
RegisterNode *op = dynamic_cast<RegisterNode *>(ticode.hlU()->asgn.m_lhs);
|
||||||
if(op)
|
if(op)
|
||||||
{
|
{
|
||||||
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
|
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
|
||||||
eReg lhsReg = id_arr[op->regiIdx].id.regi;
|
eReg lhsReg = id_arr[op->regiIdx].id.regi;
|
||||||
if((lhsReg==inserted)||Machine_X86::isSubRegisterOf(lhsReg,inserted))
|
if((lhsReg==inserted) or Machine_X86::isSubRegisterOf(lhsReg,inserted))
|
||||||
{
|
{
|
||||||
// Do not replace ax = XYZ; given ax = H << P; with H << P =
|
// Do not replace ax = XYZ; given ax = H << P; with H << P =
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
|
/** Returns whether the elements of the expression rhs are all x-clear from
|
||||||
static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
if (_exp == nullptr) /* In case expression popped is NULL */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Insert on rhs of ticode, if possible */
|
|
||||||
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
(*numHlIcodes)--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Try to insert it on lhs of ticode*/
|
|
||||||
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.m_lhs, longIdx);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
(*numHlIcodes)--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns whether the elements of the expression rhs are all x-clear from
|
|
||||||
* instruction f up to instruction t. */
|
* instruction f up to instruction t. */
|
||||||
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
|
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
|
||||||
{
|
{
|
||||||
@ -644,7 +652,7 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA
|
|||||||
{
|
{
|
||||||
if(nullptr==m_rhs)
|
if(nullptr==m_rhs)
|
||||||
return false;
|
return false;
|
||||||
if ( ! m_rhs->xClear (range_to_check, lastBBinst, locs) )
|
if ( not m_rhs->xClear (range_to_check, lastBBinst, locs) )
|
||||||
return false;
|
return false;
|
||||||
if(nullptr==m_lhs)
|
if(nullptr==m_lhs)
|
||||||
return false;
|
return false;
|
||||||
@ -674,7 +682,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
return; */
|
return; */
|
||||||
assert(pProc==g_exp_stk.func);
|
assert(pProc==g_exp_stk.func);
|
||||||
_exp = g_exp_stk.pop();
|
_exp = g_exp_stk.pop();
|
||||||
if (callee->flg & PROC_ISLIB) /* library function */
|
if (callee->isLibrary() ) /* library function */
|
||||||
{
|
{
|
||||||
if (callee->args.numArgs > 0)
|
if (callee->args.numArgs > 0)
|
||||||
{
|
{
|
||||||
@ -690,7 +698,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
else {
|
else {
|
||||||
if(numArgs<callee->args.size()) {
|
if(numArgs<callee->args.size()) {
|
||||||
if(prog.addressingMode=='l') {
|
if(prog.addressingMode=='l') {
|
||||||
if((callee->args[numArgs].type==TYPE_STR)||(callee->args[numArgs].type==TYPE_PTR)) {
|
if((callee->args[numArgs].type==TYPE_STR) or (callee->args[numArgs].type==TYPE_PTR)) {
|
||||||
RegisterNode *rn = dynamic_cast<RegisterNode *>(g_exp_stk.top());
|
RegisterNode *rn = dynamic_cast<RegisterNode *>(g_exp_stk.top());
|
||||||
AstIdent *idn = dynamic_cast<AstIdent *>(g_exp_stk.top());
|
AstIdent *idn = dynamic_cast<AstIdent *>(g_exp_stk.top());
|
||||||
if(rn) {
|
if(rn) {
|
||||||
@ -727,7 +735,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
|
callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), pProc);
|
||||||
/* Do not update the size of k if the expression was a segment register
|
/* Do not update the size of k if the expression was a segment register
|
||||||
* in a near call */
|
* in a near call */
|
||||||
if (res == false)
|
if (res == false)
|
||||||
@ -742,11 +750,11 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
/** Eliminates extraneous intermediate icode instructions when finding
|
/** Eliminates extraneous intermediate icode instructions when finding
|
||||||
* expressions. Generates new hlIcodes in the form of expression trees.
|
* expressions. Generates new hlIcodes in the form of expression trees.
|
||||||
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
||||||
void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const
|
void LOCAL_ID::processTargetIcode(ICODE &picode, int &numHlIcodes, ICODE &ticode,bool isLong) const
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
HLTYPE &p_hl(*picode->hlU());
|
HLTYPE &p_hl(*picode.hlU());
|
||||||
HLTYPE &t_hl(*ticode->hlU());
|
HLTYPE &t_hl(*ticode.hlU());
|
||||||
|
|
||||||
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
|
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
|
||||||
switch (t_hl.opcode)
|
switch (t_hl.opcode)
|
||||||
@ -756,11 +764,11 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
forwardSubsLong (lhs_ident->ident.idNode.longIdx,
|
forwardSubsLong (lhs_ident->ident.idNode.longIdx,
|
||||||
p_hl.asgn.rhs, picode,ticode,
|
p_hl.asgn.m_rhs, picode,ticode,
|
||||||
&numHlIcodes);
|
&numHlIcodes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
|
this->forwardSubs (lhs_ident, p_hl.asgn.m_rhs, picode, ticode, numHlIcodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
@ -768,7 +776,7 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
{
|
{
|
||||||
assert(lhs_ident);
|
assert(lhs_ident);
|
||||||
res = Expr::insertSubTreeLongReg (
|
res = Expr::insertSubTreeLongReg (
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.m_rhs,
|
||||||
t_hl.exp.v,
|
t_hl.exp.v,
|
||||||
lhs_ident->ident.idNode.longIdx);
|
lhs_ident->ident.idNode.longIdx);
|
||||||
}
|
}
|
||||||
@ -778,20 +786,20 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
assert(lhs_reg);
|
assert(lhs_reg);
|
||||||
res = Expr::insertSubTreeReg (
|
res = Expr::insertSubTreeReg (
|
||||||
t_hl.exp.v,
|
t_hl.exp.v,
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.m_rhs,
|
||||||
id_arr[lhs_reg->regiIdx].id.regi,
|
id_arr[lhs_reg->regiIdx].id.regi,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* register arguments */
|
case HLI_CALL: /* register arguments */
|
||||||
newRegArg ( picode, ticode);
|
newRegArg ( picode, ticode);
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -815,9 +823,9 @@ void C_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE picode) {
|
|||||||
numArgs++;
|
numArgs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
|
else if ((cb == 0) and picode->ll()->testFlags(REST_STK))
|
||||||
{
|
{
|
||||||
while (! g_exp_stk.empty())
|
while (not g_exp_stk.empty())
|
||||||
{
|
{
|
||||||
k+=processCArg (pp, func, &(*picode), numArgs);
|
k+=processCArg (pp, func, &(*picode), numArgs);
|
||||||
numArgs++;
|
numArgs++;
|
||||||
@ -838,11 +846,11 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
while(k<cb)
|
while(k<cb)
|
||||||
{
|
{
|
||||||
_exp = g_exp_stk.pop();
|
_exp = g_exp_stk.pop();
|
||||||
if (pp->flg & PROC_ISLIB) /* library function */
|
if (pp->isLibrary() ) /* library function */
|
||||||
{
|
{
|
||||||
if (pp->args.numArgs > 0)
|
if (pp->args.numArgs > 0)
|
||||||
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
||||||
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), func);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
|
||||||
}
|
}
|
||||||
else /* user function */
|
else /* user function */
|
||||||
{
|
{
|
||||||
@ -852,9 +860,10 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
{
|
{
|
||||||
fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
|
fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
|
||||||
}
|
}
|
||||||
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
else
|
||||||
|
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
||||||
}
|
}
|
||||||
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
|
||||||
}
|
}
|
||||||
if (res == false)
|
if (res == false)
|
||||||
k += _exp->hlTypeSize (func);
|
k += _exp->hlTypeSize (func);
|
||||||
@ -875,28 +884,28 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
|
|
||||||
ID *_retVal; // function return value
|
ID *_retVal; // function return value
|
||||||
Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
|
Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
|
||||||
//Expr *lhs; // exp ptr for return value of a HLI_CALL */
|
|
||||||
iICODE ticode; // Target icode */
|
iICODE ticode; // Target icode */
|
||||||
HLTYPE *ti_hl=nullptr;
|
HLTYPE *ti_hl=nullptr;
|
||||||
uint8_t regi;
|
uint8_t regi;
|
||||||
numHlIcodes = 0;
|
numHlIcodes = 0;
|
||||||
assert(&fnc->localId==&locals);
|
assert(&fnc->localId==&locals);
|
||||||
// register(s) to be forward substituted */
|
// register(s) to be forward substituted */
|
||||||
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
|
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL_ICODE>());
|
||||||
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
||||||
{
|
{
|
||||||
HLTYPE &_icHl(*picode->hlU());
|
ICODE &_ic(*picode);
|
||||||
|
HLTYPE &_icHl(*_ic.hlU());
|
||||||
numHlIcodes++;
|
numHlIcodes++;
|
||||||
if (picode->du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
|
if (_ic.du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
|
||||||
{
|
{
|
||||||
/* Check for only one use of this register. If this is
|
/* Check for only one use of this register. If this is
|
||||||
* the last definition of the register in this BB, check
|
* the last definition of the register in this BB, check
|
||||||
* that it is not liveOut from this basic block */
|
* that it is not liveOut from this basic block */
|
||||||
if (picode->du1.numUses(0)==1)
|
if (_ic.du1.numUses(0)==1)
|
||||||
{
|
{
|
||||||
/* Check that this register is not liveOut, if it
|
/* Check that this register is not liveOut, if it
|
||||||
* is the last definition of the register */
|
* is the last definition of the register */
|
||||||
regi = picode->du1.regi[0];
|
regi = _ic.du1.regi[0];
|
||||||
|
|
||||||
/* Check if we can forward substitute this register */
|
/* Check if we can forward substitute this register */
|
||||||
switch (_icHl.opcode)
|
switch (_icHl.opcode)
|
||||||
@ -905,16 +914,16 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
/* Replace rhs of current icode into target
|
/* Replace rhs of current icode into target
|
||||||
* icode expression */
|
* icode expression */
|
||||||
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]),
|
if (_icHl.asgn.m_rhs->xClear (make_iterator_range(picode.base(),_ic.du1.idx[0].uses[0]),
|
||||||
end(), locals))
|
end(), locals))
|
||||||
{
|
{
|
||||||
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false);
|
locals.processTargetIcode(_ic, numHlIcodes, *ticode,false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -923,17 +932,17 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
// pop X
|
// pop X
|
||||||
// lab1:
|
// lab1:
|
||||||
// call F() <- somehow this is marked as user of POP ?
|
// call F() <- somehow this is marked as user of POP ?
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
ti_hl = ticode->hlU();
|
ti_hl = ticode->hlU();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ti_hl->opcode != HLI_CALL) &&
|
((ti_hl->opcode != HLI_CALL) and
|
||||||
(ti_hl->opcode != HLI_RET)))
|
(ti_hl->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
||||||
switch (ticode->hl()->opcode) {
|
switch (ticode->hl()->opcode) {
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes);
|
locals.forwardSubs(_icHl.expr(), _exp, _ic, *ticode, numHlIcodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
@ -946,7 +955,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
&locals);
|
&locals);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -964,25 +973,25 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL:
|
case HLI_CALL:
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
ti_hl = ticode->hlU();
|
ti_hl = ticode->hlU();
|
||||||
_retVal = &_icHl.call.proc->retVal;
|
_retVal = &_icHl.call.proc->retVal;
|
||||||
switch (ti_hl->opcode)
|
switch (ti_hl->opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
assert(ti_hl->asgn.rhs);
|
assert(ti_hl->asgn.m_rhs);
|
||||||
_exp = _icHl.call.toAst();
|
_exp = _icHl.call.toAst();
|
||||||
res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
|
res = Expr::insertSubTreeReg (ti_hl->asgn.m_rhs,_exp, _retVal->id.regi, &locals);
|
||||||
if (! res)
|
if (not res)
|
||||||
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
||||||
//TODO: HERE missing: 2 regs
|
//TODO: HERE missing: 2 regs
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_PUSH: case HLI_RET:
|
case HLI_PUSH: case HLI_RET:
|
||||||
ti_hl->expr( _icHl.call.toAst() );
|
ti_hl->expr( _icHl.call.toAst() );
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -991,13 +1000,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
|
res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
|
||||||
if (res) /* was substituted */
|
if (res) /* was substituted */
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else /* cannot substitute function */
|
else /* cannot substitute function */
|
||||||
{
|
{
|
||||||
auto lhs = AstIdent::idID(_retVal,&locals,picode.base());
|
auto lhs = AstIdent::idID(_retVal,&locals,picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1010,35 +1019,35 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (picode->du1.getNumRegsDef() == 2) /* long regs */
|
else if (_ic.du1.getNumRegsDef() == 2) /* long regs */
|
||||||
{
|
{
|
||||||
/* Check for only one use of these registers */
|
/* Check for only one use of these registers */
|
||||||
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
|
if ((_ic.du1.numUses(0) == 1) and (_ic.du1.numUses(1) == 1))
|
||||||
{
|
{
|
||||||
regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
regi = _ic.du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
||||||
|
|
||||||
switch (_icHl.opcode)
|
switch (_icHl.opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
/* Replace rhs of current icode into target
|
/* Replace rhs of current icode into target
|
||||||
* icode expression */
|
* icode expression */
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
|
||||||
{
|
{
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true);
|
locals.processTargetIcode(_ic, numHlIcodes, *ticode,true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_POP:
|
case HLI_POP:
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
|
||||||
{
|
{
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1046,7 +1055,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
switch (ticode->hl()->opcode) {
|
switch (ticode->hl()->opcode) {
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx,
|
forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx,
|
||||||
_exp, picode.base(), ticode, &numHlIcodes);
|
_exp, _ic, *ticode, &numHlIcodes);
|
||||||
break;
|
break;
|
||||||
case HLI_JCOND: case HLI_PUSH:
|
case HLI_JCOND: case HLI_PUSH:
|
||||||
res = Expr::insertSubTreeLongReg (_exp,
|
res = Expr::insertSubTreeLongReg (_exp,
|
||||||
@ -1054,7 +1063,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
|
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1067,7 +1076,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* check for function return */
|
case HLI_CALL: /* check for function return */
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
switch (ticode->hl()->opcode)
|
switch (ticode->hl()->opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
@ -1076,33 +1085,33 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
AstIdent::Long(&locals, DST,
|
AstIdent::Long(&locals, DST,
|
||||||
ticode,HIGH_FIRST, picode.base(),
|
ticode,HIGH_FIRST, picode.base(),
|
||||||
eDEF, *(++iICODE(ticode))->ll()));
|
eDEF, *(++iICODE(ticode))->ll()));
|
||||||
ticode->hlU()->asgn.rhs = _exp;
|
ticode->hlU()->asgn.m_rhs = _exp;
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_PUSH:
|
case HLI_PUSH:
|
||||||
case HLI_RET:
|
case HLI_RET:
|
||||||
ticode->hlU()->expr( _icHl.call.toAst() );
|
ticode->hlU()->expr( _icHl.call.toAst() );
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND:
|
case HLI_JCOND:
|
||||||
_exp = _icHl.call.toAst();
|
_exp = _icHl.call.toAst();
|
||||||
_retVal = &picode->hl()->call.proc->retVal;
|
_retVal = &_ic.hl()->call.proc->retVal;
|
||||||
res = Expr::insertSubTreeLongReg (_exp,
|
res = Expr::insertSubTreeLongReg (_exp,
|
||||||
ticode->hlU()->exp.v,
|
ticode->hlU()->exp.v,
|
||||||
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
||||||
if (res) /* was substituted */
|
if (res) /* was substituted */
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else /* cannot substitute function */
|
else /* cannot substitute function */
|
||||||
{
|
{
|
||||||
auto lhs = locals.createId(_retVal,picode.base());
|
auto lhs = locals.createId(_retVal,picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1115,6 +1124,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HLI_PUSH doesn't define any registers, only uses registers.
|
/* HLI_PUSH doesn't define any registers, only uses registers.
|
||||||
* Push the associated expression to the register on the local
|
* Push the associated expression to the register on the local
|
||||||
* expression stack */
|
* expression stack */
|
||||||
@ -1122,8 +1132,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
{
|
{
|
||||||
g_exp_stk.processExpPush(numHlIcodes, *picode);
|
g_exp_stk.processExpPush(numHlIcodes, *picode);
|
||||||
}
|
}
|
||||||
else if(picode->du1.getNumRegsDef()!=0)
|
else if(_ic.du1.getNumRegsDef()!=0)
|
||||||
printf("Num def %d\n",picode->du1.getNumRegsDef());
|
printf("Num def %d\n",_ic.du1.getNumRegsDef());
|
||||||
|
|
||||||
/* For HLI_CALL instructions that use arguments from the stack,
|
/* For HLI_CALL instructions that use arguments from the stack,
|
||||||
* pop them from the expression stack and place them on the
|
* pop them from the expression stack and place them on the
|
||||||
@ -1137,11 +1147,11 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
|
|
||||||
/* If we could not substitute the result of a function,
|
/* If we could not substitute the result of a function,
|
||||||
* assign it to the corresponding registers */
|
* assign it to the corresponding registers */
|
||||||
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0))
|
if ( not _icHl.call.proc->isLibrary() and (not _ic.du1.used(0)) and (_ic.du1.getNumRegsDef() > 0))
|
||||||
{
|
{
|
||||||
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
|
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
|
||||||
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
|
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1182,44 +1192,44 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
|||||||
isBx = _liveOut.testReg(rBX);
|
isBx = _liveOut.testReg(rBX);
|
||||||
isCx = _liveOut.testReg(rCX);
|
isCx = _liveOut.testReg(rCX);
|
||||||
isDx = _liveOut.testReg(rDX);
|
isDx = _liveOut.testReg(rDX);
|
||||||
bool isAL = !isAx && _liveOut.testReg(rAL);
|
bool isAL = not isAx and _liveOut.testReg(rAL);
|
||||||
bool isAH = !isAx && _liveOut.testReg(rAH);
|
bool isAH = not isAx and _liveOut.testReg(rAH);
|
||||||
bool isBL = !isBx && _liveOut.testReg(rBL);
|
bool isBL = not isBx and _liveOut.testReg(rBL);
|
||||||
bool isBH = !isBx && _liveOut.testReg(rBH);
|
bool isBH = not isBx and _liveOut.testReg(rBH);
|
||||||
bool isCL = !isCx && _liveOut.testReg(rCL);
|
bool isCL = not isCx and _liveOut.testReg(rCL);
|
||||||
bool isCH = !isCx && _liveOut.testReg(rCH);
|
bool isCH = not isCx and _liveOut.testReg(rCH);
|
||||||
bool isDL = !isDx && _liveOut.testReg(rDL);
|
bool isDL = not isDx and _liveOut.testReg(rDL);
|
||||||
bool isDH = !isDx && _liveOut.testReg(rDH);
|
bool isDH = not isDx and _liveOut.testReg(rDH);
|
||||||
if(isAL && isAH)
|
if(isAL and isAH)
|
||||||
{
|
{
|
||||||
isAx = true;
|
isAx = true;
|
||||||
isAH=isAL=false;
|
isAH=isAL=false;
|
||||||
}
|
}
|
||||||
if(isDL && isDH)
|
if(isDL and isDH)
|
||||||
{
|
{
|
||||||
isDx = true;
|
isDx = true;
|
||||||
isDH=isDL=false;
|
isDH=isDL=false;
|
||||||
}
|
}
|
||||||
if(isBL && isBH)
|
if(isBL and isBH)
|
||||||
{
|
{
|
||||||
isBx = true;
|
isBx = true;
|
||||||
isBH=isBL=false;
|
isBH=isBL=false;
|
||||||
}
|
}
|
||||||
if(isCL && isCH)
|
if(isCL and isCH)
|
||||||
{
|
{
|
||||||
isCx = true;
|
isCx = true;
|
||||||
isCH=isCL=false;
|
isCH=isCL=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAx && isDx) /* long or pointer */
|
if (isAx and isDx) /* long or pointer */
|
||||||
{
|
{
|
||||||
retVal.type = TYPE_LONG_SIGN;
|
retVal.type = TYPE_LONG_SIGN;
|
||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
||||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
||||||
localId.propLongId (rAX, rDX, "\0");
|
localId.propLongId (rAX, rDX, "");
|
||||||
}
|
}
|
||||||
else if (isAx || isBx || isCx || isDx) /* uint16_t */
|
else if (isAx or isBx or isCx or isDx) /* uint16_t */
|
||||||
{
|
{
|
||||||
retVal.type = TYPE_WORD_SIGN;
|
retVal.type = TYPE_WORD_SIGN;
|
||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
@ -1233,7 +1243,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
|||||||
retVal.id.regi = rDX;
|
retVal.id.regi = rDX;
|
||||||
/*idx = */localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi);
|
/*idx = */localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi);
|
||||||
}
|
}
|
||||||
else if(isAL||isBL||isCL||isDL)
|
else if(isAL or isBL or isCL or isDL)
|
||||||
{
|
{
|
||||||
retVal.type = TYPE_BYTE_SIGN;
|
retVal.type = TYPE_BYTE_SIGN;
|
||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
@ -1247,7 +1257,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
|||||||
retVal.id.regi = rDL;
|
retVal.id.regi = rDL;
|
||||||
/*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
|
/*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
|
||||||
}
|
}
|
||||||
else if(isAH||isBH||isCH||isDH)
|
else if(isAH or isBH or isCH or isDH)
|
||||||
{
|
{
|
||||||
retVal.type = TYPE_BYTE_SIGN;
|
retVal.type = TYPE_BYTE_SIGN;
|
||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
@ -1283,7 +1293,7 @@ void Function::dataFlow(LivenessSet &_liveOut)
|
|||||||
elimCondCodes();
|
elimCondCodes();
|
||||||
genLiveKtes();
|
genLiveKtes();
|
||||||
liveRegAnalysis (_liveOut); /* calls dataFlow() recursively */
|
liveRegAnalysis (_liveOut); /* calls dataFlow() recursively */
|
||||||
if (! (flg & PROC_ASM)) /* can generate C for pProc */
|
if (not (flg & PROC_ASM)) /* can generate C for pProc */
|
||||||
{
|
{
|
||||||
genDU1 (); /* generate def/use level 1 chain */
|
genDU1 (); /* generate def/use level 1 chain */
|
||||||
findExps (); /* forward substitution algorithm */
|
findExps (); /* forward substitution algorithm */
|
||||||
|
|||||||
120
src/dcc.cpp
120
src/dcc.cpp
@ -4,32 +4,20 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
#include "DccFrontend.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#ifdef LLVM_EXPERIMENTAL
|
|
||||||
#include <llvm/Support/raw_os_ostream.h>
|
|
||||||
#include <llvm/Support/CommandLine.h>
|
|
||||||
#include <llvm/Support/TargetSelect.h>
|
|
||||||
#include <llvm/Support/TargetRegistry.h>
|
|
||||||
#include <llvm/Support/PrettyStackTrace.h>
|
|
||||||
#include <llvm/Support/Signals.h>
|
|
||||||
#include <llvm/Support/Host.h>
|
|
||||||
#include <llvm/Target/TargetMachine.h>
|
|
||||||
#include <llvm/Target/TargetInstrInfo.h>
|
|
||||||
#include <llvm/MC/MCAsmInfo.h>
|
|
||||||
#include <llvm/CodeGen/MachineInstrBuilder.h>
|
|
||||||
#include <llvm/TableGen/Main.h>
|
|
||||||
#include <llvm/TableGen/TableGenBackend.h>
|
|
||||||
#include <llvm/TableGen/Record.h>
|
|
||||||
#endif
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "project.h"
|
|
||||||
#include "CallGraph.h"
|
|
||||||
#include "DccFrontend.h"
|
|
||||||
|
|
||||||
/* Global variables - extern to other modules */
|
/* Global variables - extern to other modules */
|
||||||
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
@ -37,85 +25,11 @@ extern SYMTAB symtab; /* Global symbol table */
|
|||||||
extern STATS stats; /* cfg statistics */
|
extern STATS stats; /* cfg statistics */
|
||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
static char *initargs(int argc, char *argv[]);
|
static void displayTotalStats();
|
||||||
static void displayTotalStats(void);
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* main
|
* main
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef LLVM_EXPERIMENTAL
|
void setupOptions(const QCoreApplication &app) {
|
||||||
using namespace llvm;
|
|
||||||
bool TVisitor(raw_ostream &OS, RecordKeeper &Records)
|
|
||||||
{
|
|
||||||
Record *rec = Records.getDef("ADD8i8");
|
|
||||||
if(rec)
|
|
||||||
{
|
|
||||||
if(not rec->getTemplateArgs().empty())
|
|
||||||
std::cout << "Has template args\n";
|
|
||||||
auto classes(rec->getSuperClasses());
|
|
||||||
for(auto val : rec->getSuperClasses())
|
|
||||||
std::cout << "Super "<<val->getName()<<"\n";
|
|
||||||
|
|
||||||
// DagInit * in = rec->getValueAsDag(val.getName());
|
|
||||||
// in->dump();
|
|
||||||
for(const RecordVal &val : rec->getValues())
|
|
||||||
{
|
|
||||||
// val.dump();
|
|
||||||
}
|
|
||||||
rec->dump();
|
|
||||||
|
|
||||||
}
|
|
||||||
// rec = Records.getDef("CCR");
|
|
||||||
// if(rec)
|
|
||||||
// rec->dump();
|
|
||||||
// for(auto val : Records.getDefs())
|
|
||||||
// {
|
|
||||||
// //std::cout<< "Def "<<val.first<<"\n";
|
|
||||||
// }
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int testTblGen(int argc, char **argv)
|
|
||||||
{
|
|
||||||
// using namespace llvm;
|
|
||||||
// sys::PrintStackTraceOnErrorSignal();
|
|
||||||
// PrettyStackTraceProgram(argc,argv);
|
|
||||||
// cl::ParseCommandLineOptions(argc,argv);
|
|
||||||
// return llvm::TableGenMain(argv[0],TVisitor);
|
|
||||||
// InitializeNativeTarget();
|
|
||||||
// Triple TheTriple;
|
|
||||||
// std::string def = sys::getDefaultTargetTriple();
|
|
||||||
// std::string MCPU="i386";
|
|
||||||
// std::string MARCH="x86";
|
|
||||||
// InitializeAllTargetInfos();
|
|
||||||
// InitializeAllTargetMCs();
|
|
||||||
// InitializeAllAsmPrinters();
|
|
||||||
// InitializeAllAsmParsers();
|
|
||||||
// InitializeAllDisassemblers();
|
|
||||||
// std::string TargetTriple("i386-pc-linux-gnu");
|
|
||||||
// TheTriple = Triple(Triple::normalize(TargetTriple));
|
|
||||||
// MCOperand op=llvm::MCOperand::CreateImm(11);
|
|
||||||
// MCAsmInfo info;
|
|
||||||
// raw_os_ostream wrap(std::cerr);
|
|
||||||
// op.print(wrap,&info);
|
|
||||||
// wrap.flush();
|
|
||||||
// std::cerr<<"\n";
|
|
||||||
// std::string lookuperr;
|
|
||||||
// TargetRegistry::printRegisteredTargetsForVersion();
|
|
||||||
// const Target *t = TargetRegistry::lookupTarget(MARCH,TheTriple,lookuperr);
|
|
||||||
// TargetOptions opts;
|
|
||||||
// std::string Features;
|
|
||||||
// opts.PrintMachineCode=1;
|
|
||||||
// TargetMachine *tm = t->createTargetMachine(TheTriple.getTriple(),MCPU,Features,opts);
|
|
||||||
// std::cerr<<tm->getInstrInfo()->getName(97)<<"\n";
|
|
||||||
// const MCInstrDesc &ds(tm->getInstrInfo()->get(97));
|
|
||||||
// const MCOperandInfo *op1=ds.OpInfo;
|
|
||||||
// uint16_t impl_def = ds.getImplicitDefs()[0];
|
|
||||||
// std::cerr<<lookuperr<<"\n";
|
|
||||||
|
|
||||||
// exit(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void setupOptions(QCoreApplication &app) {
|
|
||||||
//[-a1a2cmsi]
|
//[-a1a2cmsi]
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription("dcc");
|
parser.setApplicationDescription("dcc");
|
||||||
@ -133,14 +47,17 @@ void setupOptions(QCoreApplication &app) {
|
|||||||
parser.addOption(o);
|
parser.addOption(o);
|
||||||
}
|
}
|
||||||
QCommandLineOption assembly("a", QCoreApplication::translate("main", "Produce assembly"),"assembly_level");
|
QCommandLineOption assembly("a", QCoreApplication::translate("main", "Produce assembly"),"assembly_level");
|
||||||
// A boolean option with multiple names (-f, --force)
|
|
||||||
//QCommandLineOption forceOption(QStringList() << "f" << "force", "Overwrite existing files.");
|
|
||||||
// An option with a value
|
|
||||||
QCommandLineOption targetFileOption(QStringList() << "o" << "output",
|
QCommandLineOption targetFileOption(QStringList() << "o" << "output",
|
||||||
QCoreApplication::translate("main", "Place output into <file>."),
|
QCoreApplication::translate("main", "Place output into <file>."),
|
||||||
QCoreApplication::translate("main", "file"));
|
QCoreApplication::translate("main", "file"));
|
||||||
|
QCommandLineOption entryPointOption(QStringList() << "E",
|
||||||
|
QCoreApplication::translate("main", "Custom entry point as hex"),
|
||||||
|
QCoreApplication::translate("main", "offset"),
|
||||||
|
"0"
|
||||||
|
);
|
||||||
parser.addOption(targetFileOption);
|
parser.addOption(targetFileOption);
|
||||||
parser.addOption(assembly);
|
parser.addOption(assembly);
|
||||||
|
parser.addOption(entryPointOption);
|
||||||
//parser.addOption(forceOption);
|
//parser.addOption(forceOption);
|
||||||
// Process the actual command line arguments given by the user
|
// Process the actual command line arguments given by the user
|
||||||
parser.addPositionalArgument("source", QCoreApplication::translate("main", "Dos Executable file to decompile."));
|
parser.addPositionalArgument("source", QCoreApplication::translate("main", "Dos Executable file to decompile."));
|
||||||
@ -162,9 +79,10 @@ void setupOptions(QCoreApplication &app) {
|
|||||||
option.Interact = false;
|
option.Interact = false;
|
||||||
option.Calls = parser.isSet(boolOpts[2]);
|
option.Calls = parser.isSet(boolOpts[2]);
|
||||||
option.filename = args.first();
|
option.filename = args.first();
|
||||||
|
option.CustomEntryPoint = parser.value(entryPointOption).toUInt(nullptr,16);
|
||||||
if(parser.isSet(targetFileOption))
|
if(parser.isSet(targetFileOption))
|
||||||
asm1_name = asm2_name = parser.value(targetFileOption);
|
asm1_name = asm2_name = parser.value(targetFileOption);
|
||||||
else if(option.asm1 || option.asm2) {
|
else if(option.asm1 or option.asm2) {
|
||||||
asm1_name = option.filename+".a1";
|
asm1_name = option.filename+".a1";
|
||||||
asm2_name = option.filename+".a2";
|
asm2_name = option.filename+".a2";
|
||||||
}
|
}
|
||||||
@ -184,7 +102,7 @@ int main(int argc, char **argv)
|
|||||||
Project::get()->create(option.filename);
|
Project::get()->create(option.filename);
|
||||||
|
|
||||||
DccFrontend fe(&app);
|
DccFrontend fe(&app);
|
||||||
if(!Project::get()->load()) {
|
if(not Project::get()->load()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
|
|||||||
@ -1,22 +1,24 @@
|
|||||||
#include "dcc_interface.h"
|
#include "dcc_interface.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
struct DccImpl : public IDcc{
|
struct DccImpl : public IDcc {
|
||||||
|
ilFunction m_current_func;
|
||||||
|
|
||||||
// IDcc interface
|
// IDcc interface
|
||||||
public:
|
public:
|
||||||
void BaseInit()
|
void BaseInit()
|
||||||
{
|
{
|
||||||
|
m_current_func = Project::get()->functions().end();
|
||||||
}
|
}
|
||||||
void Init(QObject *tgt)
|
void Init(QObject *tgt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
ilFunction GetFirstFuncHandle()
|
ilFunction GetFirstFuncHandle()
|
||||||
{
|
{
|
||||||
|
return Project::get()->functions().begin();
|
||||||
}
|
}
|
||||||
ilFunction GetCurFuncHandle()
|
ilFunction GetCurFuncHandle()
|
||||||
{
|
{
|
||||||
|
return m_current_func;
|
||||||
}
|
}
|
||||||
void analysis_Once()
|
void analysis_Once()
|
||||||
{
|
{
|
||||||
@ -34,13 +36,21 @@ public:
|
|||||||
}
|
}
|
||||||
size_t getFuncCount()
|
size_t getFuncCount()
|
||||||
{
|
{
|
||||||
|
return Project::get()->functions().size();
|
||||||
}
|
}
|
||||||
const lFunction &validFunctions() const
|
const lFunction &validFunctions() const
|
||||||
{
|
{
|
||||||
return Project::get()->functions();
|
return Project::get()->functions();
|
||||||
}
|
}
|
||||||
void SetCurFunc_by_Name(QString)
|
void SetCurFunc_by_Name(QString v)
|
||||||
{
|
{
|
||||||
|
lFunction & funcs(Project::get()->functions());
|
||||||
|
for(auto iter=funcs.begin(),fin=funcs.end(); iter!=fin; ++iter) {
|
||||||
|
if(iter->name==v) {
|
||||||
|
m_current_func = iter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QDir installDir() {
|
QDir installDir() {
|
||||||
return QDir(".");
|
return QDir(".");
|
||||||
@ -54,8 +64,7 @@ public:
|
|||||||
|
|
||||||
IDcc* IDcc::get() {
|
IDcc* IDcc::get() {
|
||||||
static IDcc *v=0;
|
static IDcc *v=0;
|
||||||
if(!v)
|
if(nullptr == v)
|
||||||
v = new DccImpl;
|
v = new DccImpl;
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
171
src/disassem.cpp
171
src/disassem.cpp
@ -2,6 +2,15 @@
|
|||||||
* dcc project disassembler
|
* dcc project disassembler
|
||||||
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#include "disassem.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -10,10 +19,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "symtab.h"
|
|
||||||
#include "disassem.h"
|
|
||||||
#include "project.h"
|
|
||||||
// Note: for the time being, there is no interactive disassembler
|
// Note: for the time being, there is no interactive disassembler
|
||||||
// for unix
|
// for unix
|
||||||
|
|
||||||
@ -70,8 +75,8 @@ static const char *szFlops3C[] =
|
|||||||
|
|
||||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||||
|
|
||||||
static void formatRM(ostringstream &p, const LLOperand &pm);
|
static void formatRM(QTextStream & p, const LLOperand &pm);
|
||||||
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
static QTextStream & strDst(QTextStream & os, uint32_t flg, const LLOperand &pm);
|
||||||
|
|
||||||
static char *strHex(uint32_t d);
|
static char *strHex(uint32_t d);
|
||||||
//static int checkScanned(uint32_t pcCur);
|
//static int checkScanned(uint32_t pcCur);
|
||||||
@ -107,7 +112,7 @@ static vector<POSSTACK_ENTRY> posStack; /* position stack */
|
|||||||
|
|
||||||
void LLInst::findJumpTargets(CIcodeRec &_pc)
|
void LLInst::findJumpTargets(CIcodeRec &_pc)
|
||||||
{
|
{
|
||||||
if (testFlags(I) && ! testFlags(JMP_ICODE) && isJmpInst())
|
if (testFlags(I) and not testFlags(JMP_ICODE) and isJmpInst())
|
||||||
{
|
{
|
||||||
/* Replace the immediate operand with an icode index */
|
/* Replace the immediate operand with an icode index */
|
||||||
iICODE labTgt=_pc.labelSrch(src().getImm2());
|
iICODE labTgt=_pc.labelSrch(src().getImm2());
|
||||||
@ -150,11 +155,11 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
auto p = (pass == 1)? asm1_name: asm2_name;
|
auto p = (pass == 1)? asm1_name: asm2_name;
|
||||||
m_fp.open(p.toStdString(),ios_base::app);
|
m_disassembly_target = new QFile(p);
|
||||||
if (!m_fp.is_open())
|
if(!m_disassembly_target->open(QFile::WriteOnly|QFile::Text|QFile::Append)) {
|
||||||
{
|
|
||||||
fatalError(CANNOT_OPEN, p.toStdString().c_str());
|
fatalError(CANNOT_OPEN, p.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
m_fp.setDevice(m_disassembly_target);
|
||||||
}
|
}
|
||||||
/* Create temporary code array */
|
/* Create temporary code array */
|
||||||
// Mike: needs objectising!
|
// Mike: needs objectising!
|
||||||
@ -177,7 +182,7 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
/* Write procedure header */
|
/* Write procedure header */
|
||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
std::string near_far=(pProc->flg & PROC_FAR)? "FAR": "NEAR";
|
const char * near_far=(pProc->flg & PROC_FAR)? "FAR": "NEAR";
|
||||||
m_fp << "\t\t"<<pProc->name<<" PROC "<< near_far<<"\n";
|
m_fp << "\t\t"<<pProc->name<<" PROC "<< near_far<<"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +197,10 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
m_fp << "\n\t\t"<<pProc->name<<" ENDP\n\n";
|
m_fp << "\n\t\t"<<pProc->name<<" ENDP\n\n";
|
||||||
m_fp.close();
|
m_fp.setDevice(nullptr);
|
||||||
|
m_disassembly_target->close();
|
||||||
|
delete m_disassembly_target;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.clear();
|
pc.clear();
|
||||||
@ -206,19 +214,23 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ostringstream oper_stream;
|
QString oper_contents;
|
||||||
ostringstream hex_bytes;
|
QTextStream oper_stream(&oper_contents);
|
||||||
ostringstream result_stream;
|
QString hex_bytes;
|
||||||
ostringstream opcode_with_mods;
|
QString result_contents;
|
||||||
ostringstream operands_s;
|
QTextStream result_stream(&result_contents);
|
||||||
oper_stream << uppercase;
|
QString opcode_with_mods;
|
||||||
hex_bytes << uppercase;
|
|
||||||
|
QString operands_contents;
|
||||||
|
QTextStream operands_s(&operands_contents);
|
||||||
|
oper_stream.setNumberFlags(QTextStream::UppercaseBase|QTextStream::UppercaseDigits);
|
||||||
|
|
||||||
/* Disassembly stage 1 --
|
/* Disassembly stage 1 --
|
||||||
* Do not try to display NO_CODE entries or synthetic instructions,
|
* Do not try to display NO_CODE entries or synthetic instructions,
|
||||||
* other than JMPs, that have been introduced for def/use analysis. */
|
* other than JMPs, that have been introduced for def/use analysis. */
|
||||||
if ((option.asm1) &&
|
if ((option.asm1) and
|
||||||
( inst.testFlags(NO_CODE) ||
|
( inst.testFlags(NO_CODE) or
|
||||||
(inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP))))
|
(inst.testFlags(SYNTHETIC) and (inst.getOpcode() != iJMP))))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -242,25 +254,28 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
cb = (uint32_t) inst.numBytes;
|
cb = (uint32_t) inst.numBytes;
|
||||||
nextInst = inst.label + cb;
|
nextInst = inst.label + cb;
|
||||||
|
|
||||||
/* Output hexa code in program image */
|
/* Output hex code in program image */
|
||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
for (j = 0; j < cb; j++)
|
for (j = 0; j < cb; j++)
|
||||||
{
|
{
|
||||||
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
|
hex_bytes += QString("%1").arg(uint16_t(prog.image()[inst.label + j]),2,16,QChar('0')).toUpper();
|
||||||
}
|
}
|
||||||
hex_bytes << ' ';
|
hex_bytes += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oper_stream << setw(POS_LAB) << left<< hex_bytes.str();
|
oper_stream.setFieldWidth(POS_LAB);
|
||||||
|
oper_stream.setFieldAlignment(QTextStream::AlignLeft);
|
||||||
|
oper_stream << hex_bytes;
|
||||||
/* Check if there is a symbol here */
|
/* Check if there is a symbol here */
|
||||||
selectTable(Label);
|
selectTable(Label);
|
||||||
oper_stream << setw(5)<<left; // align for the labels
|
oper_stream.setFieldWidth(5); // align for the labels
|
||||||
{
|
{
|
||||||
ostringstream lab_contents;
|
QString lab_contents;
|
||||||
if (readVal(lab_contents, inst.label, nullptr))
|
QTextStream lab_stream(&lab_contents);
|
||||||
|
if (readVal(lab_stream, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
lab_contents << ':'; /* Also removes the null */
|
lab_stream << ':'; /* Also removes the null */
|
||||||
}
|
}
|
||||||
else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */
|
else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */
|
||||||
{
|
{
|
||||||
@ -269,15 +284,17 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
{
|
{
|
||||||
pl[loc_ip] = ++g_lab;
|
pl[loc_ip] = ++g_lab;
|
||||||
}
|
}
|
||||||
lab_contents<< "L"<<pl[loc_ip]<<':';
|
lab_stream<< "L"<<pl[loc_ip]<<':';
|
||||||
}
|
}
|
||||||
oper_stream<< lab_contents.str();
|
lab_stream.flush();
|
||||||
|
oper_stream << lab_contents;
|
||||||
|
oper_stream.setFieldWidth(0);
|
||||||
}
|
}
|
||||||
if ((inst.getOpcode()==iSIGNEX )&& inst.testFlags(B))
|
if ((inst.getOpcode()==iSIGNEX )and inst.testFlags(B))
|
||||||
{
|
{
|
||||||
inst.setOpcode(iCBW);
|
inst.setOpcode(iCBW);
|
||||||
}
|
}
|
||||||
opcode_with_mods<<Machine_X86::opcodeName(inst.getOpcode());
|
opcode_with_mods += Machine_X86::opcodeName(inst.getOpcode());
|
||||||
|
|
||||||
switch ( inst.getOpcode() )
|
switch ( inst.getOpcode() )
|
||||||
{
|
{
|
||||||
@ -342,7 +359,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
{
|
{
|
||||||
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
||||||
selectTable(Label);
|
selectTable(Label);
|
||||||
if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */
|
if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */
|
||||||
readVal(operands_s, lab->ll()->label, nullptr))
|
readVal(operands_s, lab->ll()->label, nullptr))
|
||||||
{
|
{
|
||||||
break; /* Symbolic label. Done */
|
break; /* Symbolic label. Done */
|
||||||
@ -381,11 +398,10 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
case iCALL: case iCALLF:
|
case iCALL: case iCALLF:
|
||||||
if (inst.testFlags(I))
|
if (inst.testFlags(I))
|
||||||
{
|
{
|
||||||
if((inst.getOpcode() == iCALL))
|
QString oper = QString("%1 ptr %2")
|
||||||
operands_s<< "near";
|
.arg((inst.getOpcode() == iCALL) ? "near" : "far")
|
||||||
else
|
.arg((inst.src().proc.proc)->name);
|
||||||
operands_s<< " far";
|
operands_s<< qPrintable(oper);
|
||||||
operands_s<<" ptr "<<(inst.src().proc.proc)->name;
|
|
||||||
}
|
}
|
||||||
else if (inst.getOpcode() == iCALLF)
|
else if (inst.getOpcode() == iCALLF)
|
||||||
{
|
{
|
||||||
@ -416,14 +432,14 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
case iOUTS: case iREP_OUTS:
|
case iOUTS: case iREP_OUTS:
|
||||||
if (inst.src().segOver)
|
if (inst.src().segOver)
|
||||||
{
|
{
|
||||||
bool is_dx_src=(inst.getOpcode() == iOUTS || inst.getOpcode() == iREP_OUTS);
|
bool is_dx_src=(inst.getOpcode() == iOUTS or inst.getOpcode() == iREP_OUTS);
|
||||||
if(is_dx_src)
|
if(is_dx_src)
|
||||||
operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
|
operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
|
||||||
else
|
else
|
||||||
operands_s<<szPtr[inst.getFlag() & B];
|
operands_s<<szPtr[inst.getFlag() & B];
|
||||||
if (inst.getOpcode() == iLODS ||
|
if (inst.getOpcode() == iLODS or
|
||||||
inst.getOpcode() == iREP_LODS ||
|
inst.getOpcode() == iREP_LODS or
|
||||||
inst.getOpcode() == iOUTS ||
|
inst.getOpcode() == iOUTS or
|
||||||
inst.getOpcode() == iREP_OUTS)
|
inst.getOpcode() == iREP_OUTS)
|
||||||
{
|
{
|
||||||
operands_s<<Machine_X86::regName(inst.src().segOver); // szWreg[src.segOver-rAX]
|
operands_s<<Machine_X86::regName(inst.src().segOver); // szWreg[src.segOver-rAX]
|
||||||
@ -436,7 +452,10 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(inst.getFlag() & B)? opcode_with_mods<< "B": opcode_with_mods<< "W";
|
if(inst.getFlag() & B)
|
||||||
|
opcode_with_mods+='B';
|
||||||
|
else
|
||||||
|
opcode_with_mods+='W';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -455,8 +474,8 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
|
|
||||||
case iOUT:
|
case iOUT:
|
||||||
{
|
{
|
||||||
std::string d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
||||||
std::string d2=((inst.getFlag() & B) ? ", al": ", ax");
|
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
|
||||||
operands_s<<d1 << d2;
|
operands_s<<d1 << d2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -464,8 +483,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oper_stream << setw(15) << left <<opcode_with_mods.str();
|
oper_stream.setFieldWidth(15);
|
||||||
oper_stream << operands_s.str();
|
operands_s.flush();
|
||||||
|
oper_stream << qSetFieldWidth(15) << opcode_with_mods << qSetFieldWidth(0) << operands_contents;
|
||||||
/* Comments */
|
/* Comments */
|
||||||
if (inst.testFlags(SYNTHETIC))
|
if (inst.testFlags(SYNTHETIC))
|
||||||
{
|
{
|
||||||
@ -473,21 +493,26 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (j = inst.label, fImpure = 0; j > 0 && j < (int)nextInst; j++)
|
for (j = inst.label, fImpure = 0; j > 0 and j < (int)nextInst; j++)
|
||||||
{
|
{
|
||||||
fImpure |= BITMAP(j, BM_DATA);
|
fImpure |= BITMAP(j, BM_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result_stream.setFieldWidth(54);
|
||||||
result_stream << setw(54) << left << oper_stream.str();
|
result_stream.setFieldAlignment(QTextStream::AlignLeft);
|
||||||
|
oper_stream.flush();
|
||||||
|
result_stream << oper_contents;
|
||||||
|
result_stream.setFieldWidth(0);
|
||||||
/* Check for user supplied comment */
|
/* Check for user supplied comment */
|
||||||
selectTable(Comment);
|
selectTable(Comment);
|
||||||
ostringstream cbuf;
|
QString cbuf_contents;
|
||||||
|
QTextStream cbuf(&cbuf_contents);
|
||||||
if (readVal(cbuf, inst.label, nullptr))
|
if (readVal(cbuf, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
result_stream <<"; "<<cbuf.str();
|
cbuf.flush();
|
||||||
|
result_stream <<"; "<<*cbuf.string();
|
||||||
}
|
}
|
||||||
else if (fImpure || (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
else if (fImpure or (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
||||||
{
|
{
|
||||||
if (inst.testFlags(CASE))
|
if (inst.testFlags(CASE))
|
||||||
{
|
{
|
||||||
@ -525,8 +550,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/* output to .b code buffer */
|
/* output to .b code buffer */
|
||||||
if (inst.testFlags(SYNTHETIC))
|
if (inst.testFlags(SYNTHETIC))
|
||||||
result_stream<<";Synthetic inst";
|
result_stream<<";Synthetic inst";
|
||||||
if (pass == 3) /* output to .b code buffer */
|
if (pass == 3) { /* output to .b code buffer */
|
||||||
cCode.appendCode("%s\n", result_stream.str().c_str());
|
cCode.appendCode("%s\n", qPrintable(result_contents));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -542,7 +568,8 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
sprintf(buf,"%03d ",loc_ip);
|
sprintf(buf,"%03d ",loc_ip);
|
||||||
result_stream<<";Synthetic inst";
|
result_stream<<";Synthetic inst";
|
||||||
}
|
}
|
||||||
m_fp<<buf<< " " << result_stream.str() << "\n";
|
result_stream.flush();
|
||||||
|
m_fp<<buf<< " " << result_contents << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +578,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* formatRM
|
* formatRM
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
static void formatRM(QTextStream &p, const LLOperand &pm)
|
||||||
{
|
{
|
||||||
//char seg[4];
|
//char seg[4];
|
||||||
|
|
||||||
@ -588,7 +615,7 @@ static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* strDst
|
* strDst
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &pm)
|
static QTextStream & strDst(QTextStream &os,uint32_t flg, const LLOperand &pm)
|
||||||
{
|
{
|
||||||
/* Immediates to memory require size descriptor */
|
/* Immediates to memory require size descriptor */
|
||||||
//os << setw(WID_PTR);
|
//os << setw(WID_PTR);
|
||||||
@ -602,7 +629,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* strSrc *
|
* strSrc *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
|
QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma)
|
||||||
{
|
{
|
||||||
if(false==skip_comma)
|
if(false==skip_comma)
|
||||||
os<<", ";
|
os<<", ";
|
||||||
@ -633,14 +660,18 @@ static char *strHex(uint32_t d)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* interactDis - interactive disassembler *
|
* interactDis - interactive disassembler *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void interactDis(Function * /*initProc*/, int /*initIC*/)
|
void interactDis(Function * initProc, int initIC)
|
||||||
{
|
{
|
||||||
printf("Sorry - interactive disasassembler option not available for Unix\n");
|
QString procname = "UNKNOWN";
|
||||||
|
if(initProc)
|
||||||
|
procname = initProc->name;
|
||||||
|
|
||||||
|
qDebug() << "Wanted to start interactive disasassembler for "<<procname<<":"<<initIC;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the floating point opcodes (icode iESC) */
|
/* Handle the floating point opcodes (icode iESC) */
|
||||||
void LLInst::flops(std::ostringstream &out)
|
void LLInst::flops(QTextStream &out)
|
||||||
{
|
{
|
||||||
//char bf[30];
|
//char bf[30];
|
||||||
uint8_t op = (uint8_t)src().getImm2();
|
uint8_t op = (uint8_t)src().getImm2();
|
||||||
@ -652,8 +683,8 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
{
|
{
|
||||||
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
||||||
out<<Machine_X86::floatOpName(op)<<' ';
|
out<<Machine_X86::floatOpName(op)<<' ';
|
||||||
out <<setw(10);
|
out.setFieldWidth(10);
|
||||||
if ((op == 0x29) || (op == 0x1F))
|
if ((op == 0x29) or (op == 0x1F))
|
||||||
{
|
{
|
||||||
out << "tbyte ptr ";
|
out << "tbyte ptr ";
|
||||||
}
|
}
|
||||||
@ -683,7 +714,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out.setFieldWidth(0);
|
||||||
formatRM(out, m_dst);
|
formatRM(out, m_dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -722,7 +753,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out << Machine_X86::floatOpName(0x40+op);
|
out << Machine_X86::floatOpName(0x40+op);
|
||||||
if ((op >= 0x20) && (op <= 0x27))
|
if ((op >= 0x20) and (op <= 0x27))
|
||||||
{
|
{
|
||||||
/* This is the ST(i), ST form. */
|
/* This is the ST(i), ST form. */
|
||||||
out << "ST("<<destRegIdx - rAX<<"),ST";
|
out << "ST("<<destRegIdx - rAX<<"),ST";
|
||||||
|
|||||||
@ -11,36 +11,37 @@
|
|||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
|
||||||
static std::map<eErrorId,std::string> errorMessage =
|
static const std::map<eErrorId,std::string> errorMessage =
|
||||||
{
|
{
|
||||||
{INVALID_ARG ,"Invalid option -%c\n"},
|
{INVALID_ARG ,"Invalid option -%c\n"},
|
||||||
{INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"},
|
{INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"},
|
||||||
{INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"},
|
{INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"},
|
||||||
{FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"},
|
{FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"},
|
||||||
{FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"},
|
{FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"},
|
||||||
{CANNOT_OPEN ,"Cannot open %s\n"},
|
{CANNOT_OPEN ,"Cannot open %s\n"},
|
||||||
{CANNOT_READ ,"Error while reading %s\n"},
|
{CANNOT_READ ,"Error while reading %s\n"},
|
||||||
{MALLOC_FAILED ,"malloc of %ld bytes failed\n"},
|
{MALLOC_FAILED ,"malloc of %ld bytes failed\n"},
|
||||||
{NEWEXE_FORMAT ,"Don't understand new EXE format\n"},
|
{NEWEXE_FORMAT ,"Don't understand new EXE format\n"},
|
||||||
{NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"},
|
{NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"},
|
||||||
{INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
|
{INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
|
||||||
{INVALID_INT_BB ,"Failed to find a BB for interval\n"},
|
{INVALID_INT_BB ,"Failed to find a BB for interval\n"},
|
||||||
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
||||||
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
||||||
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
||||||
{NOT_DEF_USE ,"Def - use not supported. Def op = %d, use op = %d.\n"},
|
{NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"},
|
||||||
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
||||||
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
fatalError: displays error message and exits the program.
|
fatalError: displays error message and exits the program.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void fatalError(eErrorId errId, ...)
|
void fatalError(eErrorId errId, ...)
|
||||||
{ va_list args;
|
{
|
||||||
//#ifdef __UNIX__ /* ultrix */
|
va_list args;
|
||||||
|
//#ifdef __UNIX__ /* ultrix */
|
||||||
#if 0
|
#if 0
|
||||||
int errId;
|
int errId;
|
||||||
|
|
||||||
va_start(args);
|
va_start(args);
|
||||||
errId = va_arg(args, int);
|
errId = va_arg(args, int);
|
||||||
@ -49,10 +50,12 @@ void fatalError(eErrorId errId, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (errId == USAGE)
|
if (errId == USAGE)
|
||||||
fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
|
fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
|
||||||
else {
|
else {
|
||||||
|
auto msg_iter = errorMessage.find(errId);
|
||||||
|
assert(msg_iter!=errorMessage.end());
|
||||||
fprintf(stderr, "dcc: ");
|
fprintf(stderr, "dcc: ");
|
||||||
vfprintf(stderr, errorMessage[errId].c_str(), args);
|
vfprintf(stderr, msg_iter->second.c_str(), args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
exit((int)errId);
|
exit((int)errId);
|
||||||
@ -63,10 +66,11 @@ void fatalError(eErrorId errId, ...)
|
|||||||
reportError: reports the warning/error and continues with the program.
|
reportError: reports the warning/error and continues with the program.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void reportError(eErrorId errId, ...)
|
void reportError(eErrorId errId, ...)
|
||||||
{ va_list args;
|
{
|
||||||
//#ifdef __UNIX__ /* ultrix */
|
va_list args;
|
||||||
|
//#ifdef __UNIX__ /* ultrix */
|
||||||
#if 0
|
#if 0
|
||||||
int errId;
|
int errId;
|
||||||
|
|
||||||
va_start(args);
|
va_start(args);
|
||||||
errId = va_arg(args, int);
|
errId = va_arg(args, int);
|
||||||
@ -74,6 +78,8 @@ void reportError(eErrorId errId, ...)
|
|||||||
va_start(args, errId);
|
va_start(args, errId);
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "dcc: ");
|
fprintf(stderr, "dcc: ");
|
||||||
vfprintf(stderr, errorMessage[errId].c_str(), args);
|
auto msg_iter = errorMessage.find(errId);
|
||||||
|
assert(msg_iter!=errorMessage.end());
|
||||||
|
vfprintf(stderr, msg_iter->second.c_str(), args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,18 +9,15 @@
|
|||||||
* *
|
* *
|
||||||
\* * * * * * * * * * * * */
|
\* * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef PATLEN
|
#ifndef PATLEN
|
||||||
#define PATLEN 23
|
#define PATLEN 23
|
||||||
#define WILD 0xF4
|
#define WILD 0xF4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef bool
|
|
||||||
#define bool unsigned char
|
|
||||||
#define uint8_t unsigned char
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int pc; /* Indexes into pat[] */
|
static int pc; /* Indexes into pat[] */
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
@ -410,7 +407,7 @@ void fixWildCards(uint8_t pat[])
|
|||||||
|
|
||||||
case 0xCD: /* int nn */
|
case 0xCD: /* int nn */
|
||||||
intArg = pat[pc++];
|
intArg = pat[pc++];
|
||||||
if ((intArg >= 0x34) && (intArg <= 0x3B))
|
if ((intArg >= 0x34) and (intArg <= 0x3B))
|
||||||
{
|
{
|
||||||
/* Borland/Microsoft FP emulations */
|
/* Borland/Microsoft FP emulations */
|
||||||
if (ModRM(pat)) return;
|
if (ModRM(pat)) return;
|
||||||
|
|||||||
@ -3,14 +3,15 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <string.h>
|
#include "graph.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
#include <boost/range/rbegin.hpp>
|
#include <boost/range/rbegin.hpp>
|
||||||
#include <boost/range/rend.hpp>
|
#include <boost/range/rend.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
#include <string.h>
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "graph.h"
|
|
||||||
#include "project.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@ -19,6 +20,14 @@ extern Project g_proj;
|
|||||||
//static void mergeFallThrough(Function * pProc, BB * pBB);
|
//static void mergeFallThrough(Function * pProc, BB * pBB);
|
||||||
//static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
|
//static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
|
||||||
|
|
||||||
|
void Function::addOutEdgesForConditionalJump(BB * pBB,int next_ip, LLInst *ll)
|
||||||
|
{
|
||||||
|
pBB->addOutEdge(next_ip);
|
||||||
|
/* This is checking for jumps off into nowhere */
|
||||||
|
if ( not ll->testFlags(NO_LABEL) )
|
||||||
|
pBB->addOutEdge(ll->src().getImm2());
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* createCFG - Create the basic control flow graph
|
* createCFG - Create the basic control flow graph
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -68,16 +77,13 @@ void Function::createCFG()
|
|||||||
case iJO: case iJNO: case iJP: case iJNP:
|
case iJO: case iJNO: case iJP: case iJNP:
|
||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
pBB = BB::Create(current_range, TWO_BRANCH, this);
|
pBB = BB::Create(current_range, TWO_BRANCH, this);
|
||||||
CondJumps:
|
addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll);
|
||||||
pBB->addOutEdge(nextIcode->loc_ip);
|
|
||||||
/* This is checking for jumps off into nowhere */
|
|
||||||
if ( not ll->testFlags(NO_LABEL) )
|
|
||||||
pBB->addOutEdge(ll->src().getImm2());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||||
pBB = BB::Create(current_range, LOOP_NODE, this);
|
pBB = BB::Create(current_range, LOOP_NODE, this);
|
||||||
goto CondJumps;
|
addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll);
|
||||||
|
break;
|
||||||
|
|
||||||
case iJMPF: case iJMP:
|
case iJMPF: case iJMP:
|
||||||
if (ll->testFlags(SWITCH))
|
if (ll->testFlags(SWITCH))
|
||||||
@ -100,7 +106,7 @@ CondJumps:
|
|||||||
{
|
{
|
||||||
Function * p = ll->src().proc.proc;
|
Function * p = ll->src().proc.proc;
|
||||||
pBB = BB::Create(current_range, CALL_NODE, this);
|
pBB = BB::Create(current_range, CALL_NODE, this);
|
||||||
if (p && not ((p->flg) & TERMINATES) )
|
if (p and not ((p->flg) & TERMINATES) )
|
||||||
pBB->addOutEdge(nextIcode->loc_ip);
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -132,6 +138,8 @@ CondJumps:
|
|||||||
// end iterator will be updated by expression in for statement
|
// end iterator will be updated by expression in for statement
|
||||||
current_range=make_iterator_range(nextIcode,nextIcode);
|
current_range=make_iterator_range(nextIcode,nextIcode);
|
||||||
}
|
}
|
||||||
|
if (nextIcode == Icode.end())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (auto pr : m_ip_to_bb)
|
for (auto pr : m_ip_to_bb)
|
||||||
{
|
{
|
||||||
@ -146,7 +154,7 @@ CondJumps:
|
|||||||
}
|
}
|
||||||
auto iter2=m_ip_to_bb.find(ip);
|
auto iter2=m_ip_to_bb.find(ip);
|
||||||
if(iter2==m_ip_to_bb.end())
|
if(iter2==m_ip_to_bb.end())
|
||||||
fatalError(NO_BB, ip, name.c_str());
|
fatalError(NO_BB, ip, qPrintable(name));
|
||||||
psBB = iter2->second;
|
psBB = iter2->second;
|
||||||
elem.BBptr = psBB;
|
elem.BBptr = psBB;
|
||||||
psBB->inEdges.push_back((BB *)nullptr);
|
psBB->inEdges.push_back((BB *)nullptr);
|
||||||
@ -203,7 +211,7 @@ void Function::compressCFG()
|
|||||||
* (Un)Conditional -> Unconditional jump */
|
* (Un)Conditional -> Unconditional jump */
|
||||||
for (BB *pBB : m_actual_cfg) //m_cfg
|
for (BB *pBB : m_actual_cfg) //m_cfg
|
||||||
{
|
{
|
||||||
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
if(pBB->inEdges.empty() or (pBB->nodeType != ONE_BRANCH and pBB->nodeType != TWO_BRANCH))
|
||||||
continue;
|
continue;
|
||||||
for (TYPEADR_TYPE &edgeRef : pBB->edges)
|
for (TYPEADR_TYPE &edgeRef : pBB->edges)
|
||||||
{
|
{
|
||||||
@ -265,7 +273,7 @@ BB *BB::rmJMP(int marker, BB * pBB)
|
|||||||
{
|
{
|
||||||
marker += (int)DFS_JMP;
|
marker += (int)DFS_JMP;
|
||||||
|
|
||||||
while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
|
while (pBB->nodeType == ONE_BRANCH and pBB->size() == 1)
|
||||||
{
|
{
|
||||||
if (pBB->traversed != marker)
|
if (pBB->traversed != marker)
|
||||||
{
|
{
|
||||||
@ -292,7 +300,7 @@ BB *BB::rmJMP(int marker, BB * pBB)
|
|||||||
do {
|
do {
|
||||||
pBB = pBB->edges[0].BBptr;
|
pBB = pBB->edges[0].BBptr;
|
||||||
pBB->inEdges.pop_back(); // was --numInedges
|
pBB->inEdges.pop_back(); // was --numInedges
|
||||||
if (! pBB->inEdges.empty())
|
if (not pBB->inEdges.empty())
|
||||||
{
|
{
|
||||||
pBB->front().ll()->setFlags(NO_CODE);
|
pBB->front().ll()->setFlags(NO_CODE);
|
||||||
pBB->front().invalidate();
|
pBB->front().invalidate();
|
||||||
@ -314,11 +322,11 @@ BB *BB::rmJMP(int marker, BB * pBB)
|
|||||||
void BB::mergeFallThrough( CIcodeRec &Icode)
|
void BB::mergeFallThrough( CIcodeRec &Icode)
|
||||||
{
|
{
|
||||||
BB * pChild;
|
BB * pChild;
|
||||||
if (!this)
|
if (nullptr==this)
|
||||||
{
|
{
|
||||||
printf("mergeFallThrough on empty BB!\n");
|
printf("mergeFallThrough on empty BB!\n");
|
||||||
}
|
}
|
||||||
while (nodeType == FALL_NODE || nodeType == ONE_BRANCH)
|
while (nodeType == FALL_NODE or nodeType == ONE_BRANCH)
|
||||||
{
|
{
|
||||||
pChild = edges[0].BBptr;
|
pChild = edges[0].BBptr;
|
||||||
/* Jump to next instruction can always be removed */
|
/* Jump to next instruction can always be removed */
|
||||||
|
|||||||
165
src/hlicode.cpp
165
src/hlicode.cpp
@ -4,17 +4,17 @@
|
|||||||
* Date: September-October 1993
|
* Date: September-October 1993
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
|
#include "dcc.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "dcc.h"
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static char buf[lineSize]; /* Line buffer for hl icode output */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
||||||
void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
||||||
{
|
{
|
||||||
@ -24,12 +24,12 @@ void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
|||||||
}
|
}
|
||||||
void ICODE::checkHlCall()
|
void ICODE::checkHlCall()
|
||||||
{
|
{
|
||||||
//assert((ll()->immed.proc.cb != 0)||ll()->immed.proc.proc!=0);
|
//assert((ll()->immed.proc.cb != 0) or ll()->immed.proc.proc!=0);
|
||||||
}
|
}
|
||||||
/* Places the new HLI_CALL high-level operand in the high-level icode array */
|
/* Places the new HLI_CALL high-level operand in the high-level icode array */
|
||||||
void ICODE::newCallHl()
|
void ICODE::newCallHl()
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL_ICODE;
|
||||||
hlU()->setCall(ll()->src().proc.proc);
|
hlU()->setCall(ll()->src().proc.proc);
|
||||||
|
|
||||||
if (ll()->src().proc.cb != 0)
|
if (ll()->src().proc.cb != 0)
|
||||||
@ -48,7 +48,7 @@ void ICODE::newCallHl()
|
|||||||
* array */
|
* array */
|
||||||
void ICODE::setUnary(hlIcode op, Expr *_exp)
|
void ICODE::setUnary(hlIcode op, Expr *_exp)
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL_ICODE;
|
||||||
hlU()->set(op,_exp);
|
hlU()->set(op,_exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ void ICODE::setUnary(hlIcode op, Expr *_exp)
|
|||||||
/* Places the new HLI_JCOND high-level operand in the high-level icode array */
|
/* Places the new HLI_JCOND high-level operand in the high-level icode array */
|
||||||
void ICODE::setJCond(Expr *cexp)
|
void ICODE::setJCond(Expr *cexp)
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL_ICODE;
|
||||||
hlU()->set(HLI_JCOND,cexp);
|
hlU()->set(HLI_JCOND,cexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
|||||||
for ( ; numDefs > 0; numDefs--)
|
for ( ; numDefs > 0; numDefs--)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
|
if (du1.used(numDefs-1) or (du.lastDefRegi.testReg(regi)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +320,7 @@ void Function::highLevelGen()
|
|||||||
LLOperand *src_ll = ll->get(SRC);
|
LLOperand *src_ll = ll->get(SRC);
|
||||||
if ( ll->testFlags(NOT_HLL) )
|
if ( ll->testFlags(NOT_HLL) )
|
||||||
pIcode->invalidate();
|
pIcode->invalidate();
|
||||||
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
|
if ((pIcode->type != LOW_LEVEL_ICODE) or not pIcode->valid() )
|
||||||
continue;
|
continue;
|
||||||
_flg = ll->getFlag();
|
_flg = ll->getFlag();
|
||||||
if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
|
if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
|
||||||
@ -328,7 +328,7 @@ void Function::highLevelGen()
|
|||||||
{
|
{
|
||||||
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
||||||
rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
|
rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
|
||||||
if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
|
if(ll->m_dst.isSet() or (ll->getOpcode()==iMOD))
|
||||||
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
||||||
}
|
}
|
||||||
if(ll->getOpcode()==iPUSH) {
|
if(ll->getOpcode()==iPUSH) {
|
||||||
@ -353,7 +353,7 @@ void Function::highLevelGen()
|
|||||||
|
|
||||||
case iCALL:
|
case iCALL:
|
||||||
case iCALLF:
|
case iCALLF:
|
||||||
pIcode->type = HIGH_LEVEL;
|
pIcode->type = HIGH_LEVEL_ICODE;
|
||||||
pIcode->hl( ll->createCall() );
|
pIcode->hl( ll->createCall() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -477,82 +477,68 @@ void Function::highLevelGen()
|
|||||||
|
|
||||||
/* Returns the string that represents the procedure call of tproc (ie. with
|
/* Returns the string that represents the procedure call of tproc (ie. with
|
||||||
* actual parameters) */
|
* actual parameters) */
|
||||||
std::string Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
|
QString Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
|
||||||
{
|
{
|
||||||
//string condExp;
|
//string condExp;
|
||||||
ostringstream ostr;
|
QString ostr;
|
||||||
ostr<<tproc->name<<" (";
|
ostr+=tproc->name+" (";
|
||||||
for(const STKSYM &sym : args)
|
for(const STKSYM &sym : args)
|
||||||
{
|
{
|
||||||
if(sym.actual)
|
if(sym.actual)
|
||||||
ostr << sym.actual->walkCondExpr (this, numLoc);
|
ostr += sym.actual->walkCondExpr(this, numLoc);
|
||||||
else
|
else
|
||||||
ostr << "";
|
ostr += "";
|
||||||
if((&sym)!=&(args.back()))
|
if((&sym)!=&(args.back()))
|
||||||
ostr << ", ";
|
ostr += ", ";
|
||||||
}
|
}
|
||||||
ostr << ")";
|
ostr += ")";
|
||||||
return ostr.str();
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Displays the output of a HLI_JCOND icode. */
|
/* Displays the output of a HLI_JCOND icode. */
|
||||||
const char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
QString writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
memset (buf, ' ', sizeof(buf));
|
|
||||||
buf[0] = '\0';
|
|
||||||
strcat (buf, "if ");
|
|
||||||
if(h.opcode==HLI_INVALID)
|
if(h.opcode==HLI_INVALID)
|
||||||
{
|
{
|
||||||
return "if (*HLI_INVALID*) {\n";
|
return "if (*HLI_INVALID*) {\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(h.expr());
|
assert(h.expr());
|
||||||
Expr *inverted=h.expr()->inverse();
|
Expr *inverted=h.expr()->inverse();
|
||||||
//inverseCondOp (&h.exp);
|
//inverseCondOp (&h.exp);
|
||||||
std::string e = inverted->walkCondExpr (pProc, numLoc);
|
QString inverted_form = inverted->walkCondExpr (pProc, numLoc);
|
||||||
delete inverted;
|
delete inverted;
|
||||||
strcat (buf, e.c_str());
|
|
||||||
strcat (buf, " {\n");
|
return QString("if %1 {\n").arg(inverted_form);
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
||||||
* when the THEN clause of an if..then..else is empty. The clause is
|
* when the THEN clause of an if..then..else is empty. The clause is
|
||||||
* negated and the ELSE clause is used instead. */
|
* negated and the ELSE clause is used instead. */
|
||||||
const char *writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
|
QString writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
memset (buf, ' ', sizeof(buf));
|
QString _form;
|
||||||
buf[0] = '\0';
|
|
||||||
strcat (buf, "if ");
|
|
||||||
std::string e;
|
|
||||||
if(h.expr()==nullptr)
|
if(h.expr()==nullptr)
|
||||||
e = "( *failed condition recovery* )";
|
_form = "( *failed condition recovery* )";
|
||||||
else
|
else
|
||||||
e = h.expr()->walkCondExpr (pProc, numLoc);
|
_form = h.expr()->walkCondExpr (pProc, numLoc);
|
||||||
|
return QString("if %1 {\n").arg(_form);
|
||||||
strcat (buf, e.c_str());
|
|
||||||
strcat (buf, " {\n");
|
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string AssignType::writeOut(Function *pProc, int *numLoc) const
|
QString AssignType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
return QString("%1 = %2;\n")
|
||||||
ostr << m_lhs->walkCondExpr (pProc, numLoc);
|
.arg(m_lhs->walkCondExpr (pProc, numLoc))
|
||||||
ostr << " = ";
|
.arg(m_rhs->walkCondExpr (pProc, numLoc));
|
||||||
ostr << rhs->walkCondExpr (pProc, numLoc);
|
|
||||||
ostr << ";\n";
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
string CallType::writeOut(Function *pProc, int *numLoc) const
|
QString CallType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
return pProc->writeCall (proc, *args, numLoc) + ";\n";
|
||||||
ostr << pProc->writeCall (proc, *args, numLoc);
|
|
||||||
ostr << ";\n";
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
string ExpType::writeOut(Function *pProc, int *numLoc) const
|
QString ExpType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
if(v==nullptr)
|
if(v==nullptr)
|
||||||
return "";
|
return "";
|
||||||
@ -567,44 +553,39 @@ void HLTYPE::set(Expr *l, Expr *r)
|
|||||||
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
||||||
assert(dynamic_cast<UnaryOperator *>(l));
|
assert(dynamic_cast<UnaryOperator *>(l));
|
||||||
asgn.m_lhs=l;
|
asgn.m_lhs=l;
|
||||||
asgn.rhs=r;
|
asgn.m_rhs=r;
|
||||||
}
|
}
|
||||||
/* Returns a string with the contents of the current high-level icode.
|
/* Returns a string with the contents of the current high-level icode.
|
||||||
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
||||||
* done in a separate routine to be able to support the removal of
|
* done in a separate routine to be able to support the removal of
|
||||||
* empty THEN clauses on an if..then..else. */
|
* empty THEN clauses on an if..then..else. */
|
||||||
string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
|
QString HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
string e;
|
|
||||||
ostringstream ostr;
|
|
||||||
const HlTypeSupport *p = get();
|
const HlTypeSupport *p = get();
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
return p->writeOut(pProc,numLoc);
|
return p->writeOut(pProc,numLoc);
|
||||||
case HLI_CALL:
|
case HLI_CALL:
|
||||||
return p->writeOut(pProc,numLoc);
|
return p->writeOut(pProc,numLoc);
|
||||||
case HLI_RET:
|
case HLI_RET:
|
||||||
e = p->writeOut(pProc,numLoc);
|
{
|
||||||
if (! e.empty())
|
QString e;
|
||||||
ostr << "return (" << e << ");\n";
|
e = p->writeOut(pProc,numLoc);
|
||||||
break;
|
if (not e.isEmpty())
|
||||||
case HLI_POP:
|
return QString("return (%1);\n").arg(e);
|
||||||
ostr << "HLI_POP ";
|
break;
|
||||||
ostr << p->writeOut(pProc,numLoc);
|
|
||||||
ostr << "\n";
|
|
||||||
break;
|
|
||||||
case HLI_PUSH:
|
|
||||||
ostr << "HLI_PUSH ";
|
|
||||||
ostr << p->writeOut(pProc,numLoc);
|
|
||||||
ostr << "\n";
|
|
||||||
break;
|
|
||||||
case HLI_JCOND: //Handled elsewhere
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr," HLTYPE::write1HlIcode - Unhandled opcode %d\n",opcode);
|
|
||||||
}
|
}
|
||||||
return ostr.str();
|
case HLI_POP:
|
||||||
|
return QString("HLI_POP %1\n").arg(p->writeOut(pProc,numLoc));
|
||||||
|
case HLI_PUSH:
|
||||||
|
return QString("HLI_PUSH %1\n").arg(p->writeOut(pProc,numLoc));
|
||||||
|
case HLI_JCOND: //Handled elsewhere
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCritical() << " HLTYPE::write1HlIcode - Unhandled opcode" << opcode;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -619,16 +600,22 @@ void ICODE::writeDU()
|
|||||||
{
|
{
|
||||||
int my_idx = loc_ip;
|
int my_idx = loc_ip;
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
Machine_X86::writeRegVector(ostr,du.def);
|
{
|
||||||
if (!ostr.str().empty())
|
QTextStream ostr(&ostr_contents);
|
||||||
printf ("Def (reg) = %s\n", ostr.str().c_str());
|
Machine_X86::writeRegVector(ostr,du.def);
|
||||||
|
}
|
||||||
|
if (not ostr_contents.isEmpty())
|
||||||
|
qDebug() << QString("Def (reg) = %1\n").arg(ostr_contents);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
Machine_X86::writeRegVector(ostr,du.use);
|
{
|
||||||
if (!ostr.str().empty())
|
QTextStream ostr(&ostr_contents);
|
||||||
printf ("Use (reg) = %s\n", ostr.str().c_str());
|
Machine_X86::writeRegVector(ostr,du.use);
|
||||||
|
}
|
||||||
|
if (not ostr_contents.isEmpty())
|
||||||
|
qDebug() << QString("Use (reg) = %1\n").arg(ostr_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print du1 chain */
|
/* Print du1 chain */
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
// Object oriented icode code for dcc
|
// Object oriented icode code for dcc
|
||||||
// (C) 1997 Mike Van Emmerik
|
// (C) 1997 Mike Van Emmerik
|
||||||
|
#include "icode.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "types.h" // Common types like uint8_t, etc
|
#include "types.h" // Common types like uint8_t, etc
|
||||||
#include "ast.h" // Some icode types depend on these
|
#include "ast.h" // Some icode types depend on these
|
||||||
#include "icode.h"
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
|
ICODE::TypeFilter<HIGH_LEVEL_ICODE> ICODE::select_high_level;
|
||||||
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
|
ICODE::TypeAndValidFilter<HIGH_LEVEL_ICODE> ICODE::select_valid_high_level;
|
||||||
CIcodeRec::CIcodeRec()
|
CIcodeRec::CIcodeRec()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ void LLInst::emitGotoLabel (int indLevel)
|
|||||||
|
|
||||||
bool LLOperand::isReg() const
|
bool LLOperand::isReg() const
|
||||||
{
|
{
|
||||||
return (regi>=rAX) && (regi<=rTMP);
|
return (regi>=rAX) and (regi<=rTMP);
|
||||||
}
|
}
|
||||||
void LLOperand::addProcInformation(int param_count, CConv::Type call_conv)
|
void LLOperand::addProcInformation(int param_count, CConv::Type call_conv)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,14 +4,11 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//#include <llvm/Config/llvm-config.h>
|
//#include <llvm/Config/llvm-config.h>
|
||||||
//#if( (LLVM_VERSION_MAJOR==3 ) && (LLVM_VERSION_MINOR>3) )
|
//#if( (LLVM_VERSION_MAJOR==3 ) and (LLVM_VERSION_MINOR>3) )
|
||||||
//#include <llvm/IR/PatternMatch.h>
|
//#include <llvm/IR/PatternMatch.h>
|
||||||
//#else
|
//#else
|
||||||
//#include <llvm/Support/PatternMatch.h>
|
//#include <llvm/Support/PatternMatch.h>
|
||||||
//#endif
|
//#endif
|
||||||
#include <boost/iterator/filter_iterator.hpp>
|
|
||||||
#include <cstring>
|
|
||||||
#include <deque>
|
|
||||||
#include "idiom.h"
|
#include "idiom.h"
|
||||||
#include "idiom1.h"
|
#include "idiom1.h"
|
||||||
#include "epilogue_idioms.h"
|
#include "epilogue_idioms.h"
|
||||||
@ -22,6 +19,11 @@
|
|||||||
#include "shift_idioms.h"
|
#include "shift_idioms.h"
|
||||||
#include "arith_idioms.h"
|
#include "arith_idioms.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
#include <deque>
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* JmpInst - Returns true if opcode is a conditional or unconditional jump
|
* JmpInst - Returns true if opcode is a conditional or unconditional jump
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -122,11 +124,11 @@ void Function::findIdioms()
|
|||||||
/* Check for library functions that return a long register.
|
/* Check for library functions that return a long register.
|
||||||
* Propagate this result */
|
* Propagate this result */
|
||||||
if (pIcode->ll()->src().proc.proc != nullptr)
|
if (pIcode->ll()->src().proc.proc != nullptr)
|
||||||
if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) &&
|
if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) and
|
||||||
(pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
|
(pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
|
||||||
{
|
{
|
||||||
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
||||||
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
|
or (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
|
||||||
localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
|
localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,14 +211,14 @@ void Function::findIdioms()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if number of parameter bytes match their calling convention */
|
/* Check if number of parameter bytes match their calling convention */
|
||||||
if ((flg & PROC_HLL) && (!args.empty()))
|
if ((flg & PROC_HLL) and (not args.empty()))
|
||||||
{
|
{
|
||||||
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
|
args.m_minOff += ((flg & PROC_FAR)!=0 ? 4 : 2);
|
||||||
delta = args.maxOff - args.m_minOff;
|
delta = args.maxOff - args.m_minOff;
|
||||||
if (cbParam != delta)
|
if (cbParam != delta)
|
||||||
{
|
{
|
||||||
cbParam = delta;
|
cbParam = delta;
|
||||||
callingConv(CConv::UNKNOWN);
|
callingConv(CConv::eUnknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,7 +238,7 @@ void Function::bindIcodeOff()
|
|||||||
for(ICODE &c : Icode) // TODO: use filtered here
|
for(ICODE &c : Icode) // TODO: use filtered here
|
||||||
{
|
{
|
||||||
LLInst *ll=c.ll();
|
LLInst *ll=c.ll();
|
||||||
if (ll->testFlags(I) && ll->isJmpInst())
|
if (ll->testFlags(I) and ll->isJmpInst())
|
||||||
{
|
{
|
||||||
iICODE loc=Icode.labelSrch(ll->src().getImm2());
|
iICODE loc=Icode.labelSrch(ll->src().getImm2());
|
||||||
if (loc!=Icode.end())
|
if (loc!=Icode.end())
|
||||||
@ -256,7 +258,7 @@ void Function::bindIcodeOff()
|
|||||||
if (ll->testFlags(I) )
|
if (ll->testFlags(I) )
|
||||||
{
|
{
|
||||||
uint32_t found;
|
uint32_t found;
|
||||||
if (! Icode.labelSrch(ll->src().getImm2(), found))
|
if (not Icode.labelSrch(ll->src().getImm2(), found))
|
||||||
ll->setFlags( NO_LABEL );
|
ll->setFlags( NO_LABEL );
|
||||||
else
|
else
|
||||||
ll->replaceSrc(LLOperand::CreateImm2(found));
|
ll->replaceSrc(LLOperand::CreateImm2(found));
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "arith_idioms.h"
|
#include "arith_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -105,7 +110,7 @@ bool Idiom18::match(iICODE picode)
|
|||||||
if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
|
if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
|
||||||
return false;
|
return false;
|
||||||
regi = m_icodes[0]->ll()->m_dst.regi;
|
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
|
if( not ( m_icodes[2]->ll()->match(iCMP,regi) and
|
||||||
m_icodes[3]->ll()->conditionalJump() ) )
|
m_icodes[3]->ll()->conditionalJump() ) )
|
||||||
return false;
|
return false;
|
||||||
// Simple matching finished, select apropriate matcher based on dst type
|
// Simple matching finished, select apropriate matcher based on dst type
|
||||||
@ -118,9 +123,9 @@ bool Idiom18::match(iICODE picode)
|
|||||||
else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
|
else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
m_idiom_type = 1;
|
m_idiom_type = 1;
|
||||||
// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
// if ((m_icodes[1]->ll()->dst.regi == rSI) and (m_func->flg & SI_REGVAR))
|
||||||
// m_idiom_type = 1;
|
// m_idiom_type = 1;
|
||||||
// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
// else if ((m_icodes[1]->ll()->dst.regi == rDI) and (m_func->flg & DI_REGVAR))
|
||||||
// m_idiom_type = 1;
|
// m_idiom_type = 1;
|
||||||
}
|
}
|
||||||
else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
|
else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
|
||||||
@ -131,7 +136,8 @@ bool Idiom18::match(iICODE picode)
|
|||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
ICODE &ic(*picode);
|
ICODE &ic(*picode);
|
||||||
const Function *my_proc(ic.getParent()->getParent());
|
const Function *my_proc(ic.getParent()->getParent());
|
||||||
printf("Unsupported idiom18 type at %x in %s:%x : indexed\n",ic.loc_ip,my_proc->name.c_str(),my_proc->procEntry);
|
qWarning() << "Unsupported idiom18 type at"<< QString::number(ic.loc_ip,16)
|
||||||
|
<< "in"<< my_proc->name <<':'<< QString::number(my_proc->procEntry,16) << "- indexed";
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(m_idiom_type)
|
switch(m_idiom_type)
|
||||||
@ -141,13 +147,13 @@ bool Idiom18::match(iICODE picode)
|
|||||||
break;
|
break;
|
||||||
case 1: /* register variable */
|
case 1: /* register variable */
|
||||||
/* Check previous instruction for a MOV */
|
/* Check previous instruction for a MOV */
|
||||||
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
|
if ( m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* local */
|
case 2: /* local */
|
||||||
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
|
if (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -204,8 +210,8 @@ bool Idiom19::match(iICODE picode)
|
|||||||
/* not supported yet */ ;
|
/* not supported yet */ ;
|
||||||
else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
|
else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
|
// if (((picode->ll()->dst.regi == rSI) and (pproc->flg & SI_REGVAR)) or
|
||||||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
// ((picode->ll()->dst.regi == rDI) and (pproc->flg & DI_REGVAR)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
|
else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
|
||||||
@ -271,9 +277,9 @@ bool Idiom20::match(iICODE picode)
|
|||||||
else if ( ll_dest.isReg() ) /* register */
|
else if ( ll_dest.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
type = 1;
|
type = 1;
|
||||||
// if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
|
// if ((ll_dest.regi == rSI) and (m_func->flg & SI_REGVAR))
|
||||||
// type = 1;
|
// type = 1;
|
||||||
// else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
|
// else if ((ll_dest.regi == rDI) and (m_func->flg & DI_REGVAR))
|
||||||
// type = 1;
|
// type = 1;
|
||||||
}
|
}
|
||||||
else if (ll_dest.off) /* local variable */
|
else if (ll_dest.off) /* local variable */
|
||||||
@ -286,7 +292,7 @@ bool Idiom20::match(iICODE picode)
|
|||||||
}
|
}
|
||||||
regi = m_icodes[1]->ll()->m_dst.regi;
|
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||||
const LLOperand &mov_src(m_icodes[1]->ll()->src());
|
const LLOperand &mov_src(m_icodes[1]->ll()->src());
|
||||||
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
|
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) and m_icodes[3]->ll()->conditionalJump())
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "call_idioms.h"
|
#include "call_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* idiom3 - C calling convention.
|
* idiom3 - C calling convention.
|
||||||
@ -22,7 +25,7 @@ bool Idiom3::match(iICODE picode)
|
|||||||
/* Match ADD SP, immed */
|
/* Match ADD SP, immed */
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
m_icodes[i] = picode++;
|
m_icodes[i] = picode++;
|
||||||
if ( m_icodes[1]->ll()->testFlags(I) && m_icodes[1]->ll()->match(iADD,rSP))
|
if ( m_icodes[1]->ll()->testFlags(I) and m_icodes[1]->ll()->match(iADD,rSP))
|
||||||
{
|
{
|
||||||
m_param_count = m_icodes[1]->ll()->src().getImm2();
|
m_param_count = m_icodes[1]->ll()->src().getImm2();
|
||||||
return true;
|
return true;
|
||||||
@ -38,7 +41,7 @@ int Idiom3::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I) )
|
if (m_icodes[0]->ll()->testFlags(I) )
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -78,10 +81,10 @@ bool Idiom17::match(iICODE picode)
|
|||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
regi = m_icodes[1]->ll()->m_dst.regi;
|
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||||
if ((regi >= rAX) && (regi <= rBX))
|
if ((regi >= rAX) and (regi <= rBX))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
while (picode != m_end && picode->ll()->match(iPOP))
|
while (picode != m_end and picode->ll()->match(iPOP))
|
||||||
{
|
{
|
||||||
if (picode->ll()->m_dst.regi != regi)
|
if (picode->ll()->m_dst.regi != regi)
|
||||||
break;
|
break;
|
||||||
@ -96,7 +99,7 @@ int Idiom17::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I))
|
if (m_icodes[0]->ll()->testFlags(I))
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
|
||||||
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
||||||
{
|
{
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "epilogue_idioms.h"
|
#include "epilogue_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* popStkVars - checks for
|
* popStkVars - checks for
|
||||||
* [POP DI]
|
* [POP DI]
|
||||||
@ -14,9 +16,9 @@ void EpilogIdiom::popStkVars(iICODE pIcode)
|
|||||||
/* Match [POP DI] */
|
/* Match [POP DI] */
|
||||||
if (pIcode->ll()->match(iPOP))
|
if (pIcode->ll()->match(iPOP))
|
||||||
{
|
{
|
||||||
if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI))
|
if ((m_func->flg & DI_REGVAR) and pIcode->ll()->match(rDI))
|
||||||
m_icodes.push_front(pIcode);
|
m_icodes.push_front(pIcode);
|
||||||
else if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI))
|
else if ((m_func->flg & SI_REGVAR) and pIcode->ll()->match(rSI))
|
||||||
m_icodes.push_front(pIcode);
|
m_icodes.push_front(pIcode);
|
||||||
}
|
}
|
||||||
++pIcode;
|
++pIcode;
|
||||||
@ -25,9 +27,9 @@ void EpilogIdiom::popStkVars(iICODE pIcode)
|
|||||||
/* Match [POP SI] */
|
/* Match [POP SI] */
|
||||||
if (pIcode->ll()->match(iPOP))
|
if (pIcode->ll()->match(iPOP))
|
||||||
{
|
{
|
||||||
if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI))
|
if ((m_func->flg & SI_REGVAR) and pIcode->ll()->match(rSI))
|
||||||
m_icodes.push_front(pIcode);
|
m_icodes.push_front(pIcode);
|
||||||
else if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI))
|
else if ((m_func->flg & DI_REGVAR) and pIcode->ll()->match(rDI))
|
||||||
m_icodes.push_front(pIcode);
|
m_icodes.push_front(pIcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,7 +48,7 @@ bool Idiom2::match(iICODE pIcode)
|
|||||||
iICODE nicode;
|
iICODE nicode;
|
||||||
if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
|
if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
|
||||||
return false;
|
return false;
|
||||||
if ( pIcode->ll()->testFlags(I) || (not pIcode->ll()->match(rSP,rBP)) )
|
if ( pIcode->ll()->testFlags(I) or (not pIcode->ll()->match(rSP,rBP)) )
|
||||||
return false;
|
return false;
|
||||||
if(distance(pIcode,m_end)<3)
|
if(distance(pIcode,m_end)<3)
|
||||||
return false;
|
return false;
|
||||||
@ -55,21 +57,21 @@ bool Idiom2::match(iICODE pIcode)
|
|||||||
m_icodes.push_back(pIcode);
|
m_icodes.push_back(pIcode);
|
||||||
/* Get next icode, skip over holes in the icode array */
|
/* Get next icode, skip over holes in the icode array */
|
||||||
nicode = ++iICODE(pIcode);
|
nicode = ++iICODE(pIcode);
|
||||||
while (nicode->ll()->testFlags(NO_CODE) && (nicode != m_end))
|
while (nicode->ll()->testFlags(NO_CODE) and (nicode != m_end))
|
||||||
{
|
{
|
||||||
nicode++;
|
nicode++;
|
||||||
}
|
}
|
||||||
if(nicode == m_end)
|
if(nicode == m_end)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (nicode->ll()->match(iPOP,rBP) && ! (nicode->ll()->testFlags(I | TARGET | CASE)) )
|
if (nicode->ll()->match(iPOP,rBP) and not (nicode->ll()->testFlags(I | TARGET | CASE)) )
|
||||||
{
|
{
|
||||||
m_icodes.push_back(nicode++); // Matched POP BP
|
m_icodes.push_back(nicode++); // Matched POP BP
|
||||||
|
|
||||||
/* Match RET(F) */
|
/* Match RET(F) */
|
||||||
if ( nicode != m_end &&
|
if ( nicode != m_end and
|
||||||
!(nicode->ll()->testFlags(I | TARGET | CASE)) &&
|
not (nicode->ll()->testFlags(I | TARGET | CASE)) and
|
||||||
(nicode->ll()->match(iRET) || nicode->ll()->match(iRETF))
|
(nicode->ll()->match(iRET) or nicode->ll()->match(iRETF))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_icodes.push_back(nicode); // Matched RET
|
m_icodes.push_back(nicode); // Matched RET
|
||||||
@ -118,7 +120,7 @@ bool Idiom4::match(iICODE pIcode)
|
|||||||
{
|
{
|
||||||
iICODE prev1 = --iICODE(pIcode);
|
iICODE prev1 = --iICODE(pIcode);
|
||||||
/* Check for POP BP */
|
/* Check for POP BP */
|
||||||
if (prev1->ll()->match(iPOP,rBP) && not prev1->ll()->testFlags(I) )
|
if (prev1->ll()->match(iPOP,rBP) and not prev1->ll()->testFlags(I) )
|
||||||
m_icodes.push_back(prev1);
|
m_icodes.push_back(prev1);
|
||||||
else if(prev1!=m_func->Icode.begin())
|
else if(prev1!=m_func->Icode.begin())
|
||||||
{
|
{
|
||||||
@ -138,7 +140,7 @@ bool Idiom4::match(iICODE pIcode)
|
|||||||
}
|
}
|
||||||
int Idiom4::action()
|
int Idiom4::action()
|
||||||
{
|
{
|
||||||
if( ! m_icodes.empty()) // if not an empty RET[F] N
|
if( not m_icodes.empty()) // if not an empty RET[F] N
|
||||||
{
|
{
|
||||||
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
@ -146,7 +148,7 @@ int Idiom4::action()
|
|||||||
if(m_param_count)
|
if(m_param_count)
|
||||||
{
|
{
|
||||||
m_func->cbParam = (int16_t)m_param_count;
|
m_func->cbParam = (int16_t)m_param_count;
|
||||||
m_func->callingConv(CConv::PASCAL);
|
m_func->callingConv(CConv::ePascal);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "idiom1.h"
|
#include "idiom1.h"
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* checkStkVars - Checks for PUSH SI
|
* checkStkVars - Checks for PUSH SI
|
||||||
@ -19,14 +22,14 @@ int Idiom1::checkStkVars (iICODE pIcode)
|
|||||||
{
|
{
|
||||||
si_matched = 1;
|
si_matched = 1;
|
||||||
++pIcode;
|
++pIcode;
|
||||||
if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI
|
if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI
|
||||||
di_matched = 1;
|
di_matched = 1;
|
||||||
}
|
}
|
||||||
else if (pIcode->ll()->match(iPUSH,rDI))
|
else if (pIcode->ll()->match(iPUSH,rDI))
|
||||||
{
|
{
|
||||||
di_matched = 1;
|
di_matched = 1;
|
||||||
++pIcode;
|
++pIcode;
|
||||||
if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI
|
if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI
|
||||||
si_matched = 1;
|
si_matched = 1;
|
||||||
}
|
}
|
||||||
m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0);
|
m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0);
|
||||||
@ -60,13 +63,13 @@ bool Idiom1::match(iICODE picode)
|
|||||||
m_icodes.clear();
|
m_icodes.clear();
|
||||||
m_min_off = 0;
|
m_min_off = 0;
|
||||||
/* PUSH BP as first instruction of procedure */
|
/* PUSH BP as first instruction of procedure */
|
||||||
if ( (not picode->ll()->testFlags(I)) && picode->ll()->src().regi == rBP)
|
if ( (not picode->ll()->testFlags(I)) and picode->ll()->src().regi == rBP)
|
||||||
{
|
{
|
||||||
m_icodes.push_back( picode++ ); // insert iPUSH
|
m_icodes.push_back( picode++ ); // insert iPUSH
|
||||||
if(picode==m_end)
|
if(picode==m_end)
|
||||||
return false;
|
return false;
|
||||||
/* MOV BP, SP as next instruction */
|
/* MOV BP, SP as next instruction */
|
||||||
if ( !picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iMOV ,rBP,rSP) )
|
if ( not picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iMOV ,rBP,rSP) )
|
||||||
{
|
{
|
||||||
m_icodes.push_back( picode++ ); // insert iMOV
|
m_icodes.push_back( picode++ ); // insert iMOV
|
||||||
if(picode==m_end)
|
if(picode==m_end)
|
||||||
@ -75,7 +78,7 @@ bool Idiom1::match(iICODE picode)
|
|||||||
|
|
||||||
/* Look for SUB SP, immed */
|
/* Look for SUB SP, immed */
|
||||||
if (
|
if (
|
||||||
picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iSUB,rSP)
|
picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iSUB,rSP)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_icodes.push_back( picode++ ); // insert iSUB
|
m_icodes.push_back( picode++ ); // insert iSUB
|
||||||
@ -98,8 +101,8 @@ bool Idiom1::match(iICODE picode)
|
|||||||
if(picode == m_end)
|
if(picode == m_end)
|
||||||
return false;
|
return false;
|
||||||
/* Look for MOV BP, SP */
|
/* Look for MOV BP, SP */
|
||||||
if ( picode != m_end &&
|
if ( picode != m_end and
|
||||||
!picode->ll()->testFlags(I | TARGET | CASE) &&
|
not picode->ll()->testFlags(I | TARGET | CASE) and
|
||||||
picode->ll()->match(iMOV,rBP,rSP))
|
picode->ll()->match(iMOV,rBP,rSP))
|
||||||
{
|
{
|
||||||
m_icodes.push_back(picode);
|
m_icodes.push_back(picode);
|
||||||
@ -119,7 +122,7 @@ bool Idiom1::match(iICODE picode)
|
|||||||
m_icodes.push_back(picode++);
|
m_icodes.push_back(picode++);
|
||||||
|
|
||||||
}
|
}
|
||||||
return !m_icodes.empty();
|
return not m_icodes.empty();
|
||||||
}
|
}
|
||||||
int Idiom1::action()
|
int Idiom1::action()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "mov_idioms.h"
|
#include "mov_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -30,17 +33,17 @@ bool Idiom14::match(iICODE pIcode)
|
|||||||
LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()};
|
LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()};
|
||||||
/* Check for regL */
|
/* Check for regL */
|
||||||
m_regL = matched[0]->m_dst.regi;
|
m_regL = matched[0]->m_dst.regi;
|
||||||
if (not matched[0]->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
if (not matched[0]->testFlags(I) and ((m_regL == rAX) or (m_regL ==rBX)))
|
||||||
{
|
{
|
||||||
/* Check for XOR regH, regH */
|
/* Check for XOR regH, regH */
|
||||||
if (matched[1]->match(iXOR) && not matched[1]->testFlags(I))
|
if (matched[1]->match(iXOR) and not matched[1]->testFlags(I))
|
||||||
{
|
{
|
||||||
m_regH = matched[1]->m_dst.regi;
|
m_regH = matched[1]->m_dst.regi;
|
||||||
if (m_regH == matched[1]->src().getReg2())
|
if (m_regH == matched[1]->src().getReg2())
|
||||||
{
|
{
|
||||||
if ((m_regL == rAX) && (m_regH == rDX))
|
if ((m_regL == rAX) and (m_regH == rDX))
|
||||||
return true;
|
return true;
|
||||||
if ((m_regL == rBX) && (m_regH == rCX))
|
if ((m_regL == rBX) and (m_regH == rCX))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,10 +84,10 @@ bool Idiom13::match(iICODE pIcode)
|
|||||||
|
|
||||||
/* Check for regL */
|
/* Check for regL */
|
||||||
regi = m_icodes[0]->ll()->m_dst.regi;
|
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
|
if (not m_icodes[0]->ll()->testFlags(I) and (regi >= rAL) and (regi <= rBH))
|
||||||
{
|
{
|
||||||
/* Check for MOV regH, 0 */
|
/* Check for MOV regH, 0 */
|
||||||
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
|
if (m_icodes[1]->ll()->match(iMOV,I) and (m_icodes[1]->ll()->src().getImm2() == 0))
|
||||||
{
|
{
|
||||||
if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "neg_idioms.h"
|
#include "neg_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
@ -23,7 +26,7 @@ bool Idiom11::match (iICODE picode)
|
|||||||
for(int i=0; i<3; ++i)
|
for(int i=0; i<3; ++i)
|
||||||
m_icodes[i]=picode++;
|
m_icodes[i]=picode++;
|
||||||
type = m_icodes[0]->ll()->idType(DST);
|
type = m_icodes[0]->ll()->idType(DST);
|
||||||
if(type==CONSTANT || type == OTHER)
|
if(type==CONSTANT or type == OTHER)
|
||||||
return false;
|
return false;
|
||||||
/* Check NEG reg/mem
|
/* Check NEG reg/mem
|
||||||
* SBB reg/mem, 0*/
|
* SBB reg/mem, 0*/
|
||||||
@ -32,7 +35,7 @@ bool Idiom11::match (iICODE picode)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
|
if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) and
|
||||||
(m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
|
(m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
@ -83,11 +86,11 @@ bool Idiom16::match (iICODE picode)
|
|||||||
m_icodes[i]=picode++;
|
m_icodes[i]=picode++;
|
||||||
|
|
||||||
uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
|
uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if ((regi >= rAX) && (regi < INDEX_BX_SI))
|
if ((regi >= rAX) and (regi < INDEX_BX_SI))
|
||||||
{
|
{
|
||||||
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
|
if (m_icodes[1]->ll()->match(iSBB) and m_icodes[2]->ll()->match(iINC))
|
||||||
if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
|
if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) and
|
||||||
m_icodes[1]->ll()->match((eReg)regi) &&
|
m_icodes[1]->ll()->match((eReg)regi) and
|
||||||
m_icodes[2]->ll()->match((eReg)regi))
|
m_icodes[2]->ll()->match((eReg)regi))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "shift_idioms.h"
|
#include "shift_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
@ -18,8 +21,8 @@ bool Idiom8::match(iICODE pIcode)
|
|||||||
return false;
|
return false;
|
||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=pIcode++;
|
||||||
if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
|
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1))
|
||||||
if ( m_icodes[1]->ll()->match(iRCR,I) &&
|
if ( m_icodes[1]->ll()->match(iRCR,I) and
|
||||||
(m_icodes[1]->ll()->src().getImm2() == 1))
|
(m_icodes[1]->ll()->src().getImm2() == 1))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@ -107,8 +110,8 @@ bool Idiom12::match(iICODE pIcode)
|
|||||||
return false;
|
return false;
|
||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=pIcode++;
|
||||||
if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
|
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1))
|
||||||
if (m_icodes[1]->ll()->match(iRCL,I) && (m_icodes[1]->ll()->src().getImm2() == 1))
|
if (m_icodes[1]->ll()->match(iRCL,I) and (m_icodes[1]->ll()->src().getImm2() == 1))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -147,8 +150,8 @@ bool Idiom9::match(iICODE pIcode)
|
|||||||
return false;
|
return false;
|
||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=pIcode++;
|
||||||
if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
|
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1))
|
||||||
if (m_icodes[1]->ll()->match(iRCR,I) && (m_icodes[1]->ll()->src().getImm2() == 1))
|
if (m_icodes[1]->ll()->match(iRCR,I) and (m_icodes[1]->ll()->src().getImm2() == 1))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "dcc.h"
|
|
||||||
#include "xor_idioms.h"
|
#include "xor_idioms.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -28,11 +31,11 @@ bool Idiom21::match (iICODE picode)
|
|||||||
|
|
||||||
dst = &m_icodes[0]->ll()->m_dst;
|
dst = &m_icodes[0]->ll()->m_dst;
|
||||||
src = &m_icodes[0]->ll()->src();
|
src = &m_icodes[0]->ll()->src();
|
||||||
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
|
if ((dst->regi == src->getReg2()) and (dst->getReg2() > 0) and (dst->getReg2() < INDEX_BX_SI))
|
||||||
{
|
{
|
||||||
if ((dst->getReg2() == rDX) && m_icodes[1]->ll()->match(rAX))
|
if ((dst->getReg2() == rDX) and m_icodes[1]->ll()->match(rAX))
|
||||||
return true;
|
return true;
|
||||||
if ((dst->getReg2() == rCX) && m_icodes[1]->ll()->match(rBX))
|
if ((dst->getReg2() == rCX) and m_icodes[1]->ll()->match(rBX))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -67,7 +70,7 @@ bool Idiom7::match(iICODE picode)
|
|||||||
src = &picode->ll()->src();
|
src = &picode->ll()->src();
|
||||||
if (dst->regi == 0) /* global variable */
|
if (dst->regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
if ((dst->segValue == src->segValue) && (dst->off == src->off))
|
if ((dst->segValue == src->segValue) and (dst->off == src->off))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (dst->regi < INDEX_BX_SI) /* register */
|
else if (dst->regi < INDEX_BX_SI) /* register */
|
||||||
@ -75,9 +78,9 @@ bool Idiom7::match(iICODE picode)
|
|||||||
if (dst->regi == src->regi)
|
if (dst->regi == src->regi)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEX_BP)) /* offset from BP */
|
else if ((dst->off) and (dst->seg == rSS) and (dst->regi == INDEX_BP)) /* offset from BP */
|
||||||
{
|
{
|
||||||
if ((dst->off == src->off) && (dst->seg == src->seg) && (dst->regi == src->regi))
|
if ((dst->off == src->off) and (dst->seg == src->seg) and (dst->regi == src->regi))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -114,8 +117,8 @@ bool Idiom10::match(iICODE pIcode)
|
|||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=pIcode++;
|
||||||
/* Check OR reg, reg */
|
/* Check OR reg, reg */
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) &&
|
if (not m_icodes[0]->ll()->testFlags(I) and
|
||||||
m_icodes[0]->ll()->src().isReg() &&
|
m_icodes[0]->ll()->src().isReg() and
|
||||||
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
|
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
|
||||||
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
||||||
{
|
{
|
||||||
|
|||||||
212
src/locident.cpp
212
src/locident.cpp
@ -4,10 +4,18 @@
|
|||||||
* Date: October 1993
|
* Date: October 1993
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
|
#include "locident.h"
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "locident.h"
|
#include <QtCore/QDebug>
|
||||||
#include "dcc.h"
|
|
||||||
|
static const int LOCAL_ID_DELTA = 25;
|
||||||
|
static const int IDX_ARRAY_DELTA = 5;
|
||||||
|
|
||||||
|
|
||||||
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
||||||
{
|
{
|
||||||
return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
|
return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
|
||||||
@ -23,7 +31,7 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
|||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=f;
|
loc=f;
|
||||||
assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
|
assert(not ((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN)));
|
||||||
}
|
}
|
||||||
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||||
{
|
{
|
||||||
@ -31,7 +39,7 @@ ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
|||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=REG_FRAME;
|
loc=REG_FRAME;
|
||||||
m_longId = s;
|
m_longId = s;
|
||||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN));
|
||||||
}
|
}
|
||||||
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||||
{
|
{
|
||||||
@ -39,7 +47,7 @@ ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(fals
|
|||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=STK_FRAME;
|
loc=STK_FRAME;
|
||||||
id.longStkId = s;
|
id.longStkId = s;
|
||||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN));
|
||||||
}
|
}
|
||||||
|
|
||||||
ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
||||||
@ -48,12 +56,17 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
|||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=GLB_FRAME;
|
loc=GLB_FRAME;
|
||||||
id.longGlb = s;
|
id.longGlb = s;
|
||||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eReg ID::getPairedRegister(eReg first) const {
|
||||||
|
if (longId().h() == first)
|
||||||
|
return (longId().l());
|
||||||
|
else if (longId().l() == first)
|
||||||
|
return (longId().h());
|
||||||
|
return rUNDEF;
|
||||||
|
}
|
||||||
|
|
||||||
#define LOCAL_ID_DELTA 25
|
|
||||||
#define IDX_ARRAY_DELTA 5
|
|
||||||
|
|
||||||
/* Creates a new identifier node of type t and returns it.
|
/* Creates a new identifier node of type t and returns it.
|
||||||
* Arguments: locSym : local long symbol table
|
* Arguments: locSym : local long symbol table
|
||||||
@ -62,8 +75,7 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
|||||||
* ix : index into icode array where this var is used */
|
* ix : index into icode array where this var is used */
|
||||||
void LOCAL_ID::newIdent(hlType t, frameType f)
|
void LOCAL_ID::newIdent(hlType t, frameType f)
|
||||||
{
|
{
|
||||||
ID newid(t,f);
|
id_arr.emplace_back(t,f);
|
||||||
id_arr.push_back(newid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,19 +83,16 @@ void LOCAL_ID::newIdent(hlType t, frameType f)
|
|||||||
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
||||||
int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
|
||||||
return ((el.type == t) && (el.id.regi == regi));
|
return ((el.type == t) and (el.id.regi == regi));
|
||||||
});
|
});
|
||||||
if(found!=id_arr.end())
|
if(found!=id_arr.end())
|
||||||
return found-id_arr.begin();
|
return found-id_arr.begin();
|
||||||
/* Not in table, create new identifier */
|
/* Not in table, create new identifier */
|
||||||
newIdent (t, REG_FRAME);
|
newIdent (t, REG_FRAME);
|
||||||
idx = id_arr.size() - 1;
|
id_arr.back().id.regi = regi;
|
||||||
id_arr[idx].id.regi = regi;
|
return id_arr.size() - 1;
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -96,11 +105,8 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
|||||||
void LOCAL_ID::flagByteWordId (int off)
|
void LOCAL_ID::flagByteWordId (int off)
|
||||||
{
|
{
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
||||||
//if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) &&
|
//if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and
|
||||||
if ((en.typeBitsize()<=16) &&
|
return ((en.typeBitsize()<=16) and (en.id.bwId.off == off) and (en.id.bwId.regOff == 0));
|
||||||
(en.id.bwId.off == off) && (en.id.bwId.regOff == 0))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
if(found==id_arr.end())
|
if(found==id_arr.end())
|
||||||
{
|
{
|
||||||
@ -114,23 +120,21 @@ void LOCAL_ID::flagByteWordId (int off)
|
|||||||
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
||||||
int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
|
int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
|
||||||
if ((el.id.bwId.off == off) && (el.id.bwId.regOff == regOff))
|
if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
if(found!=id_arr.end())
|
if(found!=id_arr.end())
|
||||||
return found-id_arr.begin(); //return Index to found element
|
return found-id_arr.begin(); //return Index to found element
|
||||||
|
|
||||||
/* Not in table, create new identifier */
|
/* Not in table, create new identifier */
|
||||||
newIdent (t, STK_FRAME);
|
newIdent (t, STK_FRAME);
|
||||||
idx = id_arr.size() - 1;
|
ID &last_id(id_arr.back());
|
||||||
id_arr[idx].id.bwId.regOff = regOff;
|
last_id.id.bwId.regOff = regOff;
|
||||||
id_arr[idx].id.bwId.off = off;
|
last_id.id.bwId.off = off;
|
||||||
return (idx);
|
return id_arr.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,10 +152,10 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
|
|||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.bwGlb.seg == seg) &&
|
(id_arr[idx].id.bwGlb.seg == seg) and
|
||||||
(id_arr[idx].id.bwGlb.off == off) &&
|
(id_arr[idx].id.bwGlb.off == off) and
|
||||||
(id_arr[idx].id.bwGlb.regi == regi))
|
(id_arr[idx].id.bwGlb.regi == regi))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,31 +182,30 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
|
|||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
ID &entry(id_arr[idx]);
|
ID &entry(id_arr[idx]);
|
||||||
if(!entry.isLong() || (entry.loc != REG_FRAME))
|
if(not entry.isLongRegisterPair())
|
||||||
continue;
|
continue;
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(entry.longId().h() == regH) &&
|
(entry.longId().h() == regH) and
|
||||||
(entry.longId().l() == regL))
|
(entry.longId().l() == regL))
|
||||||
{
|
{
|
||||||
/* Check for occurrence in the list */
|
/* Check for occurrence in the list */
|
||||||
if (entry.idx.inList(ix_))
|
if (entry.idx.inList(ix_))
|
||||||
return (idx);
|
return idx;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Insert icode index in list */
|
/* Insert icode index in list */
|
||||||
entry.idx.push_back(ix_);
|
entry.idx.push_back(ix_);
|
||||||
return (idx);
|
return idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
|
id_arr.emplace_back(t, LONGID_TYPE(regH,regL));
|
||||||
id_arr.back().idx.push_back(ix_);
|
id_arr.back().idx.push_back(ix_);
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
}
|
}
|
||||||
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
/** \returns an identifier conditional expression node of type TYPE_LONG or TYPE_WORD_SIGN */
|
||||||
* TYPE_WORD_SIGN */
|
|
||||||
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
||||||
{
|
{
|
||||||
return AstIdent::idID(retVal,this,ix_);
|
return AstIdent::idID(retVal,this,ix_);
|
||||||
@ -218,16 +221,16 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
|||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.longGlb.seg == seg) &&
|
(id_arr[idx].id.longGlb.seg == seg) and
|
||||||
(id_arr[idx].id.longGlb.offH == offH) &&
|
(id_arr[idx].id.longGlb.offH == offH) and
|
||||||
(id_arr[idx].id.longGlb.offL == offL))
|
(id_arr[idx].id.longGlb.offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
printf("%d",t);
|
printf("%d",t);
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
id_arr.emplace_back(t, LONGGLB_TYPE(seg,offH,offL));
|
||||||
return (id_arr.size() - 1);
|
return id_arr.size() - 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,27 +240,20 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
|||||||
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
|
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
|
||||||
int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, hlType t)
|
int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, hlType t)
|
||||||
{
|
{
|
||||||
size_t idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.longGlb.seg == seg) &&
|
(id_arr[idx].id.longGlb.seg == seg) and
|
||||||
(id_arr[idx].id.longGlb.offH == offH) &&
|
(id_arr[idx].id.longGlb.offH == offH) and
|
||||||
(id_arr[idx].id.longGlb.offL == offL) &&
|
(id_arr[idx].id.longGlb.offL == offL) and
|
||||||
(id_arr[idx].id.longGlb.regi == regi))
|
(id_arr[idx].id.longGlb.regi == regi))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
newIdent (t, GLB_FRAME);
|
id_arr.emplace_back(t,LONGGLB_TYPE(seg,offH,offL,regi));
|
||||||
idx = id_arr.size() - 1;
|
return id_arr.size() - 1;
|
||||||
id_arr[idx].id.longGlb.seg = seg;
|
|
||||||
id_arr[idx].id.longGlb.offH = offH;
|
|
||||||
id_arr[idx].id.longGlb.offL = offL;
|
|
||||||
id_arr[idx].id.longGlb.regi = regi;
|
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,9 +268,9 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
{
|
{
|
||||||
if(id_arr[idx].loc!=STK_FRAME)
|
if(id_arr[idx].loc!=STK_FRAME)
|
||||||
continue;
|
continue;
|
||||||
if ((id_arr[idx].type == t) &&
|
if ((id_arr[idx].type == t) and
|
||||||
(id_arr[idx].longStkId().offH == offH) &&
|
(id_arr[idx].longStkId().offH == offH) and
|
||||||
(id_arr[idx].longStkId().offL == offL))
|
(id_arr[idx].longStkId().offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +279,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
flagByteWordId (offL);
|
flagByteWordId (offL);
|
||||||
|
|
||||||
/* Create new identifier */
|
/* Create new identifier */
|
||||||
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
|
id_arr.emplace_back(t,LONG_STKID_TYPE(offH,offL));
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +291,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
{
|
{
|
||||||
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
||||||
const LLOperand *pmH, *pmL;
|
const LLOperand *pmH, *pmL;
|
||||||
LLInst &p_ll(*pIcode->ll());
|
LLInst &p_ll(*pIcode->ll());
|
||||||
if (f == LOW_FIRST)
|
if (f == LOW_FIRST)
|
||||||
{
|
{
|
||||||
pmL = p_ll.get(sd);
|
pmL = p_ll.get(sd);
|
||||||
@ -320,9 +316,9 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (pmL->off) { /* offset */
|
else if (pmL->off) { /* offset */
|
||||||
if ((pmL->seg == rSS) && (pmL->regi == INDEX_BP)) /* idx on bp */
|
if ((pmL->seg == rSS) and (pmL->regi == INDEX_BP)) /* idx on bp */
|
||||||
idx = newLongStk(TYPE_LONG_SIGN, pmH->off, pmL->off);
|
idx = newLongStk(TYPE_LONG_SIGN, pmH->off, pmL->off);
|
||||||
else if ((pmL->seg == rDS) && (pmL->regi == INDEX_BX)) /* bx */
|
else if ((pmL->seg == rDS) and (pmL->regi == INDEX_BX)) /* bx */
|
||||||
{ /* glb var indexed on bx */
|
{ /* glb var indexed on bx */
|
||||||
printf("Bx indexed global, BX is an unused parameter to newLongIdx\n");
|
printf("Bx indexed global, BX is an unused parameter to newLongIdx\n");
|
||||||
idx = newLongIdx(pmH->segValue, pmH->off, pmL->off,rBX,TYPE_LONG_SIGN);
|
idx = newLongIdx(pmH->segValue, pmH->off, pmL->off,rBX,TYPE_LONG_SIGN);
|
||||||
@ -332,10 +328,10 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
printf ("long not supported, idx <> bp\n");
|
printf ("long not supported, idx <> bp\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
else /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */
|
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
|
||||||
printf ("long not supported, idx && no off\n");
|
printf ("long not supported, idx and no off\n");
|
||||||
|
|
||||||
return (idx);
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -357,24 +353,24 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
|
|||||||
pmLdst = &atOffset.m_dst;
|
pmLdst = &atOffset.m_dst;
|
||||||
pmHsrc = &pIcode->ll()->src();
|
pmHsrc = &pIcode->ll()->src();
|
||||||
pmLsrc = &atOffset.src();
|
pmLsrc = &atOffset.src();
|
||||||
// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
// if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off))
|
||||||
// {
|
// {
|
||||||
// asgn.lhs = AstIdent::LongIdx (i);
|
// asgn.lhs = AstIdent::LongIdx (i);
|
||||||
|
|
||||||
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
// {
|
// {
|
||||||
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||||
// }
|
// }
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
// else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
||||||
// {
|
// {
|
||||||
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||||
// asgn.rhs = AstIdent::LongIdx (i);
|
// asgn.rhs = AstIdent::LongIdx (i);
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (i);
|
asgn.lhs = AstIdent::LongIdx (i);
|
||||||
|
|
||||||
@ -384,7 +380,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
else if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||||
asgn.rhs = AstIdent::LongIdx (i);
|
asgn.rhs = AstIdent::LongIdx (i);
|
||||||
@ -404,7 +400,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
|
|||||||
* pProc : ptr to current procedure record
|
* pProc : ptr to current procedure record
|
||||||
* rhs, lhs : return expressions if successful. */
|
* rhs, lhs : return expressions if successful. */
|
||||||
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||||
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
/* pointers to LOW_LEVEL icodes */
|
/* pointers to LOW_LEVEL icodes */
|
||||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||||
@ -414,7 +410,7 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
|||||||
pmHsrc = &pIcode->ll()->src();
|
pmHsrc = &pIcode->ll()->src();
|
||||||
pmLsrc = &atOffset.src();
|
pmLsrc = &atOffset.src();
|
||||||
|
|
||||||
if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
|
if ((longId.h() == pmHdst->regi) and (longId.l() == pmLdst->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (i);
|
asgn.lhs = AstIdent::LongIdx (i);
|
||||||
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
@ -423,7 +419,7 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
|
else if ((longId.h() == pmHsrc->regi) and (longId.l() == pmLsrc->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
|
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
|
||||||
asgn.rhs = AstIdent::LongIdx (i);
|
asgn.rhs = AstIdent::LongIdx (i);
|
||||||
@ -432,25 +428,19 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Given an index into the local identifier table for a long register
|
/* Given an index into the local identifier table for a long register
|
||||||
* variable, determines whether regi is the high or low part, and returns
|
* variable, determines whether regi is the high or low part, and returns
|
||||||
* the other part */
|
* the other part */
|
||||||
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
eReg LOCAL_ID::getPairedRegisterAt(int idx,eReg regi) const
|
||||||
{
|
{
|
||||||
ID *id;
|
eReg res=rUNDEF; // Cristina: please check this!
|
||||||
|
const ID *id = &id_arr[idx];
|
||||||
id = &locTbl->id_arr[idx];
|
if (id->isLongRegisterPair())
|
||||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
|
||||||
{
|
{
|
||||||
if (id->longId().h() == regi)
|
res = id->getPairedRegister(regi);
|
||||||
return (id->longId().l());
|
|
||||||
else if (id->longId().l() == regi)
|
|
||||||
return (id->longId().h());
|
|
||||||
}
|
}
|
||||||
return rUNDEF; // Cristina: please check this!
|
qWarning() << "Cannot find paired register";
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -458,7 +448,7 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
* the local identifier table. If so, macros for these registers are
|
* the local identifier table. If so, macros for these registers are
|
||||||
* placed in the local identifier table, as these registers belong to a
|
* placed in the local identifier table, as these registers belong to a
|
||||||
* long register identifier. */
|
* long register identifier. */
|
||||||
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
|
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const QString &name)
|
||||||
{
|
{
|
||||||
for (ID &rid : id_arr)
|
for (ID &rid : id_arr)
|
||||||
{
|
{
|
||||||
@ -473,9 +463,9 @@ void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
|
|||||||
if (rid.id.regi == regL)
|
if (rid.id.regi == regL)
|
||||||
{
|
{
|
||||||
strcpy (rid.macro, "LO");
|
strcpy (rid.macro, "LO");
|
||||||
}
|
}
|
||||||
else // if (rid.id.regi == regH)
|
else // if (rid.id.regi == regH)
|
||||||
{
|
{
|
||||||
strcpy (rid.macro, "HI");
|
strcpy (rid.macro, "HI");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
#include <cassert>
|
|
||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
// Index registers **** temp solution
|
// Index registers **** temp solution
|
||||||
static const std::string regNames[] = {
|
static const QString regNames[] = {
|
||||||
"undef",
|
"undef",
|
||||||
"ax", "cx", "dx", "bx",
|
"ax", "cx", "dx", "bx",
|
||||||
"sp", "bp", "si", "di",
|
"sp", "bp", "si", "di",
|
||||||
@ -17,17 +22,17 @@ static const std::string regNames[] = {
|
|||||||
/* uint8_t and uint16_t registers */
|
/* uint8_t and uint16_t registers */
|
||||||
Machine_X86::Machine_X86()
|
Machine_X86::Machine_X86()
|
||||||
{
|
{
|
||||||
static_assert((sizeof(regNames)/sizeof(std::string))==LAST_REG,
|
static_assert((sizeof(regNames)/sizeof(QString))==LAST_REG,
|
||||||
"Reg count not equal number of strings");
|
"Reg count not equal number of strings");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Machine_X86::regName(eReg r)
|
const QString &Machine_X86::regName(eReg r)
|
||||||
{
|
{
|
||||||
assert(r<(sizeof(regNames)/sizeof(std::string)));
|
assert(r<(sizeof(regNames)/sizeof(QString)));
|
||||||
return regNames[r];
|
return regNames[r];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string szOps[] =
|
static const QString szOps[] =
|
||||||
{
|
{
|
||||||
"CBW", "AAA", "AAD", "AAM", "AAS", "ADC", "ADD", "AND",
|
"CBW", "AAA", "AAD", "AAM", "AAS", "ADC", "ADD", "AND",
|
||||||
"BOUND","CALL", "CALL", "CLC", "CLD", "CLI", "CMC", "CMP",
|
"BOUND","CALL", "CALL", "CLC", "CLD", "CLI", "CMC", "CMP",
|
||||||
@ -45,7 +50,7 @@ static const std::string szOps[] =
|
|||||||
"XLAT", "XOR", "INTO", "NOP", "REPNE", "REPE", "MOD"
|
"XLAT", "XOR", "INTO", "NOP", "REPNE", "REPE", "MOD"
|
||||||
};
|
};
|
||||||
/* The following opcodes are for mod != 3 */
|
/* The following opcodes are for mod != 3 */
|
||||||
static std::string szFlops1[] =
|
static const QString szFlops1[] =
|
||||||
{
|
{
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
||||||
@ -58,7 +63,7 @@ static std::string szFlops1[] =
|
|||||||
"FILD", "???", "FIST", "FISTP", "FBLD", "???", "FBSTP", "FISTP" /* 38 */
|
"FILD", "???", "FIST", "FISTP", "FBLD", "???", "FBSTP", "FISTP" /* 38 */
|
||||||
};
|
};
|
||||||
/* The following opcodes are for mod == 3 */
|
/* The following opcodes are for mod == 3 */
|
||||||
static std::string szFlops2[] =
|
static const QString szFlops2[] =
|
||||||
{
|
{
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
||||||
@ -71,17 +76,17 @@ static std::string szFlops2[] =
|
|||||||
"FILD", "???", "FIST", "FISTP", "", "???", "FBSTP", "FISTP" /* 38 */
|
"FILD", "???", "FIST", "FISTP", "", "???", "FBSTP", "FISTP" /* 38 */
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string &Machine_X86::opcodeName(unsigned r)
|
const QString &Machine_X86::opcodeName(unsigned r)
|
||||||
{
|
{
|
||||||
assert(r<(sizeof(szOps)/sizeof(std::string)));
|
assert(r<(sizeof(szOps)/sizeof(QString)));
|
||||||
return szOps[r];
|
return szOps[r];
|
||||||
}
|
}
|
||||||
const std::string &Machine_X86::floatOpName(unsigned r)
|
const QString &Machine_X86::floatOpName(unsigned r)
|
||||||
{
|
{
|
||||||
if(r>=(sizeof(szFlops1)/sizeof(std::string)))
|
if(r>=(sizeof(szFlops1)/sizeof(QString)))
|
||||||
{
|
{
|
||||||
r-= (sizeof(szFlops1)/sizeof(std::string));
|
r-= (sizeof(szFlops1)/sizeof(QString));
|
||||||
assert(r<(sizeof(szFlops2)/sizeof(std::string)));
|
assert(r<(sizeof(szFlops2)/sizeof(QString)));
|
||||||
return szFlops2[r];
|
return szFlops2[r];
|
||||||
}
|
}
|
||||||
return szFlops1[r];
|
return szFlops1[r];
|
||||||
@ -89,11 +94,11 @@ const std::string &Machine_X86::floatOpName(unsigned r)
|
|||||||
|
|
||||||
bool Machine_X86::physicalReg(eReg r)
|
bool Machine_X86::physicalReg(eReg r)
|
||||||
{
|
{
|
||||||
return (r>=rAX) && (r<rTMP);
|
return (r>=rAX) and (r<rTMP);
|
||||||
}
|
}
|
||||||
bool Machine_X86::isMemOff(eReg r)
|
bool Machine_X86::isMemOff(eReg r)
|
||||||
{
|
{
|
||||||
return r == 0 || r >= INDEX_BX_SI;
|
return r == 0 or r >= INDEX_BX_SI;
|
||||||
}
|
}
|
||||||
//TODO: Move these to Machine_X86
|
//TODO: Move these to Machine_X86
|
||||||
eReg Machine_X86::subRegH(eReg reg)
|
eReg Machine_X86::subRegH(eReg reg)
|
||||||
@ -106,18 +111,18 @@ eReg Machine_X86::subRegL(eReg reg)
|
|||||||
}
|
}
|
||||||
bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
|
bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
|
||||||
{
|
{
|
||||||
if ((parent < rAX) || (parent > rBX))
|
if ((parent < rAX) or (parent > rBX))
|
||||||
return false; // only AX -> BX are coverede by subregisters
|
return false; // only AX -> BX are coverede by subregisters
|
||||||
return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
|
return ((reg==subRegH(parent)) or (reg == subRegL(parent)));
|
||||||
}
|
}
|
||||||
bool Machine_X86::hasSubregisters(eReg reg)
|
bool Machine_X86::hasSubregisters(eReg reg)
|
||||||
{
|
{
|
||||||
return ((reg >= rAX) && (reg <= rBX));
|
return ((reg >= rAX) and (reg <= rBX));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Machine_X86::isPartOfComposite(eReg reg)
|
bool Machine_X86::isPartOfComposite(eReg reg)
|
||||||
{
|
{
|
||||||
return ((reg >= rAL) && (reg <= rBH));
|
return ((reg >= rAL) and (reg <= rBH));
|
||||||
}
|
}
|
||||||
|
|
||||||
eReg Machine_X86::compositeParent(eReg reg)
|
eReg Machine_X86::compositeParent(eReg reg)
|
||||||
@ -133,7 +138,7 @@ eReg Machine_X86::compositeParent(eReg reg)
|
|||||||
}
|
}
|
||||||
return rUNDEF;
|
return rUNDEF;
|
||||||
}
|
}
|
||||||
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet ®i)
|
void Machine_X86::writeRegVector (QTextStream &ostr,const LivenessSet ®i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||||
|
|||||||
338
src/parser.cpp
338
src/parser.cpp
@ -2,17 +2,21 @@
|
|||||||
* dcc project procedure list builder
|
* dcc project procedure list builder
|
||||||
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h> /* For exit() */
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib> /* For exit() */
|
||||||
|
#include <cstdio>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
|
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
|
||||||
@ -38,7 +42,7 @@ ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode)
|
|||||||
|
|
||||||
ICODE eIcode = ICODE();
|
ICODE eIcode = ICODE();
|
||||||
|
|
||||||
eIcode.type = LOW_LEVEL;
|
eIcode.type = LOW_LEVEL_ICODE;
|
||||||
eIcode.ll()->set(iMOV,0,rTMP);
|
eIcode.ll()->set(iMOV,0,rTMP);
|
||||||
if (ll->testFlags(B) )
|
if (ll->testFlags(B) )
|
||||||
{
|
{
|
||||||
@ -62,7 +66,7 @@ ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode)
|
|||||||
|
|
||||||
/* iMOD */
|
/* iMOD */
|
||||||
eIcode = ICODE();
|
eIcode = ICODE();
|
||||||
eIcode.type = LOW_LEVEL;
|
eIcode.type = LOW_LEVEL_ICODE;
|
||||||
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
|
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
|
||||||
eIcode.ll()->replaceSrc(_Icode.ll()->src());
|
eIcode.ll()->replaceSrc(_Icode.ll()->src());
|
||||||
eIcode.du = _Icode.du;
|
eIcode.du = _Icode.du;
|
||||||
@ -73,14 +77,14 @@ ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode)
|
|||||||
{
|
{
|
||||||
/* MOV rTMP, regDst */
|
/* MOV rTMP, regDst */
|
||||||
ICODE eIcode;
|
ICODE eIcode;
|
||||||
eIcode.type = LOW_LEVEL;
|
eIcode.type = LOW_LEVEL_ICODE;
|
||||||
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst);
|
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst);
|
||||||
eIcode.setRegDU( rTMP, eDEF);
|
eIcode.setRegDU( rTMP, eDEF);
|
||||||
if(eIcode.ll()->src().getReg2())
|
if(eIcode.ll()->src().getReg2())
|
||||||
{
|
{
|
||||||
eReg srcreg=eIcode.ll()->src().getReg2();
|
eReg srcreg=eIcode.ll()->src().getReg2();
|
||||||
eIcode.setRegDU( srcreg, eUSE);
|
eIcode.setRegDU( srcreg, eUSE);
|
||||||
if((srcreg>=rAL) && (srcreg<=rBH))
|
if((srcreg>=rAL) and (srcreg<=rBH))
|
||||||
eIcode.ll()->setFlags( B );
|
eIcode.ll()->setFlags( B );
|
||||||
}
|
}
|
||||||
eIcode.ll()->label = ll->label;
|
eIcode.ll()->label = ll->label;
|
||||||
@ -93,12 +97,12 @@ ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode)
|
|||||||
|
|
||||||
/* MOV regSrc, rTMP */
|
/* MOV regSrc, rTMP */
|
||||||
eIcode = ICODE();
|
eIcode = ICODE();
|
||||||
eIcode.type = LOW_LEVEL;
|
eIcode.type = LOW_LEVEL_ICODE;
|
||||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||||
eIcode.ll()->replaceDst(ll->src());
|
eIcode.ll()->replaceDst(ll->src());
|
||||||
if(eIcode.ll()->m_dst.regi)
|
if(eIcode.ll()->m_dst.regi)
|
||||||
{
|
{
|
||||||
if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
|
if((eIcode.ll()->m_dst.regi>=rAL) and (eIcode.ll()->m_dst.regi<=rBH))
|
||||||
eIcode.ll()->setFlags( B );
|
eIcode.ll()->setFlags( B );
|
||||||
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
||||||
}
|
}
|
||||||
@ -120,28 +124,28 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
eErrorId err;
|
eErrorId err;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
SYMTAB &global_symbol_table(Project::get()->symtab);
|
SYMTAB &global_symbol_table(Project::get()->symtab);
|
||||||
if (name.find("chkstk") != string::npos)
|
if (name.contains("chkstk"))
|
||||||
{
|
{
|
||||||
// Danger! Dcc will likely fall over in this code.
|
// Danger! Dcc will likely fall over in this code.
|
||||||
// So we act as though we have done with this proc
|
// So we act as though we have done with this proc
|
||||||
// pProc->flg &= ~TERMINATES; // Not sure about this
|
// pProc->flg &= ~TERMINATES; // Not sure about this
|
||||||
done = true;
|
|
||||||
// And mark it as a library function, so structure() won't choke on it
|
// And mark it as a library function, so structure() won't choke on it
|
||||||
flg |= PROC_ISLIB;
|
flg |= PROC_ISLIB;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (option.VeryVerbose)
|
if (option.VeryVerbose)
|
||||||
{
|
{
|
||||||
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
|
qDebug() << "Parsing proc" << name << "at" << QString::number(pstate->IP,16).toUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! done )
|
while (not done )
|
||||||
{
|
{
|
||||||
err = scan(pstate->IP, _Icode);
|
err = scan(pstate->IP, _Icode);
|
||||||
if(err)
|
if(err)
|
||||||
break;
|
break;
|
||||||
LLInst *ll = _Icode.ll();
|
LLInst *ll = _Icode.ll();
|
||||||
pstate->IP += (uint32_t)ll->numBytes;
|
pstate->IP += (uint32_t)ll->numBytes;
|
||||||
|
|
||||||
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
|
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
|
||||||
|
|
||||||
process_operands(_Icode,pstate);
|
process_operands(_Icode,pstate);
|
||||||
@ -153,14 +157,14 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
iICODE labLoc = Icode.labelSrch(ll->label);
|
iICODE labLoc = Icode.labelSrch(ll->label);
|
||||||
if (Icode.end()!=labLoc)
|
if (Icode.end()!=labLoc)
|
||||||
{ /* Synthetic jump */
|
{ /* Synthetic jump */
|
||||||
_Icode.type = LOW_LEVEL;
|
_Icode.type = LOW_LEVEL_ICODE;
|
||||||
ll->set(iJMP,I | SYNTHETIC | NO_OPS);
|
ll->set(iJMP,I | SYNTHETIC | NO_OPS);
|
||||||
ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel()));
|
ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel()));
|
||||||
ll->label = SynthLab++;
|
ll->label = SynthLab++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy Icode to Proc */
|
/* Copy Icode to Proc */
|
||||||
if ((ll->getOpcode() == iDIV) || (ll->getOpcode() == iIDIV))
|
if ((ll->getOpcode() == iDIV) or (ll->getOpcode() == iIDIV))
|
||||||
pIcode = translate_DIV(ll, _Icode);
|
pIcode = translate_DIV(ll, _Icode);
|
||||||
else if (_Icode.ll()->getOpcode() == iXCHG)
|
else if (_Icode.ll()->getOpcode() == iXCHG)
|
||||||
pIcode = translate_XCHG(ll, _Icode);
|
pIcode = translate_XCHG(ll, _Icode);
|
||||||
@ -177,6 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
{
|
{
|
||||||
STATE StCopy;
|
STATE StCopy;
|
||||||
|
uint32_t lastIp = pstate->IP - 2;
|
||||||
int ip = Icode.size()-1; /* Index of this jump */
|
int ip = Icode.size()-1; /* Index of this jump */
|
||||||
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
|
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
|
||||||
bool fBranch = false;
|
bool fBranch = false;
|
||||||
@ -186,18 +191,18 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
/* This sets up range check for indexed JMPs hopefully
|
/* This sets up range check for indexed JMPs hopefully
|
||||||
* Handles JA/JAE for fall through and JB/JBE on branch
|
* Handles JA/JAE for fall through and JB/JBE on branch
|
||||||
*/
|
*/
|
||||||
if (ip > 0 && prev.ll()->getOpcode() == iCMP && (prev.ll()->testFlags(I)))
|
if (ip > 0 and prev.ll()->getOpcode() == iCMP and (prev.ll()->testFlags(I)))
|
||||||
{
|
{
|
||||||
pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2();
|
pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2();
|
||||||
if (ll->match(iJA) || ll->match(iJBE) )
|
if (ll->match(iJA) or ll->match(iJBE) )
|
||||||
pstate->JCond.immed++;
|
pstate->JCond.immed++;
|
||||||
if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA)
|
if (ll->getOpcode() == iJAE or ll->getOpcode() == iJA)
|
||||||
pstate->JCond.regi = prev.ll()->m_dst.regi;
|
pstate->JCond.regi = prev.ll()->m_dst.regi;
|
||||||
fBranch = (bool)
|
fBranch = (bool) (ll->getOpcode() == iJB or ll->getOpcode() == iJBE);
|
||||||
(ll->getOpcode() == iJB || ll->getOpcode() == iJBE);
|
|
||||||
}
|
}
|
||||||
StCopy = *pstate;
|
StCopy = *pstate;
|
||||||
//memcpy(&StCopy, pstate, sizeof(STATE));
|
|
||||||
|
//printf("From %X condJump to %X\n", lastIp, pstate->IP);
|
||||||
|
|
||||||
/* Straight line code */
|
/* Straight line code */
|
||||||
this->FollowCtrl (pcallGraph, &StCopy); // recurrent ?
|
this->FollowCtrl (pcallGraph, &StCopy); // recurrent ?
|
||||||
@ -236,7 +241,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iINT:
|
case iINT:
|
||||||
if (ll->src().getImm2() == 0x21 && pstate->f[rAH])
|
if (ll->src().getImm2() == 0x21 and pstate->f[rAH])
|
||||||
{
|
{
|
||||||
int funcNum = pstate->r[rAH];
|
int funcNum = pstate->r[rAH];
|
||||||
int operand;
|
int operand;
|
||||||
@ -247,7 +252,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
//Icode.GetIcode(Icode.GetNumIcodes() - 1)->
|
//Icode.GetIcode(Icode.GetNumIcodes() - 1)->
|
||||||
|
|
||||||
/* Program termination: int21h, fn 00h, 31h, 4Ch */
|
/* Program termination: int21h, fn 00h, 31h, 4Ch */
|
||||||
done = (bool)(funcNum == 0x00 || funcNum == 0x31 ||
|
done = (bool)(funcNum == 0x00 or funcNum == 0x31 or
|
||||||
funcNum == 0x4C);
|
funcNum == 0x4C);
|
||||||
|
|
||||||
/* String functions: int21h, fn 09h */
|
/* String functions: int21h, fn 09h */
|
||||||
@ -262,12 +267,12 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size));
|
global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH]))
|
else if ((ll->src().getImm2() == 0x2F) and (pstate->f[rAH]))
|
||||||
{
|
{
|
||||||
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
||||||
}
|
}
|
||||||
else /* Program termination: int20h, int27h */
|
else /* Program termination: int20h, int27h */
|
||||||
done = (ll->src().getImm2() == 0x20 || ll->src().getImm2() == 0x27);
|
done = (ll->src().getImm2() == 0x20 or ll->src().getImm2() == 0x27);
|
||||||
if (done)
|
if (done)
|
||||||
pIcode->ll()->setFlags(TERMINATES);
|
pIcode->ll()->setFlags(TERMINATES);
|
||||||
break;
|
break;
|
||||||
@ -284,7 +289,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
case iSHL:
|
case iSHL:
|
||||||
if (pstate->JCond.regi == ll->m_dst.regi)
|
if (pstate->JCond.regi == ll->m_dst.regi)
|
||||||
{
|
{
|
||||||
if ((ll->testFlags(I)) && ll->src().getImm2() == 1)
|
if ((ll->testFlags(I)) and ll->src().getImm2() == 1)
|
||||||
pstate->JCond.immed *= 2;
|
pstate->JCond.immed *= 2;
|
||||||
else
|
else
|
||||||
pstate->JCond.regi = 0;
|
pstate->JCond.regi = 0;
|
||||||
@ -298,7 +303,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
|
|
||||||
case iLDS: case iLES:
|
case iLDS: case iLES:
|
||||||
if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE))
|
if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE))
|
||||||
/* && (Icode.ll()->flg & SEG_IMMED) */ )
|
/* and (Icode.ll()->flg & SEG_IMMED) */ )
|
||||||
{
|
{
|
||||||
offset = LH(&prog.image()[psym->label]);
|
offset = LH(&prog.image()[psym->label]);
|
||||||
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
|
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
|
||||||
@ -313,7 +318,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
if (err) {
|
if (err) {
|
||||||
this->flg &= ~TERMINATES;
|
this->flg &= ~TERMINATES;
|
||||||
|
|
||||||
if (err == INVALID_386OP || err == INVALID_OPCODE)
|
if (err == INVALID_386OP or err == INVALID_OPCODE)
|
||||||
{
|
{
|
||||||
fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label);
|
fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label);
|
||||||
this->flg |= PROC_BADINST;
|
this->flg |= PROC_BADINST;
|
||||||
@ -367,12 +372,185 @@ bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcod
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool Function::decodeIndirectJMP(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
|
||||||
|
{
|
||||||
|
PROG &prog(Project::get()->prog);
|
||||||
|
// mov cx,NUM_CASES
|
||||||
|
// mov bx,JUMP_TABLE
|
||||||
|
|
||||||
|
// LAB1:
|
||||||
|
// mov ax, [bx]
|
||||||
|
// cmp ax,VAL
|
||||||
|
// jz LAB2
|
||||||
|
// add bx,2
|
||||||
|
// loop LAB1
|
||||||
|
// jmp DEFAULT_CASE
|
||||||
|
// LAB2
|
||||||
|
// jmp word ptr [bx+2*NUM_CASES]
|
||||||
|
static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP};
|
||||||
|
|
||||||
|
if(Icode.size()<8)
|
||||||
|
return false;
|
||||||
|
if(&Icode.back()!=&pIcode) // not the last insn in the list skip it
|
||||||
|
return false;
|
||||||
|
if(pIcode.ll()->src().regi != INDEX_BX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// find address-wise predecessors of the icode
|
||||||
|
std::deque<ICODE *> matched;
|
||||||
|
QMap<uint32_t,ICODE *> addrmap;
|
||||||
|
for(ICODE & ic : Icode) {
|
||||||
|
addrmap[ic.ll()->GetLlLabel()] = ⁣
|
||||||
|
}
|
||||||
|
auto iter = addrmap.find(pIcode.ll()->GetLlLabel());
|
||||||
|
while(matched.size()<9) {
|
||||||
|
matched.push_front(*iter);
|
||||||
|
--iter;
|
||||||
|
if(iter==addrmap.end())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// pattern starts at the last jmp
|
||||||
|
ICODE *load_num_cases = matched[0];
|
||||||
|
ICODE *load_jump_table_addr = matched[1];
|
||||||
|
ICODE *read_case_entry_insn = matched[2];
|
||||||
|
ICODE *cmp_case_val_insn = matched[3];
|
||||||
|
ICODE *exit_loop_insn = matched[4];
|
||||||
|
ICODE *add_bx_insn = matched[5];
|
||||||
|
ICODE *loop_insn = matched[6];
|
||||||
|
ICODE *default_jmp = matched[7];
|
||||||
|
ICODE *last_jmp = matched[8];
|
||||||
|
for(int i=0; i<8; ++i) {
|
||||||
|
if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) {
|
||||||
|
qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area ";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(matched[i]->ll()->getOpcode()!=match_seq[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// verify that bx+offset == 2* case count
|
||||||
|
uint32_t num_cases = load_num_cases->ll()->src().getImm2();
|
||||||
|
if(last_jmp->ll()->src().off != 2*num_cases)
|
||||||
|
return false;
|
||||||
|
const LLOperand &op = last_jmp->ll()->src();
|
||||||
|
if(op.regi != INDEX_BX)
|
||||||
|
return false;
|
||||||
|
if(not load_jump_table_addr->ll()->src().isImmediate())
|
||||||
|
return false;
|
||||||
|
uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4;
|
||||||
|
uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2();
|
||||||
|
uint32_t default_label = cs + default_jmp->ll()->src().getImm2();
|
||||||
|
setBits(BM_DATA, table_addr, num_cases*2 + num_cases*2); // num_cases of short values + num cases short ptrs
|
||||||
|
pIcode.ll()->setFlags(SWITCH);
|
||||||
|
|
||||||
|
for(int i=0; i<num_cases; ++i) {
|
||||||
|
STATE StCopy = *pstate;
|
||||||
|
uint32_t jump_target_location = table_addr + num_cases*2 + i*2;
|
||||||
|
StCopy.IP = cs + *(uint16_t *)(prog.image()+jump_target_location);
|
||||||
|
iICODE last_current_insn = (++Icode.rbegin()).base();
|
||||||
|
FollowCtrl (pcallGraph, &StCopy);
|
||||||
|
++last_current_insn;
|
||||||
|
last_current_insn->ll()->caseEntry = i;
|
||||||
|
last_current_insn->ll()->setFlags(CASE);
|
||||||
|
pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Function::decodeIndirectJMP2(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
|
||||||
|
{
|
||||||
|
PROG &prog(Project::get()->prog);
|
||||||
|
// mov cx,NUM_CASES
|
||||||
|
// mov bx,JUMP_TABLE
|
||||||
|
|
||||||
|
// LAB1:
|
||||||
|
// mov ax, [bx]
|
||||||
|
// cmp ax, LOW_WORD_OF_VAL
|
||||||
|
// jnz LAB2
|
||||||
|
// mov ax, [bx + 2 * NUM_CASES]
|
||||||
|
// cmp ax, HIGH_WORD_OF_VAL
|
||||||
|
// jz LAB3
|
||||||
|
// LAB2
|
||||||
|
// add bx,2
|
||||||
|
// loop LAB1
|
||||||
|
// jmp DEFAULT_CASE
|
||||||
|
// LAB3
|
||||||
|
// jmp word ptr [bx+2*NUM_CASES]
|
||||||
|
static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJNE,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP};
|
||||||
|
|
||||||
|
if(Icode.size()<12)
|
||||||
|
return false;
|
||||||
|
if(&Icode.back() != &pIcode) // not the last insn in the list skip it
|
||||||
|
return false;
|
||||||
|
if(pIcode.ll()->src().regi != INDEX_BX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// find address-wise predecessors of the icode
|
||||||
|
std::deque<ICODE *> matched;
|
||||||
|
QMap<uint32_t,ICODE *> addrmap;
|
||||||
|
for(ICODE & ic : Icode) {
|
||||||
|
addrmap[ic.ll()->GetLlLabel()] = ⁣
|
||||||
|
}
|
||||||
|
auto iter = addrmap.find(pIcode.ll()->GetLlLabel());
|
||||||
|
while(matched.size()<12) {
|
||||||
|
matched.push_front(*iter);
|
||||||
|
--iter;
|
||||||
|
if(iter==addrmap.end())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// pattern starts at the last jmp
|
||||||
|
ICODE *load_num_cases = matched[0];
|
||||||
|
ICODE *load_jump_table_addr = matched[1];
|
||||||
|
ICODE *default_jmp = matched[10];
|
||||||
|
ICODE *last_jmp = matched[11];
|
||||||
|
|
||||||
|
for(int i=0; i<11; ++i) {
|
||||||
|
if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) {
|
||||||
|
qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area ";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i=0; i<12; ++i) {
|
||||||
|
if(matched[i]->ll()->getOpcode()!=match_seq[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// verify that bx+offset == 2* case count
|
||||||
|
uint32_t num_cases = load_num_cases->ll()->src().getImm2();
|
||||||
|
if(last_jmp->ll()->src().off != 4*num_cases)
|
||||||
|
return false;
|
||||||
|
const LLOperand &op = last_jmp->ll()->src();
|
||||||
|
if(op.regi != INDEX_BX)
|
||||||
|
return false;
|
||||||
|
if(not load_jump_table_addr->ll()->src().isImmediate())
|
||||||
|
return false;
|
||||||
|
uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4;
|
||||||
|
uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2();
|
||||||
|
int default_label = cs + default_jmp->ll()->src().getImm2();
|
||||||
|
setBits(BM_DATA, table_addr, num_cases*4 + num_cases*2); // num_cases of long values + num cases short ptrs
|
||||||
|
pIcode.ll()->setFlags(SWITCH);
|
||||||
|
|
||||||
|
for(int i=0; i<num_cases; ++i) {
|
||||||
|
STATE StCopy = *pstate;
|
||||||
|
uint32_t jump_target_location = table_addr + num_cases*4 + i*2;
|
||||||
|
StCopy.IP = cs + *(uint16_t *)(prog.image()+jump_target_location);
|
||||||
|
iICODE last_current_insn = (++Icode.rbegin()).base();
|
||||||
|
FollowCtrl (pcallGraph, &StCopy);
|
||||||
|
++last_current_insn;
|
||||||
|
last_current_insn->ll()->caseEntry = i;
|
||||||
|
last_current_insn->ll()->setFlags(CASE);
|
||||||
|
pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
|
bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
|
static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
|
||||||
ICODE _Icode;
|
ICODE _Icode;
|
||||||
|
uint32_t lastIp = pstate->IP - 1;
|
||||||
uint32_t cs, offTable, endTable;
|
uint32_t cs, offTable, endTable;
|
||||||
uint32_t i, k, seg, target;
|
uint32_t i, k, seg, target;
|
||||||
|
|
||||||
@ -380,7 +558,19 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
{
|
{
|
||||||
if (pIcode.ll()->getOpcode() == iJMPF)
|
if (pIcode.ll()->getOpcode() == iJMPF)
|
||||||
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
|
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
|
||||||
pstate->IP = pIcode.ll()->src().getImm2();
|
|
||||||
|
pstate->IP = pIcode.ll()->src().getImm2();
|
||||||
|
|
||||||
|
//printf("From seg:%04X JMP(F) to %X\n", lastIp, pstate->IP);
|
||||||
|
|
||||||
|
if (pstate->IP == 0xFFFF0)
|
||||||
|
{
|
||||||
|
/* Nasty (wrong) trick use to reset, consider it as terminating */
|
||||||
|
pIcode.ll()->setFlags(TERMINATES);
|
||||||
|
pstate->setState( rCS, 0);
|
||||||
|
pstate->IP = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t i = pIcode.ll()->src().getImm2();
|
int64_t i = pIcode.ll()->src().getImm2();
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
{
|
{
|
||||||
@ -390,16 +580,15 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
/* Return true if jump target is already parsed */
|
/* Return true if jump target is already parsed */
|
||||||
return Icode.alreadyDecoded(i);
|
return Icode.alreadyDecoded(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We've got an indirect JMP - look for switch() stmt. idiom of the form
|
/* We've got an indirect JMP - look for switch() stmt. idiom of the form
|
||||||
* JMP uint16_t ptr word_offset[rBX | rSI | rDI] */
|
* JMP uint16_t ptr word_offset[rBX | rSI | rDI] */
|
||||||
seg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS;
|
seg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS;
|
||||||
|
|
||||||
/* Ensure we have a uint16_t offset & valid seg */
|
/* Ensure we have a uint16_t offset & valid seg */
|
||||||
if (pIcode.ll()->match(iJMP) and (pIcode.ll()->testFlags(WORD_OFF)) &&
|
if (pIcode.ll()->match(iJMP) and (pIcode.ll()->testFlags(WORD_OFF)) and
|
||||||
pstate->f[seg] &&
|
pstate->f[seg] and
|
||||||
(pIcode.ll()->src().regi == INDEX_SI ||
|
(pIcode.ll()->src().regi == INDEX_SI or
|
||||||
pIcode.ll()->src().regi == INDEX_DI || /* Idx reg. BX, SI, DI */
|
pIcode.ll()->src().regi == INDEX_DI or /* Idx reg. BX, SI, DI */
|
||||||
pIcode.ll()->src().regi == INDEX_BX))
|
pIcode.ll()->src().regi == INDEX_BX))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -429,7 +618,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
for (i = offTable; i < endTable; i += 2)
|
for (i = offTable; i < endTable; i += 2)
|
||||||
{
|
{
|
||||||
target = cs + LH(&prog.image()[i]);
|
target = cs + LH(&prog.image()[i]);
|
||||||
if (target < endTable && target >= offTable)
|
if (target < endTable and target >= offTable)
|
||||||
endTable = target;
|
endTable = target;
|
||||||
else if (target >= (uint32_t)prog.cbImage)
|
else if (target >= (uint32_t)prog.cbImage)
|
||||||
endTable = i;
|
endTable = i;
|
||||||
@ -439,7 +628,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
{
|
{
|
||||||
target = cs + LH(&prog.image()[i]);
|
target = cs + LH(&prog.image()[i]);
|
||||||
/* Be wary of 00 00 as code - it's probably data */
|
/* Be wary of 00 00 as code - it's probably data */
|
||||||
if (! (prog.image()[target] || prog.image()[target+1]) ||
|
if (not (prog.image()[target] or prog.image()[target+1]) or
|
||||||
scan(target, _Icode))
|
scan(target, _Icode))
|
||||||
endTable = i;
|
endTable = i;
|
||||||
}
|
}
|
||||||
@ -475,6 +664,12 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(decodeIndirectJMP(pIcode,pstate,pcallGraph)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(decodeIndirectJMP2(pIcode,pstate,pcallGraph)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Can't do anything with this jump */
|
/* Can't do anything with this jump */
|
||||||
|
|
||||||
@ -499,6 +694,7 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
|||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ICODE &last_insn(Icode.back());
|
ICODE &last_insn(Icode.back());
|
||||||
STATE localState; /* Local copy of the machine state */
|
STATE localState; /* Local copy of the machine state */
|
||||||
|
uint32_t lastIp = pstate->IP - 2;
|
||||||
uint32_t off;
|
uint32_t off;
|
||||||
/* For Indirect Calls, find the function address */
|
/* For Indirect Calls, find the function address */
|
||||||
bool indirect = false;
|
bool indirect = false;
|
||||||
@ -507,13 +703,12 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
|||||||
{
|
{
|
||||||
/* Not immediate, i.e. indirect call */
|
/* Not immediate, i.e. indirect call */
|
||||||
|
|
||||||
if (pIcode.ll()->m_dst.regi && (!option.Calls))
|
if (pIcode.ll()->m_dst.regi and (not option.Calls))
|
||||||
{
|
{
|
||||||
/* We have not set the brave option to attempt to follow
|
/* We have not set the brave option to attempt to follow
|
||||||
the execution path through register indirect calls.
|
the execution path through register indirect calls.
|
||||||
So we just exit this function, and ignore the call.
|
So we just exit this function, and ignore the call.
|
||||||
We probably should not have parsed this deep, anyway.
|
We probably should not have parsed this deep, anyway. */
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,11 +776,9 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
|||||||
if (indirect)
|
if (indirect)
|
||||||
x.flg |= PROC_ICALL;
|
x.flg |= PROC_ICALL;
|
||||||
|
|
||||||
if (x.name.empty()) /* Don't overwrite existing name */
|
if (x.name.isEmpty()) /* Don't overwrite existing name */
|
||||||
{
|
{
|
||||||
ostringstream os;
|
x.name = QString("proc_%1_%2").arg(x.procEntry ,6,16,QChar('0')).arg(++prog.cProcs);
|
||||||
os<<"proc_"<< ++prog.cProcs;
|
|
||||||
x.name = os.str();
|
|
||||||
}
|
}
|
||||||
x.depth = x.depth + 1;
|
x.depth = x.depth + 1;
|
||||||
x.flg |= TERMINATES;
|
x.flg |= TERMINATES;
|
||||||
@ -595,10 +788,13 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
|||||||
pstate->IP = pIcode.ll()->src().getImm2();
|
pstate->IP = pIcode.ll()->src().getImm2();
|
||||||
if (pIcode.ll()->getOpcode() == iCALLF)
|
if (pIcode.ll()->getOpcode() == iCALLF)
|
||||||
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
|
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
|
||||||
|
|
||||||
x.state = *pstate;
|
x.state = *pstate;
|
||||||
|
|
||||||
/* Insert new procedure in call graph */
|
/* Insert new procedure in call graph */
|
||||||
pcallGraph->insertCallGraph (this, iter);
|
- pcallGraph->insertCallGraph (this, iter);
|
||||||
|
|
||||||
|
//printf("From %X CALL to %X\n", lastIp, pstate->IP);
|
||||||
|
|
||||||
/* Process new procedure */
|
/* Process new procedure */
|
||||||
x.FollowCtrl (pcallGraph, pstate);
|
x.FollowCtrl (pcallGraph, pstate);
|
||||||
@ -629,17 +825,17 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
|||||||
SYM * psym, *psym2; /* Pointer to symbol in global symbol table */
|
SYM * psym, *psym2; /* Pointer to symbol in global symbol table */
|
||||||
uint8_t dstReg = ll.m_dst.regi;
|
uint8_t dstReg = ll.m_dst.regi;
|
||||||
uint8_t srcReg = ll.src().regi;
|
uint8_t srcReg = ll.src().regi;
|
||||||
if (dstReg > 0 && dstReg < INDEX_BX_SI)
|
if (dstReg > 0 and dstReg < INDEX_BX_SI)
|
||||||
{
|
{
|
||||||
if (ll.testFlags(I))
|
if (ll.testFlags(I))
|
||||||
pstate->setState( dstReg, (int16_t)ll.src().getImm2());
|
pstate->setState( dstReg, (int16_t)ll.src().getImm2());
|
||||||
else if (srcReg == 0) /* direct memory offset */
|
else if (srcReg == 0) /* direct memory offset */
|
||||||
{
|
{
|
||||||
psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE);
|
psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE);
|
||||||
if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val))
|
if (psym and ((psym->flg & SEG_IMMED) or psym->duVal.val))
|
||||||
pstate->setState( dstReg, LH(&prog.image()[psym->label]));
|
pstate->setState( dstReg, LH(&prog.image()[psym->label]));
|
||||||
}
|
}
|
||||||
else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */
|
else if (srcReg < INDEX_BX_SI and pstate->f[srcReg]) /* reg */
|
||||||
{
|
{
|
||||||
pstate->setState( dstReg, pstate->r[srcReg]);
|
pstate->setState( dstReg, pstate->r[srcReg]);
|
||||||
|
|
||||||
@ -650,10 +846,10 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
|||||||
}
|
}
|
||||||
else if (dstReg == 0) { /* direct memory offset */
|
else if (dstReg == 0) { /* direct memory offset */
|
||||||
int size=2;
|
int size=2;
|
||||||
if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH))
|
if((ll.src().regi>=rAL)and(ll.src().regi<=rBH))
|
||||||
size=1;
|
size=1;
|
||||||
psym = lookupAddr (&ll.m_dst, pstate, size, eDEF);
|
psym = lookupAddr (&ll.m_dst, pstate, size, eDEF);
|
||||||
if (psym && ! (psym->duVal.val)) /* no initial value yet */
|
if (psym and not (psym->duVal.val)) /* no initial value yet */
|
||||||
{
|
{
|
||||||
if (ll.testFlags(I)) /* immediate */
|
if (ll.testFlags(I)) /* immediate */
|
||||||
{
|
{
|
||||||
@ -669,7 +865,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
|||||||
else if (srcReg == 0) /* direct mem offset */
|
else if (srcReg == 0) /* direct mem offset */
|
||||||
{
|
{
|
||||||
psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE);
|
psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE);
|
||||||
if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val)))
|
if (psym2 and ((psym->flg & SEG_IMMED) or (psym->duVal.val)))
|
||||||
{
|
{
|
||||||
//prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label];
|
//prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label];
|
||||||
pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]);
|
pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]);
|
||||||
@ -682,7 +878,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
|||||||
psym2->duVal.setFlags(eDuVal::USE);
|
psym2->duVal.setFlags(eDuVal::USE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */
|
else if (srcReg < INDEX_BX_SI and pstate->f[srcReg]) /* reg */
|
||||||
{
|
{
|
||||||
//prog.image()[psym->label] = (uint8_t)pstate->r[srcReg];
|
//prog.image()[psym->label] = (uint8_t)pstate->r[srcReg];
|
||||||
pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]);
|
pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]);
|
||||||
@ -864,13 +1060,13 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
|||||||
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (pm->regi == INDEX_BP_SI || pm->regi == INDEX_BP_DI)
|
else if (pm->regi == INDEX_BP_SI or pm->regi == INDEX_BP_DI)
|
||||||
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off,
|
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off,
|
||||||
(uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI));
|
(uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI));
|
||||||
|
|
||||||
else if ((pm->regi >= INDEX_SI) && (pm->regi <= INDEX_BX))
|
else if ((pm->regi >= INDEX_SI) and (pm->regi <= INDEX_BX))
|
||||||
{
|
{
|
||||||
if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */
|
if ((pm->seg == rDS) and (pm->regi == INDEX_BX)) /* bx */
|
||||||
{
|
{
|
||||||
if (pm->off > 0) /* global indexed variable */
|
if (pm->off > 0) /* global indexed variable */
|
||||||
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
|
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
|
||||||
@ -892,7 +1088,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Use of register */
|
/* Use of register */
|
||||||
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
|
else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I))))
|
||||||
pIcode.du.use.addReg(pm->regi);
|
pIcode.du.use.addReg(pm->regi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,15 +1120,15 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
|||||||
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (pm->regi == INDEX_BP_SI || pm->regi == INDEX_BP_DI)
|
else if (pm->regi == INDEX_BP_SI or pm->regi == INDEX_BP_DI)
|
||||||
{
|
{
|
||||||
pProc->localId.newByteWordStk(TYPE_WORD_SIGN, pm->off,
|
pProc->localId.newByteWordStk(TYPE_WORD_SIGN, pm->off,
|
||||||
(uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI));
|
(uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((pm->regi >= INDEX_SI) && (pm->regi <= INDEX_BX))
|
else if ((pm->regi >= INDEX_SI) and (pm->regi <= INDEX_BX))
|
||||||
{
|
{
|
||||||
if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */
|
if ((pm->seg == rDS) and (pm->regi == INDEX_BX)) /* bx */
|
||||||
{
|
{
|
||||||
if (pm->off > 0) /* global var */
|
if (pm->off > 0) /* global var */
|
||||||
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
|
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
|
||||||
@ -941,7 +1137,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Definition of register */
|
/* Definition of register */
|
||||||
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
|
else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I))))
|
||||||
{
|
{
|
||||||
assert(not pIcode.ll()->match(iPUSH));
|
assert(not pIcode.ll()->match(iPUSH));
|
||||||
pIcode.du1.addDef(pm->regi);
|
pIcode.du1.addDef(pm->regi);
|
||||||
@ -985,7 +1181,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iSAR: case iSHL: case iSHR:
|
case iSAR: case iSHL: case iSHR:
|
||||||
case iRCL: case iRCR: case iROL: case iROR:
|
case iRCL: case iRCR: case iROL: case iROR:
|
||||||
case iADD: case iADC: case iSUB: case iSBB:
|
case iADD: case iADC: case iSUB: case iSBB:
|
||||||
if (! Imm) {
|
if (not Imm) {
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
}
|
}
|
||||||
case iINC: case iDEC: case iNEG: case iNOT:
|
case iINC: case iDEC: case iNEG: case iNOT:
|
||||||
@ -1003,7 +1199,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iTEST: case iCMP:
|
case iTEST: case iCMP:
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
use(DST, pIcode, this, pstate, cb);
|
use(DST, pIcode, this, pstate, cb);
|
||||||
break;
|
break;
|
||||||
@ -1016,7 +1212,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
|
|
||||||
case iMUL: case iIMUL:
|
case iMUL: case iIMUL:
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
{
|
{
|
||||||
use (DST, pIcode, this, pstate, cb);
|
use (DST, pIcode, this, pstate, cb);
|
||||||
if (cb == 1)
|
if (cb == 1)
|
||||||
@ -1053,7 +1249,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iCALLF: /* Ignore def's on CS for now */
|
case iCALLF: /* Ignore def's on CS for now */
|
||||||
cb = 4;
|
cb = 4;
|
||||||
case iCALL: case iPUSH: case iPOP:
|
case iCALL: case iPUSH: case iPOP:
|
||||||
if (! Imm) {
|
if (not Imm) {
|
||||||
if (pIcode.ll()->getOpcode() == iPOP)
|
if (pIcode.ll()->getOpcode() == iPOP)
|
||||||
def(DST, pIcode, this, pstate, cb);
|
def(DST, pIcode, this, pstate, cb);
|
||||||
else
|
else
|
||||||
@ -1091,7 +1287,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iJMPF:
|
case iJMPF:
|
||||||
cb = 4;
|
cb = 4;
|
||||||
case iJMP:
|
case iJMP:
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1118,7 +1314,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iSCAS: case iSTOS: case iINS:
|
case iSCAS: case iSTOS: case iINS:
|
||||||
pIcode.du.def.addReg(rDI);
|
pIcode.du.def.addReg(rDI);
|
||||||
pIcode.du1.addDef(rDI);
|
pIcode.du1.addDef(rDI);
|
||||||
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
|
if (pIcode.ll()->getOpcode() == iREP_INS or pIcode.ll()->getOpcode()== iINS)
|
||||||
{
|
{
|
||||||
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
|
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
|
||||||
}
|
}
|
||||||
@ -1152,7 +1348,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
|
|
||||||
case iIN: case iOUT:
|
case iIN: case iOUT:
|
||||||
def(DST, pIcode, this, pstate, cb);
|
def(DST, pIcode, this, pstate, cb);
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
{
|
{
|
||||||
pIcode.du.use.addReg(rDX);
|
pIcode.du.use.addReg(rDX);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,15 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <cassert>
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
/* Static indentation buffer */
|
/* Static indentation buffer */
|
||||||
static constexpr int indSize=81; /* size of indentation buffer; max 20 */
|
static constexpr int indSize=81; /* size of indentation buffer; max 20 */
|
||||||
@ -64,7 +67,7 @@ bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
|
|||||||
* the nodes the procedure invokes. */
|
* the nodes the procedure invokes. */
|
||||||
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
||||||
{
|
{
|
||||||
printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
|
qDebug() << indentStr(indIdx)+proc->name;
|
||||||
for (CALL_GRAPH *cg : outEdges)
|
for (CALL_GRAPH *cg : outEdges)
|
||||||
cg->writeNodeCallGraph (indIdx + 1);
|
cg->writeNodeCallGraph (indIdx + 1);
|
||||||
}
|
}
|
||||||
@ -85,7 +88,7 @@ void CALL_GRAPH::write()
|
|||||||
/* Updates the argument table by including the register(s) (ie. lhs of
|
/* Updates the argument table by including the register(s) (ie. lhs of
|
||||||
* picode) and the actual expression (ie. rhs of picode).
|
* picode) and the actual expression (ie. rhs of picode).
|
||||||
* Note: register(s) are only included once in the table. */
|
* Note: register(s) are only included once in the table. */
|
||||||
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
void LOCAL_ID::newRegArg(ICODE &picode, ICODE &ticode) const
|
||||||
{
|
{
|
||||||
AstIdent *lhs;
|
AstIdent *lhs;
|
||||||
STKFRAME * call_args_stackframe, *target_stackframe;
|
STKFRAME * call_args_stackframe, *target_stackframe;
|
||||||
@ -98,20 +101,20 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
eReg regH; /* Registers involved in arguments */
|
eReg regH; /* Registers involved in arguments */
|
||||||
|
|
||||||
/* Flag ticode as having register arguments */
|
/* Flag ticode as having register arguments */
|
||||||
tproc = ticode->hl()->call.proc;
|
tproc = ticode.hl()->call.proc;
|
||||||
tproc->flg |= REG_ARGS;
|
tproc->flg |= REG_ARGS;
|
||||||
|
|
||||||
/* Get registers and index into target procedure's local list */
|
/* Get registers and index into target procedure's local list */
|
||||||
call_args_stackframe = ticode->hl()->call.args;
|
call_args_stackframe = ticode.hl()->call.args;
|
||||||
target_stackframe = &tproc->args;
|
target_stackframe = &tproc->args;
|
||||||
lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
|
lhs = dynamic_cast<AstIdent *>(picode.hl()->asgn.lhs());
|
||||||
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
type = lhs->ident.type();
|
type = lhs->ident.type();
|
||||||
if(type==REGISTER)
|
if(type==REGISTER)
|
||||||
assert(lhs_reg);
|
assert(lhs_reg);
|
||||||
if(type==LONG_VAR)
|
if(type==LONG_VAR)
|
||||||
assert(!lhs_reg);
|
assert(nullptr==lhs_reg);
|
||||||
if (lhs_reg)
|
if (lhs_reg)
|
||||||
{
|
{
|
||||||
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
||||||
@ -176,7 +179,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
assert(regL!=rUNDEF);
|
assert(regL!=rUNDEF);
|
||||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||||
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name);
|
||||||
}
|
}
|
||||||
target_stackframe->push_back(newsym);
|
target_stackframe->push_back(newsym);
|
||||||
target_stackframe->numArgs++;
|
target_stackframe->numArgs++;
|
||||||
@ -185,13 +188,13 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
/* Do ps (actual arguments) */
|
/* Do ps (actual arguments) */
|
||||||
STKSYM newsym;
|
STKSYM newsym;
|
||||||
newsym.setArgName(call_args_stackframe->size());
|
newsym.setArgName(call_args_stackframe->size());
|
||||||
newsym.actual = picode->hl()->asgn.rhs;
|
newsym.actual = picode.hl()->asgn.m_rhs;
|
||||||
newsym.regs = lhs;
|
newsym.regs = lhs;
|
||||||
/* Mask off high and low register(s) in picode */
|
/* Mask off high and low register(s) in picode */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
id = &id_arr[lhs_reg->regiIdx];
|
id = &id_arr[lhs_reg->regiIdx];
|
||||||
picode->du.def.clrReg(id->id.regi);
|
picode.du.def.clrReg(id->id.regi);
|
||||||
if (id->id.regi < rAL)
|
if (id->id.regi < rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
newsym.type = TYPE_WORD_SIGN;
|
||||||
else
|
else
|
||||||
@ -199,8 +202,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
break;
|
break;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &id_arr[lhs->ident.idNode.longIdx];
|
id = &id_arr[lhs->ident.idNode.longIdx];
|
||||||
picode->du.def.clrReg(id->longId().h());
|
picode.du.def.clrReg(id->longId().h());
|
||||||
picode->du.def.clrReg(id->longId().l());
|
picode.du.def.clrReg(id->longId().l());
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -227,7 +230,7 @@ bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
|
|||||||
if (expr)
|
if (expr)
|
||||||
{
|
{
|
||||||
regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
|
regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
|
||||||
if ((regi >= rES) && (regi <= rDS))
|
if ((regi >= rES) and (regi <= rDS))
|
||||||
{
|
{
|
||||||
return (opcode == iCALLF) ? false : true;
|
return (opcode == iCALLF) ? false : true;
|
||||||
}
|
}
|
||||||
@ -365,8 +368,8 @@ void STKFRAME::adjustForArgType(size_t numArg_, hlType actType_)
|
|||||||
|
|
||||||
case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_UNSIGN:
|
||||||
case TYPE_LONG_SIGN:
|
case TYPE_LONG_SIGN:
|
||||||
if ((forType == TYPE_WORD_UNSIGN) ||
|
if ((forType == TYPE_WORD_UNSIGN) or
|
||||||
(forType == TYPE_WORD_SIGN) ||
|
(forType == TYPE_WORD_SIGN) or
|
||||||
(forType == TYPE_UNKNOWN))
|
(forType == TYPE_UNKNOWN))
|
||||||
{
|
{
|
||||||
/* Merge low and high */
|
/* Merge low and high */
|
||||||
|
|||||||
@ -5,17 +5,15 @@
|
|||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
//Project g_proj;
|
|
||||||
QString asm1_name, asm2_name; /* Assembler output filenames */
|
QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
SYMTAB symtab; /* Global symbol table */
|
STATS stats; /* cfg statistics */
|
||||||
STATS stats; /* cfg statistics */
|
OPTION option; /* Command line options */
|
||||||
//PROG prog; /* programs fields */
|
|
||||||
OPTION option; /* Command line options */
|
|
||||||
Project *Project::s_instance = nullptr;
|
Project *Project::s_instance = nullptr;
|
||||||
Project::Project() : callGraph(nullptr)
|
Project::Project() : callGraph(nullptr)
|
||||||
{
|
{
|
||||||
memset(&prog,0,sizeof(prog));
|
|
||||||
}
|
}
|
||||||
void Project::initialize()
|
void Project::initialize()
|
||||||
{
|
{
|
||||||
@ -41,7 +39,7 @@ bool Project::valid(ilFunction iter)
|
|||||||
ilFunction Project::funcIter(Function *to_find)
|
ilFunction Project::funcIter(Function *to_find)
|
||||||
{
|
{
|
||||||
auto iter=std::find_if(pProcList.begin(),pProcList.end(),
|
auto iter=std::find_if(pProcList.begin(),pProcList.end(),
|
||||||
[to_find](const Function &f)->bool {return to_find==&f;});
|
[to_find](const Function &f)->bool {return to_find==&f;});
|
||||||
assert(iter!=pProcList.end());
|
assert(iter!=pProcList.end());
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
@ -50,17 +48,17 @@ ilFunction Project::findByEntry(uint32_t entry)
|
|||||||
{
|
{
|
||||||
/* Search procedure list for one with appropriate entry point */
|
/* Search procedure list for one with appropriate entry point */
|
||||||
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||||
[entry](const Function &f) { return f.procEntry==entry; });
|
[entry](const Function &f) { return f.procEntry==entry; });
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilFunction Project::createFunction(FunctionType *f,const std::string &name)
|
ilFunction Project::createFunction(FunctionType *f,const QString &name)
|
||||||
{
|
{
|
||||||
pProcList.push_back(Function::Create(f,0,name,0));
|
pProcList.push_back(*Function::Create(f,0,name,0));
|
||||||
return (++pProcList.rbegin()).base();
|
return (++pProcList.rbegin()).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Project::getSymIdxByAdd(uint32_t adr)
|
int Project::getSymIdxByAddr(uint32_t adr)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < symtab.size(); i++)
|
for (i = 0; i < symtab.size(); i++)
|
||||||
@ -87,7 +85,7 @@ hlType Project::symbolType(size_t idx)
|
|||||||
return symtab[idx].type;
|
return symtab[idx].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Project::symbolName(size_t idx)
|
const QString &Project::symbolName(size_t idx)
|
||||||
{
|
{
|
||||||
assert(validSymIdx(idx));
|
assert(validSymIdx(idx));
|
||||||
return symtab[idx].name;
|
return symtab[idx].name;
|
||||||
@ -99,8 +97,6 @@ Project *Project::get()
|
|||||||
s_instance=new Project;
|
s_instance=new Project;
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SourceMachine *Project::machine()
|
SourceMachine *Project::machine()
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -4,18 +4,20 @@
|
|||||||
* registers) along the graph. Structure the graph in this way.
|
* registers) along the graph. Structure the graph in this way.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
|
|
||||||
/* Returns whether the given icode opcode is within the range of valid
|
/* Returns whether the given icode opcode is within the range of valid
|
||||||
* high-level conditional jump icodes (iJB..iJG) */
|
* high-level conditional jump icodes (iJB..iJG) */
|
||||||
static bool isJCond (llIcode opcode)
|
static bool isJCond (llIcode opcode)
|
||||||
{
|
{
|
||||||
if ((opcode >= iJB) && (opcode <= iJG))
|
if ((opcode >= iJB) and (opcode <= iJG))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -32,10 +34,10 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc)
|
|||||||
e = pbb->edges[ELSE].BBptr;
|
e = pbb->edges[ELSE].BBptr;
|
||||||
|
|
||||||
/* Check along the THEN path */
|
/* Check along the THEN path */
|
||||||
if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
|
if ((t->size() == 1) and (t->nodeType == TWO_BRANCH) and (t->inEdges.size() == 1))
|
||||||
{
|
{
|
||||||
obb2 = t->edges[THEN].BBptr;
|
obb2 = t->edges[THEN].BBptr;
|
||||||
if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ll()->getOpcode() == iCMP))
|
if ((obb2->size() == 2) and (obb2->nodeType == TWO_BRANCH) and (obb2->front().ll()->getOpcode() == iCMP))
|
||||||
{
|
{
|
||||||
off = obb2->begin();//std::distance(iter,obb2->begin2());
|
off = obb2->begin();//std::distance(iter,obb2->begin2());
|
||||||
*arc = THEN;
|
*arc = THEN;
|
||||||
@ -44,10 +46,10 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check along the ELSE path */
|
/* Check along the ELSE path */
|
||||||
else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
|
else if ((e->size() == 1) and (e->nodeType == TWO_BRANCH) and (e->inEdges.size() == 1))
|
||||||
{
|
{
|
||||||
obb2 = e->edges[THEN].BBptr;
|
obb2 = e->edges[THEN].BBptr;
|
||||||
if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ll()->getOpcode() == iCMP))
|
if ((obb2->size() == 2) and (obb2->nodeType == TWO_BRANCH) and (obb2->front().ll()->getOpcode() == iCMP))
|
||||||
{
|
{
|
||||||
off = obb2->begin();//std::distance(iter,obb2->begin2());//obb2->front().loc_ip - i;
|
off = obb2->begin();//std::distance(iter,obb2->begin2());//obb2->front().loc_ip - i;
|
||||||
*arc = ELSE;
|
*arc = ELSE;
|
||||||
@ -66,9 +68,9 @@ static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
|||||||
return false;
|
return false;
|
||||||
// preincrement because pIcode is not checked here
|
// preincrement because pIcode is not checked here
|
||||||
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
|
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
|
||||||
if ( icodes[1]->ll()->match(iCMP) &&
|
if ( icodes[1]->ll()->match(iCMP) and
|
||||||
(isJCond ((llIcode)icodes[0]->ll()->getOpcode())) &&
|
(isJCond (icodes[0]->ll()->getOpcode())) and
|
||||||
(isJCond ((llIcode)icodes[2]->ll()->getOpcode())))
|
(isJCond (icodes[2]->ll()->getOpcode())))
|
||||||
{
|
{
|
||||||
off = initial_icode;
|
off = initial_icode;
|
||||||
advance(off,2);
|
advance(off,2);
|
||||||
@ -101,7 +103,7 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse
|
|||||||
/* Modify in edges of target basic block */
|
/* Modify in edges of target basic block */
|
||||||
auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
|
auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
|
||||||
[obb1,obb2](BB *b) -> bool {
|
[obb1,obb2](BB *b) -> bool {
|
||||||
return (b==obb1) || (b==obb2); });
|
return (b==obb1) or (b==obb2); });
|
||||||
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
||||||
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||||
|
|
||||||
@ -129,7 +131,7 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse
|
|||||||
/* Modify in edges of the ELSE basic block */
|
/* Modify in edges of the ELSE basic block */
|
||||||
tbb = obb2->edges[ELSE].BBptr;
|
tbb = obb2->edges[ELSE].BBptr;
|
||||||
auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
|
auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
|
||||||
[obb1,obb2](BB *b) -> bool { return (b==obb1) || (b==obb2); });
|
[obb1,obb2](BB *b) -> bool { return (b==obb1) or (b==obb2); });
|
||||||
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
||||||
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||||
|
|
||||||
@ -210,7 +212,7 @@ static int longJCond22 (Assignment &asgn, iICODE pIcode,iICODE pEnd)
|
|||||||
iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
|
iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
|
||||||
assert(iter!=tbb->inEdges.end());
|
assert(iter!=tbb->inEdges.end());
|
||||||
tbb->inEdges.erase(iter);
|
tbb->inEdges.erase(iter);
|
||||||
if (icodes[3]->ll()->getOpcode() == iJE) /* replace */
|
if (icodes[3]->ll()->getOpcode() == iJE) /* replace */
|
||||||
tbb->inEdges.push_back(pbb);
|
tbb->inEdges.push_back(pbb);
|
||||||
|
|
||||||
/* Update statistics */
|
/* Update statistics */
|
||||||
@ -246,7 +248,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
next1 = ++iICODE(pIcode);
|
next1 = ++iICODE(pIcode);
|
||||||
if(next1==pEnd)
|
if(next1==pEnd)
|
||||||
break;
|
break;
|
||||||
if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() ))
|
if ((pIcode->type == HIGH_LEVEL_ICODE) or ( not pIcode->valid() ))
|
||||||
continue;
|
continue;
|
||||||
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
@ -264,9 +266,9 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
condOp oper = DUMMY;
|
condOp oper = DUMMY;
|
||||||
switch (pIcode->ll()->getOpcode())
|
switch (pIcode->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iAND: oper=AND; break;
|
case iAND: oper=AND; break;
|
||||||
case iOR: oper=OR; break;
|
case iOR: oper=OR; break;
|
||||||
case iXOR: oper=XOR; break;
|
case iXOR: oper=XOR; break;
|
||||||
}
|
}
|
||||||
if(DUMMY!=oper)
|
if(DUMMY!=oper)
|
||||||
{
|
{
|
||||||
@ -288,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
}
|
}
|
||||||
//TODO: Simplify this!
|
//TODO: Simplify this!
|
||||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
|
else if ((pIcode->ll()->getOpcode() == iCMP) and (isLong23 (pIcode->getParent(), l23, &arc)))
|
||||||
{
|
{
|
||||||
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
|
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
|
||||||
{
|
{
|
||||||
@ -298,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
|
|
||||||
/* Check for long conditional equality or inequality. This requires
|
/* Check for long conditional equality or inequality. This requires
|
||||||
* 2 CMPs and 2 branches */
|
* 2 CMPs and 2 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
|
else if ((pIcode->ll()->getOpcode() == iCMP) and isLong22 (pIcode, pEnd, l23))
|
||||||
{
|
{
|
||||||
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
|
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
|
||||||
{
|
{
|
||||||
@ -321,7 +323,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
ICODE &icode(*pIcode);
|
ICODE &icode(*pIcode);
|
||||||
|
|
||||||
|
|
||||||
if ((icode.type == HIGH_LEVEL) || ( not icode.valid() ))
|
if ((icode.type == HIGH_LEVEL_ICODE) or ( not icode.valid() ))
|
||||||
continue;
|
continue;
|
||||||
if (icode.ll()->getOpcode() != next1->ll()->getOpcode())
|
if (icode.ll()->getOpcode() != next1->ll()->getOpcode())
|
||||||
continue;
|
continue;
|
||||||
@ -331,7 +333,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
case iMOV:
|
case iMOV:
|
||||||
pmH = &icode.ll()->m_dst;
|
pmH = &icode.ll()->m_dst;
|
||||||
pmL = &next1->ll()->m_dst;
|
pmL = &next1->ll()->m_dst;
|
||||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
||||||
icode.setRegDU( pmL->regi, eDEF);
|
icode.setRegDU( pmL->regi, eDEF);
|
||||||
@ -346,7 +348,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
case iPOP:
|
case iPOP:
|
||||||
pmH = &next1->ll()->m_dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
pmL = &icode.ll()->m_dst;
|
pmL = &icode.ll()->m_dst;
|
||||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
icode.setRegDU( pmH->regi, eDEF);
|
icode.setRegDU( pmH->regi, eDEF);
|
||||||
@ -362,7 +364,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
case iAND: case iOR: case iXOR:
|
case iAND: case iOR: case iXOR:
|
||||||
pmL = &icode.ll()->m_dst;
|
pmL = &icode.ll()->m_dst;
|
||||||
pmH = &next1->ll()->m_dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
|
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
|
||||||
@ -399,7 +401,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */
|
LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */
|
||||||
int arc;
|
int arc;
|
||||||
|
|
||||||
if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() ))
|
if ((pIcode->type == HIGH_LEVEL_ICODE) or ( not pIcode->valid() ))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
||||||
@ -412,7 +414,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
const LLOperand &src_op2(next1->ll()->src());
|
const LLOperand &src_op2(next1->ll()->src());
|
||||||
eReg srcReg1=src_op1.getReg2();
|
eReg srcReg1=src_op1.getReg2();
|
||||||
eReg nextReg2=src_op2.getReg2();
|
eReg nextReg2=src_op2.getReg2();
|
||||||
if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
|
if ((ref_long.h() == srcReg1) and (ref_long.l() == nextReg2))
|
||||||
{
|
{
|
||||||
pIcode->setRegDU( nextReg2, eUSE);
|
pIcode->setRegDU( nextReg2, eUSE);
|
||||||
|
|
||||||
@ -431,7 +433,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
const LONGID_TYPE &ref_long(pLocId.longId());
|
const LONGID_TYPE &ref_long(pLocId.longId());
|
||||||
const LLOperand &src_op1(pIcode->ll()->src());
|
const LLOperand &src_op1(pIcode->ll()->src());
|
||||||
const LLOperand &src_op2(next1->ll()->src());
|
const LLOperand &src_op2(next1->ll()->src());
|
||||||
if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
|
if ((ref_long.h() == src_op1.getReg2()) and (ref_long.l() == src_op2.getReg2()))
|
||||||
{
|
{
|
||||||
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
||||||
@ -447,7 +449,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
case iAND: case iOR: case iXOR:
|
case iAND: case iOR: case iXOR:
|
||||||
pmL = &pIcode->ll()->m_dst;
|
pmL = &pIcode->ll()->m_dst;
|
||||||
pmH = &next1->ll()->m_dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
pIcode->setRegDU( pmH->regi, USE_DEF);
|
pIcode->setRegDU( pmH->regi, USE_DEF);
|
||||||
@ -474,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
} /* eos */
|
} /* eos */
|
||||||
|
|
||||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
|
else if ((pIcode->ll()->getOpcode() == iCMP) and (isLong23 (pIcode->getParent(), long_loc, &arc)))
|
||||||
{
|
{
|
||||||
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
||||||
{
|
{
|
||||||
@ -485,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
|
|
||||||
/* Check for long conditional equality or inequality. This requires
|
/* Check for long conditional equality or inequality. This requires
|
||||||
* 2 CMPs and 2 branches */
|
* 2 CMPs and 2 branches */
|
||||||
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
|
else if (pIcode->ll()->match(iCMP) and (isLong22 (pIcode, pEnd, long_loc)))
|
||||||
{
|
{
|
||||||
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
||||||
{
|
{
|
||||||
@ -498,12 +500,12 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
* JX lab
|
* JX lab
|
||||||
* => HLI_JCOND (regH:regL X 0) lab
|
* => HLI_JCOND (regH:regL X 0) lab
|
||||||
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
||||||
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
|
else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond (next1->ll()->getOpcode())))
|
||||||
{
|
{
|
||||||
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
||||||
{
|
{
|
||||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.rhs = new Constant(0, 4); /* long 0 */
|
asgn.rhs = new Constant(0, 4); /* long 0 */
|
||||||
asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
|
asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
|
||||||
next1->setJCond(asgn.lhs);
|
next1->setJCond(asgn.lhs);
|
||||||
next1->copyDU(*pIcode, eUSE, eUSE);
|
next1->copyDU(*pIcode, eUSE, eUSE);
|
||||||
@ -546,7 +548,7 @@ void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
|
|||||||
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
|
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
|
||||||
void Function::propLongGlb (int /*i*/, const ID &/*pLocId*/)
|
void Function::propLongGlb (int /*i*/, const ID &/*pLocId*/)
|
||||||
{
|
{
|
||||||
printf("WARN: Function::propLongGlb not implemented");
|
printf("WARN: Function::propLongGlb not implemented\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,14 @@
|
|||||||
* constructs an equivalent reducible graph if one is not found.
|
* constructs an equivalent reducible graph if one is not found.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "dcc.h"
|
|
||||||
|
|
||||||
static int numInt; /* Number of intervals */
|
static int numInt; /* Number of intervals */
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ bool trivialGraph(BB *G)
|
|||||||
* from the list. Q is not an empty queue. */
|
* from the list. Q is not an empty queue. */
|
||||||
static BB *firstOfQueue (queue &Q)
|
static BB *firstOfQueue (queue &Q)
|
||||||
{
|
{
|
||||||
assert(!Q.empty());
|
assert(not Q.empty());
|
||||||
BB *res=Q.front();
|
BB *res=Q.front();
|
||||||
Q.pop_front();
|
Q.pop_front();
|
||||||
return res;
|
return res;
|
||||||
@ -79,7 +81,7 @@ void interval::appendNodeInt(queue &pqH, BB *node)
|
|||||||
|
|
||||||
/* Check header list for occurrence of node, if found, remove it
|
/* Check header list for occurrence of node, if found, remove it
|
||||||
* and decrement number of out-edges from this interval. */
|
* and decrement number of out-edges from this interval. */
|
||||||
if (node->beenOnH && !pqH.empty())
|
if (node->beenOnH and not pqH.empty())
|
||||||
{
|
{
|
||||||
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||||
if(found_iter!=pqH.end())
|
if(found_iter!=pqH.end())
|
||||||
@ -111,7 +113,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
|
Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
|
||||||
|
|
||||||
/* Process header nodes list H */
|
/* Process header nodes list H */
|
||||||
while (!H.empty())
|
while (not H.empty())
|
||||||
{
|
{
|
||||||
header = firstOfQueue (H);
|
header = firstOfQueue (H);
|
||||||
pI = new interval;
|
pI = new interval;
|
||||||
@ -137,7 +139,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
succ->reachingInt = header;
|
succ->reachingInt = header;
|
||||||
if (succ->inEdgeCount == 0)
|
if (succ->inEdgeCount == 0)
|
||||||
pI->appendNodeInt (H, succ);
|
pI->appendNodeInt (H, succ);
|
||||||
else if (! succ->beenOnH) /* out edge */
|
else if (not succ->beenOnH) /* out edge */
|
||||||
{
|
{
|
||||||
appendQueue (H, succ);
|
appendQueue (H, succ);
|
||||||
succ->beenOnH = true;
|
succ->beenOnH = true;
|
||||||
@ -147,7 +149,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
else /* node has been visited before */
|
else /* node has been visited before */
|
||||||
if (succ->inEdgeCount == 0)
|
if (succ->inEdgeCount == 0)
|
||||||
{
|
{
|
||||||
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
|
if (succ->reachingInt == header or succ->inInterval == pI) /* same interval */
|
||||||
{
|
{
|
||||||
if (succ != header)
|
if (succ != header)
|
||||||
pI->appendNodeInt (H, succ);
|
pI->appendNodeInt (H, succ);
|
||||||
@ -155,13 +157,13 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
else /* out edge */
|
else /* out edge */
|
||||||
pI->numOutEdges++;
|
pI->numOutEdges++;
|
||||||
}
|
}
|
||||||
else if (succ != header && succ->beenOnH)
|
else if (succ != header and succ->beenOnH)
|
||||||
pI->numOutEdges++;
|
pI->numOutEdges++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link interval I to list of intervals */
|
/* Link interval I to list of intervals */
|
||||||
if (! first)
|
if (not first)
|
||||||
{
|
{
|
||||||
m_intervals.push_back(pI);
|
m_intervals.push_back(pI);
|
||||||
J->next = pI;
|
J->next = pI;
|
||||||
@ -230,7 +232,7 @@ void freeDerivedSeq(derSeq &derivedG)
|
|||||||
derSeq_Entry::~derSeq_Entry()
|
derSeq_Entry::~derSeq_Entry()
|
||||||
{
|
{
|
||||||
freeInterval (&Ii);
|
freeInterval (&Ii);
|
||||||
// if(Gi && Gi->nodeType == INTERVAL_NODE)
|
// if(Gi and Gi->nodeType == INTERVAL_NODE)
|
||||||
// freeCFG (Gi);
|
// freeCFG (Gi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +261,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
|
|||||||
const queue &listIi(Ii->nodes);
|
const queue &listIi(Ii->nodes);
|
||||||
|
|
||||||
/* Check for more than 1 interval */
|
/* Check for more than 1 interval */
|
||||||
if (sameGraph && (listIi.size()>1))
|
if (sameGraph and (listIi.size()>1))
|
||||||
sameGraph = false;
|
sameGraph = false;
|
||||||
|
|
||||||
/* Find out edges */
|
/* Find out edges */
|
||||||
@ -309,20 +311,20 @@ bool Function::findDerivedSeq (derSeq &derivedGi)
|
|||||||
derSeq::iterator iter=derivedGi.begin();
|
derSeq::iterator iter=derivedGi.begin();
|
||||||
assert(iter!=derivedGi.end());
|
assert(iter!=derivedGi.end());
|
||||||
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
||||||
while (! trivialGraph (Gi))
|
while (not trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
||||||
iter->findIntervals(this);
|
iter->findIntervals(this);
|
||||||
|
|
||||||
/* Create Gi+1 and check if it is equivalent to Gi */
|
/* Create Gi+1 and check if it is equivalent to Gi */
|
||||||
if (! nextOrderGraph (derivedGi))
|
if (not nextOrderGraph (derivedGi))
|
||||||
break;
|
break;
|
||||||
++iter;
|
++iter;
|
||||||
Gi = iter->Gi;
|
Gi = iter->Gi;
|
||||||
stats.nOrder++;
|
stats.nOrder++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! trivialGraph (Gi))
|
if (not trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
++iter;
|
++iter;
|
||||||
derivedGi.erase(iter,derivedGi.end()); /* remove Gi+1 */
|
derivedGi.erase(iter,derivedGi.end()); /* remove Gi+1 */
|
||||||
@ -366,7 +368,7 @@ derSeq * Function::checkReducibility()
|
|||||||
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
||||||
reducible = findDerivedSeq(*der_seq);
|
reducible = findDerivedSeq(*der_seq);
|
||||||
|
|
||||||
if (! reducible)
|
if (not reducible)
|
||||||
{
|
{
|
||||||
flg |= GRAPH_IRRED;
|
flg |= GRAPH_IRRED;
|
||||||
m_actual_cfg.nodeSplitting();
|
m_actual_cfg.nodeSplitting();
|
||||||
|
|||||||
657
src/scanner.cpp
657
src/scanner.cpp
@ -1,22 +1,24 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* dcc project scanner module
|
* dcc project scanner module
|
||||||
* Implements a simple state driven scanner to convert 8086 machine code into
|
* Implements a simple state driven scanner to convert 8086 machine code into
|
||||||
* I-code
|
* I-code
|
||||||
* (C) Cristina Cifuentes, Jeff Ledermann
|
* (C) Cristina Cifuentes, Jeff Ledermann
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#include "scanner.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "dcc.h"
|
|
||||||
#include "scanner.h"
|
|
||||||
#include "project.h"
|
|
||||||
/* Parser flags */
|
/* Parser flags */
|
||||||
#define TO_REG 0x000100 /* rm is source */
|
#define TO_REG 0x000100 /* rm is source */
|
||||||
#define S_EXT 0x000200 /* sign extend */
|
#define S_EXT 0x000200 /* sign extend */
|
||||||
#define OP386 0x000400 /* 386 op-code */
|
#define OP386 0x000400 /* 386 op-code */
|
||||||
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
||||||
// defined in Enums.h #define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
|
||||||
|
|
||||||
static void rm(int i);
|
static void rm(int i);
|
||||||
static void modrm(int i);
|
static void modrm(int i);
|
||||||
@ -48,276 +50,276 @@ static void none1(int i);
|
|||||||
static void none2(int i);
|
static void none2(int i);
|
||||||
static void checkInt(int i);
|
static void checkInt(int i);
|
||||||
|
|
||||||
#define iZERO (llIcode)0 // For neatness
|
#define IC llIcode
|
||||||
#define IC llIcode
|
|
||||||
|
|
||||||
static struct {
|
struct StateTabelEntry {
|
||||||
void (*state1)(int);
|
void (*state1)(int);
|
||||||
void (*state2)(int);
|
void (*state2)(int);
|
||||||
uint32_t flg;
|
uint32_t flg;
|
||||||
llIcode opcode;
|
llIcode opcode;
|
||||||
} stateTable[] = {
|
};
|
||||||
{ modrm, none2, B , iADD }, /* 00 */
|
static const StateTabelEntry stateTable[] = {
|
||||||
{ modrm, none2, 0 , iADD }, /* 01 */
|
{ modrm, none2, B , iADD }, /* 00 */
|
||||||
{ modrm, none2, TO_REG | B , iADD }, /* 02 */
|
{ modrm, none2, 0 , iADD }, /* 01 */
|
||||||
{ modrm, none2, TO_REG , iADD }, /* 03 */
|
{ modrm, none2, TO_REG | B , iADD }, /* 02 */
|
||||||
{ data1, axImp, B , iADD }, /* 04 */
|
{ modrm, none2, TO_REG , iADD }, /* 03 */
|
||||||
{ data2, axImp, 0 , iADD }, /* 05 */
|
{ data1, axImp, B , iADD }, /* 04 */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 06 */
|
{ data2, axImp, 0 , iADD }, /* 05 */
|
||||||
{ segop, none2, NO_SRC , iPOP }, /* 07 */
|
{ segop, none2, NO_SRC , iPUSH }, /* 06 */
|
||||||
{ modrm, none2, B , iOR }, /* 08 */
|
{ segop, none2, NO_SRC , iPOP }, /* 07 */
|
||||||
{ modrm, none2, NSP , iOR }, /* 09 */
|
{ modrm, none2, B , iOR }, /* 08 */
|
||||||
{ modrm, none2, TO_REG | B , iOR }, /* 0A */
|
{ modrm, none2, NSP , iOR }, /* 09 */
|
||||||
{ modrm, none2, TO_REG | NSP , iOR }, /* 0B */
|
{ modrm, none2, TO_REG | B , iOR }, /* 0A */
|
||||||
{ data1, axImp, B , iOR }, /* 0C */
|
{ modrm, none2, TO_REG | NSP , iOR }, /* 0B */
|
||||||
{ data2, axImp, 0 , iOR }, /* 0D */
|
{ data1, axImp, B , iOR }, /* 0C */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 0E */
|
{ data2, axImp, 0 , iOR }, /* 0D */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 0F */
|
{ segop, none2, NO_SRC , iPUSH }, /* 0E */
|
||||||
{ modrm, none2, B , iADC }, /* 10 */
|
{ none1, none2, OP386 , iINVALID }, /* 0F */
|
||||||
{ modrm, none2, NSP , iADC }, /* 11 */
|
{ modrm, none2, B , iADC }, /* 10 */
|
||||||
{ modrm, none2, TO_REG | B , iADC }, /* 12 */
|
{ modrm, none2, NSP , iADC }, /* 11 */
|
||||||
{ modrm, none2, TO_REG | NSP , iADC }, /* 13 */
|
{ modrm, none2, TO_REG | B , iADC }, /* 12 */
|
||||||
{ data1, axImp, B , iADC }, /* 14 */
|
{ modrm, none2, TO_REG | NSP , iADC }, /* 13 */
|
||||||
{ data2, axImp, 0 , iADC }, /* 15 */
|
{ data1, axImp, B , iADC }, /* 14 */
|
||||||
{ segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
|
{ data2, axImp, 0 , iADC }, /* 15 */
|
||||||
{ segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
|
{ segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
|
||||||
{ modrm, none2, B , iSBB }, /* 18 */
|
{ segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
|
||||||
{ modrm, none2, NSP , iSBB }, /* 19 */
|
{ modrm, none2, B , iSBB }, /* 18 */
|
||||||
{ modrm, none2, TO_REG | B , iSBB }, /* 1A */
|
{ modrm, none2, NSP , iSBB }, /* 19 */
|
||||||
{ modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
|
{ modrm, none2, TO_REG | B , iSBB }, /* 1A */
|
||||||
{ data1, axImp, B , iSBB }, /* 1C */
|
{ modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
|
||||||
{ data2, axImp, 0 , iSBB }, /* 1D */
|
{ data1, axImp, B , iSBB }, /* 1C */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 1E */
|
{ data2, axImp, 0 , iSBB }, /* 1D */
|
||||||
{ segop, none2, NO_SRC , iPOP }, /* 1F */
|
{ segop, none2, NO_SRC , iPUSH }, /* 1E */
|
||||||
{ modrm, none2, B , iAND }, /* 20 */
|
{ segop, none2, NO_SRC , iPOP }, /* 1F */
|
||||||
{ modrm, none2, NSP , iAND }, /* 21 */
|
{ modrm, none2, B , iAND }, /* 20 */
|
||||||
{ modrm, none2, TO_REG | B , iAND }, /* 22 */
|
{ modrm, none2, NSP , iAND }, /* 21 */
|
||||||
{ modrm, none2, TO_REG | NSP , iAND }, /* 23 */
|
{ modrm, none2, TO_REG | B , iAND }, /* 22 */
|
||||||
{ data1, axImp, B , iAND }, /* 24 */
|
{ modrm, none2, TO_REG | NSP , iAND }, /* 23 */
|
||||||
{ data2, axImp, 0 , iAND }, /* 25 */
|
{ data1, axImp, B , iAND }, /* 24 */
|
||||||
{ prefix, none2, 0 , (IC)rES}, /* 26 */
|
{ data2, axImp, 0 , iAND }, /* 25 */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
|
{ prefix, none2, 0 , (IC)rES}, /* 26 */
|
||||||
{ modrm, none2, B , iSUB }, /* 28 */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
|
||||||
{ modrm, none2, 0 , iSUB }, /* 29 */
|
{ modrm, none2, B , iSUB }, /* 28 */
|
||||||
{ modrm, none2, TO_REG | B , iSUB }, /* 2A */
|
{ modrm, none2, 0 , iSUB }, /* 29 */
|
||||||
{ modrm, none2, TO_REG , iSUB }, /* 2B */
|
{ modrm, none2, TO_REG | B , iSUB }, /* 2A */
|
||||||
{ data1, axImp, B , iSUB }, /* 2C */
|
{ modrm, none2, TO_REG , iSUB }, /* 2B */
|
||||||
{ data2, axImp, 0 , iSUB }, /* 2D */
|
{ data1, axImp, B , iSUB }, /* 2C */
|
||||||
{ prefix, none2, 0 , (IC)rCS}, /* 2E */
|
{ data2, axImp, 0 , iSUB }, /* 2D */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
|
{ prefix, none2, 0 , (IC)rCS}, /* 2E */
|
||||||
{ modrm, none2, B , iXOR }, /* 30 */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
|
||||||
{ modrm, none2, NSP , iXOR }, /* 31 */
|
{ modrm, none2, B , iXOR }, /* 30 */
|
||||||
{ modrm, none2, TO_REG | B , iXOR }, /* 32 */
|
{ modrm, none2, NSP , iXOR }, /* 31 */
|
||||||
{ modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
|
{ modrm, none2, TO_REG | B , iXOR }, /* 32 */
|
||||||
{ data1, axImp, B , iXOR }, /* 34 */
|
{ modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
|
||||||
{ data2, axImp, 0 , iXOR }, /* 35 */
|
{ data1, axImp, B , iXOR }, /* 34 */
|
||||||
{ prefix, none2, 0 , (IC)rSS}, /* 36 */
|
{ data2, axImp, 0 , iXOR }, /* 35 */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
|
{ prefix, none2, 0 , (IC)rSS}, /* 36 */
|
||||||
{ modrm, none2, B , iCMP }, /* 38 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
|
||||||
{ modrm, none2, NSP , iCMP }, /* 39 */
|
{ modrm, none2, B , iCMP }, /* 38 */
|
||||||
{ modrm, none2, TO_REG | B , iCMP }, /* 3A */
|
{ modrm, none2, NSP , iCMP }, /* 39 */
|
||||||
{ modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
|
{ modrm, none2, TO_REG | B , iCMP }, /* 3A */
|
||||||
{ data1, axImp, B , iCMP }, /* 3C */
|
{ modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
|
||||||
{ data2, axImp, 0 , iCMP }, /* 3D */
|
{ data1, axImp, B , iCMP }, /* 3C */
|
||||||
{ prefix, none2, 0 , (IC)rDS}, /* 3E */
|
{ data2, axImp, 0 , iCMP }, /* 3D */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
|
{ prefix, none2, 0 , (IC)rDS}, /* 3E */
|
||||||
{ regop, none2, 0 , iINC }, /* 40 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
|
||||||
{ regop, none2, 0 , iINC }, /* 41 */
|
{ regop, none2, 0 , iINC }, /* 40 */
|
||||||
{ regop, none2, 0 , iINC }, /* 42 */
|
{ regop, none2, 0 , iINC }, /* 41 */
|
||||||
{ regop, none2, 0 , iINC }, /* 43 */
|
{ regop, none2, 0 , iINC }, /* 42 */
|
||||||
{ regop, none2, NOT_HLL , iINC }, /* 44 */
|
{ regop, none2, 0 , iINC }, /* 43 */
|
||||||
{ regop, none2, 0 , iINC }, /* 45 */
|
{ regop, none2, NOT_HLL , iINC }, /* 44 */
|
||||||
{ regop, none2, 0 , iINC }, /* 46 */
|
{ regop, none2, 0 , iINC }, /* 45 */
|
||||||
{ regop, none2, 0 , iINC }, /* 47 */
|
{ regop, none2, 0 , iINC }, /* 46 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 48 */
|
{ regop, none2, 0 , iINC }, /* 47 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 49 */
|
{ regop, none2, 0 , iDEC }, /* 48 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4A */
|
{ regop, none2, 0 , iDEC }, /* 49 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4B */
|
{ regop, none2, 0 , iDEC }, /* 4A */
|
||||||
{ regop, none2, NOT_HLL , iDEC }, /* 4C */
|
{ regop, none2, 0 , iDEC }, /* 4B */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4D */
|
{ regop, none2, NOT_HLL , iDEC }, /* 4C */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4E */
|
{ regop, none2, 0 , iDEC }, /* 4D */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4F */
|
{ regop, none2, 0 , iDEC }, /* 4E */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 50 */
|
{ regop, none2, 0 , iDEC }, /* 4F */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 51 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 50 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 52 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 51 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 53 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 52 */
|
||||||
{ regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 53 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 55 */
|
{ regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 56 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 55 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 57 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 56 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 58 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 57 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 59 */
|
{ regop, none2, NO_SRC , iPOP }, /* 58 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5A */
|
{ regop, none2, NO_SRC , iPOP }, /* 59 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5B */
|
{ regop, none2, NO_SRC , iPOP }, /* 5A */
|
||||||
{ regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
|
{ regop, none2, NO_SRC , iPOP }, /* 5B */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5D */
|
{ regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5E */
|
{ regop, none2, NO_SRC , iPOP }, /* 5D */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5F */
|
{ regop, none2, NO_SRC , iPOP }, /* 5E */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
|
{ regop, none2, NO_SRC , iPOP }, /* 5F */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
|
{ none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 63 */
|
{ memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 64 */
|
{ none1, none2, OP386 , iINVALID }, /* 63 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 65 */
|
{ none1, none2, OP386 , iINVALID }, /* 64 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 66 */
|
{ none1, none2, OP386 , iINVALID }, /* 65 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 67 */
|
{ none1, none2, OP386 , iINVALID }, /* 66 */
|
||||||
{ data2, none2, NO_SRC , iPUSH }, /* 68 */
|
{ none1, none2, OP386 , iINVALID }, /* 67 */
|
||||||
{ modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
|
{ data2, none2, NO_SRC , iPUSH }, /* 68 */
|
||||||
{ data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
|
{ modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
|
||||||
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
|
{ data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
|
||||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
|
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
|
||||||
{ strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
|
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
|
||||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
|
{ strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
|
||||||
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
|
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
|
||||||
{ dispS, none2, NOT_HLL , iJO }, /* 70 */
|
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
|
||||||
{ dispS, none2, NOT_HLL , iJNO }, /* 71 */
|
{ dispS, none2, NOT_HLL , iJO }, /* 70 */
|
||||||
{ dispS, none2, 0 , iJB }, /* 72 */
|
{ dispS, none2, NOT_HLL , iJNO }, /* 71 */
|
||||||
{ dispS, none2, 0 , iJAE }, /* 73 */
|
{ dispS, none2, 0 , iJB }, /* 72 */
|
||||||
{ dispS, none2, 0 , iJE }, /* 74 */
|
{ dispS, none2, 0 , iJAE }, /* 73 */
|
||||||
{ dispS, none2, 0 , iJNE }, /* 75 */
|
{ dispS, none2, 0 , iJE }, /* 74 */
|
||||||
{ dispS, none2, 0 , iJBE }, /* 76 */
|
{ dispS, none2, 0 , iJNE }, /* 75 */
|
||||||
{ dispS, none2, 0 , iJA }, /* 77 */
|
{ dispS, none2, 0 , iJBE }, /* 76 */
|
||||||
{ dispS, none2, 0 , iJS }, /* 78 */
|
{ dispS, none2, 0 , iJA }, /* 77 */
|
||||||
{ dispS, none2, 0 , iJNS }, /* 79 */
|
{ dispS, none2, 0 , iJS }, /* 78 */
|
||||||
{ dispS, none2, NOT_HLL , iJP }, /* 7A */
|
{ dispS, none2, 0 , iJNS }, /* 79 */
|
||||||
{ dispS, none2, NOT_HLL , iJNP }, /* 7B */
|
{ dispS, none2, NOT_HLL , iJP }, /* 7A */
|
||||||
{ dispS, none2, 0 , iJL }, /* 7C */
|
{ dispS, none2, NOT_HLL , iJNP }, /* 7B */
|
||||||
{ dispS, none2, 0 , iJGE }, /* 7D */
|
{ dispS, none2, 0 , iJL }, /* 7C */
|
||||||
{ dispS, none2, 0 , iJLE }, /* 7E */
|
{ dispS, none2, 0 , iJGE }, /* 7D */
|
||||||
{ dispS, none2, 0 , iJG }, /* 7F */
|
{ dispS, none2, 0 , iJLE }, /* 7E */
|
||||||
{ immed, data1, B , iZERO }, /* 80 */
|
{ dispS, none2, 0 , iJG }, /* 7F */
|
||||||
{ immed, data2, NSP , iZERO }, /* 81 */
|
{ immed, data1, B , iINVALID }, /* 80 */
|
||||||
{ immed, data1, B , iZERO }, /* 82 */ /* ?? */
|
{ immed, data2, NSP , iINVALID }, /* 81 */
|
||||||
{ immed, data1, NSP | S_EXT , iZERO }, /* 83 */
|
{ immed, data1, B , iINVALID }, /* 82 */ /* ?? */
|
||||||
{ modrm, none2, TO_REG | B , iTEST }, /* 84 */
|
{ immed, data1, NSP | S_EXT , iINVALID }, /* 83 */
|
||||||
{ modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
|
{ modrm, none2, TO_REG | B , iTEST }, /* 84 */
|
||||||
{ modrm, none2, TO_REG | B , iXCHG }, /* 86 */
|
{ modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
|
||||||
{ modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
|
{ modrm, none2, TO_REG | B , iXCHG }, /* 86 */
|
||||||
{ modrm, none2, B , iMOV }, /* 88 */
|
{ modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
|
||||||
{ modrm, none2, 0 , iMOV }, /* 89 */
|
{ modrm, none2, B , iMOV }, /* 88 */
|
||||||
{ modrm, none2, TO_REG | B , iMOV }, /* 8A */
|
{ modrm, none2, 0 , iMOV }, /* 89 */
|
||||||
{ modrm, none2, TO_REG , iMOV }, /* 8B */
|
{ modrm, none2, TO_REG | B , iMOV }, /* 8A */
|
||||||
{ segrm, none2, NSP , iMOV }, /* 8C */
|
{ modrm, none2, TO_REG , iMOV }, /* 8B */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
|
{ segrm, none2, NSP , iMOV }, /* 8C */
|
||||||
{ segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
|
{ memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
|
||||||
{ memReg0, none2, NO_SRC , iPOP }, /* 8F */
|
{ segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
|
||||||
{ none1, none2, NO_OPS , iNOP }, /* 90 */
|
{ memReg0, none2, NO_SRC , iPOP }, /* 8F */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 91 */
|
{ none1, none2, NO_OPS , iNOP }, /* 90 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 92 */
|
{ regop, axImp, 0 , iXCHG }, /* 91 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 93 */
|
{ regop, axImp, 0 , iXCHG }, /* 92 */
|
||||||
{ regop, axImp, NOT_HLL , iXCHG }, /* 94 */
|
{ regop, axImp, 0 , iXCHG }, /* 93 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 95 */
|
{ regop, axImp, NOT_HLL , iXCHG }, /* 94 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 96 */
|
{ regop, axImp, 0 , iXCHG }, /* 95 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
{ regop, axImp, 0 , iXCHG }, /* 96 */
|
||||||
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
||||||
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
||||||
{ dispF, none2, 0 , iCALLF }, /* 9A */
|
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
||||||
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
{ dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
|
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
|
{ none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
|
||||||
{ dispM, axImp, B , iMOV }, /* A0 */
|
{ none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
|
||||||
{ dispM, axImp, 0 , iMOV }, /* A1 */
|
{ dispM, axImp, B , iMOV }, /* A0 */
|
||||||
{ dispM, axImp, TO_REG | B , iMOV }, /* A2 */
|
{ dispM, axImp, 0 , iMOV }, /* A1 */
|
||||||
{ dispM, axImp, TO_REG , iMOV }, /* A3 */
|
{ dispM, axImp, TO_REG | B , iMOV }, /* A2 */
|
||||||
{ strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
|
{ dispM, axImp, TO_REG , iMOV }, /* A3 */
|
||||||
{ strop, memImp, IM_OPS , iMOVS }, /* A5 */
|
{ strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
|
||||||
{ strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
|
{ strop, memImp, IM_OPS , iMOVS }, /* A5 */
|
||||||
{ strop, memImp, IM_OPS , iCMPS }, /* A7 */
|
{ strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
|
||||||
{ data1, axImp, B , iTEST }, /* A8 */
|
{ strop, memImp, IM_OPS , iCMPS }, /* A7 */
|
||||||
{ data2, axImp, 0 , iTEST }, /* A9 */
|
{ data1, axImp, B , iTEST }, /* A8 */
|
||||||
{ strop, memImp, B | IM_OPS , iSTOS }, /* AA */
|
{ data2, axImp, 0 , iTEST }, /* A9 */
|
||||||
{ strop, memImp, IM_OPS , iSTOS }, /* AB */
|
{ strop, memImp, B | IM_OPS , iSTOS }, /* AA */
|
||||||
{ strop, memImp, B | IM_OPS , iLODS }, /* AC */
|
{ strop, memImp, IM_OPS , iSTOS }, /* AB */
|
||||||
{ strop, memImp, IM_OPS , iLODS }, /* AD */
|
{ strop, memImp, B | IM_OPS , iLODS }, /* AC */
|
||||||
{ strop, memImp, B | IM_OPS , iSCAS }, /* AE */
|
{ strop, memImp, IM_OPS , iLODS }, /* AD */
|
||||||
{ strop, memImp, IM_OPS , iSCAS }, /* AF */
|
{ strop, memImp, B | IM_OPS , iSCAS }, /* AE */
|
||||||
{ regop, data1, B , iMOV }, /* B0 */
|
{ strop, memImp, IM_OPS , iSCAS }, /* AF */
|
||||||
{ regop, data1, B , iMOV }, /* B1 */
|
{ regop, data1, B , iMOV }, /* B0 */
|
||||||
{ regop, data1, B , iMOV }, /* B2 */
|
{ regop, data1, B , iMOV }, /* B1 */
|
||||||
{ regop, data1, B , iMOV }, /* B3 */
|
{ regop, data1, B , iMOV }, /* B2 */
|
||||||
{ regop, data1, B , iMOV }, /* B4 */
|
{ regop, data1, B , iMOV }, /* B3 */
|
||||||
{ regop, data1, B , iMOV }, /* B5 */
|
{ regop, data1, B , iMOV }, /* B4 */
|
||||||
{ regop, data1, B , iMOV }, /* B6 */
|
{ regop, data1, B , iMOV }, /* B5 */
|
||||||
{ regop, data1, B , iMOV }, /* B7 */
|
{ regop, data1, B , iMOV }, /* B6 */
|
||||||
{ regop, data2, 0 , iMOV }, /* B8 */
|
{ regop, data1, B , iMOV }, /* B7 */
|
||||||
{ regop, data2, 0 , iMOV }, /* B9 */
|
{ regop, data2, 0 , iMOV }, /* B8 */
|
||||||
{ regop, data2, 0 , iMOV }, /* BA */
|
{ regop, data2, 0 , iMOV }, /* B9 */
|
||||||
{ regop, data2, 0 , iMOV }, /* BB */
|
{ regop, data2, 0 , iMOV }, /* BA */
|
||||||
{ regop, data2, NOT_HLL , iMOV }, /* BC */
|
{ regop, data2, 0 , iMOV }, /* BB */
|
||||||
{ regop, data2, 0 , iMOV }, /* BD */
|
{ regop, data2, NOT_HLL , iMOV }, /* BC */
|
||||||
{ regop, data2, 0 , iMOV }, /* BE */
|
{ regop, data2, 0 , iMOV }, /* BD */
|
||||||
{ regop, data2, 0 , iMOV }, /* BF */
|
{ regop, data2, 0 , iMOV }, /* BE */
|
||||||
{ shift, data1, B , iZERO }, /* C0 */
|
{ regop, data2, 0 , iMOV }, /* BF */
|
||||||
{ shift, data1, NSP | SRC_B , iZERO }, /* C1 */
|
{ shift, data1, B , iINVALID }, /* C0 */
|
||||||
{ data2, none2, 0 , iRET }, /* C2 */
|
{ shift, data1, NSP | SRC_B , iINVALID }, /* C1 */
|
||||||
{ none1, none2, NO_OPS , iRET }, /* C3 */
|
{ data2, none2, 0 , iRET }, /* C2 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
|
{ none1, none2, NO_OPS , iRET }, /* C3 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
|
{ memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
|
||||||
{ memReg0, data1, B , iMOV }, /* C6 */
|
{ memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
|
||||||
{ memReg0, data2, 0 , iMOV }, /* C7 */
|
{ memReg0, data1, B , iMOV }, /* C6 */
|
||||||
{ data2, data1, 0 , iENTER}, /* C8 */
|
{ memReg0, data2, 0 , iMOV }, /* C7 */
|
||||||
{ none1, none2, NO_OPS , iLEAVE}, /* C9 */
|
{ data2, data1, 0 , iENTER}, /* C8 */
|
||||||
{ data2, none2, 0 , iRETF }, /* CA */
|
{ none1, none2, NO_OPS , iLEAVE}, /* C9 */
|
||||||
{ none1, none2, NO_OPS , iRETF }, /* CB */
|
{ data2, none2, 0 , iRETF }, /* CA */
|
||||||
{ const3, none2, NOT_HLL , iINT }, /* CC */
|
{ none1, none2, NO_OPS , iRETF }, /* CB */
|
||||||
{ data1,checkInt, NOT_HLL , iINT }, /* CD */
|
{ const3, none2, NOT_HLL , iINT }, /* CC */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
|
{ data1,checkInt, NOT_HLL , iINT }, /* CD */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
|
{ none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
|
||||||
{ shift, const1, B , iZERO }, /* D0 */
|
{ none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
|
||||||
{ shift, const1, SRC_B , iZERO }, /* D1 */
|
{ shift, const1, B , iINVALID }, /* D0 */
|
||||||
{ shift, none1, B , iZERO }, /* D2 */
|
{ shift, const1, SRC_B , iINVALID }, /* D1 */
|
||||||
{ shift, none1, SRC_B , iZERO }, /* D3 */
|
{ shift, none1, B , iINVALID }, /* D2 */
|
||||||
{ data1, axImp, NOT_HLL , iAAM }, /* D4 */
|
{ shift, none1, SRC_B , iINVALID }, /* D3 */
|
||||||
{ data1, axImp, NOT_HLL , iAAD }, /* D5 */
|
{ data1, axImp, NOT_HLL , iAAM }, /* D4 */
|
||||||
{ none1, none2, 0 , iZERO }, /* D6 */
|
{ data1, axImp, NOT_HLL , iAAD }, /* D5 */
|
||||||
{ memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
|
{ none1, none2, 0 , iINVALID }, /* D6 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* D8 */
|
{ memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* D9 */
|
{ escop, none2, FLOAT_OP , iESC }, /* D8 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DA */
|
{ escop, none2, FLOAT_OP , iESC }, /* D9 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DB */
|
{ escop, none2, FLOAT_OP , iESC }, /* DA */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DC */
|
{ escop, none2, FLOAT_OP , iESC }, /* DB */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DD */
|
{ escop, none2, FLOAT_OP , iESC }, /* DC */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DE */
|
{ escop, none2, FLOAT_OP , iESC }, /* DD */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* Df */
|
{ escop, none2, FLOAT_OP , iESC }, /* DE */
|
||||||
{ dispS, none2, 0 , iLOOPNE}, /* E0 */
|
{ escop, none2, FLOAT_OP , iESC }, /* Df */
|
||||||
{ dispS, none2, 0 , iLOOPE}, /* E1 */
|
{ dispS, none2, 0 , iLOOPNE}, /* E0 */
|
||||||
{ dispS, none2, 0 , iLOOP }, /* E2 */
|
{ dispS, none2, 0 , iLOOPE}, /* E1 */
|
||||||
{ dispS, none2, 0 , iJCXZ }, /* E3 */
|
{ dispS, none2, 0 , iLOOP }, /* E2 */
|
||||||
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
|
{ dispS, none2, 0 , iJCXZ }, /* E3 */
|
||||||
{ data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
|
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
|
||||||
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
|
{ data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
|
||||||
{ data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
|
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
|
||||||
{ dispN, none2, 0 , iCALL }, /* E8 */
|
{ data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
|
||||||
{ dispN, none2, 0 , iJMP }, /* E9 */
|
{ dispN, none2, 0 , iCALL }, /* E8 */
|
||||||
{ dispF, none2, 0 , iJMPF }, /* EA */
|
{ dispN, none2, 0 , iJMP }, /* E9 */
|
||||||
{ dispS, none2, 0 , iJMP }, /* EB */
|
{ dispF, none2, 0 , iJMPF }, /* EA */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
|
{ dispS, none2, 0 , iJMP }, /* EB */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
|
{ none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
|
||||||
{ none1, none2, 0 , iZERO }, /* F1 */
|
{ none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
|
||||||
{ prefix, none2, 0 , iREPNE}, /* F2 */
|
{ none1, none2, 0 , iINVALID }, /* F1 */
|
||||||
{ prefix, none2, 0 , iREPE }, /* F3 */
|
{ prefix, none2, 0 , iREPNE}, /* F2 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
|
{ prefix, none2, 0 , iREPE }, /* F3 */
|
||||||
{ none1, none2, NO_OPS , iCMC }, /* F5 */
|
{ none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
|
||||||
{ arith, none1, B , iZERO }, /* F6 */
|
{ none1, none2, NO_OPS , iCMC }, /* F5 */
|
||||||
{ arith, none1, NSP , iZERO }, /* F7 */
|
{ arith, none1, B , iINVALID }, /* F6 */
|
||||||
{ none1, none2, NO_OPS , iCLC }, /* F8 */
|
{ arith, none1, NSP , iINVALID }, /* F7 */
|
||||||
{ none1, none2, NO_OPS , iSTC }, /* F9 */
|
{ none1, none2, NO_OPS , iCLC }, /* F8 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
|
{ none1, none2, NO_OPS , iSTC }, /* F9 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
|
{ none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
|
||||||
{ none1, none2, NO_OPS , iCLD }, /* FC */
|
{ none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
|
||||||
{ none1, none2, NO_OPS , iSTD }, /* FD */
|
{ none1, none2, NO_OPS , iCLD }, /* FC */
|
||||||
{ trans, none1, B , iZERO }, /* FE */
|
{ none1, none2, NO_OPS , iSTD }, /* FD */
|
||||||
{ trans, none1, NSP , iZERO } /* FF */
|
{ trans, none1, B , iINVALID }, /* FE */
|
||||||
|
{ trans, none1, NSP , iINVALID } /* FF */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static uint16_t SegPrefix, RepPrefix;
|
static uint16_t SegPrefix, RepPrefix;
|
||||||
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
||||||
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
||||||
|
|
||||||
|
|
||||||
static void decodeBranchTgt(x86_insn_t &insn)
|
static void decodeBranchTgt(x86_insn_t &insn)
|
||||||
@ -330,12 +332,12 @@ static void decodeBranchTgt(x86_insn_t &insn)
|
|||||||
int32_t addr = tgt_op->getAddress();
|
int32_t addr = tgt_op->getAddress();
|
||||||
if(tgt_op->is_relative())
|
if(tgt_op->is_relative())
|
||||||
{
|
{
|
||||||
addr += insn.addr+insn.size;
|
addr = (uint16_t)(addr + insn.addr + insn.size);
|
||||||
}
|
}
|
||||||
pIcode->ll()->replaceSrc((uint32_t)addr);
|
pIcode->ll()->replaceSrc((uint32_t)addr);
|
||||||
pIcode->ll()->setFlags(I);
|
pIcode->ll()->setFlags(I);
|
||||||
// PROG &prog(Project::get()->prog);
|
// PROG &prog(Project::get()->prog);
|
||||||
// long off = (short)getWord(); /* Signed displacement */
|
// long off = (short)getWord(); /* Signed displacement */
|
||||||
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
|
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -380,7 +382,7 @@ static void fixFloatEmulation(x86_insn_t &insn)
|
|||||||
return;
|
return;
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
uint16_t wOp=insn.x86_get_imm()->data.word;
|
uint16_t wOp=insn.x86_get_imm()->data.word;
|
||||||
if ((wOp < 0x34) || (wOp > 0x3B))
|
if ((wOp < 0x34) or (wOp > 0x3B))
|
||||||
return;
|
return;
|
||||||
uint8_t buf[16];
|
uint8_t buf[16];
|
||||||
/* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
|
/* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
|
||||||
@ -403,7 +405,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
|||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
X86_Disasm ds(opt_16_bit);
|
X86_Disasm ds(opt_16_bit);
|
||||||
int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
|
int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
|
||||||
if(cnt && l.is_valid())
|
if(cnt and l.is_valid())
|
||||||
{
|
{
|
||||||
fixFloatEmulation(l); //can change 'l'
|
fixFloatEmulation(l); //can change 'l'
|
||||||
}
|
}
|
||||||
@ -413,7 +415,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
|||||||
}
|
}
|
||||||
eReg convertRegister(const x86_reg_t ®)
|
eReg convertRegister(const x86_reg_t ®)
|
||||||
{
|
{
|
||||||
if( (reg_pc==reg.type) || (0==reg.id))
|
if( (reg_pc==reg.type) or (0==reg.id))
|
||||||
return rUNDEF;
|
return rUNDEF;
|
||||||
|
|
||||||
eReg regmap[]={ rUNDEF,
|
eReg regmap[]={ rUNDEF,
|
||||||
@ -505,7 +507,7 @@ LLOperand convertOperand(const x86_op_t &from)
|
|||||||
case op_register:
|
case op_register:
|
||||||
res.regi = convertRegister(from.data.reg); break;
|
res.regi = convertRegister(from.data.reg); break;
|
||||||
case op_immediate:
|
case op_immediate:
|
||||||
res.opz = from.data.sdword;
|
res.opz = from.data.sdword; break;
|
||||||
case op_expression:
|
case op_expression:
|
||||||
res = convertExpression(from.data.expression); break;
|
res = convertExpression(from.data.expression); break;
|
||||||
case op_offset:
|
case op_offset:
|
||||||
@ -518,7 +520,7 @@ LLOperand convertOperand(const x86_op_t &from)
|
|||||||
default:
|
default:
|
||||||
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
|
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
|
||||||
}
|
}
|
||||||
if(res.isSet() && (res.seg == rUNDEF))
|
if(res.isSet() and (res.seg == rUNDEF))
|
||||||
{
|
{
|
||||||
res.seg = rDS;
|
res.seg = rDS;
|
||||||
}
|
}
|
||||||
@ -534,8 +536,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
int op;
|
int op;
|
||||||
p = ICODE();
|
p = ICODE();
|
||||||
p.type = LOW_LEVEL;
|
p.type = LOW_LEVEL_ICODE;
|
||||||
p.ll()->label = ip; /* ip is absolute offset into image*/
|
p.ll()->label = ip; /* ip is absolute offset into image*/
|
||||||
if (ip >= (uint32_t)prog.cbImage)
|
if (ip >= (uint32_t)prog.cbImage)
|
||||||
{
|
{
|
||||||
return (IP_OUT_OF_RANGE);
|
return (IP_OUT_OF_RANGE);
|
||||||
@ -554,13 +556,13 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
op = *pInst++; /* First state - trivial */
|
op = *pInst++; /* First state - trivial */
|
||||||
/* Convert to Icode.opcode */
|
/* Convert to Icode.opcode */
|
||||||
p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK);
|
p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK);
|
||||||
(*stateTable[op].state1)(op); /* Second state */
|
(*stateTable[op].state1)(op); /* Second state */
|
||||||
(*stateTable[op].state2)(op); /* Third state */
|
(*stateTable[op].state2)(op); /* Third state */
|
||||||
|
|
||||||
} while (stateTable[op].state1 == prefix); /* Loop if prefix */
|
} while (stateTable[op].state1 == prefix); /* Loop if prefix */
|
||||||
if(p.insn.group == x86_insn_t::insn_controlflow)
|
if(p.insn.group == x86_insn_t::insn_controlflow)
|
||||||
{
|
{
|
||||||
if(p.insn.x86_get_branch_target())
|
if(p.insn.x86_get_branch_target())
|
||||||
@ -568,7 +570,7 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
}
|
}
|
||||||
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
||||||
// assert(conv==p.ll()->dst);
|
// assert(conv==p.ll()->dst);
|
||||||
if (p.ll()->getOpcode())
|
if (p.ll()->getOpcode()!=iINVALID)
|
||||||
{
|
{
|
||||||
/* Save bytes of image used */
|
/* Save bytes of image used */
|
||||||
p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
|
p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
|
||||||
@ -588,8 +590,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
static bool relocItem(const uint8_t *p)
|
static bool relocItem(const uint8_t *p)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
int i;
|
int i;
|
||||||
uint32_t off = p - prog.image();
|
uint32_t off = p - prog.image();
|
||||||
|
|
||||||
for (i = 0; i < prog.cReloc; i++)
|
for (i = 0; i < prog.cReloc; i++)
|
||||||
if (prog.relocTable[i] == off)
|
if (prog.relocTable[i] == off)
|
||||||
@ -620,42 +622,42 @@ static int signex(uint8_t b)
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* setAddress - Updates the source or destination field for the current
|
* setAddress - Updates the source or destination field for the current
|
||||||
* icode, based on fdst and the TO_REG flag.
|
* icode, based on fdst and the TO_REG flag.
|
||||||
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
||||||
* fdst == false is for reg part of the field
|
* fdst == false is for reg part of the field
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
||||||
{
|
{
|
||||||
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
||||||
LLOperand *pm = (!(stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
|
LLOperand *pm = (! (stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
|
||||||
|
|
||||||
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
||||||
* provide the value of this segment in the field segValue.
|
* provide the value of this segment in the field segValue.
|
||||||
*/
|
*/
|
||||||
if (seg) /* segment override */
|
if (seg) /* segment override */
|
||||||
{
|
{
|
||||||
pm->seg = pm->segOver = (eReg)seg;
|
pm->seg = pm->segOver = (eReg)seg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* no override, check indexed register */
|
{ /* no override, check indexed register */
|
||||||
if ((reg >= INDEX_BX_SI) && (reg == INDEX_BP_SI || reg == INDEX_BP_DI || reg == INDEX_BP))
|
if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP))
|
||||||
{
|
{
|
||||||
pm->seg = rSS; /* indexed on bp */
|
pm->seg = rSS; /* indexed on bp */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pm->seg = rDS; /* any other indexed reg */
|
pm->seg = rDS; /* any other indexed reg */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pm->regi = (eReg)reg;
|
pm->regi = (eReg)reg;
|
||||||
pm->off = (int16_t)off;
|
pm->off = (int16_t)off;
|
||||||
if (reg && reg < INDEX_BX_SI && (stateTable[i].flg & B))
|
if (reg and (reg < INDEX_BX_SI) and (stateTable[i].flg & B))
|
||||||
{
|
{
|
||||||
pm->regi = Machine_X86::subRegL(pm->regi);
|
pm->regi = Machine_X86::subRegL(pm->regi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg) /* So we can catch invalid use of segment overrides */
|
if (seg) /* So we can catch invalid use of segment overrides */
|
||||||
{
|
{
|
||||||
SegPrefix = 0;
|
SegPrefix = 0;
|
||||||
}
|
}
|
||||||
@ -671,7 +673,7 @@ static void rm(int i)
|
|||||||
uint8_t rm = *pInst++ & 7;
|
uint8_t rm = *pInst++ & 7;
|
||||||
|
|
||||||
switch (mod) {
|
switch (mod) {
|
||||||
case 0: /* No disp unless rm == 6 */
|
case 0: /* No disp unless rm == 6 */
|
||||||
if (rm == 6) {
|
if (rm == 6) {
|
||||||
setAddress(i, true, SegPrefix, 0, getWord());
|
setAddress(i, true, SegPrefix, 0, getWord());
|
||||||
pIcode->ll()->setFlags(WORD_OFF);
|
pIcode->ll()->setFlags(WORD_OFF);
|
||||||
@ -680,21 +682,21 @@ static void rm(int i)
|
|||||||
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0);
|
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* 1 uint8_t disp */
|
case 1: /* 1 uint8_t disp */
|
||||||
setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++));
|
setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* 2 uint8_t disp */
|
case 2: /* 2 uint8_t disp */
|
||||||
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord());
|
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord());
|
||||||
pIcode->ll()->setFlags(WORD_OFF);
|
pIcode->ll()->setFlags(WORD_OFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* reg */
|
case 3: /* reg */
|
||||||
setAddress(i, true, 0, rm + rAX, 0);
|
setAddress(i, true, 0, rm + rAX, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//pIcode->insn.get_dest()->
|
//pIcode->insn.get_dest()->
|
||||||
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
|
if ((stateTable[i].flg & NSP) and (pIcode->ll()->src().getReg2()==rSP or
|
||||||
pIcode->ll()->m_dst.getReg2()==rSP))
|
pIcode->ll()->m_dst.getReg2()==rSP))
|
||||||
pIcode->ll()->setFlags(NOT_HLL);
|
pIcode->ll()->setFlags(NOT_HLL);
|
||||||
}
|
}
|
||||||
@ -715,9 +717,9 @@ static void modrm(int i)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void segrm(int i)
|
static void segrm(int i)
|
||||||
{
|
{
|
||||||
int reg = REG(*pInst) + rES;
|
int reg = REG(*pInst) + rES;
|
||||||
|
|
||||||
if (reg > rDS || (reg == rCS && (stateTable[i].flg & TO_REG)))
|
if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG)))
|
||||||
pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index
|
pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index
|
||||||
else {
|
else {
|
||||||
setAddress(i, false, 0, (int16_t)reg, 0);
|
setAddress(i, false, 0, (int16_t)reg, 0);
|
||||||
@ -742,7 +744,7 @@ static void regop(int i)
|
|||||||
static void segop(int i)
|
static void segop(int i)
|
||||||
{
|
{
|
||||||
if(i==0x1E) {
|
if(i==0x1E) {
|
||||||
printf("es");
|
// printf("es");
|
||||||
}
|
}
|
||||||
setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0);
|
setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0);
|
||||||
}
|
}
|
||||||
@ -784,7 +786,7 @@ static void memImp(int i)
|
|||||||
static void memOnly(int )
|
static void memOnly(int )
|
||||||
{
|
{
|
||||||
if ((*pInst & 0xC0) == 0xC0)
|
if ((*pInst & 0xC0) == 0xC0)
|
||||||
pIcode->ll()->setOpcode((llIcode)0);
|
pIcode->ll()->setOpcode(iINVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -793,8 +795,8 @@ static void memOnly(int )
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void memReg0(int i)
|
static void memReg0(int i)
|
||||||
{
|
{
|
||||||
if (REG(*pInst) || (*pInst & 0xC0) == 0xC0)
|
if (REG(*pInst) or (*pInst & 0xC0) == 0xC0)
|
||||||
pIcode->ll()->setOpcode((llIcode)0);
|
pIcode->ll()->setOpcode(iINVALID);
|
||||||
else
|
else
|
||||||
rm(i);
|
rm(i);
|
||||||
}
|
}
|
||||||
@ -810,8 +812,8 @@ static void immed(int i)
|
|||||||
pIcode->ll()->setOpcode(immedTable[REG(*pInst)]) ;
|
pIcode->ll()->setOpcode(immedTable[REG(*pInst)]) ;
|
||||||
rm(i);
|
rm(i);
|
||||||
|
|
||||||
if (pIcode->ll()->getOpcode() == iADD || pIcode->ll()->getOpcode() == iSUB)
|
if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB)
|
||||||
pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */
|
pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -823,7 +825,7 @@ static void shift(int i)
|
|||||||
static llIcode shiftTable[8] =
|
static llIcode shiftTable[8] =
|
||||||
{
|
{
|
||||||
(llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR,
|
(llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR,
|
||||||
(llIcode)iSHL, (llIcode)iSHR, (llIcode)0, (llIcode)iSAR};
|
(llIcode)iSHL, (llIcode)iSHR, (llIcode)0, (llIcode)iSAR};
|
||||||
|
|
||||||
pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
|
pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
|
||||||
rm(i);
|
rm(i);
|
||||||
@ -838,20 +840,20 @@ static void trans(int i)
|
|||||||
{
|
{
|
||||||
static llIcode transTable[8] =
|
static llIcode transTable[8] =
|
||||||
{
|
{
|
||||||
(llIcode)iINC, iDEC, (llIcode)iCALL, (llIcode)iCALLF,
|
iINC, iDEC, iCALL, iCALLF,
|
||||||
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
iJMP, iJMPF,iPUSH, (llIcode)0
|
||||||
};
|
};
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
// if(transTable[REG(*pInst)]==iPUSH) {
|
// if(transTable[REG(*pInst)]==iPUSH) {
|
||||||
// printf("es");
|
// printf("es");
|
||||||
// }
|
// }
|
||||||
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
if ((uint8_t)REG(*pInst) < 2 or not (stateTable[i].flg & B)) { /* INC & DEC */
|
||||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||||
rm(i);
|
rm(i);
|
||||||
ll->replaceSrc( pIcode->ll()->m_dst );
|
ll->replaceSrc( pIcode->ll()->m_dst );
|
||||||
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
if (ll->match(iJMP) or ll->match(iCALL) or ll->match(iCALLF))
|
||||||
ll->setFlags(NO_OPS);
|
ll->setFlags(NO_OPS);
|
||||||
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
|
else if (ll->match(iINC) or ll->match(iPUSH) or ll->match(iDEC))
|
||||||
ll->setFlags(NO_SRC);
|
ll->setFlags(NO_SRC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -865,8 +867,8 @@ static void arith(int i)
|
|||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
static llIcode arithTable[8] =
|
static llIcode arithTable[8] =
|
||||||
{
|
{
|
||||||
iTEST, (llIcode)0, iNOT, iNEG,
|
iTEST, iINVALID, iNOT, iNEG,
|
||||||
iMUL , iIMUL, iDIV, iIDIV
|
iMUL , iIMUL, iDIV, iIDIV
|
||||||
};
|
};
|
||||||
opcode = arithTable[REG(*pInst)];
|
opcode = arithTable[REG(*pInst)];
|
||||||
pIcode->ll()->setOpcode((llIcode)opcode);
|
pIcode->ll()->setOpcode((llIcode)opcode);
|
||||||
@ -878,15 +880,15 @@ static void arith(int i)
|
|||||||
else
|
else
|
||||||
data2(i);
|
data2(i);
|
||||||
}
|
}
|
||||||
else if (!(opcode == iNOT || opcode == iNEG))
|
else if (not (opcode == iNOT or opcode == iNEG))
|
||||||
{
|
{
|
||||||
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
||||||
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
||||||
}
|
}
|
||||||
else if (opcode == iNEG || opcode == iNOT)
|
else if (opcode == iNEG or opcode == iNOT)
|
||||||
pIcode->ll()->setFlags(NO_SRC);
|
pIcode->ll()->setFlags(NO_SRC);
|
||||||
|
|
||||||
if ((opcode == iDIV) || (opcode == iIDIV))
|
if ((opcode == iDIV) or (opcode == iIDIV))
|
||||||
{
|
{
|
||||||
if ( not pIcode->ll()->testFlags(B) )
|
if ( not pIcode->ll()->testFlags(B) )
|
||||||
pIcode->ll()->setFlags(IM_TMP_DST);
|
pIcode->ll()->setFlags(IM_TMP_DST);
|
||||||
@ -916,7 +918,7 @@ static void data2(int )
|
|||||||
* but this field is being used as the number of bytes to allocate
|
* but this field is being used as the number of bytes to allocate
|
||||||
* on the stack. The procedure level is stored in the immediate
|
* on the stack. The procedure level is stored in the immediate
|
||||||
* field. There is no source operand; therefore, the flag flg is
|
* field. There is no source operand; therefore, the flag flg is
|
||||||
* set to NO_OPS. */
|
* set to NO_OPS. */
|
||||||
if (pIcode->ll()->getOpcode() == iENTER)
|
if (pIcode->ll()->getOpcode() == iENTER)
|
||||||
{
|
{
|
||||||
pIcode->ll()->m_dst.off = getWord();
|
pIcode->ll()->m_dst.off = getWord();
|
||||||
@ -943,7 +945,7 @@ static void dispN(int )
|
|||||||
{
|
{
|
||||||
|
|
||||||
//PROG &prog(Project::get()->prog);
|
//PROG &prog(Project::get()->prog);
|
||||||
/*long off = (short)*/getWord(); /* Signed displacement */
|
/*long off = (short)*/getWord(); /* Signed displacement */
|
||||||
|
|
||||||
/* Note: the result of the subtraction could be between 32k and 64k, and
|
/* Note: the result of the subtraction could be between 32k and 64k, and
|
||||||
still be positive; it is an offset from prog.Image. So this must be
|
still be positive; it is an offset from prog.Image. So this must be
|
||||||
@ -957,7 +959,7 @@ static void dispN(int )
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void dispS(int )
|
static void dispS(int )
|
||||||
{
|
{
|
||||||
/*long off =*/ signex(*pInst++); /* Signed displacement */
|
/*long off =*/ signex(*pInst++); /* Signed displacement */
|
||||||
|
|
||||||
// decodeBranchTgt();
|
// decodeBranchTgt();
|
||||||
}
|
}
|
||||||
@ -970,6 +972,7 @@ static void dispF(int i)
|
|||||||
{
|
{
|
||||||
uint16_t off = (unsigned)getWord();
|
uint16_t off = (unsigned)getWord();
|
||||||
uint16_t seg = (unsigned)getWord();
|
uint16_t seg = (unsigned)getWord();
|
||||||
|
// FIXME: this is wrong since seg here is seg value, but setAddress treats it as register id
|
||||||
setAddress(i, true, seg, 0, off);
|
setAddress(i, true, seg, 0, off);
|
||||||
// decodeBranchTgt();
|
// decodeBranchTgt();
|
||||||
}
|
}
|
||||||
@ -981,7 +984,7 @@ static void dispF(int i)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void prefix(int )
|
static void prefix(int )
|
||||||
{
|
{
|
||||||
if (pIcode->ll()->getOpcode() == iREPE || pIcode->ll()->getOpcode() == iREPNE)
|
if ((pIcode->ll()->getOpcode() == iREPE) or (pIcode->ll()->getOpcode() == iREPNE))
|
||||||
RepPrefix = pIcode->ll()->getOpcode();
|
RepPrefix = pIcode->ll()->getOpcode();
|
||||||
else
|
else
|
||||||
SegPrefix = pIcode->ll()->getOpcode();
|
SegPrefix = pIcode->ll()->getOpcode();
|
||||||
@ -989,8 +992,8 @@ static void prefix(int )
|
|||||||
|
|
||||||
inline void BumpOpcode(LLInst &ll)
|
inline void BumpOpcode(LLInst &ll)
|
||||||
{
|
{
|
||||||
llIcode ic((llIcode)ll.getOpcode());
|
llIcode ic(ll.getOpcode());
|
||||||
ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type
|
ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type
|
||||||
ll.setOpcode(ic);
|
ll.setOpcode(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,7 +1004,7 @@ static void strop(int )
|
|||||||
{
|
{
|
||||||
if (RepPrefix)
|
if (RepPrefix)
|
||||||
{
|
{
|
||||||
if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) )
|
if ( pIcode->ll()->match(iCMPS) or pIcode->ll()->match(iSCAS) )
|
||||||
{
|
{
|
||||||
if(pIcode->insn.prefix & insn_rep_zero)
|
if(pIcode->insn.prefix & insn_rep_zero)
|
||||||
{
|
{
|
||||||
@ -1075,7 +1078,7 @@ static void none2(int )
|
|||||||
static void checkInt(int )
|
static void checkInt(int )
|
||||||
{
|
{
|
||||||
uint16_t wOp = (uint16_t) pIcode->ll()->src().getImm2();
|
uint16_t wOp = (uint16_t) pIcode->ll()->src().getImm2();
|
||||||
if ((wOp >= 0x34) && (wOp <= 0x3B))
|
if ((wOp >= 0x34) and (wOp <= 0x3B))
|
||||||
{
|
{
|
||||||
/* This is a Borland/Microsoft floating point emulation instruction.
|
/* This is a Borland/Microsoft floating point emulation instruction.
|
||||||
Treat as if it is an ESC opcode */
|
Treat as if it is an ESC opcode */
|
||||||
|
|||||||
@ -133,7 +133,7 @@ void destroySymTables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Using the value, read the symbolic name */
|
/* Using the value, read the symbolic name */
|
||||||
bool readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
bool readVal(QTextStream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
||||||
{
|
{
|
||||||
return false; // no symbolic names for now
|
return false; // no symbolic names for now
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/udm.cpp
38
src/udm.cpp
@ -4,13 +4,15 @@
|
|||||||
* that just plays with abstract cfg's and intervals and such like.
|
* that just plays with abstract cfg's and intervals and such like.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <list>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "disassem.h"
|
#include "disassem.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <list>
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <CallGraph.h>
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
//static void displayCFG(Function * pProc);
|
//static void displayCFG(Function * pProc);
|
||||||
//static void displayDfs(BB * pBB);
|
//static void displayDfs(BB * pBB);
|
||||||
@ -60,7 +62,7 @@ void Function::controlFlowAnalysis()
|
|||||||
|
|
||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
{
|
{
|
||||||
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
qDebug() <<"\nDepth first traversal - Proc" <<name;
|
||||||
(*m_actual_cfg.begin())->displayDfs();
|
(*m_actual_cfg.begin())->displayDfs();
|
||||||
//m_cfg.front()->displayDfs();
|
//m_cfg.front()->displayDfs();
|
||||||
}
|
}
|
||||||
@ -74,9 +76,16 @@ void udm(void)
|
|||||||
|
|
||||||
/* Build the control flow graph, find idioms, and convert low-level
|
/* Build the control flow graph, find idioms, and convert low-level
|
||||||
* icodes to high-level ones */
|
* icodes to high-level ones */
|
||||||
|
Project *proj = Project::get();
|
||||||
Disassembler ds(2);
|
Disassembler ds(2);
|
||||||
for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
|
for (auto iter = proj->pProcList.rbegin(); iter!=proj->pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
|
Function &f(*iter);
|
||||||
|
if(option.CustomEntryPoint) {
|
||||||
|
if(f.procEntry!=option.CustomEntryPoint) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
iter->buildCFG(ds);
|
iter->buildCFG(ds);
|
||||||
}
|
}
|
||||||
if (option.asm2)
|
if (option.asm2)
|
||||||
@ -87,10 +96,23 @@ void udm(void)
|
|||||||
* and intermediate instructions. Find expressions by forward
|
* and intermediate instructions. Find expressions by forward
|
||||||
* substitution algorithm */
|
* substitution algorithm */
|
||||||
LivenessSet live_regs;
|
LivenessSet live_regs;
|
||||||
Project::get()->pProcList.front().dataFlow (live_regs);
|
if(option.CustomEntryPoint) {
|
||||||
|
ilFunction iter = proj->findByEntry(option.CustomEntryPoint);
|
||||||
|
if(iter==proj->pProcList.end()) {
|
||||||
|
qCritical()<< "No function found at entry point" << QString::number(option.CustomEntryPoint,16);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iter->dataFlow(live_regs);
|
||||||
|
iter->controlFlowAnalysis();
|
||||||
|
delete proj->callGraph;
|
||||||
|
proj->callGraph = new CALL_GRAPH;
|
||||||
|
proj->callGraph->proc = iter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
proj->pProcList.front().dataFlow (live_regs);
|
||||||
|
|
||||||
/* Control flow analysis - structuring algorithm */
|
/* Control flow analysis - structuring algorithm */
|
||||||
for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
|
for (auto iter = proj->pProcList.rbegin(); iter!=proj->pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
iter->controlFlowAnalysis();
|
iter->controlFlowAnalysis();
|
||||||
}
|
}
|
||||||
@ -101,7 +123,7 @@ void udm(void)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void Function::displayCFG()
|
void Function::displayCFG()
|
||||||
{
|
{
|
||||||
printf("\nBasic Block List - Proc %s", name.c_str());
|
qDebug() << "\nBasic Block List - Proc"<<name;
|
||||||
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
||||||
{
|
{
|
||||||
pBB->display();
|
pBB->display();
|
||||||
|
|||||||
@ -1 +1,4 @@
|
|||||||
|
add_subdirectory(dispsrch)
|
||||||
add_subdirectory(makedsig)
|
add_subdirectory(makedsig)
|
||||||
|
add_subdirectory(readsig)
|
||||||
|
add_subdirectory(parsehdr)
|
||||||
|
|||||||
9
tools/dispsrch/CMakeLists.txt
Normal file
9
tools/dispsrch/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
add_executable(dispsig dispsig)
|
||||||
|
|
||||||
|
target_link_libraries(dispsig dcc_hash)
|
||||||
|
qt5_use_modules(dispsig Core)
|
||||||
|
|
||||||
|
add_executable(srchsig srchsig)
|
||||||
|
|
||||||
|
target_link_libraries(srchsig dcc_hash dcc_lib)
|
||||||
|
qt5_use_modules(srchsig Core)
|
||||||
@ -1,191 +1,164 @@
|
|||||||
/* Quick program to copy a named signature to a small file */
|
/* Quick program to copy a named signature to a small file */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
|
|
||||||
/* statics */
|
#include <QtCore/QString>
|
||||||
byte buf[100];
|
#include <memory.h>
|
||||||
int numKeys; /* Number of hash table entries (keys) */
|
#include <stdio.h>
|
||||||
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
#include <stdlib.h>
|
||||||
int PatLen; /* Size of the keys (pattern length) */
|
#include <string.h>
|
||||||
int SymLen; /* Max size of the symbols, including null */
|
|
||||||
FILE *f; /* File being read */
|
|
||||||
FILE *f2; /* File being written */
|
|
||||||
|
|
||||||
static word *T1base, *T2base; /* Pointers to start of T1, T2 */
|
/* statics */
|
||||||
static word *g; /* g[] */
|
uint8_t buf[100];
|
||||||
|
int numKeys; /* Number of hash table entries (keys) */
|
||||||
|
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
||||||
|
int PatLen; /* Size of the keys (pattern length) */
|
||||||
|
int SymLen; /* Max size of the symbols, including null */
|
||||||
|
FILE *f; /* File being read */
|
||||||
|
FILE *f2; /* File being written */
|
||||||
|
|
||||||
|
static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
|
||||||
|
static uint16_t *g; /* g[] */
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
void grab(int n);
|
void grab(int n);
|
||||||
word readFileShort(void);
|
uint16_t readFileShort(void);
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
|
|
||||||
|
#define SYMLEN 16
|
||||||
#define SYMLEN 16
|
#define PATLEN 23
|
||||||
#define PATLEN 23
|
|
||||||
|
|
||||||
/* Hash table structure */
|
/* Hash table structure */
|
||||||
typedef struct HT_tag
|
typedef struct HT_tag {
|
||||||
{
|
char htSym[SYMLEN];
|
||||||
char htSym[SYMLEN];
|
uint8_t htPat[PATLEN];
|
||||||
byte htPat[PATLEN];
|
|
||||||
} HT;
|
} HT;
|
||||||
|
|
||||||
HT ht; /* One hash table entry */
|
HT ht; /* One hash table entry */
|
||||||
|
PerfectHash g_pattern_hasher;
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
uint16_t w, len;
|
||||||
|
int i;
|
||||||
|
|
||||||
void
|
if (argc <= 3) {
|
||||||
main(int argc, char *argv[])
|
printf("Usage: dispsig <SigFilename> <FunctionName> <BinFileName>\n");
|
||||||
{
|
printf("Example: dispsig dccm8s.sig printf printf.bin\n");
|
||||||
word w, len;
|
exit(1);
|
||||||
int i;
|
}
|
||||||
|
|
||||||
if (argc <= 3)
|
if ((f = fopen(argv[1], "rb")) == NULL) {
|
||||||
{
|
printf("Cannot open %s\n", argv[1]);
|
||||||
printf("Usage: dispsig <SigFilename> <FunctionName> <BinFileName>\n");
|
exit(2);
|
||||||
printf("Example: dispsig dccm8s.sig printf printf.bin\n");
|
}
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((f = fopen(argv[1], "rb")) == NULL)
|
if ((f2 = fopen(argv[3], "wb")) == NULL) {
|
||||||
{
|
printf("Cannot write to %s\n", argv[3]);
|
||||||
printf("Cannot open %s\n", argv[1]);
|
exit(2);
|
||||||
exit(2);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((f2 = fopen(argv[3], "wb")) == NULL)
|
/* Read the parameters */
|
||||||
{
|
grab(4);
|
||||||
printf("Cannot write to %s\n", argv[3]);
|
if (memcmp("dccs", buf, 4) != 0) {
|
||||||
exit(2);
|
printf("Not a dccs file!\n");
|
||||||
}
|
exit(3);
|
||||||
|
}
|
||||||
|
numKeys = readFileShort();
|
||||||
|
numVert = readFileShort();
|
||||||
|
PatLen = readFileShort();
|
||||||
|
SymLen = readFileShort();
|
||||||
|
|
||||||
|
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
||||||
|
g_pattern_hasher.setHashParams(
|
||||||
|
numKeys, /* The number of symbols */
|
||||||
|
PatLen, /* The length of the pattern to be hashed */
|
||||||
|
256, /* The character set of the pattern (0-FF) */
|
||||||
|
0, /* Minimum pattern character value */
|
||||||
|
numVert); /* Specifies C, the sparseness of the graph. See Czech, Havas and Majewski for details */
|
||||||
|
|
||||||
|
T1base = g_pattern_hasher.readT1();
|
||||||
|
T2base = g_pattern_hasher.readT2();
|
||||||
|
g = g_pattern_hasher.readG();
|
||||||
|
|
||||||
|
|
||||||
/* Read the parameters */
|
/* Read T1 and T2 tables */
|
||||||
grab(4);
|
grab(2);
|
||||||
if (memcmp("dccs", buf, 4) != 0)
|
if (memcmp("T1", buf, 2) != 0) {
|
||||||
{
|
printf("Expected 'T1'\n");
|
||||||
printf("Not a dccs file!\n");
|
exit(3);
|
||||||
exit(3);
|
}
|
||||||
}
|
len = PatLen * 256 * sizeof(uint16_t);
|
||||||
numKeys = readFileShort();
|
w = readFileShort();
|
||||||
numVert = readFileShort();
|
if (w != len) {
|
||||||
PatLen = readFileShort();
|
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
||||||
SymLen = readFileShort();
|
exit(4);
|
||||||
|
}
|
||||||
|
if (fread(T1base, 1, len, f) != len) {
|
||||||
|
printf("Could not read T1\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
grab(2);
|
||||||
hashParams( /* Set the parameters for the hash table */
|
if (memcmp("T2", buf, 2) != 0) {
|
||||||
numKeys, /* The number of symbols */
|
printf("Expected 'T2'\n");
|
||||||
PatLen, /* The length of the pattern to be hashed */
|
exit(3);
|
||||||
256, /* The character set of the pattern (0-FF) */
|
}
|
||||||
0, /* Minimum pattern character value */
|
w = readFileShort();
|
||||||
numVert); /* Specifies C, the sparseness of the graph.
|
if (w != len) {
|
||||||
See Czech, Havas and Majewski for details
|
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
||||||
*/
|
exit(4);
|
||||||
|
}
|
||||||
|
if (fread(T2base, 1, len, f) != len) {
|
||||||
|
printf("Could not read T2\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
T1base = readT1();
|
/* Now read the function g[] */
|
||||||
T2base = readT2();
|
grab(2);
|
||||||
g = readG();
|
if (memcmp("gg", buf, 2) != 0) {
|
||||||
|
printf("Expected 'gg'\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
len = numVert * sizeof(uint16_t);
|
||||||
|
w = readFileShort();
|
||||||
|
if (w != len) {
|
||||||
|
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
if (fread(g, 1, len, f) != len) {
|
||||||
|
printf("Could not read T2\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read T1 and T2 tables */
|
/* This is now the hash table */
|
||||||
grab(2);
|
grab(2);
|
||||||
if (memcmp("T1", buf, 2) != 0)
|
if (memcmp("ht", buf, 2) != 0) {
|
||||||
{
|
printf("Expected 'ht'\n");
|
||||||
printf("Expected 'T1'\n");
|
exit(3);
|
||||||
exit(3);
|
}
|
||||||
}
|
w = readFileShort();
|
||||||
len = PatLen * 256 * sizeof(word);
|
if (w != numKeys * (SymLen + PatLen + sizeof(uint16_t))) {
|
||||||
w = readFileShort();
|
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
||||||
if (w != len)
|
exit(6);
|
||||||
{
|
}
|
||||||
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
QString argv2(argv[2]);
|
||||||
exit(4);
|
for (i = 0; i < numKeys; i++) {
|
||||||
}
|
if (fread(&ht, 1, SymLen + PatLen, f) != (size_t)(SymLen + PatLen)) {
|
||||||
if (fread(T1base, 1, len, f) != len)
|
|
||||||
{
|
|
||||||
printf("Could not read T1\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
grab(2);
|
|
||||||
if (memcmp("T2", buf, 2) != 0)
|
|
||||||
{
|
|
||||||
printf("Expected 'T2'\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
w = readFileShort();
|
|
||||||
if (w != len)
|
|
||||||
{
|
|
||||||
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
if (fread(T2base, 1, len, f) != len)
|
|
||||||
{
|
|
||||||
printf("Could not read T2\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now read the function g[] */
|
|
||||||
grab(2);
|
|
||||||
if (memcmp("gg", buf, 2) != 0)
|
|
||||||
{
|
|
||||||
printf("Expected 'gg'\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
len = numVert * sizeof(word);
|
|
||||||
w = readFileShort();
|
|
||||||
if (w != len)
|
|
||||||
{
|
|
||||||
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
if (fread(g, 1, len, f) != len)
|
|
||||||
{
|
|
||||||
printf("Could not read T2\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This is now the hash table */
|
|
||||||
grab(2);
|
|
||||||
if (memcmp("ht", buf, 2) != 0)
|
|
||||||
{
|
|
||||||
printf("Expected 'ht'\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
w = readFileShort();
|
|
||||||
if (w != numKeys * (SymLen + PatLen + sizeof(word)))
|
|
||||||
{
|
|
||||||
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
|
||||||
exit(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (i=0; i < numKeys; i++)
|
|
||||||
{
|
|
||||||
if (fread(&ht, 1, SymLen + PatLen, f) != (size_t)(SymLen + PatLen))
|
|
||||||
{
|
|
||||||
printf("Could not read pattern %d from %s\n", i, argv[1]);
|
printf("Could not read pattern %d from %s\n", i, argv[1]);
|
||||||
exit(7);
|
exit(7);
|
||||||
}
|
}
|
||||||
if (stricmp(ht.htSym, argv[2]) == 0)
|
if (argv2.compare(ht.htSym, Qt::CaseInsensitive) == 0) {
|
||||||
{
|
|
||||||
/* Found it! */
|
/* Found it! */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (i == numKeys)
|
if (i == numKeys) {
|
||||||
{
|
|
||||||
printf("Function %s not found!\n", argv[2]);
|
printf("Function %s not found!\n", argv[2]);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Function %s index %d\n", ht.htSym, i);
|
printf("Function %s index %d\n", ht.htSym, i);
|
||||||
for (i=0; i < PatLen; i++)
|
for (i = 0; i < PatLen; i++) {
|
||||||
{
|
|
||||||
printf("%02X ", ht.htPat[i]);
|
printf("%02X ", ht.htPat[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,56 +166,36 @@ main(int argc, char *argv[])
|
|||||||
fclose(f2);
|
fclose(f2);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanup(void) {
|
||||||
void
|
/* Free the storage for variable sized tables etc */
|
||||||
cleanup(void)
|
if (T1base)
|
||||||
{
|
free(T1base);
|
||||||
/* Free the storage for variable sized tables etc */
|
if (T2base)
|
||||||
if (T1base) free(T1base);
|
free(T2base);
|
||||||
if (T2base) free(T2base);
|
if (g)
|
||||||
if (g) free(g);
|
free(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab(int n)
|
void grab(int n) {
|
||||||
{
|
if (fread(buf, 1, n, f) != (size_t)n) {
|
||||||
if (fread(buf, 1, n, f) != (size_t)n)
|
printf("Could not read\n");
|
||||||
{
|
exit(11);
|
||||||
printf("Could not read\n");
|
}
|
||||||
exit(11);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word
|
uint16_t readFileShort(void) {
|
||||||
readFileShort(void)
|
uint8_t b1, b2;
|
||||||
{
|
|
||||||
byte b1, b2;
|
|
||||||
|
|
||||||
if (fread(&b1, 1, 1, f) != 1)
|
if (fread(&b1, 1, 1, f) != 1) {
|
||||||
{
|
printf("Could not read\n");
|
||||||
printf("Could not read\n");
|
exit(11);
|
||||||
exit(11);
|
}
|
||||||
}
|
if (fread(&b2, 1, 1, f) != 1) {
|
||||||
if (fread(&b2, 1, 1, f) != 1)
|
printf("Could not read\n");
|
||||||
{
|
exit(11);
|
||||||
printf("Could not read\n");
|
}
|
||||||
exit(11);
|
return (b2 << 8) + b1;
|
||||||
}
|
|
||||||
return (b2 << 8) + b1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Following two functions not needed unless creating tables */
|
|
||||||
|
|
||||||
void getKey(int i, byte **keys)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display key i */
|
|
||||||
void
|
|
||||||
dispKey(int i)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,287 +1,245 @@
|
|||||||
/* Quick program to see if a pattern is in a sig file. Pattern is supplied
|
/* Quick program to see if a pattern is in a sig file. Pattern is supplied
|
||||||
in a small .bin or .com style file */
|
in a small .bin or .com style file */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
|
|
||||||
/* statics */
|
#include <memory.h>
|
||||||
byte buf[100];
|
#include <stdio.h>
|
||||||
int numKeys; /* Number of hash table entries (keys) */
|
#include <stdlib.h>
|
||||||
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
|
||||||
int PatLen; /* Size of the keys (pattern length) */
|
|
||||||
int SymLen; /* Max size of the symbols, including null */
|
|
||||||
FILE *f; /* Sig file being read */
|
|
||||||
FILE *fpat; /* Pattern file being read */
|
|
||||||
|
|
||||||
static word *T1base, *T2base; /* Pointers to start of T1, T2 */
|
/* statics */
|
||||||
static word *g; /* g[] */
|
uint8_t buf[100];
|
||||||
|
int numKeys; /* Number of hash table entries (keys) */
|
||||||
|
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
||||||
|
int PatLen; /* Size of the keys (pattern length) */
|
||||||
|
int SymLen; /* Max size of the symbols, including null */
|
||||||
|
FILE *f; /* Sig file being read */
|
||||||
|
FILE *fpat; /* Pattern file being read */
|
||||||
|
|
||||||
|
static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
|
||||||
|
static uint16_t *g; /* g[] */
|
||||||
|
|
||||||
#define SYMLEN 16
|
#define SYMLEN 16
|
||||||
#define PATLEN 23
|
#define PATLEN 23
|
||||||
|
|
||||||
typedef struct HT_tag
|
typedef struct HT_tag {
|
||||||
{
|
/* Hash table structure */
|
||||||
/* Hash table structure */
|
char htSym[SYMLEN];
|
||||||
char htSym[SYMLEN];
|
uint8_t htPat[PATLEN];
|
||||||
byte htPat[PATLEN];
|
|
||||||
} HT;
|
} HT;
|
||||||
|
|
||||||
HT *ht; /* Declare a pointer to a hash table */
|
HT *ht; /* Declare a pointer to a hash table */
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
void grab(int n);
|
void grab(int n);
|
||||||
word readFileShort(void);
|
uint16_t readFileShort(void);
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
void fixWildCards(char *buf); /* In fixwild.c */
|
extern void fixWildCards(uint8_t pat[]); /* In fixwild.c */
|
||||||
void pattSearch(void);
|
void pattSearch(void);
|
||||||
|
PerfectHash g_pattern_hasher;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
uint16_t w, len;
|
||||||
|
int h, i;
|
||||||
|
int patlen;
|
||||||
|
|
||||||
void
|
if (argc <= 2) {
|
||||||
main(int argc, char *argv[])
|
printf("Usage: srchsig <SigFilename> <PattFilename>\n");
|
||||||
{
|
printf("Searches the signature file for the given pattern\n");
|
||||||
word w, len;
|
printf("e.g. %s dccm8s.sig mypatt.bin\n", argv[0]);
|
||||||
int h, i;
|
exit(1);
|
||||||
int patlen;
|
}
|
||||||
|
|
||||||
if (argc <= 2)
|
if ((f = fopen(argv[1], "rb")) == NULL) {
|
||||||
{
|
printf("Cannot open signature file %s\n", argv[1]);
|
||||||
printf("Usage: srchsig <SigFilename> <PattFilename>\n");
|
exit(2);
|
||||||
printf("Searches the signature file for the given pattern\n");
|
}
|
||||||
printf("e.g. %s dccm8s.sig mypatt.bin\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((f = fopen(argv[1], "rb")) == NULL)
|
if ((fpat = fopen(argv[2], "rb")) == NULL) {
|
||||||
{
|
printf("Cannot open pattern file %s\n", argv[2]);
|
||||||
printf("Cannot open signature file %s\n", argv[1]);
|
exit(2);
|
||||||
exit(2);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((fpat = fopen(argv[2], "rb")) == NULL)
|
/* Read the parameters */
|
||||||
{
|
grab(4);
|
||||||
printf("Cannot open pattern file %s\n", argv[2]);
|
if (memcmp("dccs", buf, 4) != 0) {
|
||||||
exit(2);
|
printf("Not a dccs file!\n");
|
||||||
}
|
exit(3);
|
||||||
|
}
|
||||||
|
numKeys = readFileShort();
|
||||||
|
numVert = readFileShort();
|
||||||
|
PatLen = readFileShort();
|
||||||
|
SymLen = readFileShort();
|
||||||
|
|
||||||
/* Read the parameters */
|
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
||||||
grab(4);
|
g_pattern_hasher.setHashParams(
|
||||||
if (memcmp("dccs", buf, 4) != 0)
|
numKeys, /* The number of symbols */
|
||||||
{
|
PatLen, /* The length of the pattern to be hashed */
|
||||||
printf("Not a dccs file!\n");
|
256, /* The character set of the pattern (0-FF) */
|
||||||
exit(3);
|
0, /* Minimum pattern character value */
|
||||||
}
|
numVert); /* Specifies C, the sparseness of the graph. See Czech, Havas
|
||||||
numKeys = readFileShort();
|
and Majewski for details */
|
||||||
numVert = readFileShort();
|
|
||||||
PatLen = readFileShort();
|
|
||||||
SymLen = readFileShort();
|
|
||||||
|
|
||||||
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
T1base = g_pattern_hasher.readT1();
|
||||||
hashParams( /* Set the parameters for the hash table */
|
T2base = g_pattern_hasher.readT2();
|
||||||
numKeys, /* The number of symbols */
|
g = g_pattern_hasher.readG();
|
||||||
PatLen, /* The length of the pattern to be hashed */
|
|
||||||
256, /* The character set of the pattern (0-FF) */
|
|
||||||
0, /* Minimum pattern character value */
|
|
||||||
numVert); /* Specifies C, the sparseness of the graph.
|
|
||||||
See Czech, Havas and Majewski for details
|
|
||||||
*/
|
|
||||||
|
|
||||||
T1base = readT1();
|
/* Read T1 and T2 tables */
|
||||||
T2base = readT2();
|
grab(2);
|
||||||
g = readG();
|
if (memcmp("T1", buf, 2) != 0) {
|
||||||
|
printf("Expected 'T1'\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
len = PatLen * 256 * sizeof(uint16_t);
|
||||||
|
w = readFileShort();
|
||||||
|
if (w != len) {
|
||||||
|
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
if (fread(T1base, 1, len, f) != len) {
|
||||||
|
printf("Could not read T1\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read T1 and T2 tables */
|
grab(2);
|
||||||
grab(2);
|
if (memcmp("T2", buf, 2) != 0) {
|
||||||
if (memcmp("T1", buf, 2) != 0)
|
printf("Expected 'T2'\n");
|
||||||
{
|
exit(3);
|
||||||
printf("Expected 'T1'\n");
|
}
|
||||||
exit(3);
|
w = readFileShort();
|
||||||
}
|
if (w != len) {
|
||||||
len = PatLen * 256 * sizeof(word);
|
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
||||||
w = readFileShort();
|
exit(4);
|
||||||
if (w != len)
|
}
|
||||||
{
|
if (fread(T2base, 1, len, f) != len) {
|
||||||
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
printf("Could not read T2\n");
|
||||||
exit(4);
|
exit(5);
|
||||||
}
|
}
|
||||||
if (fread(T1base, 1, len, f) != len)
|
|
||||||
{
|
|
||||||
printf("Could not read T1\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
grab(2);
|
/* Now read the function g[] */
|
||||||
if (memcmp("T2", buf, 2) != 0)
|
grab(2);
|
||||||
{
|
if (memcmp("gg", buf, 2) != 0) {
|
||||||
printf("Expected 'T2'\n");
|
printf("Expected 'gg'\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
w = readFileShort();
|
len = numVert * sizeof(uint16_t);
|
||||||
if (w != len)
|
w = readFileShort();
|
||||||
{
|
if (w != len) {
|
||||||
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
if (fread(T2base, 1, len, f) != len)
|
if (fread(g, 1, len, f) != len) {
|
||||||
{
|
printf("Could not read T2\n");
|
||||||
printf("Could not read T2\n");
|
exit(5);
|
||||||
exit(5);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Now read the function g[] */
|
/* This is now the hash table */
|
||||||
grab(2);
|
/* First allocate space for the table */
|
||||||
if (memcmp("gg", buf, 2) != 0)
|
if ((ht = (HT *)malloc(numKeys * sizeof(HT))) == 0) {
|
||||||
{
|
printf("Could not allocate hash table\n");
|
||||||
printf("Expected 'gg'\n");
|
exit(1);
|
||||||
exit(3);
|
}
|
||||||
}
|
grab(2);
|
||||||
len = numVert * sizeof(word);
|
if (memcmp("ht", buf, 2) != 0) {
|
||||||
w = readFileShort();
|
printf("Expected 'ht'\n");
|
||||||
if (w != len)
|
exit(3);
|
||||||
{
|
}
|
||||||
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
w = readFileShort();
|
||||||
exit(4);
|
if (w != numKeys * (SymLen + PatLen + sizeof(uint16_t))) {
|
||||||
}
|
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
||||||
if (fread(g, 1, len, f) != len)
|
exit(6);
|
||||||
{
|
}
|
||||||
printf("Could not read T2\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (i = 0; i < numKeys; i++) {
|
||||||
|
if ((int)fread(&ht[i], 1, SymLen + PatLen, f) != SymLen + PatLen) {
|
||||||
|
printf("Could not read\n");
|
||||||
|
exit(11);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This is now the hash table */
|
/* Read the pattern to buf */
|
||||||
/* First allocate space for the table */
|
if ((patlen = fread(buf, 1, 100, fpat)) == 0) {
|
||||||
if ((ht = (HT *)malloc(numKeys * sizeof(HT))) == 0)
|
printf("Could not read pattern\n");
|
||||||
{
|
exit(11);
|
||||||
printf("Could not allocate hash table\n");
|
}
|
||||||
exit(1);
|
if (patlen != PATLEN) {
|
||||||
}
|
|
||||||
grab(2);
|
|
||||||
if (memcmp("ht", buf, 2) != 0)
|
|
||||||
{
|
|
||||||
printf("Expected 'ht'\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
w = readFileShort();
|
|
||||||
if (w != numKeys * (SymLen + PatLen + sizeof(word)))
|
|
||||||
{
|
|
||||||
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
|
||||||
exit(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i < numKeys; i++)
|
|
||||||
{
|
|
||||||
if ((int)fread(&ht[i], 1, SymLen + PatLen, f) != SymLen + PatLen)
|
|
||||||
{
|
|
||||||
printf("Could not read\n");
|
|
||||||
exit(11);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the pattern to buf */
|
|
||||||
if ((patlen = fread(buf, 1, 100, fpat)) == 0)
|
|
||||||
{
|
|
||||||
printf("Could not read pattern\n");
|
|
||||||
exit(11);
|
|
||||||
}
|
|
||||||
if (patlen != PATLEN)
|
|
||||||
{
|
|
||||||
printf("Error: pattern length is %d, should be %d\n", patlen, PATLEN);
|
printf("Error: pattern length is %d, should be %d\n", patlen, PATLEN);
|
||||||
exit(12);
|
exit(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix the wildcards */
|
/* Fix the wildcards */
|
||||||
fixWildCards(buf);
|
fixWildCards(buf);
|
||||||
|
|
||||||
printf("Pattern:\n");
|
printf("Pattern:\n");
|
||||||
for (i=0; i < PATLEN; i++)
|
for (i = 0; i < PATLEN; i++)
|
||||||
printf("%02X ", buf[i]);
|
printf("%02X ", buf[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
h = hash(buf);
|
|
||||||
printf("Pattern hashed to %d (0x%X), symbol %s\n", h, h, ht[h].htSym);
|
|
||||||
if (memcmp(ht[h].htPat, buf, PATLEN) == 0)
|
|
||||||
{
|
|
||||||
printf("Pattern matched");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Pattern mismatch: found following pattern\n");
|
|
||||||
for (i=0; i < PATLEN; i++)
|
|
||||||
printf("%02X ", ht[h].htPat[i]);
|
|
||||||
printf("\n");
|
|
||||||
pattSearch(); /* Look for it the hard way */
|
|
||||||
}
|
|
||||||
cleanup();
|
|
||||||
free(ht);
|
|
||||||
fclose(f);
|
|
||||||
fclose(fpat);
|
|
||||||
|
|
||||||
|
h = g_pattern_hasher.hash(buf);
|
||||||
|
printf("Pattern hashed to %d (0x%X), symbol %s\n", h, h, ht[h].htSym);
|
||||||
|
if (memcmp(ht[h].htPat, buf, PATLEN) == 0) {
|
||||||
|
printf("Pattern matched");
|
||||||
|
} else {
|
||||||
|
printf("Pattern mismatch: found following pattern\n");
|
||||||
|
for (i = 0; i < PATLEN; i++)
|
||||||
|
printf("%02X ", ht[h].htPat[i]);
|
||||||
|
printf("\n");
|
||||||
|
pattSearch(); /* Look for it the hard way */
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
free(ht);
|
||||||
|
fclose(f);
|
||||||
|
fclose(fpat);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pattSearch(void)
|
void pattSearch(void) {
|
||||||
{
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i < numKeys; i++)
|
for (i = 0; i < numKeys; i++) {
|
||||||
{
|
if ((i % 100) == 0)
|
||||||
if ((i % 100) == 0) printf("\r%d ", i);
|
printf("\r%d ", i);
|
||||||
if (memcmp(ht[i].htPat, buf, PATLEN) == 0)
|
if (memcmp(ht[i].htPat, buf, PATLEN) == 0) {
|
||||||
{
|
printf("\nPattern matched offset %d (0x%X)\n", i, i);
|
||||||
printf("\nPattern matched offset %d (0x%X)\n", i, i);
|
}
|
||||||
}
|
}
|
||||||
}
|
printf("\n");
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanup(void) {
|
||||||
void
|
/* Free the storage for variable sized tables etc */
|
||||||
cleanup(void)
|
if (T1base)
|
||||||
{
|
free(T1base);
|
||||||
/* Free the storage for variable sized tables etc */
|
if (T2base)
|
||||||
if (T1base) free(T1base);
|
free(T2base);
|
||||||
if (T2base) free(T2base);
|
if (g)
|
||||||
if (g) free(g);
|
free(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab(int n)
|
void grab(int n) {
|
||||||
{
|
if (fread(buf, 1, n, f) != (size_t)n) {
|
||||||
if (fread(buf, 1, n, f) != (size_t)n)
|
printf("Could not read\n");
|
||||||
{
|
exit(11);
|
||||||
printf("Could not read\n");
|
}
|
||||||
exit(11);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word
|
uint16_t readFileShort(void) {
|
||||||
readFileShort(void)
|
uint8_t b1, b2;
|
||||||
{
|
|
||||||
byte b1, b2;
|
|
||||||
|
|
||||||
if (fread(&b1, 1, 1, f) != 1)
|
if (fread(&b1, 1, 1, f) != 1) {
|
||||||
{
|
printf("Could not read\n");
|
||||||
printf("Could not read\n");
|
exit(11);
|
||||||
exit(11);
|
}
|
||||||
}
|
if (fread(&b2, 1, 1, f) != 1) {
|
||||||
if (fread(&b2, 1, 1, f) != 1)
|
printf("Could not read\n");
|
||||||
{
|
exit(11);
|
||||||
printf("Could not read\n");
|
}
|
||||||
exit(11);
|
return (b2 << 8) + b1;
|
||||||
}
|
|
||||||
return (b2 << 8) + b1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Following two functions not needed unless creating tables */
|
/* Following two functions not needed unless creating tables */
|
||||||
|
|
||||||
void getKey(int i, byte **keys)
|
void getKey(int i, uint8_t **keys) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display key i */
|
/* Display key i */
|
||||||
void
|
void dispKey(int i) {}
|
||||||
dispKey(int i)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
#include "LIB_PatternCollector.h"
|
#include "LIB_PatternCollector.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstring>
|
#include <algorithm>
|
||||||
/** \note there is an untested assumption that the *first* segment definition
|
/** \note there is an untested assumption that the *first* segment definition
|
||||||
with class CODE will be the one containing all useful functions in the
|
with class CODE will be the one containing all useful functions in the
|
||||||
LEDATA records. Functions such as _exit() have more than one segment
|
LEDATA records. Functions such as _exit() have more than one segment
|
||||||
@ -49,7 +52,7 @@ int LIB_PatternCollector::readSyms(FILE *fl)
|
|||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!feof(fl))
|
while (not feof(fl))
|
||||||
{
|
{
|
||||||
type = readByte(fl);
|
type = readByte(fl);
|
||||||
len = readWord(fl);
|
len = readWord(fl);
|
||||||
@ -88,7 +91,7 @@ int LIB_PatternCollector::readSyms(FILE *fl)
|
|||||||
++segnum;
|
++segnum;
|
||||||
|
|
||||||
b = readByte(fl); /* Class name index */
|
b = readByte(fl); /* Class name index */
|
||||||
if ((b == codeLNAMES) && (codeSEGDEF == NONE))
|
if ((b == codeLNAMES) and (codeSEGDEF == NONE))
|
||||||
{
|
{
|
||||||
/* This is the segment defining the code class */
|
/* This is the segment defining the code class */
|
||||||
codeSEGDEF = segnum;
|
codeSEGDEF = segnum;
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
#include "TPL_PatternCollector.h"
|
#include "TPL_PatternCollector.h"
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
/** \note Fundamental problem: there seems to be no information linking the names
|
/** \note Fundamental problem: there seems to be no information linking the names
|
||||||
@ -255,7 +258,7 @@ void TPL_PatternCollector::enterUnitProcs(FILE *f)
|
|||||||
readString(f);
|
readString(f);
|
||||||
strcpy(name, (char *)buf);
|
strcpy(name, (char *)buf);
|
||||||
cat = readByte(f);
|
cat = readByte(f);
|
||||||
if ((cat == charProc) || (cat == charFunc))
|
if ((cat == charProc) or (cat == charFunc))
|
||||||
{
|
{
|
||||||
grab(f,skipPmap); /* Skip to the pmap */
|
grab(f,skipPmap); /* Skip to the pmap */
|
||||||
pmapOff = readShort(f); /* pmap offset */
|
pmapOff = readShort(f); /* pmap offset */
|
||||||
@ -278,7 +281,7 @@ void TPL_PatternCollector::enterUnitProcs(FILE *f)
|
|||||||
int TPL_PatternCollector::readSyms(FILE *f)
|
int TPL_PatternCollector::readSyms(FILE *f)
|
||||||
{
|
{
|
||||||
grab(f,4);
|
grab(f,4);
|
||||||
if ((strncmp((char *)buf, "TPU0", 4) != 0) && ((strncmp((char *)buf, "TPU5", 4) != 0)))
|
if ((strncmp((char *)buf, "TPU0", 4) != 0) and ((strncmp((char *)buf, "TPU5", 4) != 0)))
|
||||||
{
|
{
|
||||||
printf("Not a Turbo Pascal version 4 or 5 library file\n");
|
printf("Not a Turbo Pascal version 4 or 5 library file\n");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|||||||
@ -25,8 +25,11 @@
|
|||||||
* *
|
* *
|
||||||
\* * * * * * * * * * * * */
|
\* * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef PATLEN
|
#ifndef PATLEN
|
||||||
#define PATLEN 23
|
#define PATLEN 23
|
||||||
#define WILD 0xF4
|
#define WILD 0xF4
|
||||||
@ -417,7 +420,7 @@ void fixWildCards(uint8_t pat[])
|
|||||||
|
|
||||||
case 0xCD: /* Int nn */
|
case 0xCD: /* Int nn */
|
||||||
intArg = pat[pc++];
|
intArg = pat[pc++];
|
||||||
if ((intArg >= 0x34) && (intArg <= 0x3B))
|
if ((intArg >= 0x34) and (intArg <= 0x3B))
|
||||||
{
|
{
|
||||||
/* Borland/Microsoft FP emulations */
|
/* Borland/Microsoft FP emulations */
|
||||||
if (ModRM(pat)) return;
|
if (ModRM(pat)) return;
|
||||||
|
|||||||
@ -3,13 +3,14 @@
|
|||||||
#include "LIB_PatternCollector.h"
|
#include "LIB_PatternCollector.h"
|
||||||
#include "TPL_PatternCollector.h"
|
#include "TPL_PatternCollector.h"
|
||||||
#include "perfhlib.h" /* Symbol table prototypes */
|
#include "perfhlib.h" /* Symbol table prototypes */
|
||||||
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -21,7 +22,7 @@
|
|||||||
|
|
||||||
void saveFile(FILE *fl, const PerfectHash &p_hash, PatternCollector *coll); /* Save the info */
|
void saveFile(FILE *fl, const PerfectHash &p_hash, PatternCollector *coll); /* Save the info */
|
||||||
|
|
||||||
int numKeys; /* Number of useful codeview symbols */
|
static int numKeys; /* Number of useful codeview symbols */
|
||||||
|
|
||||||
|
|
||||||
static void printUsage(bool longusage) {
|
static void printUsage(bool longusage) {
|
||||||
@ -48,7 +49,7 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
QString arg2 = app.arguments()[1];
|
QString arg2 = app.arguments()[1];
|
||||||
if (arg2.startsWith("-h") || arg2.startsWith("-?"))
|
if (arg2.startsWith("-h") or arg2.startsWith("-?"))
|
||||||
{
|
{
|
||||||
printUsage(true);
|
printUsage(true);
|
||||||
return 0;
|
return 0;
|
||||||
@ -58,6 +59,9 @@ int main(int argc, char *argv[])
|
|||||||
collector = new TPL_PatternCollector;
|
collector = new TPL_PatternCollector;
|
||||||
} else if(arg2.endsWith(".lib")) {
|
} else if(arg2.endsWith(".lib")) {
|
||||||
collector = new LIB_PatternCollector;
|
collector = new LIB_PatternCollector;
|
||||||
|
} else {
|
||||||
|
qCritical() << "Unsupported file type.";
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if ((srcfile = fopen(argv[1], "rb")) == NULL)
|
if ((srcfile = fopen(argv[1], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
add_executable(parselib parsehdr.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(parselib dcc_hash)
|
||||||
|
qt5_use_modules(parselib Core)
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
/*$Log: locident.h,v $
|
/*$Log: locident.h,v $
|
||||||
* Revision 1.6 94/02/22 15:20:23 cifuente
|
* Revision 1.6 94/02/22 15:20:23 cifuente
|
||||||
* Code generation is done.
|
* Code generation is done.
|
||||||
@ -26,92 +27,92 @@
|
|||||||
|
|
||||||
/* Type definition */
|
/* Type definition */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Int csym; /* # symbols used */
|
Int csym; /* # symbols used */
|
||||||
Int alloc; /* # symbols allocated */
|
Int alloc; /* # symbols allocated */
|
||||||
Int *idx; /* Array of integer indexes */
|
Int *idx; /* Array of integer indexes */
|
||||||
} IDX_ARRAY;
|
} IDX_ARRAY;
|
||||||
|
|
||||||
/* Type definitions used in the decompiled program */
|
/* Type definitions used in the decompiled program */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TYPE_UNKNOWN = 0, /* unknown so far */
|
TYPE_UNKNOWN = 0, /* unknown so far */
|
||||||
TYPE_BYTE_SIGN, /* signed byte (8 bits) */
|
TYPE_BYTE_SIGN, /* signed byte (8 bits) */
|
||||||
TYPE_BYTE_UNSIGN, /* unsigned byte */
|
TYPE_BYTE_UNSIGN, /* unsigned byte */
|
||||||
TYPE_WORD_SIGN, /* signed word (16 bits) */
|
TYPE_WORD_SIGN, /* signed word (16 bits) */
|
||||||
TYPE_WORD_UNSIGN, /* unsigned word (16 bits) */
|
TYPE_WORD_UNSIGN, /* unsigned word (16 bits) */
|
||||||
TYPE_LONG_SIGN, /* signed long (32 bits) */
|
TYPE_LONG_SIGN, /* signed long (32 bits) */
|
||||||
TYPE_LONG_UNSIGN, /* unsigned long (32 bits) */
|
TYPE_LONG_UNSIGN, /* unsigned long (32 bits) */
|
||||||
TYPE_RECORD, /* record structure */
|
TYPE_RECORD, /* record structure */
|
||||||
TYPE_PTR, /* pointer (32 bit ptr) */
|
TYPE_PTR, /* pointer (32 bit ptr) */
|
||||||
TYPE_STR, /* string */
|
TYPE_STR, /* string */
|
||||||
TYPE_CONST, /* constant (any type) */
|
TYPE_CONST, /* constant (any type) */
|
||||||
TYPE_FLOAT, /* floating point */
|
TYPE_FLOAT, /* floating point */
|
||||||
TYPE_DOUBLE, /* double precision float */
|
TYPE_DOUBLE, /* double precision float */
|
||||||
} hlType;
|
} hlType;
|
||||||
|
|
||||||
static char *hlTypes[13] = {"", "char", "unsigned char", "int", "unsigned int",
|
static char *hlTypes[13] = {"", "char", "unsigned char", "int", "unsigned int",
|
||||||
"long", "unsigned long", "record", "int *", "char *",
|
"long", "unsigned long", "record", "int *", "char *",
|
||||||
"", "float", "double"};
|
"", "float", "double"};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STK_FRAME, /* For stack vars */
|
STK_FRAME, /* For stack vars */
|
||||||
REG_FRAME, /* For register variables */
|
REG_FRAME, /* For register variables */
|
||||||
GLB_FRAME, /* For globals */
|
GLB_FRAME, /* For globals */
|
||||||
} frameType;
|
} frameType;
|
||||||
|
|
||||||
|
|
||||||
/* Enumeration to determine whether pIcode points to the high or low part
|
/* Enumeration to determine whether pIcode points to the high or low part
|
||||||
* of a long number */
|
* of a long number */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HIGH_FIRST, /* High value is first */
|
HIGH_FIRST, /* High value is first */
|
||||||
LOW_FIRST, /* Low value is first */
|
LOW_FIRST, /* Low value is first */
|
||||||
} hlFirst;
|
} hlFirst;
|
||||||
|
|
||||||
|
|
||||||
/* LOCAL_ID */
|
/* LOCAL_ID */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
hlType type; /* Probable type */
|
hlType type; /* Probable type */
|
||||||
boolT illegal;/* Boolean: not a valid field any more */
|
boolT illegal;/* Boolean: not a valid field any more */
|
||||||
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
|
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
|
||||||
frameType loc; /* Frame location */
|
frameType loc; /* Frame location */
|
||||||
boolT hasMacro;/* Identifier requires a macro */
|
boolT hasMacro;/* Identifier requires a macro */
|
||||||
char macro[10];/* Macro for this identifier */
|
char macro[10];/* Macro for this identifier */
|
||||||
char name[20];/* Identifier's name */
|
char name[20];/* Identifier's name */
|
||||||
union { /* Different types of identifiers */
|
union { /* Different types of identifiers */
|
||||||
byte regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */
|
byte regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */
|
||||||
struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
|
struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
|
||||||
byte regOff; /* register offset (if any) */
|
byte regOff; /* register offset (if any) */
|
||||||
Int off; /* offset from BP */
|
Int off; /* offset from BP */
|
||||||
} bwId;
|
} bwId;
|
||||||
struct _bwGlb { /* For TYPE_BYTE(WORD)_(UN)SIGN globals */
|
struct _bwGlb { /* For TYPE_BYTE(WORD)_(UN)SIGN globals */
|
||||||
int16 seg; /* segment value */
|
int16 seg; /* segment value */
|
||||||
int16 off; /* offset */
|
int16 off; /* offset */
|
||||||
byte regi; /* optional indexed register */
|
byte regi; /* optional indexed register */
|
||||||
} bwGlb;
|
} bwGlb;
|
||||||
struct _longId{ /* For TYPE_LONG_(UN)SIGN registers */
|
struct _longId{ /* For TYPE_LONG_(UN)SIGN registers */
|
||||||
byte h; /* high register */
|
byte h; /* high register */
|
||||||
byte l; /* low register */
|
byte l; /* low register */
|
||||||
} longId;
|
} longId;
|
||||||
struct _longStkId { /* For TYPE_LONG_(UN)SIGN on the stack */
|
struct _longStkId { /* For TYPE_LONG_(UN)SIGN on the stack */
|
||||||
Int offH; /* high offset from BP */
|
Int offH; /* high offset from BP */
|
||||||
Int offL; /* low offset from BP */
|
Int offL; /* low offset from BP */
|
||||||
} longStkId;
|
} longStkId;
|
||||||
struct { /* For TYPE_LONG_(UN)SIGN globals */
|
struct { /* For TYPE_LONG_(UN)SIGN globals */
|
||||||
int16 seg; /* segment value */
|
int16 seg; /* segment value */
|
||||||
int16 offH; /* offset high */
|
int16 offH; /* offset high */
|
||||||
int16 offL; /* offset low */
|
int16 offL; /* offset low */
|
||||||
byte regi; /* optional indexed register */
|
byte regi; /* optional indexed register */
|
||||||
} longGlb;
|
} longGlb;
|
||||||
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
||||||
dword h; /* high word */
|
dword h; /* high word */
|
||||||
dword l; /* low word */
|
dword l; /* low word */
|
||||||
} longKte;
|
} longKte;
|
||||||
} id;
|
} id;
|
||||||
} ID;
|
} ID;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Int csym; /* No. of symbols in the table */
|
Int csym; /* No. of symbols in the table */
|
||||||
Int alloc; /* No. of symbols allocated */
|
Int alloc; /* No. of symbols allocated */
|
||||||
ID *id; /* Identifier */
|
ID *id; /* Identifier */
|
||||||
} LOCAL_ID;
|
} LOCAL_ID;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Enums.h"
|
||||||
/*
|
/*
|
||||||
*$Log: parsehdr.h,v $
|
*$Log: parsehdr.h,v $
|
||||||
*/
|
*/
|
||||||
@ -8,11 +10,8 @@ typedef unsigned char byte; /* 8 bits */
|
|||||||
typedef unsigned short word; /* 16 bits */
|
typedef unsigned short word; /* 16 bits */
|
||||||
typedef unsigned char boolT; /* 8 bits */
|
typedef unsigned char boolT; /* 8 bits */
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
|
|
||||||
#define BUFF_SIZE 8192 /* Holds a declaration */
|
#define BUFF_SIZE 8192 /* Holds a declaration */
|
||||||
#define FBUF_SIZE 32700 /* Holds part of a header file */
|
#define FBUF_SIZE 32700 /* Holds part of a header file */
|
||||||
|
|
||||||
#define NARGS 15
|
#define NARGS 15
|
||||||
#define NAMES_L 160
|
#define NAMES_L 160
|
||||||
@ -38,11 +37,8 @@ void phWarning(char *errmsg);
|
|||||||
|
|
||||||
#define SYMLEN 16 /* Including the null */
|
#define SYMLEN 16 /* Including the null */
|
||||||
#define Int long /* For locident.h */
|
#define Int long /* For locident.h */
|
||||||
#define int16 short int /* For locident.h */
|
//#include "locident.h" /* For the hlType enum */
|
||||||
#include "locident.h" /* For the hlType enum */
|
//#define bool unsigned char /* For internal use */
|
||||||
#define bool unsigned char /* For internal use */
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
struct ph_func_tag
|
struct ph_func_tag
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
add_executable(readsig readsig.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(readsig dcc_hash)
|
||||||
|
qt5_use_modules(readsig Core)
|
||||||
@ -1,239 +1,221 @@
|
|||||||
/* Quick program to read the output from makedsig */
|
/* Quick program to read the output from makedsig */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <io.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
|
|
||||||
/* statics */
|
/* statics */
|
||||||
byte buf[100];
|
uint8_t buf[100];
|
||||||
int numKeys; /* Number of hash table entries (keys) */
|
int numKeys; /* Number of hash table entries (keys) */
|
||||||
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
int numVert; /* Number of vertices in the graph (also size of g[]) */
|
||||||
int PatLen; /* Size of the keys (pattern length) */
|
int PatLen; /* Size of the keys (pattern length) */
|
||||||
int SymLen; /* Max size of the symbols, including null */
|
int SymLen; /* Max size of the symbols, including null */
|
||||||
FILE *f; /* File being read */
|
FILE *f; /* File being read */
|
||||||
|
|
||||||
static word *T1base, *T2base; /* Pointers to start of T1, T2 */
|
|
||||||
static word *g; /* g[] */
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
void grab(int n);
|
void grab(int n);
|
||||||
word readFileShort(void);
|
uint16_t readFileShort(void);
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
|
|
||||||
static bool bDispAll = FALSE;
|
static bool bDispAll = false;
|
||||||
|
static PerfectHash g_pattern_hasher;
|
||||||
|
static uint16_t *T1base;
|
||||||
|
static uint16_t *T2base;
|
||||||
|
static uint16_t *g;
|
||||||
|
|
||||||
void
|
int main(int argc, char *argv[])
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
word w, len;
|
uint16_t w, len;
|
||||||
int h, i, j;
|
int h, i, j;
|
||||||
long filePos;
|
long filePos;
|
||||||
|
|
||||||
if (argc <= 1)
|
if (argc <= 1)
|
||||||
{
|
{
|
||||||
printf("Usage: readsig [-a] <SigFilename>\n");
|
printf("Usage: readsig [-a] <SigFilename>\n");
|
||||||
printf("-a for all symbols (else just duplicates)\n");
|
printf("-a for all symbols (else just duplicates)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
|
|
||||||
if (strcmp(argv[i], "-a") == 0)
|
if (strcmp(argv[i], "-a") == 0)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
bDispAll = TRUE;
|
bDispAll = true;
|
||||||
}
|
}
|
||||||
if ((f = fopen(argv[i], "rb")) == NULL)
|
if ((f = fopen(argv[i], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
printf("Cannot open %s\n", argv[i]);
|
printf("Cannot open %s\n", argv[i]);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the parameters */
|
/* Read the parameters */
|
||||||
grab(4);
|
grab(4);
|
||||||
if (memcmp("dccs", buf, 4) != 0)
|
if (memcmp("dccs", buf, 4) != 0)
|
||||||
{
|
{
|
||||||
printf("Not a dccs file!\n");
|
printf("Not a dccs file!\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
numKeys = readFileShort();
|
numKeys = readFileShort();
|
||||||
numVert = readFileShort();
|
numVert = readFileShort();
|
||||||
PatLen = readFileShort();
|
PatLen = readFileShort();
|
||||||
SymLen = readFileShort();
|
SymLen = readFileShort();
|
||||||
|
|
||||||
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
|
||||||
hashParams( /* Set the parameters for the hash table */
|
g_pattern_hasher.setHashParams(
|
||||||
numKeys, /* The number of symbols */
|
numKeys, /* The number of symbols */
|
||||||
PatLen, /* The length of the pattern to be hashed */
|
PatLen, /* The length of the pattern to be hashed */
|
||||||
256, /* The character set of the pattern (0-FF) */
|
256, /* The character set of the pattern (0-FF) */
|
||||||
0, /* Minimum pattern character value */
|
0, /* Minimum pattern character value */
|
||||||
numVert); /* Specifies C, the sparseness of the graph.
|
numVert); /* Specifies C, the sparseness of the graph. See Czech, Havas and Majewski for details */
|
||||||
See Czech, Havas and Majewski for details
|
|
||||||
*/
|
|
||||||
|
|
||||||
T1base = readT1();
|
T1base = g_pattern_hasher.readT1();
|
||||||
T2base = readT2();
|
T2base = g_pattern_hasher.readT2();
|
||||||
g = readG();
|
g = g_pattern_hasher.readG();
|
||||||
|
|
||||||
/* Read T1 and T2 tables */
|
/* Read T1 and T2 tables */
|
||||||
grab(2);
|
grab(2);
|
||||||
if (memcmp("T1", buf, 2) != 0)
|
if (memcmp("T1", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'T1'\n");
|
printf("Expected 'T1'\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
len = PatLen * 256 * sizeof(word);
|
len = PatLen * 256 * sizeof(uint16_t);
|
||||||
w = readFileShort();
|
w = readFileShort();
|
||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
printf("Problem with size of T1: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
if (fread(T1base, 1, len, f) != len)
|
if (fread(T1base, 1, len, f) != len)
|
||||||
{
|
{
|
||||||
printf("Could not read T1\n");
|
printf("Could not read T1\n");
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
grab(2);
|
grab(2);
|
||||||
if (memcmp("T2", buf, 2) != 0)
|
if (memcmp("T2", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'T2'\n");
|
printf("Expected 'T2'\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
w = readFileShort();
|
w = readFileShort();
|
||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
printf("Problem with size of T2: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
if (fread(T2base, 1, len, f) != len)
|
if (fread(T2base, 1, len, f) != len)
|
||||||
{
|
{
|
||||||
printf("Could not read T2\n");
|
printf("Could not read T2\n");
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now read the function g[] */
|
/* Now read the function g[] */
|
||||||
grab(2);
|
grab(2);
|
||||||
if (memcmp("gg", buf, 2) != 0)
|
if (memcmp("gg", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'gg'\n");
|
printf("Expected 'gg'\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
len = numVert * sizeof(word);
|
len = numVert * sizeof(uint16_t);
|
||||||
w = readFileShort();
|
w = readFileShort();
|
||||||
if (w != len)
|
if (w != len)
|
||||||
{
|
{
|
||||||
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
printf("Problem with size of g[]: file %d, calc %d\n", w, len);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
if (fread(g, 1, len, f) != len)
|
if (fread(g, 1, len, f) != len)
|
||||||
{
|
{
|
||||||
printf("Could not read T2\n");
|
printf("Could not read T2\n");
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is now the hash table */
|
/* This is now the hash table */
|
||||||
grab(2);
|
grab(2);
|
||||||
if (memcmp("ht", buf, 2) != 0)
|
if (memcmp("ht", buf, 2) != 0)
|
||||||
{
|
{
|
||||||
printf("Expected 'ht'\n");
|
printf("Expected 'ht'\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
w = readFileShort();
|
w = readFileShort();
|
||||||
if (w != numKeys * (SymLen + PatLen + sizeof(word)))
|
if (w != numKeys * (SymLen + PatLen + sizeof(uint16_t)))
|
||||||
{
|
{
|
||||||
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
printf("Problem with size of hash table: file %d, calc %d\n", w, len);
|
||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bDispAll)
|
if (bDispAll)
|
||||||
{
|
{
|
||||||
fseek(f, 0, SEEK_CUR); /* Needed due to bug in MS fread()! */
|
filePos = ftell(f);
|
||||||
filePos = _lseek(fileno(f), 0, SEEK_CUR);
|
for (i=0; i < numKeys; i++)
|
||||||
for (i=0; i < numKeys; i++)
|
{
|
||||||
{
|
grab(SymLen + PatLen);
|
||||||
grab(SymLen + PatLen);
|
|
||||||
|
|
||||||
printf("%16s ", buf);
|
printf("%16s ", buf);
|
||||||
for (j=0; j < PatLen; j++)
|
for (j=0; j < PatLen; j++)
|
||||||
{
|
{
|
||||||
printf("%02X", buf[SymLen+j]);
|
printf("%02X", buf[SymLen+j]);
|
||||||
if ((j%4) == 3) printf(" ");
|
if ((j%4) == 3) printf(" ");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("\n\n\n");
|
printf("\n\n\n");
|
||||||
fseek(f, filePos, SEEK_SET);
|
fseek(f, filePos, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < numKeys; i++)
|
for (i=0; i < numKeys; i++)
|
||||||
{
|
{
|
||||||
grab(SymLen + PatLen);
|
grab(SymLen + PatLen);
|
||||||
|
|
||||||
h = hash(&buf[SymLen]);
|
h = g_pattern_hasher.hash(&buf[SymLen]);
|
||||||
if (h != i)
|
if (h != i)
|
||||||
{
|
{
|
||||||
printf("Symbol %16s (index %3d) hashed to %d\n",
|
printf("Symbol %16s (index %3d) hashed to %d\n", buf, i, h);
|
||||||
buf, i, h);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
printf("Done!\n");
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
|
printf("Done!\n");
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup(void)
|
cleanup(void)
|
||||||
{
|
{
|
||||||
/* Free the storage for variable sized tables etc */
|
// TODO: g_pattern_hasher.hashCleanup();
|
||||||
if (T1base) free(T1base);
|
/* Free the storage for variable sized tables etc */
|
||||||
if (T2base) free(T2base);
|
if (T1base) free(T1base);
|
||||||
if (g) free(g);
|
if (T2base) free(T2base);
|
||||||
|
if (g) free(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab(int n)
|
void grab(int n)
|
||||||
{
|
{
|
||||||
if (fread(buf, 1, n, f) != (size_t)n)
|
if (fread(buf, 1, n, f) != (size_t)n)
|
||||||
{
|
{
|
||||||
printf("Could not read\n");
|
printf("Could not read\n");
|
||||||
exit(11);
|
exit(11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
word
|
uint16_t readFileShort(void)
|
||||||
readFileShort(void)
|
|
||||||
{
|
{
|
||||||
byte b1, b2;
|
uint8_t b1, b2;
|
||||||
|
|
||||||
if (fread(&b1, 1, 1, f) != 1)
|
if (fread(&b1, 1, 1, f) != 1)
|
||||||
{
|
{
|
||||||
printf("Could not read\n");
|
printf("Could not read\n");
|
||||||
exit(11);
|
exit(11);
|
||||||
}
|
}
|
||||||
if (fread(&b2, 1, 1, f) != 1)
|
if (fread(&b2, 1, 1, f) != 1)
|
||||||
{
|
{
|
||||||
printf("Could not read\n");
|
printf("Could not read\n");
|
||||||
exit(11);
|
exit(11);
|
||||||
}
|
}
|
||||||
return (b2 << 8) + b1;
|
return (b2 << 8) + b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Following two functions not needed unless creating tables */
|
|
||||||
|
|
||||||
void getKey(int i, byte **keys)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display key i */
|
|
||||||
void
|
|
||||||
dispKey(int i)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user