Working towards gui integration with exetoc_qt
This commit is contained in:
parent
3603877f42
commit
36b063c183
68
3rd_party/libdisasm/INTEL_BUGS
vendored
Normal file
68
3rd_party/libdisasm/INTEL_BUGS
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
PMOVMSKB
|
||||||
|
Gd, Pq1H
|
||||||
|
PMOVMSKB
|
||||||
|
(66)
|
||||||
|
Gd, Vdq1H
|
||||||
|
|
||||||
|
should be
|
||||||
|
|
||||||
|
PMOVMSKB
|
||||||
|
Gd, Qq1H
|
||||||
|
PMOVMSKB
|
||||||
|
(66)
|
||||||
|
Gd, Wdq1H
|
||||||
|
|
||||||
|
The instruction represented by this opcode expression does not support any
|
||||||
|
operand to be a memory location.
|
||||||
|
|
||||||
|
MASKMOVQ
|
||||||
|
Pq, Pq1H
|
||||||
|
MASKMOVDQU
|
||||||
|
(66)
|
||||||
|
Vdq, Vdq1H
|
||||||
|
|
||||||
|
should be
|
||||||
|
|
||||||
|
MASKMOVQ
|
||||||
|
Pq, Pq1H
|
||||||
|
MASKMOVDQU
|
||||||
|
(66)
|
||||||
|
Vdq, Wdq1H
|
||||||
|
|
||||||
|
MOVMSKPS
|
||||||
|
Gd, Vps1H
|
||||||
|
MOVMSKPD
|
||||||
|
(66)
|
||||||
|
Gd, Vpd1H
|
||||||
|
|
||||||
|
should be
|
||||||
|
|
||||||
|
MOVMSKPS
|
||||||
|
Gd, Wps1H
|
||||||
|
MOVMSKPD
|
||||||
|
(66)
|
||||||
|
Gd, Wpd1H
|
||||||
|
|
||||||
|
The opcode table entries for LFS, LGS, and LSS
|
||||||
|
|
||||||
|
L[FGS]S
|
||||||
|
Mp
|
||||||
|
|
||||||
|
should be
|
||||||
|
|
||||||
|
L[FGS]S
|
||||||
|
Gv,Mp
|
||||||
|
|
||||||
|
MOVHLPS
|
||||||
|
Vps, Vps
|
||||||
|
|
||||||
|
MOVLHPS
|
||||||
|
Vps, Vps
|
||||||
|
|
||||||
|
should be
|
||||||
|
|
||||||
|
MOVHLPS
|
||||||
|
Vps, Wps
|
||||||
|
|
||||||
|
MOVLHPS
|
||||||
|
Vps, Wps
|
||||||
137
3rd_party/libdisasm/LICENSE
vendored
Normal file
137
3rd_party/libdisasm/LICENSE
vendored
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The "Clarified Artistic License"
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The intent of this document is to state the conditions under which a
|
||||||
|
Package may be copied, such that the Copyright Holder maintains some
|
||||||
|
semblance of artistic control over the development of the package,
|
||||||
|
while giving the users of the package the right to use and distribute
|
||||||
|
the Package in a more-or-less customary fashion, plus the right to make
|
||||||
|
reasonable modifications.
|
||||||
|
|
||||||
|
Definitions:
|
||||||
|
|
||||||
|
"Package" refers to the collection of files distributed by the
|
||||||
|
Copyright Holder, and derivatives of that collection of files
|
||||||
|
created through textual modification.
|
||||||
|
|
||||||
|
"Standard Version" refers to such a Package if it has not been
|
||||||
|
modified, or has been modified in accordance with the wishes
|
||||||
|
of the Copyright Holder as specified below.
|
||||||
|
|
||||||
|
"Copyright Holder" is whoever is named in the copyright or
|
||||||
|
copyrights for the package.
|
||||||
|
|
||||||
|
"You" is you, if you're thinking about copying or distributing
|
||||||
|
this Package.
|
||||||
|
|
||||||
|
"Distribution fee" is a fee you charge for providing a copy of this
|
||||||
|
Package to another party.
|
||||||
|
|
||||||
|
"Freely Available" means that no fee is charged for the right to use
|
||||||
|
the item, though there may be fees involved in handling the item.
|
||||||
|
|
||||||
|
1. You may make and give away verbatim copies of the source form of the
|
||||||
|
Standard Version of this Package without restriction, provided that you
|
||||||
|
duplicate all of the original copyright notices and associated disclaimers.
|
||||||
|
|
||||||
|
2. You may apply bug fixes, portability fixes and other modifications
|
||||||
|
derived from the Public Domain, or those made Freely Available, or from
|
||||||
|
the Copyright Holder. A Package modified in such a way shall still be
|
||||||
|
considered the Standard Version.
|
||||||
|
|
||||||
|
3. You may otherwise modify your copy of this Package in any way, provided
|
||||||
|
that you insert a prominent notice in each changed file stating how and
|
||||||
|
when you changed that file, and provided that you do at least ONE of the
|
||||||
|
following:
|
||||||
|
|
||||||
|
a) place your modifications in the Public Domain or otherwise make them
|
||||||
|
Freely Available, such as by posting said modifications to Usenet or
|
||||||
|
an equivalent medium, or placing the modifications on a major archive
|
||||||
|
site allowing unrestricted access to them, or by allowing the Copyright
|
||||||
|
Holder to include your modifications in the Standard Version of the
|
||||||
|
Package.
|
||||||
|
|
||||||
|
b) use the modified Package only within your corporation or organization.
|
||||||
|
|
||||||
|
c) rename any non-standard executables so the names do not conflict
|
||||||
|
with standard executables, which must also be provided, and provide
|
||||||
|
a separate manual page for each non-standard executable that clearly
|
||||||
|
documents how it differs from the Standard Version.
|
||||||
|
|
||||||
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
|
e) permit and encourge anyone who receives a copy of the modified Package
|
||||||
|
permission to make your modifications Freely Available in some specific
|
||||||
|
way.
|
||||||
|
|
||||||
|
4. You may distribute the programs of this Package in object code or
|
||||||
|
executable form, provided that you do at least ONE of the following:
|
||||||
|
|
||||||
|
a) distribute a Standard Version of the executables and library files,
|
||||||
|
together with instructions (in the manual page or equivalent) on where
|
||||||
|
to get the Standard Version.
|
||||||
|
|
||||||
|
b) accompany the distribution with the machine-readable source of
|
||||||
|
the Package with your modifications.
|
||||||
|
|
||||||
|
c) give non-standard executables non-standard names, and clearly
|
||||||
|
document the differences in manual pages (or equivalent), together
|
||||||
|
with instructions on where to get the Standard Version.
|
||||||
|
|
||||||
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
|
e) offer the machine-readable source of the Package, with your
|
||||||
|
modifications, by mail order.
|
||||||
|
|
||||||
|
5. You may charge a distribution fee for any distribution of this Package.
|
||||||
|
If you offer support for this Package, you may charge any fee you choose
|
||||||
|
for that support. You may not charge a license fee for the right to use
|
||||||
|
this Package itself. You may distribute this Package in aggregate with
|
||||||
|
other (possibly commercial and possibly nonfree) programs as part of a
|
||||||
|
larger (possibly commercial and possibly nonfree) software distribution,
|
||||||
|
and charge license fees for other parts of that software distribution,
|
||||||
|
provided that you do not advertise this Package as a product of your own.
|
||||||
|
If the Package includes an interpreter, You may embed this Package's
|
||||||
|
interpreter within an executable of yours (by linking); this shall be
|
||||||
|
construed as a mere form of aggregation, provided that the complete
|
||||||
|
Standard Version of the interpreter is so embedded.
|
||||||
|
|
||||||
|
6. The scripts and library files supplied as input to or produced as
|
||||||
|
output from the programs of this Package do not automatically fall
|
||||||
|
under the copyright of this Package, but belong to whoever generated
|
||||||
|
them, and may be sold commercially, and may be aggregated with this
|
||||||
|
Package. If such scripts or library files are aggregated with this
|
||||||
|
Package via the so-called "undump" or "unexec" methods of producing a
|
||||||
|
binary executable image, then distribution of such an image shall
|
||||||
|
neither be construed as a distribution of this Package nor shall it
|
||||||
|
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||||
|
not represent such an executable image as a Standard Version of this
|
||||||
|
Package.
|
||||||
|
|
||||||
|
7. C subroutines (or comparably compiled subroutines in other
|
||||||
|
languages) supplied by you and linked into this Package in order to
|
||||||
|
emulate subroutines and variables of the language defined by this
|
||||||
|
Package shall not be considered part of this Package, but are the
|
||||||
|
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||||
|
not change the language in any way that would cause it to fail the
|
||||||
|
regression tests for the language.
|
||||||
|
|
||||||
|
8. Aggregation of the Standard Version of the Package with a commercial
|
||||||
|
distribution is always permitted provided that the use of this Package is
|
||||||
|
embedded; that is, when no overt attempt is made to make this Package's
|
||||||
|
interfaces visible to the end user of the commercial distribution.
|
||||||
|
Such use shall not be construed as a distribution of this Package.
|
||||||
|
|
||||||
|
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
The End
|
||||||
12
3rd_party/libdisasm/NAMESPACE.TXT
vendored
Normal file
12
3rd_party/libdisasm/NAMESPACE.TXT
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
The rewritten libdisasm code uses the following namespaces:
|
||||||
|
|
||||||
|
|
||||||
|
Prefix Namespace
|
||||||
|
----------------------------------------------------
|
||||||
|
x86_ Global 'libdisasm' namespace
|
||||||
|
ia32_ Internal IA32 ISA namespace
|
||||||
|
ia64_ Internal IA64 ISA namespace
|
||||||
|
ix64_ Internal X86-64 ISA namespace
|
||||||
|
|
||||||
|
Note that the 64-bit ISAs are not yet supported/written.
|
||||||
2
3rd_party/libdisasm/README
vendored
Normal file
2
3rd_party/libdisasm/README
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
This is a cut-up version of libdisasm originally from the bastard project http://bastard.sourceforge.net/
|
||||||
|
|
||||||
43
3rd_party/libdisasm/TODO
vendored
Normal file
43
3rd_party/libdisasm/TODO
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
x86_format.c
|
||||||
|
------------
|
||||||
|
intel: jmpf -> jmp, callf -> call
|
||||||
|
att: jmpf -> ljmp, callf -> lcall
|
||||||
|
|
||||||
|
opcode table
|
||||||
|
------------
|
||||||
|
finish typing instructions
|
||||||
|
fix flag clear/set/toggle types
|
||||||
|
|
||||||
|
ix64 stuff
|
||||||
|
----------
|
||||||
|
document output file formats in web page
|
||||||
|
features doc: register aliases, implicit operands, stack mods,
|
||||||
|
ring0 flags, eflags, cpu model/isa
|
||||||
|
|
||||||
|
ia32_handle_* implementation
|
||||||
|
|
||||||
|
fix operand 0F C2
|
||||||
|
CMPPS
|
||||||
|
|
||||||
|
* sysenter, sysexit as CALL types -- preceded by MSR writes
|
||||||
|
* SYSENTER/SYSEXIT stack : overwrites SS, ESP
|
||||||
|
* stos, cmps, scas, movs, ins, outs, lods -> OP_PTR
|
||||||
|
* OP_SIZE in implicit operands
|
||||||
|
* use OP_SIZE to choose reg sizes!
|
||||||
|
|
||||||
|
DONE?? :
|
||||||
|
implicit operands: provide action ?
|
||||||
|
e.g. add/inc for stach, write, etc
|
||||||
|
replace table numbers in opcodes.dat with
|
||||||
|
#defines for table names
|
||||||
|
|
||||||
|
replace 0 with INSN_INVALID [or maybe FF for imnvalid and 00 for Not Applicable */
|
||||||
|
no wait that is only for prefix tables -- n/p
|
||||||
|
|
||||||
|
if ( prefx) only use if insn != invalid
|
||||||
|
|
||||||
|
these should cover all the wacky disasm exceptions
|
||||||
|
|
||||||
|
for the rep one we can chet, match only a 0x90
|
||||||
|
|
||||||
|
todo: privilege | ring
|
||||||
36
3rd_party/libdisasm/ia32_fixup.cpp
vendored
Normal file
36
3rd_party/libdisasm/ia32_fixup.cpp
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const char * mem_fixup[256] = {
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 00 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 08 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 10 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 18 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 20 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 28 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 30 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 38 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 40 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 48 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 50 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 58 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 60 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 68 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 70 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 78 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 80 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 88 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 90 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 98 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* A0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* A8 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* B0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* B8 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* C0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* C8 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* D0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* D8 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* E0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* E8 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* F0 */
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL /* F8 */
|
||||||
|
};
|
||||||
3206
3rd_party/libdisasm/ia32_opcode.dat
vendored
Normal file
3206
3rd_party/libdisasm/ia32_opcode.dat
vendored
Normal file
File diff suppressed because it is too large
Load Diff
49
3rd_party/libdisasm/libdisasm.def
vendored
Normal file
49
3rd_party/libdisasm/libdisasm.def
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
;libdisasm.def : Declares the module parameters
|
||||||
|
|
||||||
|
LIBRARY "libdisasm.dll"
|
||||||
|
DESCRIPTION "libdisasm exported functions"
|
||||||
|
EXPORTS
|
||||||
|
x86_addr_size @1
|
||||||
|
x86_cleanup @2
|
||||||
|
x86_disasm @3
|
||||||
|
x86_disasm_forward @4
|
||||||
|
x86_disasm_range @5
|
||||||
|
x86_endian @6
|
||||||
|
x86_format_header @7
|
||||||
|
x86_format_insn @8
|
||||||
|
x86_format_mnemonic @9
|
||||||
|
x86_format_operand @10
|
||||||
|
x86_fp_reg @11
|
||||||
|
x86_get_branch_target @12
|
||||||
|
x86_get_imm @13
|
||||||
|
x86_get_options @14
|
||||||
|
x86_get_raw_imm @15
|
||||||
|
x86_get_rel_offset @16
|
||||||
|
x86_imm_signsized @17
|
||||||
|
x86_imm_sized @18
|
||||||
|
x86_init @19
|
||||||
|
x86_insn_is_tagged @20
|
||||||
|
x86_insn_is_valid @21
|
||||||
|
x86_invariant_disasm @22
|
||||||
|
x86_ip_reg @23
|
||||||
|
x86_max_insn_size @24
|
||||||
|
x86_op_size @25
|
||||||
|
x86_operand_1st @26
|
||||||
|
x86_operand_2nd @27
|
||||||
|
x86_operand_3rd @28
|
||||||
|
x86_operand_count @29
|
||||||
|
x86_operand_foreach @30
|
||||||
|
x86_operand_new @31
|
||||||
|
x86_operand_size @32
|
||||||
|
x86_oplist_free @33
|
||||||
|
x86_reg_from_id @34
|
||||||
|
x86_report_error @35
|
||||||
|
x86_set_insn_addr @36
|
||||||
|
x86_set_insn_block @37
|
||||||
|
x86_set_insn_function @38
|
||||||
|
x86_set_insn_offset @39
|
||||||
|
x86_set_options @40
|
||||||
|
x86_set_reporter @41
|
||||||
|
x86_size_disasm @42
|
||||||
|
x86_sp_reg @43
|
||||||
|
x86_tag_insn @44
|
||||||
@ -12,7 +12,7 @@ IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
|||||||
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()
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ set(dcc_LIB_SOURCES
|
|||||||
src/control.cpp
|
src/control.cpp
|
||||||
src/dataflow.cpp
|
src/dataflow.cpp
|
||||||
src/disassem.cpp
|
src/disassem.cpp
|
||||||
|
src/DccFrontend.cpp
|
||||||
src/error.cpp
|
src/error.cpp
|
||||||
src/fixwild.cpp
|
src/fixwild.cpp
|
||||||
src/frontend.cpp
|
|
||||||
src/graph.cpp
|
src/graph.cpp
|
||||||
src/hlicode.cpp
|
src/hlicode.cpp
|
||||||
src/hltype.cpp
|
src/hltype.cpp
|
||||||
@ -77,6 +77,7 @@ set(dcc_LIB_SOURCES
|
|||||||
src/symtab.cpp
|
src/symtab.cpp
|
||||||
src/udm.cpp
|
src/udm.cpp
|
||||||
src/BasicBlock.cpp
|
src/BasicBlock.cpp
|
||||||
|
src/dcc_interface.cpp
|
||||||
)
|
)
|
||||||
set(dcc_SOURCES
|
set(dcc_SOURCES
|
||||||
src/dcc.cpp
|
src/dcc.cpp
|
||||||
@ -85,6 +86,7 @@ set(dcc_HEADERS
|
|||||||
include/ast.h
|
include/ast.h
|
||||||
include/bundle.h
|
include/bundle.h
|
||||||
include/BinaryImage.h
|
include/BinaryImage.h
|
||||||
|
include/DccFrontend.h
|
||||||
include/dcc.h
|
include/dcc.h
|
||||||
include/disassem.h
|
include/disassem.h
|
||||||
include/dosdcc.h
|
include/dosdcc.h
|
||||||
@ -113,18 +115,21 @@ set(dcc_HEADERS
|
|||||||
include/Procedure.h
|
include/Procedure.h
|
||||||
include/StackFrame.h
|
include/StackFrame.h
|
||||||
include/BasicBlock.h
|
include/BasicBlock.h
|
||||||
|
include/dcc_interface.h
|
||||||
|
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
||||||
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
||||||
|
|
||||||
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
||||||
|
qt5_use_modules(dcc_lib Core)
|
||||||
#cotire(dcc_lib)
|
#cotire(dcc_lib)
|
||||||
|
|
||||||
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 disasm_s ${REQ_LLVM_LIBRARIES} ncurses LLVMSupport)
|
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES} ncurses LLVMSupport)
|
||||||
qt5_use_modules(dcc_original Core)
|
qt5_use_modules(dcc_original Core)
|
||||||
|
#ADD_SUBDIRECTORY(gui)
|
||||||
if(dcc_build_tests)
|
if(dcc_build_tests)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
struct PROG /* Loaded program image parameters */
|
struct PROG /* Loaded program image parameters */
|
||||||
{
|
{
|
||||||
int16_t initCS;
|
int16_t initCS;
|
||||||
@ -8,15 +9,17 @@ struct PROG /* Loaded program image parameters */
|
|||||||
uint16_t initSP;
|
uint16_t initSP;
|
||||||
bool fCOM; /* Flag set if COM program (else EXE)*/
|
bool fCOM; /* Flag set if COM program (else EXE)*/
|
||||||
int cReloc; /* No. of relocation table entries */
|
int cReloc; /* No. of relocation table entries */
|
||||||
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; /* Memory bitmap ptr */
|
||||||
int cProcs; /* Number of procedures so far */
|
int cProcs; /* Number of procedures so far */
|
||||||
int offMain; /* The offset of the main() proc */
|
int offMain; /* The offset of the main() proc */
|
||||||
uint16_t segMain; /* The segment of the main() proc */
|
uint16_t segMain; /* The segment of the main() proc */
|
||||||
bool bSigs; /* True if signatures loaded */
|
bool bSigs; /* True if signatures loaded */
|
||||||
int cbImage; /* Length of image in bytes */
|
int cbImage; /* Length of image in bytes */
|
||||||
const uint8_t *image() const {return Imagez;}
|
|
||||||
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
||||||
int addressingMode;
|
int addressingMode;
|
||||||
|
public:
|
||||||
|
const uint8_t *image() const {return Imagez;}
|
||||||
|
void displayLoadInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
19
include/CallGraph.h
Normal file
19
include/CallGraph.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Procedure.h"
|
||||||
|
/* CALL GRAPH NODE */
|
||||||
|
struct CALL_GRAPH
|
||||||
|
{
|
||||||
|
ilFunction proc; /* Pointer to procedure in pProcList */
|
||||||
|
std::vector<CALL_GRAPH *> outEdges; /* array of out edges */
|
||||||
|
public:
|
||||||
|
void write();
|
||||||
|
CALL_GRAPH()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void writeNodeCallGraph(int indIdx);
|
||||||
|
bool insertCallGraph(ilFunction caller, ilFunction callee);
|
||||||
|
bool insertCallGraph(Function *caller, ilFunction callee);
|
||||||
|
void insertArc(ilFunction newProc);
|
||||||
|
};
|
||||||
|
//extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
||||||
17
include/DccFrontend.h
Normal file
17
include/DccFrontend.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QObject>
|
||||||
|
class Project;
|
||||||
|
class DccFrontend : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
void LoadImage();
|
||||||
|
void parse(Project &proj);
|
||||||
|
std::string m_fname;
|
||||||
|
public:
|
||||||
|
explicit DccFrontend(QObject *parent = 0);
|
||||||
|
bool FrontEnd(); /* frontend.c */
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
};
|
||||||
@ -9,6 +9,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@ -26,7 +27,7 @@ extern bundle cCode; /* Output C procedure's declaration and code */
|
|||||||
|
|
||||||
/**** Global variables ****/
|
/**** Global variables ****/
|
||||||
|
|
||||||
extern std::string asm1_name, asm2_name; /* Assembler output filenames */
|
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
|
|
||||||
typedef struct { /* Command line option flags */
|
typedef struct { /* Command line option flags */
|
||||||
unsigned verbose : 1;
|
unsigned verbose : 1;
|
||||||
@ -37,7 +38,7 @@ typedef struct { /* Command line option flags */
|
|||||||
unsigned Stats : 1;
|
unsigned Stats : 1;
|
||||||
unsigned Interact : 1; /* Interactive mode */
|
unsigned Interact : 1; /* Interactive mode */
|
||||||
unsigned Calls : 1; /* Follow register indirect calls */
|
unsigned Calls : 1; /* Follow register indirect calls */
|
||||||
std::string filename; /* The input filename */
|
QString filename; /* The input filename */
|
||||||
} OPTION;
|
} OPTION;
|
||||||
|
|
||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
@ -71,22 +72,11 @@ extern STATS stats; /* Icode statistics */
|
|||||||
|
|
||||||
|
|
||||||
/**** Global function prototypes ****/
|
/**** Global function prototypes ****/
|
||||||
class DccFrontend
|
|
||||||
{
|
|
||||||
void LoadImage(Project &proj);
|
|
||||||
void parse(Project &proj);
|
|
||||||
std::string m_fname;
|
|
||||||
public:
|
|
||||||
DccFrontend(const std::string &fname) : m_fname(fname)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
bool FrontEnd(); /* frontend.c */
|
|
||||||
};
|
|
||||||
|
|
||||||
void udm(void); /* udm.c */
|
void udm(void); /* udm.c */
|
||||||
void freeCFG(BB * cfg); /* graph.c */
|
void freeCFG(BB * cfg); /* graph.c */
|
||||||
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
|
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
|
||||||
void BackEnd(const std::string &filename, CALL_GRAPH *); /* backend.c */
|
void BackEnd(CALL_GRAPH *); /* backend.c */
|
||||||
extern char *cChar(uint8_t c); /* backend.c */
|
extern char *cChar(uint8_t c); /* backend.c */
|
||||||
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
|
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
|
||||||
void parse (CALL_GRAPH * *); /* parser.c */
|
void parse (CALL_GRAPH * *); /* parser.c */
|
||||||
|
|||||||
25
include/dcc_interface.h
Normal file
25
include/dcc_interface.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Procedure.h"
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <llvm/ADT/ilist.h>
|
||||||
|
|
||||||
|
class IXmlTarget;
|
||||||
|
|
||||||
|
struct IDcc {
|
||||||
|
static IDcc *get();
|
||||||
|
virtual void BaseInit()=0;
|
||||||
|
virtual void Init(QObject *tgt)=0;
|
||||||
|
virtual lFunction::iterator GetFirstFuncHandle()=0;
|
||||||
|
virtual lFunction::iterator GetCurFuncHandle()=0;
|
||||||
|
virtual void analysis_Once()=0;
|
||||||
|
virtual void load(QString name)=0; // load and preprocess -> find entry point
|
||||||
|
virtual void prtout_asm(IXmlTarget *,int level=0)=0;
|
||||||
|
virtual void prtout_cpp(IXmlTarget *,int level=0)=0;
|
||||||
|
virtual size_t getFuncCount()=0;
|
||||||
|
virtual const lFunction &validFunctions() const =0;
|
||||||
|
virtual void SetCurFunc_by_Name(QString )=0;
|
||||||
|
virtual QDir installDir()=0;
|
||||||
|
virtual QDir dataDir(QString kind)=0;
|
||||||
|
};
|
||||||
@ -8,22 +8,25 @@
|
|||||||
#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>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <QtCore/QString>
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
|
class QString;
|
||||||
class SourceMachine;
|
class SourceMachine;
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
class IProject
|
class IProject
|
||||||
{
|
{
|
||||||
virtual PROG *binary()=0;
|
virtual PROG *binary()=0;
|
||||||
virtual const std::string & project_name() const =0;
|
virtual const QString & project_name() const =0;
|
||||||
virtual const std::string & binary_path() const =0;
|
virtual const QString & binary_path() const =0;
|
||||||
};
|
};
|
||||||
class Project : public IProject
|
class Project : public IProject
|
||||||
{
|
{
|
||||||
static Project *s_instance;
|
static Project *s_instance;
|
||||||
std::string m_fname;
|
QString m_fname;
|
||||||
std::string m_project_name;
|
QString m_project_name;
|
||||||
|
QString m_output_path;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
typedef llvm::iplist<Function> FunctionListType;
|
||||||
@ -41,9 +44,12 @@ typedef FunctionListType lFunction;
|
|||||||
Project(); // default constructor,
|
Project(); // default constructor,
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void create(const std::string & a);
|
void create(const QString &a);
|
||||||
const std::string &project_name() const {return m_project_name;}
|
bool load();
|
||||||
const std::string &binary_path() const {return m_fname;}
|
const QString &output_path() const {return m_output_path;}
|
||||||
|
const QString &project_name() const {return m_project_name;}
|
||||||
|
const QString &binary_path() const {return m_fname;}
|
||||||
|
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 std::string &name);
|
||||||
@ -60,6 +66,7 @@ public:
|
|||||||
PROG * binary() {return &prog;}
|
PROG * binary() {return &prog;}
|
||||||
SourceMachine *machine();
|
SourceMachine *machine();
|
||||||
|
|
||||||
|
const FunctionListType &functions() const { return pProcList; }
|
||||||
protected:
|
protected:
|
||||||
void initialize();
|
void initialize();
|
||||||
void writeGlobSymTable();
|
void writeGlobSymTable();
|
||||||
|
|||||||
BIN
prototypes/dcclibs.dat
Normal file
BIN
prototypes/dcclibs.dat
Normal file
Binary file not shown.
BIN
sigs/dccb2s.sig
Normal file
BIN
sigs/dccb2s.sig
Normal file
Binary file not shown.
@ -28,11 +28,11 @@ BB *BB::Create(const rCODE &r,eBBKind _nodeType, Function *parent)
|
|||||||
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
||||||
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
||||||
pnewBB->instructions = r;
|
pnewBB->instructions = r;
|
||||||
int addr = pnewBB->begin()->loc_ip;
|
|
||||||
/* Mark the basic block to which the icodes belong to, but only for
|
/* Mark the basic block to which the icodes belong to, but only for
|
||||||
* real code basic blocks (ie. not interval bbs) */
|
* real code basic blocks (ie. not interval bbs) */
|
||||||
if(parent)
|
if(parent)
|
||||||
{
|
{
|
||||||
|
int addr = pnewBB->begin()->loc_ip;
|
||||||
//setInBB should automatically handle if our range is empty
|
//setInBB should automatically handle if our range is empty
|
||||||
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
||||||
|
|
||||||
@ -40,10 +40,10 @@ BB *BB::Create(const rCODE &r,eBBKind _nodeType, Function *parent)
|
|||||||
parent->m_ip_to_bb[addr] = pnewBB;
|
parent->m_ip_to_bb[addr] = pnewBB;
|
||||||
parent->m_actual_cfg.push_back(pnewBB);
|
parent->m_actual_cfg.push_back(pnewBB);
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
}
|
|
||||||
|
|
||||||
if ( r.begin() != parent->Icode.end() ) /* Only for code BB's */
|
if ( r.begin() != parent->Icode.end() ) /* Only for code BB's */
|
||||||
stats.numBBbef++;
|
stats.numBBbef++;
|
||||||
|
}
|
||||||
return pnewBB;
|
return pnewBB;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ void BB::displayDfs()
|
|||||||
dfsFirstNum, dfsLastNum,
|
dfsFirstNum, dfsLastNum,
|
||||||
immedDom == MAX ? -1 : immedDom);
|
immedDom == MAX ? -1 : immedDom);
|
||||||
printf("loopType = %s, loopHead = %d, latchNode = %d, follow = %d\n",
|
printf("loopType = %s, loopHead = %d, latchNode = %d, follow = %d\n",
|
||||||
s_loopType[loopType],
|
s_loopType[(int)loopType],
|
||||||
loopHead == MAX ? -1 : loopHead,
|
loopHead == MAX ? -1 : loopHead,
|
||||||
latchNode == MAX ? -1 : latchNode,
|
latchNode == MAX ? -1 : latchNode,
|
||||||
loopFollow == MAX ? -1 : loopFollow);
|
loopFollow == MAX ? -1 : loopFollow);
|
||||||
@ -136,12 +136,14 @@ void BB::displayDfs()
|
|||||||
*/
|
*/
|
||||||
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, bool &repCond)
|
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, bool &repCond)
|
||||||
{
|
{
|
||||||
|
if(loopType == eNodeHeaderType::NO_TYPE)
|
||||||
|
return nullptr;
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ICODE* picode;
|
ICODE* picode;
|
||||||
switch (loopType)
|
switch (loopType)
|
||||||
{
|
{
|
||||||
case WHILE_TYPE:
|
case eNodeHeaderType::WHILE_TYPE:
|
||||||
picode = &this->back();
|
picode = &this->back();
|
||||||
|
|
||||||
/* Check for error in while condition */
|
/* Check for error in while condition */
|
||||||
@ -169,15 +171,16 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REPEAT_TYPE:
|
case eNodeHeaderType::REPEAT_TYPE:
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"do {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"do {\n";
|
||||||
picode = &latch->back();
|
picode = &latch->back();
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENDLESS_TYPE:
|
case eNodeHeaderType::ENDLESS_TYPE:
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
||||||
picode = &latch->back();
|
picode = &latch->back();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cCode.appendCode(ostr.str());
|
cCode.appendCode(ostr.str());
|
||||||
stats.numHLIcode += 1;
|
stats.numHLIcode += 1;
|
||||||
@ -209,10 +212,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
/* Check for start of loop */
|
/* Check for start of loop */
|
||||||
repCond = false;
|
repCond = false;
|
||||||
latch = nullptr;
|
latch = nullptr;
|
||||||
if (loopType)
|
|
||||||
{
|
|
||||||
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
|
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the code for this basic block */
|
/* Write the code for this basic block */
|
||||||
if (repCond == false)
|
if (repCond == false)
|
||||||
@ -227,12 +227,12 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check type of loop/node and process code */
|
/* Check type of loop/node and process code */
|
||||||
if ( loopType ) /* there is a loop */
|
if ( loopType!=eNodeHeaderType::NO_TYPE ) /* there is a loop */
|
||||||
{
|
{
|
||||||
assert(latch);
|
assert(latch);
|
||||||
if (this != latch) /* loop is over several bbs */
|
if (this != latch) /* loop is over several bbs */
|
||||||
{
|
{
|
||||||
if (loopType == WHILE_TYPE)
|
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
||||||
{
|
{
|
||||||
succ = edges[THEN].BBptr;
|
succ = edges[THEN].BBptr;
|
||||||
if (succ->dfsLastNum == loopFollow)
|
if (succ->dfsLastNum == loopFollow)
|
||||||
@ -248,7 +248,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
|
|
||||||
/* Loop epilogue: generate the loop trailer */
|
/* Loop epilogue: generate the loop trailer */
|
||||||
indLevel--;
|
indLevel--;
|
||||||
if (loopType == WHILE_TYPE)
|
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
/* Check if there is need to repeat other statements involved
|
/* Check if there is need to repeat other statements involved
|
||||||
@ -260,9 +260,9 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
||||||
cCode.appendCode(ostr.str());
|
cCode.appendCode(ostr.str());
|
||||||
}
|
}
|
||||||
else if (loopType == 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 == REPEAT_TYPE)
|
else if (loopType == eNodeHeaderType::REPEAT_TYPE)
|
||||||
{
|
{
|
||||||
string e = "//*failed*//";
|
string e = "//*failed*//";
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
|
|||||||
410
src/DccFrontend.cpp
Normal file
410
src/DccFrontend.cpp
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <cstdio>
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "DccFrontend.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "disassem.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Loader
|
||||||
|
{
|
||||||
|
bool loadIntoProject(IProject *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSP { /* PSP structure */
|
||||||
|
uint16_t int20h; /* interrupt 20h */
|
||||||
|
uint16_t eof; /* segment, end of allocation block */
|
||||||
|
uint8_t res1; /* reserved */
|
||||||
|
uint8_t dosDisp[5]; /* far call to DOS function dispatcher */
|
||||||
|
uint8_t int22h[4]; /* vector for terminate routine */
|
||||||
|
uint8_t int23h[4]; /* vector for ctrl+break routine */
|
||||||
|
uint8_t int24h[4]; /* vector for error routine */
|
||||||
|
uint8_t res2[22]; /* reserved */
|
||||||
|
uint16_t segEnv; /* segment address of environment block */
|
||||||
|
uint8_t res3[34]; /* reserved */
|
||||||
|
uint8_t int21h[6]; /* opcode for int21h and far return */
|
||||||
|
uint8_t res4[6]; /* reserved */
|
||||||
|
uint8_t fcb1[16]; /* default file control block 1 */
|
||||||
|
uint8_t fcb2[16]; /* default file control block 2 */
|
||||||
|
uint8_t res5[4]; /* reserved */
|
||||||
|
uint8_t cmdTail[0x80]; /* command tail and disk transfer area */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct MZHeader { /* EXE file header */
|
||||||
|
uint8_t sigLo; /* .EXE signature: 0x4D 0x5A */
|
||||||
|
uint8_t sigHi;
|
||||||
|
uint16_t lastPageSize; /* Size of the last page */
|
||||||
|
uint16_t numPages; /* Number of pages in the file */
|
||||||
|
uint16_t numReloc; /* Number of relocation items */
|
||||||
|
uint16_t numParaHeader; /* # of paragraphs in the header */
|
||||||
|
uint16_t minAlloc; /* Minimum number of paragraphs */
|
||||||
|
uint16_t maxAlloc; /* Maximum number of paragraphs */
|
||||||
|
uint16_t initSS; /* Segment displacement of stack */
|
||||||
|
uint16_t initSP; /* Contents of SP at entry */
|
||||||
|
uint16_t checkSum; /* Complemented checksum */
|
||||||
|
uint16_t initIP; /* Contents of IP at entry */
|
||||||
|
uint16_t initCS; /* Segment displacement of code */
|
||||||
|
uint16_t relocTabOffset; /* Relocation table offset */
|
||||||
|
uint16_t overlayNum; /* Overlay number */
|
||||||
|
} header;
|
||||||
|
|
||||||
|
#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */
|
||||||
|
|
||||||
|
//static void LoadImage(char *filename);
|
||||||
|
static void displayMemMap(void);
|
||||||
|
/****************************************************************************
|
||||||
|
* displayLoadInfo - Displays low level loader type info.
|
||||||
|
***************************************************************************/
|
||||||
|
void PROG::displayLoadInfo(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("File type is %s\n", (fCOM)?"COM":"EXE");
|
||||||
|
if (! fCOM) {
|
||||||
|
printf("Signature = %02X%02X\n", header.sigLo, header.sigHi);
|
||||||
|
printf("File size %% 512 = %04X\n", LH(&header.lastPageSize));
|
||||||
|
printf("File size / 512 = %04X pages\n", LH(&header.numPages));
|
||||||
|
printf("# relocation items = %04X\n", LH(&header.numReloc));
|
||||||
|
printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader));
|
||||||
|
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
|
||||||
|
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
|
||||||
|
}
|
||||||
|
printf("Load image size = %04" PRIiPTR "\n", cbImage - sizeof(PSP));
|
||||||
|
printf("Initial SS:SP = %04X:%04X\n", initSS, initSP);
|
||||||
|
printf("Initial CS:IP = %04X:%04X\n", initCS, initIP);
|
||||||
|
|
||||||
|
if (option.VeryVerbose && cReloc)
|
||||||
|
{
|
||||||
|
printf("\nRelocation Table\n");
|
||||||
|
for (i = 0; i < cReloc; i++)
|
||||||
|
{
|
||||||
|
printf("%06X -> [%04X]\n", relocTable[i],LH(image() + relocTable[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* fill - Fills line for displayMemMap()
|
||||||
|
****************************************************************************/
|
||||||
|
static void fill(int ip, char *bf)
|
||||||
|
{
|
||||||
|
PROG &prog(Project::get()->prog);
|
||||||
|
static uint8_t type[4] = {'.', 'd', 'c', 'x'};
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++, ip++)
|
||||||
|
{
|
||||||
|
*bf++ = ' ';
|
||||||
|
*bf++ = (ip < prog.cbImage)? type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' ';
|
||||||
|
}
|
||||||
|
*bf = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* displayMemMap - Displays the memory bitmap
|
||||||
|
****************************************************************************/
|
||||||
|
static void displayMemMap(void)
|
||||||
|
{
|
||||||
|
PROG &prog(Project::get()->prog);
|
||||||
|
|
||||||
|
char c, b1[33], b2[33], b3[33];
|
||||||
|
uint8_t i;
|
||||||
|
int ip = 0;
|
||||||
|
|
||||||
|
printf("\nMemory Map\n");
|
||||||
|
while (ip < prog.cbImage)
|
||||||
|
{
|
||||||
|
fill(ip, b1);
|
||||||
|
printf("%06X %s\n", ip, b1);
|
||||||
|
ip += 16;
|
||||||
|
for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
|
||||||
|
; /* Check if all same */
|
||||||
|
if (i > 32)
|
||||||
|
{
|
||||||
|
fill(ip, b2); /* Skip until next two are not same */
|
||||||
|
fill(ip+16, b3);
|
||||||
|
if (! (strcmp(b1, b2) || strcmp(b1, b3)))
|
||||||
|
{
|
||||||
|
printf(" :\n");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ip += 16;
|
||||||
|
fill(ip+16, b1);
|
||||||
|
} while (! strcmp(b1, b2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
DccFrontend::DccFrontend(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
|
||||||
|
* rewritter, and displays any useful information.
|
||||||
|
****************************************************************************/
|
||||||
|
bool DccFrontend::FrontEnd ()
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Do depth first flow analysis building call graph and procedure list,
|
||||||
|
* and attaching the I-code to each procedure */
|
||||||
|
parse (*Project::get());
|
||||||
|
|
||||||
|
if (option.asm1)
|
||||||
|
{
|
||||||
|
std::cout << "dcc: writing assembler file "<<asm1_name.toStdString()<<'\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search through code looking for impure references and flag them */
|
||||||
|
Disassembler ds(1);
|
||||||
|
for(Function &f : Project::get()->pProcList)
|
||||||
|
{
|
||||||
|
f.markImpure();
|
||||||
|
if (option.asm1)
|
||||||
|
{
|
||||||
|
ds.disassem(&f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (option.Interact)
|
||||||
|
{
|
||||||
|
interactDis(&Project::get()->pProcList.front(), 0); /* Interactive disassembler */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Converts jump target addresses to icode offsets */
|
||||||
|
for(Function &f : Project::get()->pProcList)
|
||||||
|
{
|
||||||
|
f.bindIcodeOff();
|
||||||
|
}
|
||||||
|
/* Print memory bitmap */
|
||||||
|
if (option.Map)
|
||||||
|
displayMemMap();
|
||||||
|
return(true); // we no longer own proj !
|
||||||
|
}
|
||||||
|
struct DosLoader {
|
||||||
|
protected:
|
||||||
|
void prepareImage(PROG &prog,size_t sz,QFile &fp) {
|
||||||
|
/* Allocate a block of memory for the program. */
|
||||||
|
prog.cbImage = sz + sizeof(PSP);
|
||||||
|
prog.Imagez = new uint8_t [prog.cbImage];
|
||||||
|
prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */
|
||||||
|
prog.Imagez[1] = 0x20; /* for termination checking */
|
||||||
|
/* Read in the image past where a PSP would go */
|
||||||
|
if (sz != fp.read((char *)prog.Imagez + sizeof(PSP),sz))
|
||||||
|
fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct ComLoader : public DosLoader {
|
||||||
|
bool canLoad(QFile &fp) {
|
||||||
|
fp.seek(0);
|
||||||
|
char sig[2];
|
||||||
|
if(2==fp.read(sig,2)) {
|
||||||
|
return not (sig[0] == 0x4D && sig[1] == 0x5A);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool load(PROG &prog,QFile &fp) {
|
||||||
|
/* 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 = 0x100;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct ExeLoader : public DosLoader {
|
||||||
|
bool canLoad(QFile &fp) {
|
||||||
|
if(fp.size()<sizeof(header))
|
||||||
|
return false;
|
||||||
|
MZHeader tmp_header;
|
||||||
|
fp.seek(0);
|
||||||
|
fp.read((char *)&tmp_header, sizeof(header));
|
||||||
|
if(not (tmp_header.sigLo == 0x4D && tmp_header.sigHi == 0x5A))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* This is a typical DOS kludge! */
|
||||||
|
if (LH(&header.relocTabOffset) == 0x40)
|
||||||
|
{
|
||||||
|
qDebug() << "Don't understand new EXE format";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool load(PROG &prog,QFile &fp) {
|
||||||
|
/* Read rest of header */
|
||||||
|
fp.seek(0);
|
||||||
|
if (fp.read((char *)&header, sizeof(header)) != sizeof(header))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Calculate the load module size.
|
||||||
|
* This is the number of pages in the file
|
||||||
|
* less the length of the header and reloc table
|
||||||
|
* less the number of bytes unused on last page
|
||||||
|
*/
|
||||||
|
uint32_t cb = (uint32_t)LH(&header.numPages) * 512 - (uint32_t)LH(&header.numParaHeader) * 16;
|
||||||
|
if (header.lastPageSize)
|
||||||
|
{
|
||||||
|
cb -= 512 - LH(&header.lastPageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We quietly ignore minAlloc and maxAlloc since for our
|
||||||
|
* purposes it doesn't really matter where in real memory
|
||||||
|
* the program would end up. EXE programs can't really rely on
|
||||||
|
* their load location so setting the PSP segment to 0 is fine.
|
||||||
|
* Certainly programs that prod around in DOS or BIOS are going
|
||||||
|
* to have to load DS from a constant so it'll be pretty
|
||||||
|
* obvious.
|
||||||
|
*/
|
||||||
|
prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
|
||||||
|
prog.initIP = (int16_t)LH(&header.initIP);
|
||||||
|
prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
|
||||||
|
prog.initSP = (int16_t)LH(&header.initSP);
|
||||||
|
prog.cReloc = (int16_t)LH(&header.numReloc);
|
||||||
|
|
||||||
|
/* Allocate the relocation table */
|
||||||
|
if (prog.cReloc)
|
||||||
|
{
|
||||||
|
prog.relocTable.resize(prog.cReloc);
|
||||||
|
fp.seek(LH(&header.relocTabOffset));
|
||||||
|
|
||||||
|
/* Read in seg:offset pairs and convert to Image ptrs */
|
||||||
|
uint8_t buf[4];
|
||||||
|
for (int i = 0; i < prog.cReloc; i++)
|
||||||
|
{
|
||||||
|
fp.read((char *)buf,4);
|
||||||
|
prog.relocTable[i] = LH(buf) + (((int)LH(buf+2) + EXE_RELOCATION)<<4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Seek to start of image */
|
||||||
|
uint32_t start_of_image= LH(&header.numParaHeader) * 16;
|
||||||
|
fp.seek(start_of_image);
|
||||||
|
/* Allocate a block of memory for the program. */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Relocate segment constants */
|
||||||
|
for(uint32_t v : prog.relocTable) {
|
||||||
|
uint8_t *p = &prog.Imagez[v];
|
||||||
|
uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION;
|
||||||
|
*p++ = (uint8_t)(w & 0x00FF);
|
||||||
|
*p = (uint8_t)((w & 0xFF00) >> 8);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/*****************************************************************************
|
||||||
|
* LoadImage
|
||||||
|
****************************************************************************/
|
||||||
|
bool Project::load()
|
||||||
|
{
|
||||||
|
// addTask(loaderSelection,PreCond(BinaryImage))
|
||||||
|
// addTask(applyLoader,PreCond(Loader))
|
||||||
|
const char *fname = binary_path().toLocal8Bit().data();
|
||||||
|
QFile finfo(binary_path());
|
||||||
|
/* Open the input file */
|
||||||
|
if(!finfo.open(QFile::ReadOnly)) {
|
||||||
|
fatalError(CANNOT_OPEN, fname);
|
||||||
|
}
|
||||||
|
/* Read in first 2 bytes to check EXE signature */
|
||||||
|
if (finfo.size()<=2)
|
||||||
|
{
|
||||||
|
fatalError(CANNOT_READ, fname);
|
||||||
|
}
|
||||||
|
ComLoader com_loader;
|
||||||
|
ExeLoader exe_loader;
|
||||||
|
if(exe_loader.canLoad(finfo)) {
|
||||||
|
prog.fCOM = false;
|
||||||
|
return exe_loader.load(prog,finfo);
|
||||||
|
}
|
||||||
|
if(com_loader.canLoad(finfo)) {
|
||||||
|
prog.fCOM = true;
|
||||||
|
return com_loader.load(prog,finfo);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t SynthLab;
|
||||||
|
/* Parses the program, builds the call graph, and returns the list of
|
||||||
|
* procedures found */
|
||||||
|
void DccFrontend::parse(Project &proj)
|
||||||
|
{
|
||||||
|
PROG &prog(proj.prog);
|
||||||
|
STATE state;
|
||||||
|
|
||||||
|
/* Set initial state */
|
||||||
|
state.setState(rES, 0); /* PSP segment */
|
||||||
|
state.setState(rDS, 0);
|
||||||
|
state.setState(rCS, prog.initCS);
|
||||||
|
state.setState(rSS, prog.initSS);
|
||||||
|
state.setState(rSP, prog.initSP);
|
||||||
|
state.IP = ((uint32_t)prog.initCS << 4) + prog.initIP;
|
||||||
|
SynthLab = SYNTHESIZED_MIN;
|
||||||
|
|
||||||
|
/* Check for special settings of initial state, based on idioms of the
|
||||||
|
startup code */
|
||||||
|
state.checkStartup();
|
||||||
|
Function *start_proc;
|
||||||
|
/* Make a struct for the initial procedure */
|
||||||
|
if (prog.offMain != -1)
|
||||||
|
{
|
||||||
|
start_proc = proj.createFunction(0,"main");
|
||||||
|
start_proc->retVal.loc = REG_FRAME;
|
||||||
|
start_proc->retVal.type = TYPE_WORD_SIGN;
|
||||||
|
start_proc->retVal.id.regi = rAX;
|
||||||
|
/* We know where main() is. Start the flow of control from there */
|
||||||
|
start_proc->procEntry = prog.offMain;
|
||||||
|
/* In medium and large models, the segment of main may (will?) not be
|
||||||
|
the same as the initial CS segment (of the startup code) */
|
||||||
|
state.setState(rCS, prog.segMain);
|
||||||
|
state.IP = prog.offMain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_proc = proj.createFunction(0,"start");
|
||||||
|
/* Create initial procedure at program start address */
|
||||||
|
start_proc->procEntry = (uint32_t)state.IP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The state info is for the first procedure */
|
||||||
|
start_proc->state = state;
|
||||||
|
|
||||||
|
/* Set up call graph initial node */
|
||||||
|
proj.callGraph = new CALL_GRAPH;
|
||||||
|
proj.callGraph->proc = start_proc;
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
SetupLibCheck();
|
||||||
|
//BUG: proj and g_proj are 'live' at this point !
|
||||||
|
|
||||||
|
/* Recursively build entire procedure list */
|
||||||
|
start_proc->FollowCtrl(proj.callGraph, &state);
|
||||||
|
|
||||||
|
/* This proc needs to be called to clean things up from SetupLibCheck() */
|
||||||
|
CleanupLibCheck();
|
||||||
|
}
|
||||||
@ -4,6 +4,8 @@
|
|||||||
* 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 <QFile>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
@ -167,13 +169,13 @@ void Project::writeGlobSymTable()
|
|||||||
|
|
||||||
/* 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 char *fileName)
|
static void writeHeader (std::ostream &_ios, const std::string &fileName)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
/* Write header information */
|
/* Write header information */
|
||||||
cCode.init();
|
cCode.init();
|
||||||
cCode.appendDecl( "/*\n");
|
cCode.appendDecl( "/*\n");
|
||||||
cCode.appendDecl( " * Input file\t: %s\n", fileName);
|
cCode.appendDecl( " * Input file\t: %s\n", fileName.c_str());
|
||||||
cCode.appendDecl( " * File type\t: %s\n", (prog.fCOM)?"COM":"EXE");
|
cCode.appendDecl( " * File type\t: %s\n", (prog.fCOM)?"COM":"EXE");
|
||||||
cCode.appendDecl( " */\n\n#include \"dcc.h\"\n\n");
|
cCode.appendDecl( " */\n\n#include \"dcc.h\"\n\n");
|
||||||
|
|
||||||
@ -341,22 +343,21 @@ 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 (const std::string &fileName, CALL_GRAPH * pcallGraph)
|
void BackEnd(CALL_GRAPH * pcallGraph)
|
||||||
{
|
{
|
||||||
std::ofstream fs; /* Output C file */
|
std::ofstream fs; /* Output C file */
|
||||||
|
|
||||||
/* Get output file name */
|
/* Get output file name */
|
||||||
std::string outNam(fileName);
|
QString outNam(Project::get()->output_name("b")); /* b for beta */
|
||||||
outNam = outNam.substr(0,outNam.rfind("."))+".b"; /* b for beta */
|
|
||||||
|
|
||||||
/* Open output file */
|
/* Open output file */
|
||||||
fs.open(outNam);
|
fs.open(outNam.toStdString());
|
||||||
if(!fs.is_open())
|
if(!fs.is_open())
|
||||||
fatalError (CANNOT_OPEN, outNam.c_str());
|
fatalError (CANNOT_OPEN, outNam.toStdString().c_str());
|
||||||
printf ("dcc: Writing C beta file %s\n", outNam.c_str());
|
std::cout<<"dcc: Writing C beta file "<<outNam.toStdString()<<"\n";
|
||||||
|
|
||||||
/* Header information */
|
/* Header information */
|
||||||
writeHeader (fs, option.filename.c_str());
|
writeHeader (fs, option.filename.toStdString());
|
||||||
|
|
||||||
/* Initialize total Icode instructions statistics */
|
/* Initialize total Icode instructions statistics */
|
||||||
stats.totalLL = 0;
|
stats.totalLL = 0;
|
||||||
@ -367,7 +368,7 @@ void BackEnd (const std::string &fileName, CALL_GRAPH * pcallGraph)
|
|||||||
|
|
||||||
/* Close output file */
|
/* Close output file */
|
||||||
fs.close();
|
fs.close();
|
||||||
printf ("dcc: Finished writing C beta file\n");
|
std::cout << "dcc: Finished writing C beta file\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,17 +5,16 @@
|
|||||||
* (C) Mike van Emmerik
|
* (C) Mike van Emmerik
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifdef __BORLAND__
|
|
||||||
#include <mem.h>
|
|
||||||
#else
|
|
||||||
#include <memory.h>
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
|
#include "dcc_interface.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define NIL -1 /* Used like NULL, but 0 is valid */
|
#define NIL -1 /* Used like NULL, but 0 is valid */
|
||||||
|
|
||||||
@ -300,10 +299,11 @@ void SetupLibCheck(void)
|
|||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
uint16_t w, len;
|
uint16_t w, len;
|
||||||
int i;
|
int i;
|
||||||
|
IDcc *dcc = IDcc::get();
|
||||||
if ((g_file = fopen(sSigName, "rb")) == nullptr)
|
QString fpath = dcc->dataDir("sigs").absoluteFilePath(sSigName);
|
||||||
|
if ((g_file = fopen(qPrintable(fpath), "rb")) == nullptr)
|
||||||
{
|
{
|
||||||
printf("Warning: cannot open signature file %s\n", sSigName);
|
printf("Warning: cannot open signature file %s\n", qPrintable(fpath));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +638,6 @@ void STATE::checkStartup()
|
|||||||
char chModel = 'x';
|
char chModel = 'x';
|
||||||
char chVendor = 'x';
|
char chVendor = 'x';
|
||||||
char chVersion = 'x';
|
char chVersion = 'x';
|
||||||
char *pPath;
|
|
||||||
char temp[4];
|
char temp[4];
|
||||||
|
|
||||||
startOff = ((uint32_t)prog.initCS << 4) + prog.initIP;
|
startOff = ((uint32_t)prog.initCS << 4) + prog.initIP;
|
||||||
@ -829,21 +828,6 @@ void STATE::checkStartup()
|
|||||||
|
|
||||||
gotVendor:
|
gotVendor:
|
||||||
|
|
||||||
/* Use the DCC environment variable to set where the .sig files will
|
|
||||||
be found. Otherwise, assume current directory */
|
|
||||||
pPath = getenv("DCC");
|
|
||||||
if (pPath)
|
|
||||||
{
|
|
||||||
strcpy(sSigName, pPath); /* Use path given */
|
|
||||||
if (sSigName[strlen(sSigName)-1] != '/')
|
|
||||||
{
|
|
||||||
strcat(sSigName, "/"); /* Append a slash if necessary */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(sSigName, "./"); /* Current directory */
|
|
||||||
}
|
|
||||||
strcat(sSigName, "dcc");
|
strcat(sSigName, "dcc");
|
||||||
temp[1] = '\0';
|
temp[1] = '\0';
|
||||||
temp[0] = chVendor;
|
temp[0] = chVendor;
|
||||||
@ -866,45 +850,30 @@ gotVendor:
|
|||||||
*/
|
*/
|
||||||
void readProtoFile(void)
|
void readProtoFile(void)
|
||||||
{
|
{
|
||||||
|
IDcc *dcc = IDcc::get();
|
||||||
|
QString szProFName = dcc->dataDir("prototypes").absoluteFilePath(DCCLIBS); /* Full name of dclibs.lst */
|
||||||
|
|
||||||
FILE *fProto;
|
FILE *fProto;
|
||||||
char *pPath; /* Point to the environment string */
|
char *pPath; /* Point to the environment string */
|
||||||
char szProFName[81]; /* Full name of dclibs.lst */
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Use the DCC environment variable to set where the dcclibs.lst file will
|
if ((fProto = fopen(qPrintable(szProFName), "rb")) == nullptr)
|
||||||
be found. Otherwise, assume current directory */
|
|
||||||
pPath = getenv("DCC");
|
|
||||||
if (pPath)
|
|
||||||
{
|
{
|
||||||
strcpy(szProFName, pPath); /* Use path given */
|
printf("Warning: cannot open library prototype data file %s\n", qPrintable(szProFName));
|
||||||
if (szProFName[strlen(szProFName)-1] != '/')
|
|
||||||
{
|
|
||||||
strcat(szProFName, "/"); /* Append a slash if necessary */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(szProFName, "./"); /* Current directory */
|
|
||||||
}
|
|
||||||
strcat(szProFName, DCCLIBS);
|
|
||||||
|
|
||||||
if ((fProto = fopen(szProFName, "rb")) == nullptr)
|
|
||||||
{
|
|
||||||
printf("Warning: cannot open library prototype data file %s\n", szProFName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grab(4, fProto);
|
grab(4, fProto);
|
||||||
if (strncmp(buf, "dccp", 4) != 0)
|
if (strncmp(buf, "dccp", 4) != 0)
|
||||||
{
|
{
|
||||||
printf("%s is not a dcc prototype file\n", szProFName);
|
printf("%s is not a dcc prototype file\n", qPrintable(szProFName));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
grab(2, fProto);
|
grab(2, fProto);
|
||||||
if (strncmp(buf, "FN", 2) != 0)
|
if (strncmp(buf, "FN", 2) != 0)
|
||||||
{
|
{
|
||||||
printf("FN (Function Name) subsection expected in %s\n", szProFName);
|
printf("FN (Function Name) subsection expected in %s\n", qPrintable(szProFName));
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,7 +900,7 @@ void readProtoFile(void)
|
|||||||
grab(2, fProto);
|
grab(2, fProto);
|
||||||
if (strncmp(buf, "PM", 2) != 0)
|
if (strncmp(buf, "PM", 2) != 0)
|
||||||
{
|
{
|
||||||
printf("PM (Parameter) subsection expected in %s\n", szProFName);
|
printf("PM (Parameter) subsection expected in %s\n", qPrintable(szProFName));
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -168,7 +168,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
(inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
|
(inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
|
||||||
inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
|
inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
|
||||||
{
|
{
|
||||||
head->loopType = REPEAT_TYPE;
|
head->loopType = eNodeHeaderType::REPEAT_TYPE;
|
||||||
if (latchNode->edges[0].BBptr == head)
|
if (latchNode->edges[0].BBptr == head)
|
||||||
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
@ -177,7 +177,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
head->loopType = WHILE_TYPE;
|
head->loopType = eNodeHeaderType::WHILE_TYPE;
|
||||||
if (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum))
|
if (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum))
|
||||||
head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
|
head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
@ -186,7 +186,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
}
|
}
|
||||||
else /* head = anything besides 2-way, latch = 2-way */
|
else /* head = anything besides 2-way, latch = 2-way */
|
||||||
{
|
{
|
||||||
head->loopType = REPEAT_TYPE;
|
head->loopType = eNodeHeaderType::REPEAT_TYPE;
|
||||||
if (latchNode->edges[THEN].BBptr == head)
|
if (latchNode->edges[THEN].BBptr == head)
|
||||||
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
@ -196,12 +196,12 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
else /* latch = 1-way */
|
else /* latch = 1-way */
|
||||||
if (latchNode->nodeType == LOOP_NODE)
|
if (latchNode->nodeType == LOOP_NODE)
|
||||||
{
|
{
|
||||||
head->loopType = REPEAT_TYPE;
|
head->loopType = eNodeHeaderType::REPEAT_TYPE;
|
||||||
head->loopFollow = latchNode->edges[0].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[0].BBptr->dfsLastNum;
|
||||||
}
|
}
|
||||||
else if (intNodeType == TWO_BRANCH)
|
else if (intNodeType == TWO_BRANCH)
|
||||||
{
|
{
|
||||||
head->loopType = WHILE_TYPE;
|
head->loopType = eNodeHeaderType::WHILE_TYPE;
|
||||||
pbb = latchNode;
|
pbb = latchNode;
|
||||||
thenDfs = head->edges[THEN].BBptr->dfsLastNum;
|
thenDfs = head->edges[THEN].BBptr->dfsLastNum;
|
||||||
elseDfs = head->edges[ELSE].BBptr->dfsLastNum;
|
elseDfs = head->edges[ELSE].BBptr->dfsLastNum;
|
||||||
@ -222,7 +222,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
* 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 = ENDLESS_TYPE;
|
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
||||||
findEndlessFollow (pProc, loopNodes, head);
|
findEndlessFollow (pProc, loopNodes, head);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
head->loopType = ENDLESS_TYPE;
|
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
||||||
findEndlessFollow (pProc, loopNodes, head);
|
findEndlessFollow (pProc, loopNodes, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -143,7 +143,6 @@ void Function::elimCondCodes ()
|
|||||||
//auto reversed_instructions = pBB->range() | reversed;
|
//auto reversed_instructions = pBB->range() | reversed;
|
||||||
for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
|
for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
|
||||||
{
|
{
|
||||||
ICODE &useIcode(*useAt);
|
|
||||||
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) || ( ! useAt->valid() ) || ( 0 == use ))
|
||||||
@ -159,7 +158,6 @@ void Function::elimCondCodes ()
|
|||||||
continue;
|
continue;
|
||||||
notSup = false;
|
notSup = false;
|
||||||
LLOperand *dest_ll = defIcode.ll()->get(DST);
|
LLOperand *dest_ll = defIcode.ll()->get(DST);
|
||||||
LLOperand *src_ll = defIcode.ll()->get(SRC);
|
|
||||||
if ((useAtOp >= iJB) && (useAtOp <= iJNS))
|
if ((useAtOp >= iJB) && (useAtOp <= iJNS))
|
||||||
{
|
{
|
||||||
iICODE befDefAt = (++riICODE(defAt)).base();
|
iICODE befDefAt = (++riICODE(defAt)).base();
|
||||||
|
|||||||
52
src/dcc.cpp
52
src/dcc.cpp
@ -4,26 +4,10 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <cstring>
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "project.h"
|
|
||||||
|
|
||||||
#include "CallGraph.h"
|
|
||||||
/* Global variables - extern to other modules */
|
|
||||||
extern std::string asm1_name, asm2_name; /* Assembler output filenames */
|
|
||||||
extern SYMTAB symtab; /* Global symbol table */
|
|
||||||
extern STATS stats; /* cfg statistics */
|
|
||||||
//PROG prog; /* programs fields */
|
|
||||||
extern OPTION option; /* Command line options */
|
|
||||||
//Function * pProcList; /* List of procedures, topologically sort */
|
|
||||||
//Function * pLastProc; /* Pointer to last node in procedure list */
|
|
||||||
//FunctionListType pProcList;
|
|
||||||
//CALL_GRAPH *callGraph; /* Call graph of the program */
|
|
||||||
|
|
||||||
static char *initargs(int argc, char *argv[]);
|
|
||||||
static void displayTotalStats(void);
|
|
||||||
#include <llvm/Support/raw_os_ostream.h>
|
#include <llvm/Support/raw_os_ostream.h>
|
||||||
#include <llvm/Support/CommandLine.h>
|
#include <llvm/Support/CommandLine.h>
|
||||||
#include <llvm/Support/TargetSelect.h>
|
#include <llvm/Support/TargetSelect.h>
|
||||||
@ -39,11 +23,24 @@ static void displayTotalStats(void);
|
|||||||
#include <llvm/TableGen/Main.h>
|
#include <llvm/TableGen/Main.h>
|
||||||
#include <llvm/TableGen/TableGenBackend.h>
|
#include <llvm/TableGen/TableGenBackend.h>
|
||||||
#include <llvm/TableGen/Record.h>
|
#include <llvm/TableGen/Record.h>
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
#include "DccFrontend.h"
|
||||||
|
|
||||||
|
/* Global variables - extern to other modules */
|
||||||
|
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
|
extern SYMTAB symtab; /* Global symbol table */
|
||||||
|
extern STATS stats; /* cfg statistics */
|
||||||
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
|
static char *initargs(int argc, char *argv[]);
|
||||||
|
static void displayTotalStats(void);
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* main
|
* main
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <QtCore/QFile>
|
|
||||||
#include <iostream>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
bool TVisitor(raw_ostream &OS, RecordKeeper &Records)
|
bool TVisitor(raw_ostream &OS, RecordKeeper &Records)
|
||||||
{
|
{
|
||||||
@ -161,9 +158,9 @@ void setupOptions(QCoreApplication &app) {
|
|||||||
option.Stats = parser.isSet(boolOpts[4]);
|
option.Stats = parser.isSet(boolOpts[4]);
|
||||||
option.Interact = false;
|
option.Interact = false;
|
||||||
option.Calls = parser.isSet(boolOpts[2]);
|
option.Calls = parser.isSet(boolOpts[2]);
|
||||||
option.filename = args.first().toStdString();
|
option.filename = args.first();
|
||||||
if(parser.isSet(targetFileOption))
|
if(parser.isSet(targetFileOption))
|
||||||
asm1_name = asm2_name = parser.value(targetFileOption).toStdString();
|
asm1_name = asm2_name = parser.value(targetFileOption);
|
||||||
else if(option.asm1 || option.asm2) {
|
else if(option.asm1 || option.asm2) {
|
||||||
asm1_name = option.filename+".a1";
|
asm1_name = option.filename+".a1";
|
||||||
asm2_name = option.filename+".a2";
|
asm2_name = option.filename+".a2";
|
||||||
@ -181,7 +178,14 @@ int main(int argc, char **argv)
|
|||||||
* building the call graph and attaching appropriate bits of code for
|
* building the call graph and attaching appropriate bits of code for
|
||||||
* each procedure.
|
* each procedure.
|
||||||
*/
|
*/
|
||||||
DccFrontend fe(option.filename);
|
Project::get()->create(option.filename);
|
||||||
|
|
||||||
|
DccFrontend fe(&app);
|
||||||
|
if(!Project::get()->load()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (option.verbose)
|
||||||
|
Project::get()->prog.displayLoadInfo();
|
||||||
if(false==fe.FrontEnd ())
|
if(false==fe.FrontEnd ())
|
||||||
return -1;
|
return -1;
|
||||||
if(option.asm1)
|
if(option.asm1)
|
||||||
@ -198,7 +202,7 @@ int main(int argc, char **argv)
|
|||||||
* analysis, data flow etc. and outputs it to output file ready for
|
* analysis, data flow etc. and outputs it to output file ready for
|
||||||
* re-compilation.
|
* re-compilation.
|
||||||
*/
|
*/
|
||||||
BackEnd(!asm1_name.empty() ? asm1_name:option.filename, Project::get()->callGraph);
|
BackEnd(Project::get()->callGraph);
|
||||||
|
|
||||||
Project::get()->callGraph->write();
|
Project::get()->callGraph->write();
|
||||||
|
|
||||||
|
|||||||
61
src/dcc_interface.cpp
Normal file
61
src/dcc_interface.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "dcc_interface.h"
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
struct DccImpl : public IDcc{
|
||||||
|
|
||||||
|
|
||||||
|
// IDcc interface
|
||||||
|
public:
|
||||||
|
void BaseInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Init(QObject *tgt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ilFunction GetFirstFuncHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ilFunction GetCurFuncHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void analysis_Once()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void load(QString name)
|
||||||
|
{
|
||||||
|
option.filename = name;
|
||||||
|
Project::get()->create(name);
|
||||||
|
}
|
||||||
|
void prtout_asm(IXmlTarget *, int level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void prtout_cpp(IXmlTarget *, int level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
size_t getFuncCount()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const lFunction &validFunctions() const
|
||||||
|
{
|
||||||
|
return Project::get()->functions();
|
||||||
|
}
|
||||||
|
void SetCurFunc_by_Name(QString)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QDir installDir() {
|
||||||
|
return QDir(".");
|
||||||
|
}
|
||||||
|
QDir dataDir(QString kind) { // return directory containing decompilation helper data -> signatures/includes/etc.
|
||||||
|
QDir res(installDir());
|
||||||
|
res.cd(kind);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IDcc* IDcc::get() {
|
||||||
|
static IDcc *v=0;
|
||||||
|
if(!v)
|
||||||
|
v = new DccImpl;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
@ -150,10 +150,10 @@ 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,ios_base::app);
|
m_fp.open(p.toStdString(),ios_base::app);
|
||||||
if (!m_fp.is_open())
|
if (!m_fp.is_open())
|
||||||
{
|
{
|
||||||
fatalError(CANNOT_OPEN, p.c_str());
|
fatalError(CANNOT_OPEN, p.toStdString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Create temporary code array */
|
/* Create temporary code array */
|
||||||
|
|||||||
@ -3,7 +3,12 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <llvm/Config/llvm-config.h>
|
||||||
|
#if( (LLVM_VERSION_MAJOR==3 ) && (LLVM_VERSION_MINOR>3) )
|
||||||
|
#include <llvm/IR/PatternMatch.h>
|
||||||
|
#else
|
||||||
#include <llvm/Support/PatternMatch.h>
|
#include <llvm/Support/PatternMatch.h>
|
||||||
|
#endif
|
||||||
#include <boost/iterator/filter_iterator.hpp>
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|||||||
@ -27,16 +27,16 @@ bool Idiom14::match(iICODE pIcode)
|
|||||||
return false;
|
return false;
|
||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=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 = m_icodes[0]->ll()->m_dst.regi;
|
m_regL = matched[0]->m_dst.regi;
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
if (not matched[0]->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
||||||
{
|
{
|
||||||
/* Check for XOR regH, regH */
|
/* Check for XOR regH, regH */
|
||||||
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
|
if (matched[1]->match(iXOR) && not matched[1]->testFlags(I))
|
||||||
{
|
{
|
||||||
m_regH = m_icodes[1]->ll()->m_dst.regi;
|
m_regH = matched[1]->m_dst.regi;
|
||||||
if (m_regH == m_icodes[1]->ll()->src().getReg2())
|
if (m_regH == matched[1]->src().getReg2())
|
||||||
{
|
{
|
||||||
if ((m_regL == rAX) && (m_regH == rDX))
|
if ((m_regL == rAX) && (m_regH == rDX))
|
||||||
return true;
|
return true;
|
||||||
@ -49,14 +49,11 @@ bool Idiom14::match(iICODE pIcode)
|
|||||||
}
|
}
|
||||||
int Idiom14::action()
|
int Idiom14::action()
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
AstIdent *lhs;
|
|
||||||
Expr *rhs;
|
|
||||||
|
|
||||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
|
int idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
|
||||||
lhs = AstIdent::LongIdx (idx);
|
AstIdent *lhs = AstIdent::LongIdx (idx);
|
||||||
m_icodes[0]->setRegDU( m_regH, eDEF);
|
m_icodes[0]->setRegDU( m_regH, eDEF);
|
||||||
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
Expr *rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@ -20,70 +20,8 @@ static void setBits(int16_t type, uint32_t start, uint32_t len);
|
|||||||
static void process_MOV(LLInst &ll, STATE * pstate);
|
static void process_MOV(LLInst &ll, STATE * pstate);
|
||||||
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
|
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
|
||||||
void interactDis(Function * initProc, int ic);
|
void interactDis(Function * initProc, int ic);
|
||||||
static uint32_t SynthLab;
|
extern uint32_t SynthLab;
|
||||||
|
|
||||||
/* Parses the program, builds the call graph, and returns the list of
|
|
||||||
* procedures found */
|
|
||||||
void DccFrontend::parse(Project &proj)
|
|
||||||
{
|
|
||||||
PROG &prog(proj.prog);
|
|
||||||
STATE state;
|
|
||||||
|
|
||||||
/* Set initial state */
|
|
||||||
state.setState(rES, 0); /* PSP segment */
|
|
||||||
state.setState(rDS, 0);
|
|
||||||
state.setState(rCS, prog.initCS);
|
|
||||||
state.setState(rSS, prog.initSS);
|
|
||||||
state.setState(rSP, prog.initSP);
|
|
||||||
state.IP = ((uint32_t)prog.initCS << 4) + prog.initIP;
|
|
||||||
SynthLab = SYNTHESIZED_MIN;
|
|
||||||
|
|
||||||
// default-construct a Function object !
|
|
||||||
/*auto func = */;
|
|
||||||
|
|
||||||
/* Check for special settings of initial state, based on idioms of the
|
|
||||||
startup code */
|
|
||||||
state.checkStartup();
|
|
||||||
Function *start_proc;
|
|
||||||
/* Make a struct for the initial procedure */
|
|
||||||
if (prog.offMain != -1)
|
|
||||||
{
|
|
||||||
start_proc = proj.createFunction(0,"main");
|
|
||||||
start_proc->retVal.loc = REG_FRAME;
|
|
||||||
start_proc->retVal.type = TYPE_WORD_SIGN;
|
|
||||||
start_proc->retVal.id.regi = rAX;
|
|
||||||
/* We know where main() is. Start the flow of control from there */
|
|
||||||
start_proc->procEntry = prog.offMain;
|
|
||||||
/* In medium and large models, the segment of main may (will?) not be
|
|
||||||
the same as the initial CS segment (of the startup code) */
|
|
||||||
state.setState(rCS, prog.segMain);
|
|
||||||
state.IP = prog.offMain;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start_proc = proj.createFunction(0,"start");
|
|
||||||
/* Create initial procedure at program start address */
|
|
||||||
start_proc->procEntry = (uint32_t)state.IP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The state info is for the first procedure */
|
|
||||||
start_proc->state = state;
|
|
||||||
|
|
||||||
/* Set up call graph initial node */
|
|
||||||
proj.callGraph = new CALL_GRAPH;
|
|
||||||
proj.callGraph->proc = start_proc;
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
SetupLibCheck();
|
|
||||||
//BUG: proj and g_proj are 'live' at this point !
|
|
||||||
|
|
||||||
/* Recursively build entire procedure list */
|
|
||||||
start_proc->FollowCtrl(proj.callGraph, &state);
|
|
||||||
|
|
||||||
/* This proc needs to be called to clean things up from SetupLibCheck() */
|
|
||||||
CleanupLibCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the size of the string pointed by sym and delimited by delim.
|
/* Returns the size of the string pointed by sym and delimited by delim.
|
||||||
* Size includes delimiter. */
|
* Size includes delimiter. */
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
@ -5,7 +7,7 @@
|
|||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
//Project g_proj;
|
//Project g_proj;
|
||||||
string asm1_name, asm2_name; /* Assembler output filenames */
|
QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
SYMTAB symtab; /* Global symbol table */
|
SYMTAB symtab; /* Global symbol table */
|
||||||
STATS stats; /* cfg statistics */
|
STATS stats; /* cfg statistics */
|
||||||
//PROG prog; /* programs fields */
|
//PROG prog; /* programs fields */
|
||||||
@ -20,19 +22,26 @@ void Project::initialize()
|
|||||||
delete callGraph;
|
delete callGraph;
|
||||||
callGraph = nullptr;
|
callGraph = nullptr;
|
||||||
}
|
}
|
||||||
void Project::create(const string &a)
|
void Project::create(const QString &a)
|
||||||
{
|
{
|
||||||
|
initialize();
|
||||||
m_fname=a;
|
m_fname=a;
|
||||||
string::size_type ext_loc=a.find_last_of('.');
|
auto ext_loc=a.lastIndexOf('.');
|
||||||
string::size_type slash_loc=a.find_last_of('/',ext_loc);
|
auto slash_loc=a.lastIndexOf('/',ext_loc);
|
||||||
if(slash_loc==string::npos)
|
if(slash_loc==-1)
|
||||||
slash_loc=0;
|
slash_loc=0;
|
||||||
else
|
else
|
||||||
slash_loc++;
|
slash_loc++;
|
||||||
if(ext_loc!=string::npos)
|
if(ext_loc!=-1) {
|
||||||
m_project_name = a.substr(slash_loc,(ext_loc-slash_loc));
|
m_project_name = a.mid(slash_loc,ext_loc-slash_loc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_project_name = a.substr(slash_loc);
|
m_project_name = a.mid(slash_loc);
|
||||||
|
m_output_path = a.left(slash_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Project::output_name(const char *ext) {
|
||||||
|
return m_output_path+QDir::separator()+m_project_name+"."+ext;
|
||||||
}
|
}
|
||||||
bool Project::valid(ilFunction iter)
|
bool Project::valid(ilFunction iter)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user