Re-activate unit testing and starting work on proper memory segmentation support
Use Qt testing framework. Reorganize source file references in CMakeLists.txt Add simplistic Address header and type ( typedef for now )
This commit is contained in:
parent
171abc0415
commit
3905c4e281
134
CMakeLists.txt
134
CMakeLists.txt
@ -25,12 +25,14 @@ find_package(Boost)
|
|||||||
|
|
||||||
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
||||||
IF(dcc_build_tests)
|
IF(dcc_build_tests)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
FIND_PACKAGE(GMock)
|
find_package(Qt5Test)
|
||||||
|
#FIND_PACKAGE(GMock)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
|
${PROJECT_SOURCE_DIR}
|
||||||
3rd_party/libdisasm
|
3rd_party/libdisasm
|
||||||
include
|
include
|
||||||
include/idioms
|
include/idioms
|
||||||
@ -38,135 +40,7 @@ INCLUDE_DIRECTORIES(
|
|||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(3rd_party)
|
ADD_SUBDIRECTORY(3rd_party)
|
||||||
ADD_SUBDIRECTORY(common)
|
ADD_SUBDIRECTORY(common)
|
||||||
ADD_SUBDIRECTORY(tools)
|
ADD_SUBDIRECTORY(tools)
|
||||||
|
|
||||||
|
|
||||||
set(dcc_LIB_SOURCES
|
|
||||||
src/CallConvention.cpp
|
|
||||||
src/ast.cpp
|
|
||||||
src/backend.cpp
|
|
||||||
src/bundle.cpp
|
|
||||||
src/chklib.cpp
|
|
||||||
src/comwrite.cpp
|
|
||||||
src/control.cpp
|
|
||||||
src/dataflow.cpp
|
|
||||||
src/disassem.cpp
|
|
||||||
src/DccFrontend.cpp
|
|
||||||
src/error.cpp
|
|
||||||
src/fixwild.cpp
|
|
||||||
src/graph.cpp
|
|
||||||
src/hlicode.cpp
|
|
||||||
src/hltype.cpp
|
|
||||||
src/machine_x86.cpp
|
|
||||||
src/icode.cpp
|
|
||||||
src/RegisterNode
|
|
||||||
src/idioms.cpp
|
|
||||||
src/idioms/idiom1.cpp
|
|
||||||
src/idioms/arith_idioms.cpp
|
|
||||||
src/idioms/call_idioms.cpp
|
|
||||||
src/idioms/epilogue_idioms.cpp
|
|
||||||
src/idioms/mov_idioms.cpp
|
|
||||||
src/idioms/neg_idioms.cpp
|
|
||||||
src/idioms/shift_idioms.cpp
|
|
||||||
src/idioms/xor_idioms.cpp
|
|
||||||
src/locident.cpp
|
|
||||||
src/liveness_set.cpp
|
|
||||||
src/parser.h
|
|
||||||
src/parser.cpp
|
|
||||||
src/procs.cpp
|
|
||||||
src/project.cpp
|
|
||||||
src/Procedure.cpp
|
|
||||||
src/proplong.cpp
|
|
||||||
src/reducible.cpp
|
|
||||||
src/scanner.cpp
|
|
||||||
src/symtab.cpp
|
|
||||||
src/udm.cpp
|
|
||||||
src/BasicBlock.cpp
|
|
||||||
src/dcc_interface.cpp
|
|
||||||
|
|
||||||
src/Command.cpp
|
|
||||||
src/Command.h
|
|
||||||
src/Loaders.cpp
|
|
||||||
src/Loaders.h
|
|
||||||
src/FollowControlFlow.cpp
|
|
||||||
src/FollowControlFlow.h
|
|
||||||
|
|
||||||
src/AutomatedPlanner
|
|
||||||
)
|
|
||||||
set(dcc_UI_SOURCES
|
|
||||||
src/ui/DccMainWindow.ui
|
|
||||||
src/ui/DccMainWindow.h
|
|
||||||
src/ui/DccMainWindow.cpp
|
|
||||||
src/ui/FunctionViewWidget.ui
|
|
||||||
src/ui/FunctionViewWidget.h
|
|
||||||
src/ui/FunctionViewWidget.cpp
|
|
||||||
src/ui/FunctionListDockWidget.ui
|
|
||||||
src/ui/FunctionListDockWidget.cpp
|
|
||||||
src/ui/FunctionListDockWidget.h
|
|
||||||
src/ui/RenderTags.cpp
|
|
||||||
src/ui/RenderTags.h
|
|
||||||
src/ui/CommandQueueView.cpp
|
|
||||||
src/ui/CommandQueueView.h
|
|
||||||
src/ui/CommandQueueView.ui
|
|
||||||
)
|
|
||||||
set(dcc_SOURCES
|
|
||||||
src/dcc.cpp
|
|
||||||
)
|
|
||||||
set(dcc_HEADERS
|
|
||||||
include/ast.h
|
|
||||||
include/bundle.h
|
|
||||||
include/BinaryImage.h
|
|
||||||
include/DccFrontend.h
|
|
||||||
include/Enums.h
|
|
||||||
include/dcc.h
|
|
||||||
include/disassem.h
|
|
||||||
include/dosdcc.h
|
|
||||||
include/error.h
|
|
||||||
include/graph.h
|
|
||||||
include/hlicode.h
|
|
||||||
include/machine_x86.h
|
|
||||||
include/icode.h
|
|
||||||
include/idioms/idiom.h
|
|
||||||
include/idioms/idiom1.h
|
|
||||||
include/idioms/arith_idioms.h
|
|
||||||
include/idioms/call_idioms.h
|
|
||||||
include/idioms/epilogue_idioms.h
|
|
||||||
include/idioms/mov_idioms.h
|
|
||||||
include/idioms/neg_idioms.h
|
|
||||||
include/idioms/shift_idioms.h
|
|
||||||
include/idioms/xor_idioms.h
|
|
||||||
include/locident.h
|
|
||||||
include/CallConvention.h
|
|
||||||
include/project.h
|
|
||||||
include/scanner.h
|
|
||||||
include/state.h
|
|
||||||
include/symtab.h
|
|
||||||
include/types.h
|
|
||||||
include/Procedure.h
|
|
||||||
include/StackFrame.h
|
|
||||||
include/BasicBlock.h
|
|
||||||
include/dcc_interface.h
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
|
||||||
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
|
||||||
|
|
||||||
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
|
||||||
qt5_use_modules(dcc_lib Core)
|
|
||||||
#cotire(dcc_lib)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_UI_SOURCES})
|
|
||||||
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
|
||||||
TARGET_LINK_LIBRARIES(dcc_original dcc_lib dcc_hash disasm_s)
|
|
||||||
qt5_use_modules(dcc_original Core Widgets)
|
|
||||||
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD 11)
|
|
||||||
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD_REQUIRED ON)
|
|
||||||
#ADD_SUBDIRECTORY(gui)
|
|
||||||
if(dcc_build_tests)
|
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|||||||
21
CMakeScripts/DCC_Macros.cmake
Normal file
21
CMakeScripts/DCC_Macros.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MACRO(ADD_UNIT_TEST name)
|
||||||
|
IF(NOT ${name}_TEST_VISITED)
|
||||||
|
# add the loader as a dll
|
||||||
|
ADD_EXECUTABLE(${name} ${ARGN})
|
||||||
|
qt5_use_modules(${name} Core)
|
||||||
|
MESSAGE(WARNING "Adding test " ${name} " " ${ARGN})
|
||||||
|
TARGET_LINK_LIBRARIES(${name} ${UNIT_TEST_LIBS})
|
||||||
|
ADD_TEST(NAME ${name} COMMAND ${name})
|
||||||
|
set_property(TEST ${name} APPEND PROPERTY ENVIRONMENT DCC_TEST_BASE=${PROJECT_SOURCE_DIR})
|
||||||
|
SET(${name}_TEST_VISITED true)
|
||||||
|
ENDIF()
|
||||||
|
ENDMACRO()
|
||||||
|
|
||||||
|
function(ADD_QTEST NAME)
|
||||||
|
add_executable(${NAME} ${NAME}.cpp ${NAME}.h) #${PROTO_SRCS} ${PROTO_HDRS}
|
||||||
|
target_link_libraries(${NAME} ${test_LIBRARIES})
|
||||||
|
qt5_use_modules(${NAME} Core Test)
|
||||||
|
|
||||||
|
add_test( NAME ${NAME} COMMAND $<TARGET_FILE:${NAME}>)
|
||||||
|
set_property(TEST ${NAME} APPEND PROPERTY ENVIRONMENT DCC_TEST_BASE=${PROJECT_SOURCE_DIR})
|
||||||
|
endfunction()
|
||||||
6
src/Address.h
Normal file
6
src/Address.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uint32_t LinearAddress;
|
||||||
|
#define INVALID_ADDR Address(~0U)
|
||||||
@ -1,13 +1,131 @@
|
|||||||
SET(dcc_test_SOURCES
|
set(dcc_LIB_SOURCES
|
||||||
tests/comwrite.cpp
|
CallConvention.cpp
|
||||||
tests/project.cpp
|
ast.cpp
|
||||||
tests/loader.cpp
|
backend.cpp
|
||||||
|
bundle.cpp
|
||||||
|
chklib.cpp
|
||||||
|
comwrite.cpp
|
||||||
|
control.cpp
|
||||||
|
dataflow.cpp
|
||||||
|
disassem.cpp
|
||||||
|
DccFrontend.cpp
|
||||||
|
error.cpp
|
||||||
|
fixwild.cpp
|
||||||
|
graph.cpp
|
||||||
|
hlicode.cpp
|
||||||
|
hltype.cpp
|
||||||
|
machine_x86.cpp
|
||||||
|
icode.cpp
|
||||||
|
RegisterNode
|
||||||
|
idioms.cpp
|
||||||
|
idioms/idiom1.cpp
|
||||||
|
idioms/arith_idioms.cpp
|
||||||
|
idioms/call_idioms.cpp
|
||||||
|
idioms/epilogue_idioms.cpp
|
||||||
|
idioms/mov_idioms.cpp
|
||||||
|
idioms/neg_idioms.cpp
|
||||||
|
idioms/shift_idioms.cpp
|
||||||
|
idioms/xor_idioms.cpp
|
||||||
|
locident.cpp
|
||||||
|
liveness_set.cpp
|
||||||
|
parser.h
|
||||||
|
parser.cpp
|
||||||
|
procs.cpp
|
||||||
|
project.cpp
|
||||||
|
Procedure.cpp
|
||||||
|
proplong.cpp
|
||||||
|
reducible.cpp
|
||||||
|
scanner.cpp
|
||||||
|
symtab.cpp
|
||||||
|
udm.cpp
|
||||||
|
BasicBlock.cpp
|
||||||
|
dcc_interface.cpp
|
||||||
|
|
||||||
|
MemoryChunk
|
||||||
|
MemorySegment
|
||||||
|
MemorySegmentCoordinator
|
||||||
|
|
||||||
|
Command.cpp
|
||||||
|
Command.h
|
||||||
|
Loaders.cpp
|
||||||
|
Loaders.h
|
||||||
|
FollowControlFlow.cpp
|
||||||
|
FollowControlFlow.h
|
||||||
|
|
||||||
|
AutomatedPlanner
|
||||||
|
)
|
||||||
|
set(dcc_UI_SOURCES
|
||||||
|
ui/DccMainWindow.ui
|
||||||
|
ui/DccMainWindow.h
|
||||||
|
ui/DccMainWindow.cpp
|
||||||
|
ui/FunctionViewWidget.ui
|
||||||
|
ui/FunctionViewWidget.h
|
||||||
|
ui/FunctionViewWidget.cpp
|
||||||
|
ui/FunctionListDockWidget.ui
|
||||||
|
ui/FunctionListDockWidget.cpp
|
||||||
|
ui/FunctionListDockWidget.h
|
||||||
|
ui/RenderTags.cpp
|
||||||
|
ui/RenderTags.h
|
||||||
|
ui/CommandQueueView.cpp
|
||||||
|
ui/CommandQueueView.h
|
||||||
|
ui/CommandQueueView.ui
|
||||||
|
)
|
||||||
|
set(dcc_HEADERS
|
||||||
|
../include/ast.h
|
||||||
|
../include/bundle.h
|
||||||
|
../include/BinaryImage.h
|
||||||
|
../include/DccFrontend.h
|
||||||
|
../include/Enums.h
|
||||||
|
../include/dcc.h
|
||||||
|
../include/disassem.h
|
||||||
|
../include/dosdcc.h
|
||||||
|
../include/error.h
|
||||||
|
../include/graph.h
|
||||||
|
../include/hlicode.h
|
||||||
|
../include/machine_x86.h
|
||||||
|
../include/icode.h
|
||||||
|
../include/idioms/idiom.h
|
||||||
|
../include/idioms/idiom1.h
|
||||||
|
../include/idioms/arith_idioms.h
|
||||||
|
../include/idioms/call_idioms.h
|
||||||
|
../include/idioms/epilogue_idioms.h
|
||||||
|
../include/idioms/mov_idioms.h
|
||||||
|
../include/idioms/neg_idioms.h
|
||||||
|
../include/idioms/shift_idioms.h
|
||||||
|
../include/idioms/xor_idioms.h
|
||||||
|
../include/locident.h
|
||||||
|
../include/CallConvention.h
|
||||||
|
../include/project.h
|
||||||
|
../include/scanner.h
|
||||||
|
../include/state.h
|
||||||
|
../include/symtab.h
|
||||||
|
../include/types.h
|
||||||
|
../include/Procedure.h
|
||||||
|
../include/StackFrame.h
|
||||||
|
../include/BasicBlock.h
|
||||||
|
../include/dcc_interface.h
|
||||||
)
|
)
|
||||||
include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include)
|
|
||||||
add_executable(tester ${dcc_test_SOURCES})
|
|
||||||
ADD_DEPENDENCIES(tester dcc_lib)
|
|
||||||
|
|
||||||
target_link_libraries(tester dcc_lib disasm_s
|
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
||||||
${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES})
|
|
||||||
add_test(dcc-tests tester)
|
set(dcc_SOURCES
|
||||||
|
dcc.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SOURCE_GROUP(Source FILES ${dcc_SOURCES} ${dcc_LIB_SOURCES})
|
||||||
|
|
||||||
|
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
||||||
|
qt5_use_modules(dcc_lib Core)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_UI_SOURCES})
|
||||||
|
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
||||||
|
TARGET_LINK_LIBRARIES(dcc_original dcc_lib dcc_hash disasm_s)
|
||||||
|
qt5_use_modules(dcc_original Core Widgets)
|
||||||
|
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD 11)
|
||||||
|
SET_PROPERTY(TARGET dcc_original PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(dcc_build_tests)
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
endif()
|
||||||
|
|||||||
22
src/MemoryChunk.cpp
Normal file
22
src/MemoryChunk.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "MemoryChunk.h"
|
||||||
|
|
||||||
|
#include <boost/icl/interval.hpp>
|
||||||
|
#include <boost/icl/right_open_interval.hpp>
|
||||||
|
#include <boost/icl/left_open_interval.hpp>
|
||||||
|
#include <boost/icl/closed_interval.hpp>
|
||||||
|
#include <boost/icl/open_interval.hpp>
|
||||||
|
|
||||||
|
using namespace boost::icl;
|
||||||
|
MemoryChunk::MemoryChunk(LinearAddress start, LinearAddress fin) : m_start(start),m_fin(fin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryChunk::contains(LinearAddress addr) const
|
||||||
|
{
|
||||||
|
return addr>=m_start && addr<m_fin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t MemoryChunk::size() const
|
||||||
|
{
|
||||||
|
return m_fin-m_start;
|
||||||
|
}
|
||||||
24
src/MemoryChunk.h
Normal file
24
src/MemoryChunk.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef BYTECHUNK_H
|
||||||
|
#define BYTECHUNK_H
|
||||||
|
|
||||||
|
#include "Address.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <inttypes.h>
|
||||||
|
/**
|
||||||
|
* @brief The MemoryChunk class represents a continuous range of Addresses
|
||||||
|
*/
|
||||||
|
class MemoryChunk
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LinearAddress m_start;
|
||||||
|
LinearAddress m_fin;
|
||||||
|
public:
|
||||||
|
MemoryChunk(LinearAddress start,LinearAddress fin);
|
||||||
|
bool contains(LinearAddress addr) const;
|
||||||
|
uint64_t size() const;
|
||||||
|
|
||||||
|
std::pair<LinearAddress,LinearAddress> bounds() const { return std::make_pair(m_start,m_fin); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BYTECHUNK_H
|
||||||
5
src/MemorySegment.cpp
Normal file
5
src/MemorySegment.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "MemorySegment.h"
|
||||||
|
|
||||||
|
MemorySegment::MemorySegment(LinearAddress base, LinearAddress start, LinearAddress fin) : MemoryChunk(start,fin) {
|
||||||
|
m_base = base;
|
||||||
|
}
|
||||||
19
src/MemorySegment.h
Normal file
19
src/MemorySegment.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MemoryChunk.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
/**
|
||||||
|
* @brief The MemorySegment represents a single chunk of memory with additional properties.
|
||||||
|
*/
|
||||||
|
class MemorySegment : public MemoryChunk
|
||||||
|
{
|
||||||
|
uint16_t m_base;
|
||||||
|
int m_flags;
|
||||||
|
QString m_name;
|
||||||
|
public:
|
||||||
|
MemorySegment(LinearAddress base,LinearAddress start,LinearAddress fin);
|
||||||
|
const QString &getName() const { return m_name; }
|
||||||
|
void setName(const QString &v) { m_name = v; }
|
||||||
|
};
|
||||||
|
|
||||||
54
src/MemorySegmentCoordinator.cpp
Normal file
54
src/MemorySegmentCoordinator.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "MemorySegmentCoordinator.h"
|
||||||
|
|
||||||
|
#include <boost/icl/interval_map.hpp>
|
||||||
|
#include <boost/icl/split_interval_map.hpp>
|
||||||
|
#include <utility>
|
||||||
|
using namespace boost::icl;
|
||||||
|
class MemorySegmentCoordinatorImpl {
|
||||||
|
boost::icl::interval_map<LinearAddress,SegmentHolder> m_segmentation_map;
|
||||||
|
public:
|
||||||
|
bool addSegment(LinearAddress base, LinearAddress start, LinearAddress fin, const char * name, int flags) {
|
||||||
|
if(start>fin)
|
||||||
|
return false;
|
||||||
|
if(start<base)
|
||||||
|
return false;
|
||||||
|
MemorySegment *seg = new MemorySegment(base,start,fin);
|
||||||
|
seg->setName(name);
|
||||||
|
//
|
||||||
|
auto segment_bounds(seg->bounds());
|
||||||
|
m_segmentation_map.add(std::make_pair(
|
||||||
|
interval<LinearAddress>::right_open(segment_bounds.first,segment_bounds.second),
|
||||||
|
seg)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint32_t numberOfSegments() const { return interval_count(m_segmentation_map); }
|
||||||
|
const MemorySegment *get(LinearAddress addr) {
|
||||||
|
auto iter = m_segmentation_map.find(addr);
|
||||||
|
if(iter==m_segmentation_map.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return iter->second;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MemorySegmentCoordinator::MemorySegmentCoordinator()
|
||||||
|
{
|
||||||
|
m_impl = new MemorySegmentCoordinatorImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemorySegmentCoordinator::addSegment(LinearAddress base, LinearAddress start, LinearAddress fin, const char * name, int flags)
|
||||||
|
{
|
||||||
|
return m_impl->addSegment(base,start,fin,name,flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MemorySegmentCoordinator::size()
|
||||||
|
{
|
||||||
|
return m_impl->numberOfSegments();
|
||||||
|
}
|
||||||
|
|
||||||
|
MemorySegment *MemorySegmentCoordinator::getSegment(LinearAddress addr)
|
||||||
|
{
|
||||||
|
return const_cast<MemorySegment *>(m_impl->get(addr));
|
||||||
|
}
|
||||||
34
src/MemorySegmentCoordinator.h
Normal file
34
src/MemorySegmentCoordinator.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MemorySegment.h"
|
||||||
|
|
||||||
|
struct SegmentHolder {
|
||||||
|
SegmentHolder() : val(nullptr) {}
|
||||||
|
SegmentHolder(MemorySegment *inf) : val(inf) {}
|
||||||
|
|
||||||
|
MemorySegment *operator->() { return val;}
|
||||||
|
MemorySegment &operator*() const { return *val;}
|
||||||
|
operator MemorySegment *() { return val;}
|
||||||
|
operator const MemorySegment *() const { return val;}
|
||||||
|
SegmentHolder operator+=(const SegmentHolder &/*s*/) {
|
||||||
|
throw std::runtime_error("Cannot aggregate MemorySegments !");
|
||||||
|
}
|
||||||
|
|
||||||
|
MemorySegment *val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The MemorySegmentCoordinator class is responsible for:
|
||||||
|
* - Managing the lifetime of MemorySegments
|
||||||
|
* - Providing convenience functions for querying the segment-related data
|
||||||
|
*/
|
||||||
|
class MemorySegmentCoordinator
|
||||||
|
{
|
||||||
|
class MemorySegmentCoordinatorImpl *m_impl;
|
||||||
|
public:
|
||||||
|
MemorySegmentCoordinator();
|
||||||
|
|
||||||
|
bool addSegment(LinearAddress base,LinearAddress start,LinearAddress fin,const char *name,int flags);
|
||||||
|
uint32_t size();
|
||||||
|
MemorySegment *getSegment(LinearAddress addr);
|
||||||
|
};
|
||||||
24
src/tests/CMakeLists.txt
Normal file
24
src/tests/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
set(TESTS
|
||||||
|
ProjectTests
|
||||||
|
LoaderTests
|
||||||
|
MemoryChunkTests
|
||||||
|
MemorySegmentCoordinatorTests
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
include(DCC_Macros)
|
||||||
|
|
||||||
|
set(target_INCLUDE_DIR
|
||||||
|
..
|
||||||
|
)
|
||||||
|
include_directories(${target_INCLUDE_DIR}
|
||||||
|
../../frontend/sparc
|
||||||
|
../../frontend/pentium
|
||||||
|
)
|
||||||
|
|
||||||
|
set(test_LIBRARIES
|
||||||
|
dcc_lib dcc_hash disasm_s
|
||||||
|
)
|
||||||
|
foreach(t ${TESTS})
|
||||||
|
ADD_QTEST(${t})
|
||||||
|
endforeach()
|
||||||
15
src/tests/LoaderTests.cpp
Normal file
15
src/tests/LoaderTests.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "LoaderTests.h"
|
||||||
|
|
||||||
|
#include "project.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
void LoaderTest::testDummy() {
|
||||||
|
QVERIFY2(false,"No tests written for loader");
|
||||||
|
}
|
||||||
|
QTEST_MAIN(LoaderTest)
|
||||||
7
src/tests/LoaderTests.h
Normal file
7
src/tests/LoaderTests.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
class LoaderTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testDummy();
|
||||||
|
};
|
||||||
22
src/tests/MemoryChunkTests.cpp
Normal file
22
src/tests/MemoryChunkTests.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "MemoryChunkTests.h"
|
||||||
|
|
||||||
|
#include "MemoryChunk.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
void MemoryChunkTest::testIfConstructionWorksProperly() {
|
||||||
|
MemoryChunk mc(0,10);
|
||||||
|
QCOMPARE(mc.size(),size_t(10));
|
||||||
|
QVERIFY(mc.contains(1));
|
||||||
|
QVERIFY(not mc.contains(10));
|
||||||
|
QVERIFY(not mc.contains(-1));
|
||||||
|
QVERIFY(not mc.contains(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(MemoryChunkTest)
|
||||||
7
src/tests/MemoryChunkTests.h
Normal file
7
src/tests/MemoryChunkTests.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
class MemoryChunkTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testIfConstructionWorksProperly();
|
||||||
|
};
|
||||||
55
src/tests/MemorySegmentCoordinatorTests.cpp
Normal file
55
src/tests/MemorySegmentCoordinatorTests.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "MemorySegmentCoordinatorTests.h"
|
||||||
|
|
||||||
|
#include "MemorySegmentCoordinator.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
void MemorySegmentCoordinatorTest::testSimpleQueries()
|
||||||
|
{
|
||||||
|
MemorySegmentCoordinator segmenter;
|
||||||
|
segmenter.addSegment(
|
||||||
|
LinearAddress(0x10),
|
||||||
|
LinearAddress(0x13),LinearAddress(0x20),
|
||||||
|
".text",4);
|
||||||
|
MemorySegment * seg;
|
||||||
|
QCOMPARE(segmenter.getSegment(LinearAddress(0x9)),(MemorySegment *)nullptr);
|
||||||
|
seg = segmenter.getSegment(0x14);
|
||||||
|
QVERIFY(seg!=nullptr);
|
||||||
|
if(seg) {
|
||||||
|
QCOMPARE(seg->getName(),QString(".text"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MemorySegmentCoordinatorTest::testAddingSegments()
|
||||||
|
{
|
||||||
|
MemorySegmentCoordinator segmenter;
|
||||||
|
QVERIFY(segmenter.addSegment(
|
||||||
|
LinearAddress(0x10),
|
||||||
|
LinearAddress(0x13),LinearAddress(0x20),
|
||||||
|
".text",4));
|
||||||
|
QCOMPARE(segmenter.size(),uint32_t(1));
|
||||||
|
QVERIFY(segmenter.addSegment(
|
||||||
|
LinearAddress(0x20),
|
||||||
|
LinearAddress(0x22),LinearAddress(0x33),
|
||||||
|
".text",4));
|
||||||
|
QVERIFY2(not segmenter.addSegment(
|
||||||
|
LinearAddress(0x20),
|
||||||
|
LinearAddress(0x40),LinearAddress(0x20),
|
||||||
|
".text",4),"Adding segment with start>fin should fail");
|
||||||
|
QVERIFY2(not segmenter.addSegment(
|
||||||
|
LinearAddress(0x20),
|
||||||
|
LinearAddress(0x10),LinearAddress(0x20),
|
||||||
|
".text",4),"Segment start should be >= base");
|
||||||
|
QCOMPARE(segmenter.size(),uint32_t(2));
|
||||||
|
}
|
||||||
|
void MemorySegmentCoordinatorTest::testAddingIntersectingSegments()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(MemorySegmentCoordinatorTest)
|
||||||
9
src/tests/MemorySegmentCoordinatorTests.h
Normal file
9
src/tests/MemorySegmentCoordinatorTests.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
class MemorySegmentCoordinatorTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testAddingSegments();
|
||||||
|
void testAddingIntersectingSegments();
|
||||||
|
void testSimpleQueries();
|
||||||
|
};
|
||||||
53
src/tests/ProjectTests.cpp
Normal file
53
src/tests/ProjectTests.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "ProjectTests.h"
|
||||||
|
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
static bool logset = false;
|
||||||
|
static QString TEST_BASE;
|
||||||
|
static QDir baseDir;
|
||||||
|
|
||||||
|
void ProjectTest::initTestCase() {
|
||||||
|
if (!logset) {
|
||||||
|
TEST_BASE = QProcessEnvironment::systemEnvironment().value("DCC_TEST_BASE", "");
|
||||||
|
baseDir = QDir(TEST_BASE);
|
||||||
|
if (TEST_BASE.isEmpty()) {
|
||||||
|
qWarning() << "DCC_TEST_BASE environment variable not set, will assume '..', many test may fail";
|
||||||
|
TEST_BASE = "..";
|
||||||
|
baseDir = QDir("..");
|
||||||
|
}
|
||||||
|
logset = true;
|
||||||
|
// Boomerang::get()->setProgPath(TEST_BASE);
|
||||||
|
// Boomerang::get()->setPluginPath(TEST_BASE + "/out");
|
||||||
|
// Boomerang::get()->setLogger(new NullLogger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ProjectTest::testNewProjectIsInitalized() {
|
||||||
|
Project p;
|
||||||
|
QCOMPARE((CALL_GRAPH *)nullptr,p.callGraph);
|
||||||
|
QVERIFY(p.pProcList.empty());
|
||||||
|
QVERIFY(p.binary_path().isEmpty());
|
||||||
|
QVERIFY(p.project_name().isEmpty());
|
||||||
|
QVERIFY(p.symtab.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectTest::testCreatedProjectHasValidNames() {
|
||||||
|
Project p;
|
||||||
|
QStringList strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro\\ ject3"};
|
||||||
|
QStringList expected = {"Project1","Project2","Pro\\ ject3"};
|
||||||
|
for(size_t i=0; i<strs.size(); i++)
|
||||||
|
{
|
||||||
|
p.create(strs[i]);
|
||||||
|
QCOMPARE((CALL_GRAPH *)nullptr,p.callGraph);
|
||||||
|
QVERIFY(p.pProcList.empty());
|
||||||
|
QCOMPARE(expected[i],p.project_name());
|
||||||
|
QCOMPARE(strs[i],p.binary_path());
|
||||||
|
QVERIFY(p.symtab.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QTEST_MAIN(ProjectTest)
|
||||||
10
src/tests/ProjectTests.h
Normal file
10
src/tests/ProjectTests.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
class ProjectTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void testNewProjectIsInitalized();
|
||||||
|
void testCreatedProjectHasValidNames();
|
||||||
|
void initTestCase();
|
||||||
|
};
|
||||||
@ -1,14 +0,0 @@
|
|||||||
#include "project.h"
|
|
||||||
#include "loader.h"
|
|
||||||
#include <gmock/gmock.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(Loader, NewProjectIsInitalized) {
|
|
||||||
Project p;
|
|
||||||
EXPECT_EQ(nullptr,p.callGraph);
|
|
||||||
ASSERT_TRUE(p.pProcList.empty());
|
|
||||||
ASSERT_TRUE(p.binary_path().empty());
|
|
||||||
ASSERT_TRUE(p.project_name().empty());
|
|
||||||
ASSERT_TRUE(p.symtab.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
#include "project.h"
|
|
||||||
#include <gmock/gmock.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(Project, NewProjectIsInitalized) {
|
|
||||||
Project p;
|
|
||||||
EXPECT_EQ(nullptr,p.callGraph);
|
|
||||||
ASSERT_TRUE(p.pProcList.empty());
|
|
||||||
ASSERT_TRUE(p.binary_path().empty());
|
|
||||||
ASSERT_TRUE(p.project_name().empty());
|
|
||||||
ASSERT_TRUE(p.symtab.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Project, CreatedProjectHasValidNames) {
|
|
||||||
Project p;
|
|
||||||
std::vector<std::string> strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro\\ ject3"};
|
|
||||||
std::vector<std::string> expected = {"Project1","Project2","Pro\\ ject3"};
|
|
||||||
for(size_t i=0; i<strs.size(); i++)
|
|
||||||
{
|
|
||||||
p.create(strs[i]);
|
|
||||||
EXPECT_EQ(nullptr,p.callGraph);
|
|
||||||
ASSERT_TRUE(p.pProcList.empty());
|
|
||||||
EXPECT_EQ(expected[i],p.project_name());
|
|
||||||
EXPECT_EQ(strs[i],p.binary_path());
|
|
||||||
ASSERT_TRUE(p.symtab.empty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -406,8 +406,9 @@ void phChar(char ch) {
|
|||||||
/* Take a lump of data from a header file, and churn the state machine
|
/* Take a lump of data from a header file, and churn the state machine
|
||||||
through each char */
|
through each char */
|
||||||
boolT phData(char *buff, int ndata) {
|
boolT phData(char *buff, int ndata) {
|
||||||
int i, j;
|
int i;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
int j=0;
|
||||||
char cLine[81];
|
char cLine[81];
|
||||||
char cfLine[90];
|
char cfLine[90];
|
||||||
#endif
|
#endif
|
||||||
@ -415,7 +416,6 @@ boolT phData(char *buff, int ndata) {
|
|||||||
if (ndata < 1) {
|
if (ndata < 1) {
|
||||||
ndata = strlen(buff);
|
ndata = strlen(buff);
|
||||||
}
|
}
|
||||||
j = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < ndata; i++) {
|
for (i = 0; i < ndata; i++) {
|
||||||
phChar(buff[i]);
|
phChar(buff[i]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user