Compare commits

...

51 Commits

Author SHA1 Message Date
Godzil
b58f315c98 cleanup things, stop trying with CS 2018-09-19 17:59:25 +01:00
Godzil
7687c2b7d2 Trying to make parser to correctly handle CS 2018-09-18 18:50:13 +01:00
Artur K
0abbce6f4e
Merge pull request #32 from nemerle/add-license-1
Create LICENSE
2018-03-23 19:59:48 +01:00
Artur K
8ffdf657ec
Create LICENSE
Original code was using GPL.
2018-03-23 19:59:34 +01:00
nemerle
2232a76033 Disregard signed/unsigned difference in AstIdent::idID 2017-02-13 16:14:38 +01:00
nemerle
d6af9c1555 Add iInvalid enum value for invalid instructions
Various cleanups.
2017-02-13 13:24:54 +01:00
nemerle
d7acc8cd4d rename otherLongRegi to getPairedRegisterAt, make it a method of
LOCAL_ID struct.
2017-02-13 12:31:30 +01:00
nemerle
a5f1d17e83 Various code cleanups. 2017-02-13 12:11:29 +01:00
nemerle
29efcd5be1 Remove references to malloc.h closes #28 2017-02-07 12:09:58 +01:00
Artur K
4656db9484 Merge pull request #25 from gitter-badger/gitter-badge
Add a Gitter chat badge to Readme.md
2016-05-23 13:30:14 +02:00
The Gitter Badger
b33d7239e5 Add Gitter badge 2016-05-23 11:28:47 +00:00
Artur K
e1f0c084f8 Merge pull request #24 from lab313ru/patch-1
Fixed symbol name collision in parsehdr
2016-05-20 10:13:45 +02:00
Lab 313
e2a6b25345 Fixed collision with round math.h function 2016-05-20 11:01:00 +03:00
nemerle
f210ed78c2 Add the last of the original tools dispsig and srchsig
Closes #22
2016-05-19 20:15:37 +02:00
nemerle
ccc8cc526b Add readsig tool to build
As requested in #22
2016-05-19 20:03:49 +02:00
nemerle
cd6797499f Add parsehdr to the build
As requested in #22

(cherry picked from commit d5985b4b97cb06a89050c34674878c6430432fe1)
2016-05-19 19:52:48 +02:00
nemerle
b60903306f Fix memset-of-non-POD bug.
PROG contains vector, but was memset.
2016-05-19 16:17:08 +02:00
nemerle
1df7cb3be4 Fix msvc detection + prevent range library from pulling in boost::regex 2016-05-19 14:45:03 +02:00
nemerle
a7265f06b0 Fix msvc detection in cmake 2016-05-19 14:14:26 +02:00
nemerle
58532f4402 Removing LLVM dependency contd. 2016-05-19 12:40:59 +02:00
nemerle
7d986ef661 Removing LLVM dependencies WIP 2016-05-19 11:14:46 +02:00
nemerle
7f4197acc1 Use cmake features to mark c++11 as a required standard 2016-05-19 10:44:45 +02:00
nemerle
e71c8051c3 Rename icodeType entries
Following 2f80f16e6f76e3794ddc35ac9a6c1a86cb11cd28
2016-05-19 10:27:15 +02:00
nemerle
73cf949e25 Undefine PASCAL if it's defined as a macro
Following 0af07017b9c2f14435bd0fd103ae199cbf840bb0
2016-05-19 10:20:51 +02:00
nemerle
b2be1cf2da Simplify: SetupLibCheck does not depend on PROG or Project classes.
It also does not exit the program when ".sig" loader fails.

Use QString to build signature filename.
2016-04-26 13:42:41 +02:00
nemerle
94e3016a5b Fix SetCurFunc_by_Name implementation 2016-04-26 13:36:57 +02:00
nemerle
145a50369e Fix: Jump labels were printed incorrectly. 2016-04-26 13:35:20 +02:00
Vladimir Kryvian
d77927c608 Added new line for "removeRegFromLong not supproted" message in icode.h. 2016-04-26 10:06:00 +02:00
Vladimir Kryvian
3bb72987a6 Fixed double import with correct one in makedsig. 2016-04-26 10:05:10 +02:00
nemerle
c782892db4 Prevent the use of msvc's min/max macros 2016-04-26 09:26:28 +02:00
nemerle
a944ea5da8 Implement some of the methods in DccImpl 2016-04-26 09:23:34 +02:00
nemerle
d1738ea630 New feature: option to decompile only a specific function.
Similar to boomerang's -E option:

```
dcc -E 0x1222 ./TARGET.EXE
```

Will only decompile function at given address.
This might help in isolating dcc crashes.
2016-04-26 00:46:56 +02:00
nemerle
5f39236ba2 Fix LOCAL_ID::newLongIdx 2016-04-26 00:27:49 +02:00
nemerle
ede09ddae3 Record native function address as part of the name.
Might help while debugging dcc's handling of large programs.
2016-04-25 16:08:51 +02:00
nemerle
34b1f4f4fe Fix: long processing regression introduced in
bb007ddefc0465d36d394fbc4dbe811a633fc72e

Invalidated instructions should still be processed in findBBExps
2016-04-25 16:02:58 +02:00
nemerle
d6249916e1 More logic operator replacements.
Use Qt string classes.
2016-04-25 15:51:58 +02:00
nemerle
9cd3226536 Normalize logic operation keywords and add use msvc fix
Logical or should be only 'or','and','not', and not error prone
'||','&&','!'
2016-04-25 11:39:07 +02:00
nemerle
3f217e83da Add header that will contain msvc fixes 2016-04-25 10:08:25 +02:00
nemerle
652cfb67c3 Add simple gitattributes 2016-04-25 10:03:55 +02:00
nemerle
c0e9ba2fb3 Add addOutEdgesForConditionalJump to header 2016-04-25 10:03:30 +02:00
nemerle
5963f5fd4d Thanks to @lab313ru : fix bad iterator usage
Trying to increment past the end in graph.cpp

Also removed a goto by extracting a common function.
2016-04-24 12:22:15 +02:00
nemerle
12ee08f87e Implement two new switch idioms closes #14 2016-04-23 20:05:11 +02:00
nemerle
5c85c92d1a Replace tabs with spaces 2016-04-22 11:45:23 +02:00
nemerle
b509d0fcf0 Extend disassembly failure reporting a bit. 2016-04-22 10:47:14 +02:00
nemerle
bb007ddefc Stop processing invalidated instructions in dataflow 2016-04-22 10:36:29 +02:00
nemerle
9129d48429 Comment out a debugging printf 2016-04-22 10:35:41 +02:00
nemerle
d105182051 Add missing \n to error printf 2016-04-22 10:35:14 +02:00
nemerle
157a968372 Assume TYPE_STR is returned in exactly the same way as TYPE_PTR is 2016-04-22 10:34:36 +02:00
Artur K
bae2a582f1 Merge pull request #11 from lab313ru/lab313ru-patch-1
Lab313ru patch 1
2016-04-22 09:19:02 +02:00
Lab 313
19191876e2 Update libdis.h
Fixed negative address getting.
2016-04-22 02:37:22 +03:00
Lab 313
fcfe3c1f4b Update scanner.cpp
Fixed negative address calculating.
2016-04-22 02:35:40 +03:00
79 changed files with 4300 additions and 3999 deletions

6
.gitattributes vendored Normal file
View File

@ -0,0 +1,6 @@
* text=auto
*.c text
*.cpp text
*.ui text
*.qrc text
*.h text

View File

@ -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;

View File

@ -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
View 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.

View File

@ -6,6 +6,8 @@ To reflect those fixes, I've edited the original readme a bit.
dcc Distribution dcc Distribution
================ ================
[![Join the chat at https://gitter.im/nemerle/dcc](https://badges.gitter.im/nemerle/dcc.svg)](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)

View File

@ -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;

View File

@ -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]);

View File

@ -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 */

View File

@ -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);

View File

@ -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();

View File

@ -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 &);
}; };

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
}; };

View File

@ -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;
}; };

View File

@ -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 &regName(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 &regi); static void writeRegVector (QTextStream & ostr, const LivenessSet &regi);
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
View File

@ -0,0 +1,3 @@
#ifdef _MSC_VER
#include <iso646.h>
#endif

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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++;

View File

@ -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";
} }

View File

@ -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 */

View File

@ -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;
} }

View File

@ -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)

View File

@ -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);
} }

View File

@ -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";
} }

View 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);
} }

View File

@ -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);
} }

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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)

View File

@ -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;
} }

View File

@ -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";

View File

@ -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);
} }

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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)
{ {

View File

@ -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));

View File

@ -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)
{ {

View File

@ -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();

View File

@ -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;
} }

View File

@ -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()
{ {

View File

@ -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.
{ {

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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()
{ {

View File

@ -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");
} }
} }

View File

@ -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 &regi) void Machine_X86::writeRegVector (QTextStream &ostr,const LivenessSet &regi)
{ {
int j; int j;
for (j = rAX; j < INDEX_BX_SI; j++) for (j = rAX; j < INDEX_BX_SI; j++)

View File

@ -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()] = &ic;
}
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()] = &ic;
}
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);
} }

View File

@ -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 */

View File

@ -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;

View File

@ -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");
} }

View File

@ -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();

View File

@ -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 &reg) eReg convertRegister(const x86_reg_t &reg)
{ {
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 */

View File

@ -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
} }

View File

@ -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();

View File

@ -1 +1,4 @@
add_subdirectory(dispsrch)
add_subdirectory(makedsig) add_subdirectory(makedsig)
add_subdirectory(readsig)
add_subdirectory(parsehdr)

View 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)

View File

@ -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)
{
} }

View File

@ -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)
{
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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)
{ {

View File

@ -0,0 +1,4 @@
add_executable(parselib parsehdr.cpp)
target_link_libraries(parselib dcc_hash)
qt5_use_modules(parselib Core)

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
add_executable(readsig readsig.cpp)
target_link_libraries(readsig dcc_hash)
qt5_use_modules(readsig Core)

View File

@ -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)
{
}