Alessandro/refactor/llvmmultiversion cmake (#111)

* Change copyright notice in all the places. Trying to get cmake to download all the things

* CMake refactor

* Added the lib repository installer

* Fixed a couple of paths in library repository scripts

* Spelling and a missing .gitignore file.

* The google test library was not correctly linked

* Removed the pre-compiled XED library

* Removed unused files; fixed the INSTALL directives. Added automatic protobuf generation.

* Added a package generator script for ArchLinux

* Merged in Alessandro's cmake magic

* Cleanups, compatibility changes

* CMake cleanup.

 o Removed the cmake folder as it is no longer used.
 o Removed the library_repository_installer directory and
   replaced it with a submodule to the newly introduced
   cxx_common repository.
 o Added the 'use_remill_semantics' branch of mcsema as a
   submodule under tools/cmake.
 o Updated the README instructions (added --recursive to the
   git clone command).

Warning: the mcsema submodule is pointing to my fork of the
repository!

* CMake: avoid re-defining the C/CXX/ASM compiler.

This will prevent CMake from looping forever when using submodules.

* The tools/mcsema submodule now points to the official repository.

* mcsema submodule update

* Updated the mcsema git submodule to track the newest changes.

* Various CMake fixes (see details).

 o External include headers were not correctly marked
   as SYSTEM. This caused them to output warnings and
   break the build.
 o The PROJECT_SOURCE CMake variable has been replaced
   with CMAKE_SOURCE_DIR.
 o Updated the mcsema submodule to point to the latest
   CMake fixes.

* Getting closer to having the test case runner work again without using the CFG protobufs.

* Trying to make things use ubuntu clang/llvm packages

* Update to the mcsema submodule.

* Minor changes for llvm version compatibility

* Test cases should run now. Had to compile the lifted testcases to a .S file, as with the .bc file, they were being optimized away.. I think. The compilation to assembly seems unusually slow, though.

* Minor change

* Some stuff for llvm 4.0 support

* Remove mcsema sub-module

* Remove cxx-common submodule

* First steps toward getting travis working again

* Attempt at getting travis working again

* Using https for cloning instead of ssh

* Minor build script update

* Added ISEL_ prefix to isels to make it easier for ForEachISel to find them. Commented out the defer_inlining intrinsics.

* Changes related to mcsema2

* Simplify runtime targets generation. (#110)

* CMake refactor: Added a new language 'BC' for the bitcode (see details).

The language is used to generate the runtimes used by the architecture
modules. The required executables (clang++ and llvm-link) are
automatically detected in the same way as other compilers are.

A new CMake function has been added and it can be used to easily
generate runtime targets in a way similar to add_executable:

    add_runtime(<name> SOURCE <source list> ADDRESS_SIZE <n>
        DEFINITIONS <definition list>)

Additionally, all files ending with the *.bcpp extensions will
automatically invoke the bitcode compiler when listed in an
active target.

This should open support for parallel compilation! You just have to
list all your .cpp files when calling add_runtime.

* CMake: Fixes to the BC language handler.

* CMake/BC: Use '.bo' for object files. X86 runtime: Add -g/-O flags.
This commit is contained in:
Peter Goodman
2017-05-15 13:00:33 -04:00
committed by GitHub
parent 00ac9298f9
commit e1bdbdba9e
359 changed files with 4630 additions and 47860 deletions
+13 -1
View File
@@ -1,4 +1,16 @@
# Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved.
# Copyright (c) 2017 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
install_manifest.txt
Makefile
-1
View File
@@ -20,7 +20,6 @@ install:
- ./scripts/travis/install.sh
before_script:
- cd build
- if [[ "${TRAVIS_OS_NAME}" == "linux" ]] ; then make build_x86_tests ; fi
script:
- if [[ "${TRAVIS_OS_NAME}" == "linux" ]] ; then ctest ; fi
notifications:
+1
View File
@@ -6,6 +6,7 @@ The following individuals have graciously contributed their time to improving
Remill:
- [Akshay Kumar](https://github.com/kumarak)
- [Alessandro Gario](https://github.com/alessandrogario)
- [Douglas Goddard](https://github.com/douggard)
- [Kareem El-Faramawi](https://github.com/krx)
- [Peter Goodman](https://github.com/pgoodman)
+173 -108
View File
@@ -1,138 +1,203 @@
# Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved.
# Copyright (c) 2017 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
project(remill)
cmake_minimum_required (VERSION 3.2)
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR "Remill and its tools are 64-bit only tools.")
endif()
enable_language(ASM)
# add the BC (bitcode) language definition
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/BCCompiler")
include(CTest)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(REMILL_SOURCE_DIR "${PROJECT_SOURCE_DIR}")
find_package(LLVM 3.9 REQUIRED)
#
# compiler selection
#
if (DEFINED ENV{TRAILOFBITS_LIBRARIES})
set(LIBRARY_REPOSITORY_ROOT $ENV{TRAILOFBITS_LIBRARIES})
include("${LIBRARY_REPOSITORY_ROOT}/cmake/repository.cmake")
message(STATUS "Using the following library repository: ${LIBRARY_REPOSITORY_ROOT}")
else ()
message(STATUS "Using system libraries")
endif ()
# llvm
if (DEFINED ENV{LLVM_INSTALL_PREFIX})
set(LLVM_INSTALL_PREFIX $ENV{LLVM_INSTALL_PREFIX})
endif ()
if (DEFINED LLVM_INSTALL_PREFIX)
list(APPEND FINDPACKAGE_LLVM_HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/llvm/")
list(APPEND FINDPACKAGE_LLVM_HINTS "${LLVM_INSTALL_PREFIX}/share/llvm/cmake/")
message(STATUS "Using LLVM_INSTALL_PREFIX hints for find_package(LLVM): ${FINDPACKAGE_LLVM_HINTS}")
endif ()
# it is important to avoid re-defining these variables if they have been already
# set or you risk ending up in a configure loop!
if (NOT DEFINED CMAKE_C_COMPILER)
if (DEFINED LLVM_INSTALL_PREFIX)
set(CMAKE_C_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang")
else ()
set(CMAKE_C_COMPILER "clang")
endif ()
endif ()
if (NOT DEFINED CMAKE_CXX_COMPILER)
if (DEFINED LLVM_INSTALL_PREFIX)
set(CMAKE_CXX_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang++")
else ()
set(CMAKE_CXX_COMPILER "clang++")
endif ()
endif ()
if (NOT DEFINED CMAKE_ASM_COMPILER)
if (DEFINED LLVM_INSTALL_PREFIX)
set(CMAKE_ASM_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang")
else ()
set(CMAKE_ASM_COMPILER ${CMAKE_CXX_COMPILER})
endif ()
endif ()
if (NOT DEFINED CMAKE_LLVM_LINK)
if (DEFINED LLVM_INSTALL_PREFIX)
set(CMAKE_LLVM_LINK "${LLVM_INSTALL_PREFIX}/bin/llvm-link")
else ()
set(CMAKE_LLVM_LINK "llvm-link")
endif ()
endif ()
enable_language(C)
enable_language(CXX)
enable_language(ASM)
#
# compiler settings
#
# enable the gnu extensions
set(CMAKE_CXX_EXTENSIONS ON)
# visual studio already defaults to c++11
if (NOT WIN32)
set(CMAKE_CXX_STANDARD 11)
endif ()
# warnings and compiler settings
set(PROJECT_CXXWARNINGS "-Wall -Wextra -Werror -pedantic -Wno-unused-parameter -Wno-c++98-compat -Wno-unreachable-code-return -Wno-nested-anon-types -Wno-extended-offsetof -Wno-gnu-anonymous-struct -Wno-gnu-designator -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -Wno-gnu-statement-expression -Wno-return-type-c-linkage -Wno-c99-extensions -Wno-ignored-attributes -Wno-unused-local-typedef")
set(PROJECT_CXXFLAGS "${PROJECT_CXXFLAGS} -Wno-unknown-warning-option ${PROJECT_CXXWARNINGS} -fPIC -fno-omit-frame-pointer -fvisibility-inlines-hidden -fno-exceptions -fno-asynchronous-unwind-tables -fno-rtti")
# default build type
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif ()
# debug symbols
if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(PROJECT_CXXFLAGS "${PROJECT_CXXFLAGS} -gdwarf-2 -g3")
endif ()
# optimization flags and definitions
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(PROJECT_CXXFLAGS "${PROJECT_CXXFLAGS} -O0")
else ()
set(PROJECT_CXXFLAGS "${PROJECT_CXXFLAGS} -O3")
list(APPEND PROJECT_DEFINITIONS "NDEBUG")
endif ()
#
# libraries
#
find_package(LLVM REQUIRED CONFIG HINTS ${FINDPACKAGE_LLVM_HINTS})
set(LLVM_LIBRARIES LLVMCore LLVMSupport LLVMAnalysis LLVMipo LLVMIRReader LLVMBitReader LLVMBitWriter LLVMTransformUtils LLVMScalarOpts LLVMLTO)
list(APPEND PROJECT_LIBRARIES ${LLVM_LIBRARIES})
list(APPEND PROJECT_DEFINITIONS ${LLVM_DEFINITIONS})
list(APPEND PROJECT_INCLUDEDIRECTORIES ${LLVM_INCLUDE_DIRS})
# xed
find_package(XED REQUIRED)
find_package(GLOG REQUIRED)
find_package(GFLAGS REQUIRED)
find_package(Protobuf REQUIRED)
list(APPEND PROJECT_LIBRARIES ${XED_LIBRARIES})
list(APPEND PROJECT_INCLUDEDIRECTORIES ${XED_INCLUDE_DIRS})
include_directories("${PROJECT_SOURCE_DIR}")
include_directories("${LLVM_INCLUDE_DIRS}")
include_directories("${XED_INCLUDE_DIRS}")
include_directories("${GLOG_INCLUDE_DIRS}")
include_directories("${GFLAGS_INCLUDE_DIRS}")
include_directories("${PROTOBUF_INCLUDE_DIRS}")
include_directories("${CMAKE_CURRENT_LIST_DIR}")
# google log module
find_package(glog REQUIRED)
list(APPEND PROJECT_LIBRARIES glog::glog)
set(CMAKE_ASM_COMPILER ${CMAKE_CXX_COMPILER})
# gflags
find_package(gflags REQUIRED)
list(APPEND PROJECT_LIBRARIES gflags)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
#
# target settings
#
if(NOT DEFINED CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang-3.9")
endif()
list(APPEND PROJECT_DEFINITIONS "INSTALL_SEMANTICS_DIR=\"${CMAKE_INSTALL_PREFIX}share/remill/semantics/\"")
list(APPEND PROJECT_DEFINITIONS "BUILD_SEMANTICS_DIR=\"${CMAKE_CURRENT_BINARY_DIR}/remill/Arch/X86/Runtime/\"")
if(NOT DEFINED CMAKE_CXX_COMPILER)
set(CMAKE_CXX_COMPILER ${CMAKE_C_COMPILER})
endif()
if(NOT DEFINED CMAKE_ASM_COMPILER)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
endif()
if(NOT DEFINED CMAKE_LLVM_LINK)
set(CMAKE_LLVM_LINK "${LLVM_INSTALL_PREFIX}/bin/llvm-link")
endif()
if(UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
add_definitions(${LLVM_DEFINITIONS})
add_compile_options(
-Wall
-Wextra
-Werror
-pedantic
-g3
-O0
-Wno-unused-parameter
-Wno-c++98-compat
-Wno-unreachable-code-return
-Wno-nested-anon-types
-Wno-extended-offsetof
-Wno-gnu-anonymous-struct
-Wno-gnu-designator
-Wno-variadic-macros
-Wno-gnu-zero-variadic-macro-arguments
-Wno-gnu-statement-expression
-Wno-return-type-c-linkage
-Wno-c99-extensions
-Wno-ignored-attributes
-Wno-unused-local-typedef
-fno-omit-frame-pointer
-fvisibility-inlines-hidden
-fno-exceptions
-fno-rtti
-fno-asynchronous-unwind-tables
-fno-rtti
-std=gnu++11
-m64
-DINSTALL_SEMANTICS_DIR="${CMAKE_INSTALL_PREFIX}/share/remill/semantics/"
-DBUILD_SEMANTICS_DIR="${CMAKE_CURRENT_BINARY_DIR}/remill/Arch/X86/Runtime/"
-DGOOGLE_PROTOBUF_NO_RTTI
)
add_library(remill STATIC
add_library(${PROJECT_NAME} STATIC
remill/Arch/X86/Arch.cpp
remill/Arch/Arch.cpp
remill/Arch/Instruction.cpp
remill/Arch/Name.cpp
remill/CFG/BlockHasher.cpp
remill/CFG/CFG.cpp
remill/BC/IntrinsicTable.cpp
remill/BC/Lifter.cpp
remill/BC/Optimizer.cpp
remill/BC/Util.cpp
remill/OS/FileSystem.cpp
remill/OS/OS.cpp
third_party/murmurhash/MurmurHash2.cpp)
target_link_libraries(remill
${GFLAGS_LIBRARIES}
${GLOG_LIBRARIES}
${XED_LIBRARIES}
${PROTOBUF_LIBRARIES}
LLVMCore
LLVMSupport
LLVMAnalysis
LLVMipo
LLVMIRReader
LLVMBitReader
LLVMBitWriter
LLVMTransformUtils
LLVMScalarOpts
LLVMLTO
)
install(
TARGETS remill
ARCHIVE DESTINATION lib
)
# this is needed for the #include directives with absolutes paths to work correctly; it must
# also be set to PUBLIC since remill-lift includes some files directly
list(APPEND PROJECT_INCLUDEDIRECTORIES ${CMAKE_SOURCE_DIR})
# add everything as public; the remill_lift executable will inherit all settings from us
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_LIBRARIES})
target_include_directories(${PROJECT_NAME} PUBLIC SYSTEM ${PROJECT_INCLUDEDIRECTORIES})
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_DEFINITIONS})
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${PROJECT_CXXFLAGS})
#
# install directives
#
install(DIRECTORY DESTINATION "share/remill")
#
# additional targets
#
add_custom_target(semantics)
add_subdirectory(remill/Arch/X86/Runtime)
add_subdirectory(tools)
# mcsema needs to be manually cloned into this repo.
if (EXISTS ${CMAKE_SOURCE_DIR}/tools/mcsema)
add_subdirectory(tools/mcsema)
endif ()
add_subdirectory(tests/X86)
# only enable tests when compiling under x64
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if(UNIX AND NOT APPLE)
set(LINUX TRUE)
add_subdirectory(tests/X86)
endif ()
endif ()
+1 -26
View File
@@ -173,29 +173,4 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Trail of Bits, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
END OF TERMS AND CONDITIONS
+12 -58
View File
@@ -1,8 +1,9 @@
# Remill
Remill is a static binary translator that translates machine code into [LLVM bitcode](http://llvm.org/docs/LangRef.html). It translates x86 and amd64 machine code (including AVX and AVX512) into LLVM bitcode.
Remill focuses on accurately lifting instructions. It is meant to be used as a library for other tools, e.g. [McSema](https://github.com/trailofbits/mcsema).
## Build Status
| | master |
@@ -15,7 +16,6 @@ Remill is a static binary translator that translates machine code into [LLVM bit
- [How to contribute](docs/CONTRIBUTING.md)
- [How to implement the semantics of an instruction](docs/ADD_AN_INSTRUCTION.md)
- [How instructions are lifted](docs/LIFE_OF_AN_INSTRUCTION.md)
- [How binaries are represented](docs/CFG_FORMAT.md)
- [The design and architecture of Remill](docs/DESIGN.md)
## Getting Help
@@ -34,19 +34,14 @@ We are actively working on porting Remill to macOS.
| ---- | ------- |
| [Git](https://git-scm.com/) | Latest |
| [CMake](https://cmake.org/) | 3.2+ |
| [Google Log](https://github.com/google/glog) | 0.3.3 |
| [Google Test](https://github.com/google/googletest) | 1.6.0 |
| [Google Protobuf](https://github.com/google/protobuf) | 2.6.1 |
| [LLVM](http://llvm.org/) | 3.9 |
| [Clang](http://clang.llvm.org/) | 3.9 |
| [Google Flags](https://github.com/google/glog) | 2.2.0 |
| [Google Log](https://github.com/google/glog) | 0.3.4 |
| [Google Test](https://github.com/google/googletest) | 1.8.0 |
| [LLVM](http://llvm.org/) | 3.5+ |
| [Clang](http://clang.llvm.org/) | 3.5+ |
| [Intel XED](https://software.intel.com/en-us/articles/xed-x86-encoder-decoder-software-library) | 2016-02-02 |
| [Python](https://www.python.org/) | 2.7 |
| [Python Package Index](https://pypi.python.org/pypi) | Latest |
| [python-magic](https://pypi.python.org/pypi/python-magic) | Latest |
| Unzip | Latest |
| [python-protobuf](https://pypi.python.org/pypi/protobuf) | 2.6.1 |
| [Binary Ninja](https://binary.ninja) | Latest |
| [IDA Pro](https://www.hex-rays.com/products/ida) | 6.7+ |
## Getting and Building the Code
@@ -63,30 +58,11 @@ sudo apt-get upgrade
sudo apt-get install \
git \
cmake \
libgoogle-glog-dev \
libgtest-dev \
libprotoc-dev libprotobuf-dev libprotobuf-dev protobuf-compiler \
python2.7 python-pip \
g++-multilib \
build-essential \
unzip \
software-properties-common \
realpath
sudo pip install --upgrade pip
sudo pip install python-magic 'protobuf==2.6.1'
```
##### Using IDA on 64 bit Ubuntu
If your IDA install does not use the system's Python, you can add the `protobuf` library manually to IDA's zip of modules.
```
# Python module dir is generally in /usr/lib or /usr/local/lib
touch /path/to/python2.7/dist-packages/google/__init__.py
cd /path/to/lib/python2.7/dist-packages/
sudo zip -rv /path/to/ida-6.X/python/lib/python27.zip google/
sudo chown your_user:your_user /home/taxicat/ida-6.7/python/lib/python27.zip
```
##### Upgrade CMake (Ubuntu 14.04)
@@ -106,14 +82,14 @@ sudo apt-get install cmake
```
brew install glog
brew install protobuf
```
### Step 2: Clone and Enter the Repository
#### Clone the repository
```shell
git clone git@github.com:trailofbits/remill.git
This will also clone the cxx_common module (used to generate a library repository) and mcsema.
git clone --resursive git@github.com:trailofbits/remill.git
```
#### Enter the repository
@@ -121,17 +97,11 @@ git clone git@github.com:trailofbits/remill.git
cd remill
```
#### Run the Build Script
#### Build the code.
```shell
./build.sh
```
### Step 3: Install the disassembler
```shell
sudo python tools/setup.py install
```
## Building and Running the Test Suite
### Build Google Test
@@ -153,20 +123,4 @@ ctest
## Try it Out
If you have a 64 bit dll, you can get started with the following commands. First, you recover control flow graph information using `remill-disass`, this can use either IDA Pro or Binary Ninja as the disassembler.
```shell
remill-disass --disassembler /path/to/ida/idal64 --arch amd64 --output target.cfg --binary libsomething.dll
```
Once you have the control flow graph information, you can lift the target binary using `remill-lift`.
```shell
remill-lift --arch amd64 --os linux --cfg target.cfg --bc_out target.bc
```
When the bitcode has been recovered by `remill-lift`, it is a good idea to optimize it using `remill-opt`.
```shell
remill-opt --bc_in target.bc --bc_out opt_target.bc
```
Remill is a library, and so there is no single way to try it. However, you can head on over to the [McSema](https://github.com/trailofbits/mcsema) repository and try that!
-144
View File
@@ -1,144 +0,0 @@
IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING.
Do not copy, install, or use the "Materials" provided under this
license agreement ("Agreement"), until you have carefully read the
following terms and conditions. By copying, installing, or otherwise
using the Materials, you agree to be bound by the terms of this
Agreement. If you do not agree to the terms of this Agreement, do not
copy, install, or use the Materials.
Pre-Release License Agreement for Pre-Release Software
1. PRE-RELEASE: The Materials are pre-release code, which may not be
fully functional and which Intel may substantially modify in producing
any final version. Intel can provide no assurance that it will ever
produce or make generally available a final version.
2. LICENSE DEFINITIONS:
A. "Materials" are defined as the software, documentation, license key
codes and other materials, including any updates and upgrade thereto,
for the applicable pre-release software (which may be found at
http://whatif.intel.com/), that are provided to you under this
Agreement.
3. LICENSE GRANT:
A. Subject to all of the terms and conditions of this Agreement, Intel
Corporation ("Intel") grants to you a non-exclusive, non-assignable
copyright license to make only the minimum number of copies of the
Materials reasonably necessary for your internal testing and
development of your products.
B. Subject to all of the terms and conditions of this Agreement, Intel
grants to you a non-exclusive, non-assignable copyright license to
modify the Materials that are provided in source code (human readable)
form.
C. If the Materials include the file named 'redist.txt', then subject
to all of the terms and conditions of this Agreement and any specific
restrictions which may appear in the 'redist.txt' file, Intel grants
to you a non-exclusive, non-assignable copyright license to
redistribute the files (unmodified or modified by you) listed in the
'redist.txt' file only as part of the application you develop with the
Materials.
4. LICENSE RESTRICTIONS:
A. You may not reverse-assemble, reverse-compile, or otherwise
reverse-engineer any software provided solely in binary form.
B. You may not distribute any portion of Materials, whether in source
or binary form, to any third party, except as specified in this
Agreement.
5. COPYRIGHT: Title to the Materials and all copies thereof remain
with Intel or its suppliers. The Materials are copyrighted and are
protected by United States copyright laws and international treaty
provisions. You will not remove any copyright notice from the
Materials. You agree to prevent any unauthorized copying of the
Materials. Except as expressly provided herein, Intel does not grant
any express or implied right to you under Intel patents, copyrights,
trademarks, or trade secret information. Subject to Intel's ownership
of the Materials, all right, title and interest in and to your
modifications shall belong to you.
6. REPLACEMENTS: The Materials are provided "AS IS" without warranty
of any kind. If the media on which the Materials are furnished are
found to be defective in material or workmanship under normal use for
a period of ninety (90) days from the date of receipt, Intel's entire
liability and your exclusive remedy shall be the replacement of the
media. This offer is void if the media defect results from accident,
abuse, or misapplication.
7. LIMITATION OF LIABILITY: THE ABOVE REPLACEMENT PROVISION IS THE
ONLY WARRANTY OF ANY KIND. INTEL OFFERS NO OTHER WARRANTY EITHER
EXPRESS OR IMPLIED INCLUDING THOSE OF MERCHANTABILITY, NONINFRINGEMENT
OF THIRD- PARTY INTELLECTUAL PROPERTY OR FITNESS FOR A PARTICULAR
PURPOSE. NEITHER INTEL NOR ITS SUPPLIERS SHALL BE LIABLE FOR ANY
DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
OR OTHER LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE
SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR
LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE
ABOVE LIMITATION MAY NOT APPLY TO YOU.
8. UNAUTHORIZED USE: THE MATERIALS ARE NOT DESIGNED, INTENDED, OR
AUTHORIZED FOR USE IN ANY TYPE OF SYSTEM OR APPLICATION IN WHICH THE
FAILURE OF THE MATERIALS COULD CREATE A SITUATION WHERE PERSONAL
INJURY OR DEATH MAY OCCUR (E.G MEDICAL SYSTEMS, LIFE SUSTAINING OR
LIFE SAVING SYSTEMS). Should the buyer purchase or use the Materials
for any such unintended or unauthorized use, the buyer shall indemnify
and hold Intel and its officers, subsidiaries and affiliates harmless
against all claims, costs, damages, and expenses, and reasonable
attorney fees arising out of, directly or indirectly, any claim of
product liability, personal injury or death associated with such
unintended or unauthorized use, even if such claim alleges that Intel
was negligent regarding the design or manufacture of the part.
9. USER SUBMISSIONS: You agree that any material, information or other
communication, including all data, images, sounds, text, and other
things embodied therein, you transmit or post to an Intel website or
provide to Intel under this Agreement will be considered
non-confidential ("Communications"). Intel will have no
confidentiality obligations with respect to the Communications. You
agree that Intel and its designees will be free to copy, modify,
create derivative works, publicly display, disclose, distribute,
license and sublicense through multiple tiers of distribution and
licensees, incorporate and otherwise use the Communications, including
derivative works thereto, for any and all commercial or non-commercial
purposes.
10. TERMINATION OF THIS LICENSE: The term of this Agreement will
commence on the date this Agreement is accepted by You and will
continue until terminated. This Agreement will terminate without
notice on the last day of the pre-release period, which is specified
elsewhere in the Materials, or upon the commercial release of the
Materials. Intel may terminate this Agreement at any time, with or
without cause, with written notice to you. Upon termination, you will
immediately destroy the Materials or return all copies of the
Materials to Intel along with any copies you have made.
11. U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
"RESTRICTED RIGHTS". Use, duplication or disclosure by the Government
is subject to restrictions set forth in FAR52.227-14 and
DFAR252.227-7013 et seq. or its successor. Use of the Materials by the
Government constitutes acknowledgment of Intel's rights in them.
12. EXPORT RESTRICTED RIGHTS: This software is subject to the
U.S. Export Administration Regulations and other U.S. law, and may not
be exported or re-exported to certain countries (Burma, Cuba, Iran,
North Korea, Sudan, and Syria) or to persons or entities prohibited
from receiving U.S. exports (including Denied Parties, Specially
Designated Nationals, and entities on the Bureau of Export
Administration Entity List or involved with missile technology or
nuclear, chemical or biological weapons).
13. APPLICABLE LAWS: Any claim arising under or relating to this
Agreement shall be governed by the internal substantive laws of the
State of Delaware or federal courts located in Delaware, without
regard to principles of conflict of laws. You may not export the
Materials in violation of applicable export laws.
* Other names and brands may be claimed as the property of others
-6
View File
@@ -1,6 +0,0 @@
This file is redist.txt.
The files in the directories "include", "lib", "doc", "misc",
"mbuild", and "examples" if present, are allowed to be redistributed
subject to the terms of the license found in the LICENSE.txt file.
Binary file not shown.
Binary file not shown.
-33252
View File
File diff suppressed because it is too large Load Diff
-73
View File
@@ -1,73 +0,0 @@
#!/usr/bin/env bash
# Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved.
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BUILD_DIR=${DIR}/build
LLVM_DIR=llvm
ARCH=$(uname -m)
LLVM_VER=3.9.0
case $(uname -s) in
Darwin)
OS=apple-darwin
FILE=clang+llvm-${LLVM_VER}-${ARCH}-${OS}.tar.xz
;;
Linux)
OS=linux-gnu
DISTRO=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
DIST_VERSION=$(lsb_release -sr)
if [ $DIST_VERSION == "15.04" ]; then
DIST_VERSION="14.04"
fi
FILE=clang+llvm-${LLVM_VER}-${ARCH}-${OS}-${DISTRO}-${DIST_VERSION}.tar.xz
;;
*)
echo '[!] Unsupported OS'
exit 1
;;
esac
echo "[+] Creating '${BUILD_DIR}'"
mkdir -p ${BUILD_DIR}
pushd ${BUILD_DIR}
if [ ! -f ${FILE} ]; then
echo "[+] Downloading Clang+LLVM.."
wget http://llvm.org/releases/${LLVM_VER}/${FILE}
if [ "$?" != "0" ]; then
echo "[!] Unsupported operating system."
echo "[!] Check http://llvm.org/releases/${LLVM_VER}/ to see what LLVM"
echo "[!] packages are available."
exit 2
fi
fi
if [ ! -d ${LLVM_DIR} ]; then
echo "[+] Extracting.."
mkdir ${LLVM_DIR}
tar xf ${FILE} -C ${LLVM_DIR} --strip-components=1
fi
echo "[+] Installing Xed"
$DIR/scripts/unix/install_xed.sh
echo "[+] Installing gtest"
$DIR/scripts/unix/install_gtest.sh
echo "[+] Compiling protobufs"
$DIR/scripts/unix/compile_protobufs.sh
echo "[+] Running cmake"
LLVM_DIR=${BUILD_DIR}/${LLVM_DIR}
LLVM_DIR=$(realpath ${LLVM_DIR})
BINDIR=${LLVM_DIR}/bin
LLVM_DIR=${LLVM_DIR}/lib/cmake/llvm
cmake -DLLVM_DIR=${LLVM_DIR} -DCMAKE_C_COMPILER=${BINDIR}/clang -DCMAKE_CXX_COMPILER=${BINDIR}/clang++ -DCMAKE_LLVM_LINK=${BINDIR}/llvm-link ${DIR}
echo "[+] Building"
make
echo "[+] installing"
sudo make install
@@ -0,0 +1,8 @@
set(CMAKE_BC_COMPILER "@CMAKE_BC_COMPILER@")
set(CMAKE_BC_LINKER "@CMAKE_BC_LINKER@")
set(CMAKE_BC_COMPILER_LOADED 1)
set(CMAKE_BC_SOURCE_FILE_EXTENSIONS bcpp)
set(CMAKE_BC_OUTPUT_EXTENSION .bo)
set(CMAKE_BC_OUTPUT_EXTENSION_REPLACE 1)
set(CMAKE_BC_COMPILER_ENV_VAR "BC_COMPILER")
+69
View File
@@ -0,0 +1,69 @@
set(DEFAULT_BC_COMPILER_FLAGS "-std=gnu++11 -emit-llvm -Wno-unknown-warning-option -Werror -Wall -Wshadow -Wconversion -Wpadded -pedantic -Wshorten-64-to-32 -Wno-gnu-anonymous-struct -Wno-return-type-c-linkage -Wno-gnu-zero-variadic-macro-arguments -Wno-nested-anon-types -Wno-extended-offsetof -Wno-gnu-statement-expression -Wno-c99-extensions -Wno-ignored-attributes -mtune=generic -fno-vectorize -fno-slp-vectorize -ffreestanding -fno-common -fno-builtin -fno-exceptions -fno-rtti -fno-asynchronous-unwind-tables -Wno-unneeded-internal-declaration -Wno-unused-function")
if (NOT CMAKE_BC_COMPILE_OBJECT)
if (NOT DEFINED CMAKE_BC_COMPILER)
message(SEND_ERROR "The bitcode compiler was not found!")
endif ()
set(CMAKE_BC_COMPILE_OBJECT "${CMAKE_BC_COMPILER} <DEFINES> <INCLUDES> ${DEFAULT_BC_COMPILER_FLAGS} <FLAGS> -c <SOURCE> -o <OBJECT>")
endif ()
if (NOT CMAKE_BC_LINK_EXECUTABLE)
if (NOT DEFINED CMAKE_BC_LINKER)
message(SEND_ERROR "The bitcode linker was not found!")
endif ()
set(CMAKE_BC_LINK_EXECUTABLE "${CMAKE_BC_LINKER} <OBJECTS> -o <TARGET>")
endif ()
if (NOT CMAKE_INCLUDE_FLAG_BC)
set(CMAKE_INCLUDE_FLAG_BC -I)
endif ()
# this is the runtime target generator, used in a similar way to add_executable
set(add_runtime_usage "add_runtime(target_name SOURCES <source file list> ADDRESS_SIZE <size>")
function (add_runtime target_name)
foreach (macro_parameter ${ARGN})
if ("${macro_parameter}" STREQUAL "SOURCES")
set(state "${macro_parameter}")
continue ()
elseif ("${macro_parameter}" STREQUAL "ADDRESS_SIZE")
set(state "${macro_parameter}")
continue ()
endif ()
if ("${state}" STREQUAL "SOURCES")
set_source_files_properties("${macro_parameter}" PROPERTIES LANGUAGE BC)
list(APPEND source_file_list "${macro_parameter}")
elseif ("${state}" STREQUAL "ADDRESS_SIZE")
if (NOT "${macro_parameter}" MATCHES "^[0-9]+$")
message(SEND_ERROR "Invalid ADDRESS_SIZE parameter passed to add_runtime")
endif ()
list(APPEND definitions "ADDRESS_SIZE_BITS=${macro_parameter}")
set(address_size_bits_found True)
else ()
message(SEND_ERROR "Syntax error. Usage: ${add_runtime_usage}")
endif ()
endforeach ()
foreach (source_file ${sourcefile_list})
set_source_files_properties("${source_file}" PROPERTIES LANGUAGE BC)
endforeach ()
if (NOT address_size_bits_found)
message(SEND_ERROR "Missing address size.")
endif ()
if ("${source_file_list}" STREQUAL "")
message(SEND_ERROR "No source files specified.")
endif ()
add_executable("${target_name}" ${source_file_list})
target_compile_definitions("${target_name}" PRIVATE ${definitions})
set_target_properties("${target_name}" PROPERTIES SUFFIX ".bc")
endfunction ()
@@ -0,0 +1,54 @@
if (NOT DEFINED CMAKE_BC_COMPILER)
if (NOT "$ENV{LLVM_INSTALL_PREFIX}" STREQUAL "")
message(STATUS "Setting LLVM_INSTALL_PREFIX from the environment variable...")
set(LLVM_INSTALL_PREFIX $ENV{TRAILOFBITS_LIBRARIES})
endif ()
if (NOT "${LLVM_INSTALL_PREFIX}" STREQUAL "")
message(STATUS "Using LLVM_INSTALL_PREFIX to locate the bitcode compiler")
if (NOT EXISTS "${LLVM_INSTALL_PREFIX}/bin/clang++")
message(SEND_ERROR "Could not find the bitcode compiler set in environment variable LLVM_INSTALL_PREFIX: $ENV{LLVM_INSTALL_PREFIX}.")
endif ()
if (NOT EXISTS "${LLVM_INSTALL_PREFIX}/bin/llvm-link")
message(SEND_ERROR "Could not find the bitcode linker set in environment variable LLVM_INSTALL_PREFIX: $ENV{LLVM_INSTALL_PREFIX}.")
endif ()
set(CMAKE_BC_COMPILER "${LLVM_INSTALL_PREFIX}/bin/clang++" CACHE PATH "Bitcode Compiler")
set(CMAKE_BC_LINKER "${LLVM_INSTALL_PREFIX}/bin/llvm-link" CACHE PATH "Bitcode Linker")
set(CMAKE_BC_COMPILER_ENV_VAR "BC_COMPILER")
else ()
find_program(CLANG_PATH
NAMES "clang++"
PATHS "/usr/bin" "/usr/local/bin"
)
find_program(LLVMLINK_PATH
NAMES "llvm-link"
PATHS "/usr/bin" "/usr/local/bin"
)
if (NOT DEFINED CLANG_PATH OR NOT DEFINED LLVMLINK_PATH)
message(SEND_ERROR "Could not find the bitcode compiler and linker. Either install Clang in the default or define the LLVM_INSTALL_PREFIX environment variable.")
endif ()
set(CMAKE_BC_COMPILER "${CLANG_PATH}" CACHE PATH "Bitcode Compiler")
set(CMAKE_BC_LINKER "${LLVMLINK_PATH}" CACHE PATH "Bitcode Linker")
set(CMAKE_BC_COMPILER_ENV_VAR "BC_COMPILER")
endif ()
endif ()
mark_as_advanced(CMAKE_BC_COMPILER)
mark_as_advanced(CMAKE_BC_LINKER)
mark_as_advanced(CMAKE_BC_COMPILER_ENV_VAR)
if (NOT "${CMAKE_BC_COMPILER}" STREQUAL "")
message(STATUS "Found bitcode compiler: ${CMAKE_BC_COMPILER}")
endif ()
if (NOT "${CMAKE_BC_LINKER}" STREQUAL "")
message(STATUS "Found bitcode linker: ${CMAKE_BC_LINKER}")
endif ()
configure_file(${CMAKE_SOURCE_DIR}/cmake/BCCompiler/CMakeBCCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeBCCompiler.cmake @ONLY)
@@ -0,0 +1 @@
set(CMAKE_BC_COMPILER_WORKS 1 CACHE INTERNAL "")
-52
View File
@@ -1,52 +0,0 @@
# https://github.com/yahoo/caffe/blob/master/cmake/Modules/FindGFlags.cmake
# - Try to find GFLAGS
#
# The following variables are optionally searched for defaults
# GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found
#
# The following are set after configuration is done:
# GFLAGS_FOUND
# GFLAGS_INCLUDE_DIRS
# GFLAGS_LIBRARIES
# GFLAGS_LIBRARYRARY_DIRS
include(FindPackageHandleStandardArgs)
set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
# We are testing only a couple of files in the include directories
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR})
endif()
if(MSVC)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
find_library(GFLAGS_LIBRARY gflags)
endif()
find_package_handle_standard_args(GFlags DEFAULT_MSG GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY)
if(GFLAGS_FOUND)
set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR})
set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY})
message(STATUS "Found gflags (include: ${GFLAGS_INCLUDE_DIR}, library: ${GFLAGS_LIBRARY})")
mark_as_advanced(GFLAGS_LIBRARY_DEBUG GFLAGS_LIBRARY_RELEASE
GFLAGS_LIBRARY GFLAGS_INCLUDE_DIR GFLAGS_ROOT_DIR)
endif()
-81
View File
@@ -1,81 +0,0 @@
# https://github.com/yahoo/caffe/blob/master/cmake/Modules/FindGlog.cmake
# - Try to find the Google Glog library
#
# This module defines the following variables
#
# GLOG_FOUND - Was Glog found
# GLOG_INCLUDE_DIRS - the Glog include directories
# GLOG_LIBRARIES - Link to this
#
# This module accepts the following variables
#
# GLOG_ROOT - Can be set to Glog install path or Windows build path
#
if (NOT DEFINED GLOG_ROOT)
set (GLOG_ROOT /usr /usr/local)
endif (NOT DEFINED GLOG_ROOT)
if(MSVC)
set(LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/Release)
else(MSVC)
set (LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/lib)
endif(MSVC)
macro(_FIND_GLOG_LIBRARIES _var)
find_library(${_var}
NAMES ${ARGN}
PATHS ${LIB_PATHS} /opt/local/lib
/usr/lib/x86_64-linux-gnu
/usr/local/lib
/usr/lib
PATH_SUFFIXES lib
)
mark_as_advanced(${_var})
endmacro()
macro(_GLOG_APPEND_LIBRARIES _list _release)
set(_debug ${_release}_DEBUG)
if(${_debug})
set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}})
else()
set(${_list} ${${_list}} ${${_release}})
endif()
endmacro()
# Linux/OS X builds
find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h
PATHS ${GLOG_ROOT}/include/glog
/usr/include/glog
/opt/local/include/glog # default location in Macports
)
# Find the libraries
# Linux/OS X builds
if(UNIX)
_FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.so)
endif(UNIX)
if(APPLE)
_FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.dylib)
endif(APPLE)
if(GLOG_FOUND)
message(STATUS "glog library found at ${GLOG_LIBRARIES}")
endif()
# handle the QUIETLY and REQUIRED arguments and set GLOG_FOUND to TRUE if
# all listed variables are TRUE
include("${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Glog DEFAULT_MSG
GLOG_LIBRARIES)
# Linux/OS X builds
set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
string(REGEX REPLACE "/libglog.so" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES})
if(GLOG_FOUND)
message(STATUS "Found glog (include: ${GLOG_INCLUDE_DIRS}, library: ${GLOG_LIBRARIES})")
# _GLOG_APPEND_LIBRARIES(GLOG GLOG_LIBRARIES)
endif()
-159
View File
@@ -1,159 +0,0 @@
# Locate the Google C++ Testing Framework.
#
# Defines the following variables:
#
# GTEST_FOUND - Found the Google Testing framework
# GTEST_INCLUDE_DIRS - Include directories
#
# Also defines the library variables below as normal
# variables. These contain debug/optimized keywords when
# a debugging library is found.
#
# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest-main
# GTEST_LIBRARIES - libgtest
# GTEST_MAIN_LIBRARIES - libgtest-main
#
# Accepts the following variables as input:
#
# GTEST_ROOT - (as a CMake or environment variable)
# The root directory of the gtest install prefix
#
# GTEST_MSVC_SEARCH - If compiling with MSVC, this variable can be set to
# "MD" or "MT" to enable searching a GTest build tree
# (defaults: "MD")
#
#-----------------------
# Example Usage:
#
# enable_testing()
# find_package(GTest REQUIRED)
# include_directories(${GTEST_INCLUDE_DIRS})
#
# add_executable(foo foo.cc)
# target_link_libraries(foo ${GTEST_BOTH_LIBRARIES})
#
# add_test(AllTestsInFoo foo)
#
#-----------------------
#
# If you would like each Google test to show up in CTest as
# a test you may use the following macro.
# NOTE: It will slow down your tests by running an executable
# for each test and test fixture. You will also have to rerun
# CMake after adding or removing tests or test fixtures.
#
# GTEST_ADD_TESTS(executable extra_args ARGN)
# executable = The path to the test executable
# extra_args = Pass a list of extra arguments to be passed to
# executable enclosed in quotes (or "" for none)
# ARGN = A list of source files to search for tests & test
# fixtures.
#
# Example:
# set(FooTestArgs --foo 1 --bar 2)
# add_executable(FooTest FooUnitTest.cc)
# GTEST_ADD_TESTS(FooTest "${FooTestArgs}" FooUnitTest.cc)
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009 Philip Lowman <philip@yhbt.com>
# Copyright 2009 Daniel Blezek <blezek@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
#
# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
function(GTEST_ADD_TESTS executable extra_args)
if(NOT ARGN)
message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
endif()
foreach(source ${ARGN})
file(READ "${source}" contents)
string(REGEX MATCHALL "TEST_?F?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
foreach(hit ${found_tests})
string(REGEX REPLACE ".*\\( *([A-Za-z_0-9]+), *([A-Za-z_0-9]+) *\\).*" "\\1.\\2" test_name ${hit})
add_test(${test_name} ${executable} --gtest_filter=${test_name} ${extra_args})
list(APPEND _test_names ${test_name})
endforeach()
endforeach()
set(GTEST_ADD_TEST_NAMES ${_test_names} PARENT_SCOPE)
endfunction()
function(_gtest_append_debugs _endvar _library)
if(${_library} AND ${_library}_DEBUG)
set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
else()
set(_output ${${_library}})
endif()
set(${_endvar} ${_output} PARENT_SCOPE)
endfunction()
function(_gtest_find_library _name)
find_library(${_name}
NAMES ${ARGN}
HINTS
$ENV{GTEST_ROOT}
${GTEST_ROOT}
PATH_SUFFIXES ${_gtest_libpath_suffixes}
)
mark_as_advanced(${_name})
endfunction()
#
if(NOT DEFINED GTEST_MSVC_SEARCH)
set(GTEST_MSVC_SEARCH MD)
endif()
set(_gtest_libpath_suffixes lib)
if(MSVC)
if(GTEST_MSVC_SEARCH STREQUAL "MD")
list(APPEND _gtest_libpath_suffixes
msvc/gtest-md/Debug
msvc/gtest-md/Release)
elseif(GTEST_MSVC_SEARCH STREQUAL "MT")
list(APPEND _gtest_libpath_suffixes
msvc/gtest/Debug
msvc/gtest/Release)
endif()
endif()
find_path(GTEST_INCLUDE_DIR gtest/gtest.h
HINTS
$ENV{GTEST_ROOT}/include
${GTEST_ROOT}/include
)
mark_as_advanced(GTEST_INCLUDE_DIR)
if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
# The provided /MD project files for Google Test add -md suffixes to the
# library names.
_gtest_find_library(GTEST_LIBRARY gtest-md gtest)
_gtest_find_library(GTEST_LIBRARY_DEBUG gtest-mdd gtestd)
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main-md gtest_main)
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
else()
_gtest_find_library(GTEST_LIBRARY gtest)
_gtest_find_library(GTEST_LIBRARY_DEBUG gtestd)
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main)
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
if(GTEST_FOUND)
set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
_gtest_append_debugs(GTEST_LIBRARIES GTEST_LIBRARY)
_gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
endif()
-75
View File
@@ -1,75 +0,0 @@
# - Try to find the Intel XED library
#
# This module defines the following variables
#
# XED_FOUND - Was XED found
# XED_INCLUDE_DIRS - the XED include directories
# XED_LIBRARIES - Link to this
#
# This module accepts the following variables
#
# XED_ROOT - Can be set to XED install path or Windows build path
#
if (NOT DEFINED XED_ROOT)
set (XED_ROOT /usr /usr/local)
endif (NOT DEFINED XED_ROOT)
set (LIB_PATHS ${XED_ROOT} ${XED_ROOT}/lib)
macro(_FIND_XED_LIBRARIES _var)
find_library(${_var}
NAMES ${ARGN}
PATHS ${LIB_PATHS} /opt/local/lib
/usr/lib/x86_64-linux-gnu
/usr/local/lib
/usr/lib
PATH_SUFFIXES lib
)
mark_as_advanced(${_var})
endmacro()
macro(_XED_APPEND_LIBRARIES _list _release)
set(_debug ${_release}_DEBUG)
if(${_debug})
set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}})
else()
set(${_list} ${${_list}} ${${_release}})
endif()
endmacro()
# Linux/OS X builds
find_path(XED_INCLUDE_DIR NAMES intel/xed-interface.h
PATHS ${XED_ROOT}/include
/usr/include
/opt/local/include
)
# Find the libraries
# Linux/OS X builds
if(UNIX)
_FIND_XED_LIBRARIES(XED_LIBRARIES libxed.so)
endif(UNIX)
if(APPLE)
_FIND_XED_LIBRARIES(XED_LIBRARIES libxed.a)
endif(APPLE)
if(XED_FOUND)
message(STATUS "xed library found at ${XED_LIBRARIES}")
endif()
# handle the QUIETLY and REQUIRED arguments and set XED_FOUND to TRUE if
# all listed variables are TRUE
include("${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XED DEFAULT_MSG
XED_LIBRARIES)
# Linux/OS X builds
set(XED_INCLUDE_DIRS ${XED_INCLUDE_DIR})
string(REGEX REPLACE "/libxed.so" "" XED_LIBRARIES_DIR ${XED_LIBRARIES})
if(XED_FOUND)
message(STATUS "Found xed (include: ${XED_INCLUDE_DIRS}, library: ${XED_LIBRARIES})")
# _XED_APPEND_LIBRARIES(XED XED_LIBRARIES)
endif()
+5
View File
@@ -0,0 +1,5 @@
pkg
remill
src
*.pkg.tar.xz
+39
View File
@@ -0,0 +1,39 @@
pkgname=remill
pkgver=20170417_35c6221
pkgrel=0
arch=('x86_64')
pkgdesc="Machine code to LLVM binary translator."
url="https://github.com/trailofbits/remill"
license=('Apache')
makedepends=('git')
provides=('remill')
conflicts=('remill')
source=("${pkgname}::git+https://github.com/trailofbits/remill.git#branch=alessandro/refactor/cmake")
sha1sums=('SKIP')
pkgver() {
cd "${srcdir}/${pkgname}"
git log -1 --date=format:%Y%m%d --pretty=format:%ad_%h
}
build() {
if [ ! -d build ] ; then
mkdir build
cd build
else
cd build
make clean
fi
cmake -DCMAKE_INSTALL_PREFIX=${pkgdir} ${srcdir}/${pkgname}
make -j `nproc`
}
package() {
cd build
make install
}
-117
View File
@@ -1,117 +0,0 @@
# How Remill reads code: the control-flow graph format
This document describes one of the main inputs to Remill, a control-flow graph
formatted and stored as a protocol buffer. The file format is described in the
[CFG.proto](/remill/CFG/CFG.proto) file.
## Instructions
Instructions are encoded with the `Instr` message type:
```protobuf
message Instr {
required bytes bytes = 1;
required uint64 address = 2;
}
```
The two fields of this message are:
- `bytes`: The raw bytes of the instruction
- `address`: The address of the instruction within the executable or object file
![Instructions in Binary Ninja](images/instruction_address_and_bytes.png)
In the above example from Binary Ninja, an `Instr` data structure for the `call sub_8048a40` would have:
- `bytes` as `"\xe8\xa3\xd2\xff\xff"`
- `address` as `0804b798`
In practice, the `address` field is really just an offset from the beginning of a binary. The location at which binaries can be loaded varies according to the OS, as well as the current execution of the binary. For example, a shared library is likely to be loaded at different runtime memory addresses during different program executions when [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) is enabled.
## Basic blocks
Basic blocks of code an encoded with the `Block` message type:
```protobuf
message Block {
required uint64 address = 1;
required bool is_addressable = 2;
repeated Instr instructions = 3;
}
```
Basic blocks in the CFG format are not equivalent to basic blocks as presented in the IDA or Binary Ninja GUIs. Notice that the basic block in the above image has four instructions. In Remill, this assembly listing correspond to the three highlighted basic blocks:
![Blocks in Remill](images/basic_blocks.png)
In Remill, all basic blocks end at control-flow instructions, or at fall-through instructions. The following general rules apply:
- The ends of blocks in IDA or Binary Ninja are also the ends of `Block`s in Remill
- Blocks in IDA or Binary Ninja containing `call` instructions must be split into distinct `Block`s in remill, each "sub" block ending at the `call` instruction. Other split points (on x86) are `syscall`, `sysret`, `sysenter`, `sysexit`, `int`, `int3`, `into`, `bound`, and `cpuid`.
The `address`es of the individual `Block`s are `0804b793` (red), `0804b798` (green), and `0804b79d` (blue), respectively.
The `is_addressable` field in the `Block` message is more subtle and exposes a detail about how control-flow in Remill is represented. Remill is a block-based binary translator. Whereas [McSema](https://github.com/trailofbits/mcsema) translates whole functions at a time, Remill only translates one block at a time.
Each `Block` message in the CFG protocol buffer is represented by a distinct LLVM function in the lifted bitcode. Control-flow between basic blocks in the machine code is represented as function [tail calls](https://en.wikipedia.org/wiki/Tail_call) between between lifted block functions. This raises the following question: how are "indirect" control-flows (`ret`, `jmp reg`, `jmp mem`, `call reg`, and `call mem`) represented in the LLVM bitcode?
The transfer of control for indirect control-flows are modelled using the following Remill [intrinsics](INTRINSICS.md). These instrinsics do not encode the mechanics of the control flows, however. For example, a function call instruction on x86 (`call`) modifies the stack and then jumps to the target. The [semantics functions](/remill/Arch/X86/Semantics/CALL_RET.cpp) are responsible for performing the stack manipulations of the call and modifying the instruction pointer. The intrinsics are responsible for the actual "transfer" of control to another lifted basic block.
- `jmp reg/mem` is represented as a tail-call to `__remill_jump`
- `call reg/mem` is represented as a tail-call to `__remill_function_call`
- `ret` is represented as a tail-call to `__remill_function_return`
Getting back to the `is_addressable` field. The idea here is that any basic block that *could* be targeted by an indirect control-flow should have its corresponding `Block` marked as `is_addressible`. To that end, the block following a `call` instruction is addressable because it is likely to be the target of a `ret` instruction. The block beginning an exported function is addressable because it is exposed to the outside world. The entry blocks associated with function pointers stored in [vtables](https://en.wikipedia.org/wiki/Virtual_method_table) in the `.data` section are addressable because they are likely to be the targets of indirect `call`s.
Finally, the `instructions` list is as you would expect: a list of `Instr` messages, each corresponding to a machine code instruction within the block.
## Named blocks
Named basic blocks are used to represent imported and exported functions. For example, an executable that imports libc and calls `printf` would have a named block, whose address would be the address of `sprintf`. The following message type is used to represent a named block:
```protobuf
enum Visibility {
EXPORTED = 0;
IMPORTED = 1;
}
message NamedBlock {
required string name = 1;
required uint64 address = 2;
required Visibility visibility = 3;
}
```
Following along with the `sprintf` example, the `NamedBlock` associated with the entry point to `sprintf` would be `"sprintf"`. The `address` field is a bit more subtle than what was described above.
If `sprintf` is an imported function, then how can we know its address? In practice (at least in ELF binaries), there is a [thunk](https://en.wikipedia.org/wiki/Thunk) used to represent the address of `sprintf`. For example, below is the thunk for sprintf:
![Blocks in Remill](images/sprintf_thunk.png)
```assembly
sprintf@plt:
0x0000000000404b60 <+0>: jmp QWORD PTR [rip+0x63ba02] # 0xa40568
0x0000000000404b66 <+6>: push 0xc
0x0000000000404b6b <+11>: jmp 0x404a90
```
So, in the `NamedBlock` message, the `address` of `sprintf` will be `0404b60`.
The `sprintf` function is imported, and so we will assign its `visibility` to be `IMPORTED`. Importantly, we don't want to have a `Block` that conflicts with an imported `NamedBlock`. That is, the CFG file *must not* contain a `Block` with the same address as a `NamedBlock` that is `IMPORTED`.
If we were lifting a shared library, and our shared library exported the function `foo`, then the `visibility` of `foo` would be `EXPORTED`. In this case, there *must be* a `Block` whose `address` matches that in the `NamedBlock`.
## Module
The `Module` message ties everything together. It includes all `Block`s and `NamedBlock`s:
```protobuf
message Module {
repeated Block blocks = 1;
repeated NamedBlock named_blocks = 2;
repeated uint64 referenced_blocks = 3;
}
```
It also includes `referenced_blocks`. The `Module` message is not required to, but can, contain all code within a binary. In fact, one can produce one `Module` message per function/subroutine found within the binary.
The `referenced_blocks` must be populated in the case where a `Module` does not include all blocks within the binary. For example, suppose our `Module` did not contain the code associated with `sub_804b89c` and `sub_8048a40`. In this case, the addresses `0804b89c` and `08048a40` must be added to the `referenced_blocks` list.
+1 -2
View File
@@ -1,8 +1,7 @@
# Design and architecture of Remill
Remill translates machine code, and *only* machine code, into LLVM bitcode. Remill's translation approach is inspired by [dynamic](https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool)
[binary](https://github.com/DynamoRIO/dynamorio) [translators](https://github.com/Granary/granary2). Remill translates one [basic block](https://en.wikipedia.org/wiki/Basic_block) of machine code into LLVM bitcode at a time. The translation process defers many decisions to downstream consumers on how the translated bitcode should be interpreted.
Remill translates machine code, and *only* machine code, into LLVM bitcode. The translation process defers many decisions to downstream consumers on how the translated bitcode should be interpreted.
## Intrinsics
-13
View File
@@ -1,13 +0,0 @@
# What problem Remill solves
Remill is designed first and foremost for dynamic program analysis. The two motivating use cases are [taint tracking](https://en.wikipedia.org/wiki/Taint_checking), and [symbolic execution](https://en.wikipedia.org/wiki/Symbolic_execution).
Remill was designed with the following goals in mind.
- It should be easy to add new instruction implementations. Instruction semantics are implemented using C++. Instruction implementations should be thoroughly tested.
- Remill-produced bitcode should achieve the sometimes conflicting goals of maintaining the semantics of the translated machine code and enabling aggressive optimization of the produced bitcode.
- Decisions affecting the use of the produced bitcode should be deferred via intrinsics. Remill-produced bitcode should not commit a consumer of that bitcode to one use case.
+19 -2
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>
#include <gflags/gflags.h>
@@ -10,7 +24,10 @@
#include "remill/Arch/Name.h"
#include "remill/OS/OS.h"
DECLARE_string(arch);
DEFINE_string(arch, "", "Architecture of the code being translated. "
"Valid architectures: x86, amd64 (with or without "
"`_avx` or `_avx512` appended).");
DECLARE_string(os);
namespace remill {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_ARCH_H_
#define REMILL_ARCH_ARCH_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_INSTRUCTION_H_
#define REMILL_ARCH_INSTRUCTION_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remill/Arch/Name.h"
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_NAME_H_
#define REMILL_ARCH_NAME_H_
+16 -2
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_DEFINITIONS_H_
#define REMILL_ARCH_RUNTIME_DEFINITIONS_H_
@@ -34,7 +48,7 @@
// Define a specific instruction selection variable.
#define DEF_ISEL(name) \
extern "C" constexpr auto name [[gnu::used]]
extern "C" constexpr auto ISEL_ ## name [[gnu::used]]
// Define a semantics implementing function.
#define DEF_SEM(name, ...) \
+15 -3
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_HYPERCALL_H_
#define REMILL_ARCH_RUNTIME_HYPERCALL_H_
@@ -17,8 +31,6 @@ class SyncHyperCall {
kAMD64EmulateInstruction,
kAssertPrivileged,
kDebugBreakpoint
};
} __attribute__((packed));
+16 -2
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_SEMANTICS_INSTRINSICS_CPP_
#define REMILL_ARCH_SEMANTICS_INSTRINSICS_CPP_
@@ -49,7 +63,7 @@ extern "C" void __remill_intrinsics(void) {
USED(__remill_atomic_begin);
USED(__remill_atomic_end);
USED(__remill_defer_inlining);
// USED(__remill_defer_inlining);
USED(__remill_error);
+20 -6
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_INTRINSICS_H_
#define REMILL_ARCH_RUNTIME_INTRINSICS_H_
@@ -74,11 +88,11 @@ extern float32_t __remill_undefined_f32(void);
[[gnu::used, gnu::const]]
extern float64_t __remill_undefined_f64(void);
// Inlining control. The idea here is that sometimes we want to defer inlining
// until a later time, and we need to communicate what should eventually be
// inlined, even if it's not currently inlined.
[[gnu::used]]
extern void __remill_defer_inlining(void);
//// Inlining control. The idea here is that sometimes we want to defer inlining
//// until a later time, and we need to communicate what should eventually be
//// inlined, even if it's not currently inlined.
//[[gnu::used]]
//extern void __remill_defer_inlining(void);
// Generic error.
[[gnu::used]]
+27 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_OPERATORS_H_
#define REMILL_ARCH_RUNTIME_OPERATORS_H_
@@ -89,6 +103,18 @@ uint64_t _Read(Memory *, uint64_t val) {
return val;
}
// Read a value directly.
ALWAYS_INLINE static
float32_t _Read(Memory *, float32_t val) {
return val;
}
// Read a value directly.
ALWAYS_INLINE static
float64_t _Read(Memory *, float64_t val) {
return val;
}
template <typename T>
ALWAYS_INLINE static
T _Read(Memory *, In<T> imm) {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_RUNTIME_H_
#define REMILL_ARCH_RUNTIME_RUNTIME_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_STATE_H_
#define REMILL_ARCH_RUNTIME_STATE_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_RUNTIME_TYPES_H_
#define REMILL_ARCH_RUNTIME_TYPES_H_
+62 -7
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>
@@ -6,6 +20,8 @@
#include <sstream>
#include <string>
#include <llvm/IR/Attributes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#undef HAS_FEATURE_AVX
@@ -21,6 +37,7 @@
#include "remill/Arch/X86/Arch.h"
#include "remill/Arch/X86/XED.h"
#include "remill/Arch/X86/Runtime/State.h"
#include "remill/BC/Version.h"
#include "remill/OS/OS.h"
namespace remill {
@@ -299,7 +316,35 @@ static bool DecodeXED(xed_decoded_inst_t *xedd,
static Operand::Register RegOp(xed_reg_enum_t reg) {
Operand::Register reg_op;
if (XED_REG_INVALID != reg) {
reg_op.name = xed_reg_enum_t2str(reg);
switch (reg) {
case XED_REG_ST0:
reg_op.name = "ST0";
break;
case XED_REG_ST1:
reg_op.name = "ST1";
break;
case XED_REG_ST2:
reg_op.name = "ST2";
break;
case XED_REG_ST3:
reg_op.name = "ST3";
break;
case XED_REG_ST4:
reg_op.name = "ST4";
break;
case XED_REG_ST5:
reg_op.name = "ST5";
break;
case XED_REG_ST6:
reg_op.name = "ST6";
break;
case XED_REG_ST7:
reg_op.name = "ST7";
break;
default:
reg_op.name = xed_reg_enum_t2str(reg);
break;
}
if (XED_REG_X87_FIRST <= reg && XED_REG_X87_LAST >= reg) {
reg_op.size = 64;
} else {
@@ -722,14 +767,24 @@ void X86Arch::PrepareModule(llvm::Module *mod) const {
mod->setTargetTriple(triple);
// Go and remove compile-time attributes added into the semantics. These
// can screw up later compilation.
// can screw up later compilation. We purposefully compile semantics with
// things like auto-vectorization disabled so that it keeps the bitcode
// to a simpler subset of the available LLVM instruction set. If/when we
// compile this bitcode back into machine code, we may want to use those
// features, and clang will complain if we try to do so if these metadata
// remain present.
auto &context = mod->getContext();
llvm::AttributeSet target_attribs;
target_attribs = target_attribs.addAttribute(
context, llvm::AttributeSet::FunctionIndex, "target-features");
target_attribs = target_attribs.addAttribute(
context, llvm::AttributeSet::FunctionIndex, "target-cpu");
for (llvm::Function &func : *mod) {
auto attribs = func.getAttributes();
attribs = attribs.removeAttribute(
context, llvm::AttributeSet::FunctionIndex, "target-features");
attribs = attribs.removeAttribute(
context, llvm::AttributeSet::FunctionIndex, "target-cpu");
attribs = attribs.removeAttributes(
context, llvm::AttributeSet::FunctionIndex, target_attribs);
func.setAttributes(attribs);
}
}
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_ARCH_H_
#define REMILL_ARCH_X86_ARCH_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remill/Arch/X86/Runtime/State.h"
+30 -101
View File
@@ -1,110 +1,39 @@
# Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved.
cmake_minimum_required (VERSION 3.2)
project(x86_runtime BC)
macro(COMPILE_X86_SEMANTICS name address_size has_avx has_avx512)
set(SEMANTICS_CXX_FLAGS
set(X86RUNTIME_SOURCEFILES
Instructions.cpp
BasicBlock.cpp
)
-I${PROJECT_SOURCE_DIR}
-emit-llvm
-DADDRESS_SIZE_BITS=${address_size}
-DHAS_FEATURE_AVX=${has_avx}
-DHAS_FEATURE_AVX512=${has_avx512}
set_source_files_properties(Instructions.cpp PROPERTIES COMPILE_FLAGS "-O3 -g0")
set_source_files_properties(BasicBlock.cpp PROPERTIES COMPILE_FLAGS "-O0 -g3")
-std=gnu++11
# TODO(pag): This should be what I do, but I've observed strange LLVM
# code gen issues, where 32-bit code whose data layout is
# converted to 64-bit code will sometimes miscompile pointers
# as 32-bit. This is, of course, in bitcode that doesn't
# do any ptrtoint or inttoptr casts! And this issue doesn't
# show up when certain amounts of very aggressive
# optimizations are performed to the file before converting
# to 32-bit >:-(
# -m${address_size}
-Wall
-Werror
-Wshadow
-Wconversion
-Wpadded
-pedantic
-Wshorten-64-to-32
-Wno-gnu-anonymous-struct
-Wno-return-type-c-linkage
-Wno-gnu-zero-variadic-macro-arguments
-Wno-nested-anon-types
-Wno-extended-offsetof
-Wno-gnu-statement-expression
-Wno-c99-extensions
-Wno-ignored-attributes
set(X86RUNTIME_COMPILEOPTIONS
-mno-sse
-mno-avx
-mno-3dnow
)
# All of these are needed to disable vectorization, both in the LLVM
# optimizer, and in the Clang front-end.
-mtune=generic
-mno-sse
-mno-avx
-mno-3dnow
-fno-vectorize
-fno-slp-vectorize
-ffreestanding
-fno-common
-fno-builtin
-fno-exceptions
-fno-rtti
-fno-asynchronous-unwind-tables
set(X86RUNTIME_INCLUDEDIRECTORIES ${CMAKE_SOURCE_DIR})
-Wno-unneeded-internal-declaration
-Wno-unused-function
)
function (add_runtime_helper target_name address_bit_size enable_avx enable_avx512)
message(" > Generating runtime target: ${target_name}")
add_custom_target(${name}.bc
COMMAND ${CMAKE_LLVM_LINK}
BasicBlock.${name}.bc
Instructions.${name}.bc
-o ${name}.bc
DEPENDS BasicBlock.${name}.bc
Instructions.${name}.bc
)
add_runtime(${target_name} SOURCES ${X86RUNTIME_SOURCEFILES} ADDRESS_SIZE ${address_bit_size})
# Note: `-O0 -g3` is significant here. We need to make sure that we can
# recover variables names within `__remill_basic_block` that may have
# been lost when the code was compiled.
add_custom_command(
OUTPUT BasicBlock.${name}.bc
COMMAND ${CMAKE_CXX_COMPILER}
${SEMANTICS_CXX_FLAGS}
-O0 -g3
-c ${CMAKE_CURRENT_SOURCE_DIR}/BasicBlock.cpp
-o BasicBlock.${name}.bc
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/BasicBlock.cpp
)
# Note: Some debug info *must* be preserved. This is so that we can have
# debug info on lifted blocks that call these inlinable instruction
# functions, without LLVM going and complaining about calling an
# inlineable function with debug info.
add_custom_command(
OUTPUT Instructions.${name}.bc
COMMAND ${CMAKE_CXX_COMPILER}
${SEMANTICS_CXX_FLAGS}
-O3 -g0
-c ${CMAKE_CURRENT_SOURCE_DIR}/Instructions.cpp
-o Instructions.${name}.bc
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Instructions.cpp
)
target_include_directories(${target_name} PRIVATE ${X86RUNTIME_INCLUDEDIRECTORIES})
target_compile_options(${target_name} PRIVATE ${X86RUNTIME_COMPILEOPTIONS})
target_compile_definitions(${target_name} PRIVATE "HAS_FEATURE_AVX=${enable_avx}")
target_compile_definitions(${target_name} PRIVATE "HAS_FEATURE_AVX512=${enable_avx512}")
endfunction ()
add_dependencies(semantics ${name}.bc)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.bc
DESTINATION share/remill/semantics
)
add_runtime_helper(x86 32 0 0)
add_runtime_helper(x86_avx 32 1 0)
add_runtime_helper(x86_avx512 32 1 1)
endmacro()
COMPILE_X86_SEMANTICS(x86 32 0 0)
COMPILE_X86_SEMANTICS(x86_avx 32 1 0)
COMPILE_X86_SEMANTICS(x86_avx512 32 1 1)
COMPILE_X86_SEMANTICS(amd64 64 0 0)
COMPILE_X86_SEMANTICS(amd64_avx 64 1 0)
COMPILE_X86_SEMANTICS(amd64_avx512 64 1 1)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_runtime_helper(amd64 64 0 0)
add_runtime_helper(amd64_avx 64 1 0)
add_runtime_helper(amd64_avx512 64 1 1)
endif ()
+15 -7
View File
@@ -1,4 +1,18 @@
/* Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remill/Arch/Runtime/Intrinsics.h"
#include "remill/Arch/Runtime/Operators.h"
@@ -130,17 +144,11 @@ DEF_SEM(HandleInvalidInstruction) {
return memory;
}
DEF_SEM(HandleBreakpoint) {
return __remill_sync_hyper_call(
memory, state, SyncHyperCall::kDebugBreakpoint);
}
} // namespace
// Takes the place of an unsupported instruction.
DEF_ISEL(UNSUPPORTED_INSTRUCTION) = HandleUnsupported;
DEF_ISEL(INVALID_INSTRUCTION) = HandleInvalidInstruction;
DEF_ISEL(BREAKPOINT_INSTRUCTION) = HandleBreakpoint;
#include "remill/Arch/X86/Semantics/FLAGS.cpp"
#include "remill/Arch/X86/Semantics/BINARY.cpp"
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_RUNTIME_OPERATORS_H_
#define REMILL_ARCH_X86_RUNTIME_OPERATORS_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_RUNTIME_STATE_H_
#define REMILL_ARCH_X86_RUNTIME_STATE_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_RUNTIME_TYPES_H_
#define REMILL_ARCH_X86_RUNTIME_TYPES_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_BINARY_H_
#define REMILL_ARCH_X86_SEMANTICS_BINARY_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_CALL_RET_H_
#define REMILL_ARCH_X86_SEMANTICS_CALL_RET_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_CMOV_H_
#define REMILL_ARCH_X86_SEMANTICS_CMOV_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_CONVERT_H_
#define REMILL_ARCH_X86_SEMANTICS_CONVERT_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_DATAXFER_H_
#define REMILL_ARCH_X86_SEMANTICS_DATAXFER_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_FLAGOP_H_
#define REMILL_ARCH_X86_SEMANTICS_FLAGOP_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_FLAGS_H_
#define REMILL_ARCH_X86_SEMANTICS_FLAGS_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_FMA_H_
#define REMILL_ARCH_X86_SEMANTICS_FMA_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_INTERRUPT_H_
#define REMILL_ARCH_X86_SEMANTICS_INTERRUPT_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_LOGICAL_H_
#define REMILL_ARCH_X86_SEMANTICS_LOGICAL_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_MISC_H_
#define REMILL_ARCH_X86_SEMANTICS_MISC_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Akshay Kumar (iit.akshay@gmail.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_MMX_H_
#define REMILL_ARCH_X86_SEMANTICS_MMX_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_NOP_H_
#define REMILL_ARCH_X86_SEMANTICS_NOP_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_POP_H_
#define REMILL_ARCH_X86_SEMANTICS_POP_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_PUSH_H_
#define REMILL_ARCH_X86_SEMANTICS_PUSH_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_ROTATE_H_
#define REMILL_ARCH_X86_SEMANTICS_ROTATE_H_
+15 -2
View File
@@ -1,5 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
DEF_SEM(XBEGIN, R8W cond, PC taken, PC not_taken) {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_SHIFT_H_
#define REMILL_ARCH_X86_SEMANTICS_SHIFT_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_SSE_H_
#define REMILL_ARCH_X86_SEMANTICS_SSE_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_STRINGOP_H_
#define REMILL_ARCH_X86_SEMANTICS_STRINGOP_H_
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
+97 -81
View File
@@ -1,4 +1,18 @@
/* Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_X87_H_
#define REMILL_ARCH_X86_SEMANTICS_X87_H_
@@ -45,107 +59,107 @@ DEF_SEM(FLD, RF80W, T src1) {
return memory;
}
DEF_SEM(FLDLN2, RF80W) {
DEF_SEM(DoFLDLN2) {
uint64_t ln_2 = 0x3fe62e42fefa39efULL;
PUSH_X87_STACK(reinterpret_cast<float64_t &>(ln_2));
return memory;
}
DEF_SEM(FLD1, RF80W) {
DEF_SEM(DoFLD1) {
PUSH_X87_STACK(1.0); // +1.0.
return memory;
}
DEF_SEM(FLDZ, RF80W) {
DEF_SEM(DoFLDZ) {
PUSH_X87_STACK(0.0); // +0.0.
return memory;
}
DEF_SEM(FLDLG2, RF80W) {
DEF_SEM(DoFLDLG2) {
uint64_t log10_2 = 0x3fd34413509f79ffULL;
PUSH_X87_STACK(reinterpret_cast<float64_t &>(log10_2));
return memory;
}
DEF_SEM(FLDL2T, RF80W) {
DEF_SEM(DoFLDL2T) {
uint64_t log2_10 = 0x400a934f0979a371ULL;
PUSH_X87_STACK(reinterpret_cast<float64_t &>(log2_10));
return memory;
}
DEF_SEM(FLDL2E, RF80W) {
DEF_SEM(DoFLDL2E) {
uint64_t log2_e = 0x3ff71547652b82feULL;
PUSH_X87_STACK(reinterpret_cast<float64_t &>(log2_e));
return memory;
}
DEF_SEM(FLDPI, RF80W) {
DEF_SEM(DoFLDPI) {
uint64_t pi = 0x400921fb54442d18ULL;
PUSH_X87_STACK(reinterpret_cast<float64_t &>(pi));
return memory;
}
DEF_SEM(FABS, RF80W dst, RF80 src) {
Write(dst, FAbs(Read(src)));
DEF_SEM(DoFABS) {
Write(X87_ST0, FAbs(Read(X87_ST0)));
return memory;
}
DEF_SEM(FCHS, RF80W dst, RF80 src) {
Write(dst, FNeg(Read(src)));
DEF_SEM(DoFCHS) {
Write(X87_ST0, FNeg(Read(X87_ST0)));
return memory;
}
DEF_SEM(FCOS, RF80W dst, RF80 src) {
Write(dst, __builtin_cos(Read(src)));
DEF_SEM(DoFCOS) {
Write(X87_ST0, __builtin_cos(Read(X87_ST0)));
return memory;
}
DEF_SEM(FSIN, RF80W dst, RF80 src) {
Write(dst, __builtin_sin(Read(src)));
DEF_SEM(DoFSIN) {
Write(X87_ST0, __builtin_sin(Read(X87_ST0)));
return memory;
}
DEF_SEM(FPTAN, RF80W dst, RF80 src, RF80W) {
Write(dst, __builtin_tan(Read(src)));
DEF_SEM(DoFPTAN) {
Write(X87_ST0, __builtin_tan(Read(X87_ST0)));
PUSH_X87_STACK(1.0);
return memory;
}
DEF_SEM(FPATAN, RF80 st0, RF80W st1_dst, RF80 st1) {
Write(st1_dst, __builtin_atan(FDiv(Read(st1), Read(st0))));
DEF_SEM(DoFPATAN) {
Write(X87_ST1, __builtin_atan(FDiv(Read(X87_ST1), Read(X87_ST0))));
(void) POP_X87_STACK();
return memory;
}
DEF_SEM(FSQRT, RF80W dst, RF80 src) {
Write(dst, __builtin_sqrt(Read(src)));
DEF_SEM(DoFSQRT) {
Write(X87_ST0, __builtin_sqrt(Read(X87_ST0)));
return memory;
}
DEF_SEM(FSINCOS, RF80W dst, RF80 src, RF80W) {
auto val = Read(src);
Write(dst, __builtin_sin(val));
DEF_SEM(DoFSINCOS) {
auto val = Read(X87_ST0);
Write(X87_ST0, __builtin_sin(val));
PUSH_X87_STACK(__builtin_cos(val));
return memory;
}
DEF_SEM(FSCALE, RF80W dst, RF80 st0, RF80 st1) {
auto st1_int = __builtin_trunc(Read(st1)); // Round toward zero.
DEF_SEM(DoFSCALE) {
auto st1_int = __builtin_trunc(Read(X87_ST1)); // Round toward zero.
auto shift = __builtin_exp2(st1_int);
Write(dst, FMul(Read(st0), shift));
Write(X87_ST0, FMul(Read(X87_ST0), shift));
return memory;
}
DEF_SEM(F2XM1, RF80W dst, RF80 src) {
Write(dst, FSub(__builtin_exp2(Read(src)), 1.0));
DEF_SEM(DoF2XM1) {
Write(X87_ST0, FSub(__builtin_exp2(Read(X87_ST0)), 1.0));
return memory;
}
DEF_SEM(FPREM, RF80W dst, RF80 src1, RF80 src2) {
float64_t st0 = Read(src1);
float64_t st1 = Read(src2);
DEF_SEM(DoFPREM) {
float64_t st0 = Read(X87_ST0);
float64_t st1 = Read(X87_ST1);
auto rem = __builtin_fmod(st0, st1);
Write(dst, rem);
Write(X87_ST0, rem);
auto quot = Int64(FTruncTowardZero64(FDiv(st0, st1)));
auto quot_lsb = TruncTo<uint8_t>(UInt64(SAbs(quot)));
@@ -156,11 +170,11 @@ DEF_SEM(FPREM, RF80W dst, RF80 src1, RF80 src2) {
return memory;
}
DEF_SEM(FPREM1, RF80W dst, RF80 src1, RF80 src2) {
float64_t st0 = Read(src1);
float64_t st1 = Read(src2);
DEF_SEM(DoFPREM1) {
float64_t st0 = Read(X87_ST0);
float64_t st1 = Read(X87_ST1);
auto rem = __builtin_remainder(st0, st1);
Write(dst, rem);
Write(X87_ST0, rem);
auto quot = Float64ToInt64(FDiv(st0, st1));
auto quot_lsb = TruncTo<uint8_t>(UInt64(SAbs(quot)));
state.sw.c0 = UAnd(UShr(quot_lsb, 2_u8), 1_u8); // Q2.
@@ -196,29 +210,29 @@ DEF_ISEL(FLD_ST0_X87) = FLD<RF80>;
DEF_ISEL(FLD_ST0_MEMm64real) = FLD<MF64>;
DEF_ISEL(FLD_ST0_MEMmem80real) = FLD<MF80>;
DEF_ISEL(FLDLN2_ST0) = FLDLN2;
DEF_ISEL(FLD1_ST0) = FLD1;
DEF_ISEL(FLDZ_ST0) = FLDZ;
DEF_ISEL(FLDLG2_ST0) = FLDLG2;
DEF_ISEL(FLDL2T_ST0) = FLDL2T;
DEF_ISEL(FLDL2E_ST0) = FLDL2E;
DEF_ISEL(FLDPI_ST0) = FLDPI;
DEF_ISEL(FLDLN2) = DoFLDLN2;
DEF_ISEL(FLD1) = DoFLD1;
DEF_ISEL(FLDZ) = DoFLDZ;
DEF_ISEL(FLDLG2) = DoFLDLG2;
DEF_ISEL(FLDL2T) = DoFLDL2T;
DEF_ISEL(FLDL2E) = DoFLDL2E;
DEF_ISEL(FLDPI) = DoFLDPI;
DEF_ISEL(FNOP) = FPU_NOP;
DEF_ISEL(FWAIT) = DoFWAIT;
DEF_ISEL(FNCLEX) = DoFNCLEX;
DEF_ISEL(FABS_ST0) = FABS;
DEF_ISEL(FCHS_ST0) = FCHS;
DEF_ISEL(FCOS_ST0) = FCOS;
DEF_ISEL(FSIN_ST0) = FSIN;
DEF_ISEL(FPTAN_ST0_ST1) = FPTAN;
DEF_ISEL(FPATAN_ST0_ST1) = FPATAN;
DEF_ISEL(FSQRT_ST0) = FSQRT;
DEF_ISEL(FSINCOS_ST0_ST1) = FSINCOS;
DEF_ISEL(FSCALE_ST0_ST1) = FSCALE;
DEF_ISEL(F2XM1_ST0) = F2XM1;
DEF_ISEL(FPREM_ST0_ST1) = FPREM;
DEF_ISEL(FPREM1_ST0_ST1) = FPREM1;
DEF_ISEL(FABS) = DoFABS;
DEF_ISEL(FCHS) = DoFCHS;
DEF_ISEL(FCOS) = DoFCOS;
DEF_ISEL(FSIN) = DoFSIN;
DEF_ISEL(FPTAN) = DoFPTAN;
DEF_ISEL(FPATAN) = DoFPATAN;
DEF_ISEL(FSQRT) = DoFSQRT;
DEF_ISEL(FSINCOS) = DoFSINCOS;
DEF_ISEL(FSCALE) = DoFSCALE;
DEF_ISEL(F2XM1) = DoF2XM1;
DEF_ISEL(FPREM) = DoFPREM;
DEF_ISEL(FPREM1) = DoFPREM1;
namespace {
@@ -520,8 +534,8 @@ DEF_ISEL(FXCH_ST0_X87_DDC1) = FXCH;
namespace {
DEF_SEM(FXAM, RF80W, RF80 src) {
auto st0 = Read(src);
DEF_SEM(DoFXAM) {
auto st0 = Read(X87_ST0);
uint8_t sign = __builtin_signbit(st0) == 0 ? 0_u8 : 1_u8;
auto c = __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
@@ -596,8 +610,8 @@ DEF_HELPER(UnorderedCompare, float64_t src1, float64_t src2) -> void {
}
}
DEF_SEM(FTST, RF80W, RF80 src1) {
auto st0 = Read(src1);
DEF_SEM(DoFTST) {
auto st0 = Read(X87_ST0);
state.sw.c1 = 0;
UnorderedCompare(memory, state, st0, 0.0);
return memory;
@@ -620,8 +634,10 @@ DEF_SEM(FUCOMP, RF80 src1, S2 src2) {
return memory;
}
DEF_SEM(FUCOMPP, RF80 src1, RF80 src2) {
memory = FUCOM<RF80>(memory, state, src1, src2);
DEF_SEM(DoFUCOMPP) {
RF80 st0 = {X87_ST0};
RF80 st1 = {X87_ST1};
memory = FUCOM<RF80>(memory, state, st0, st1);
(void) POP_X87_STACK();
(void) POP_X87_STACK();
return memory;
@@ -668,12 +684,12 @@ DEF_SEM(FUCOMIP, RF80 src1, RF80 src2) {
} // namespace
DEF_ISEL(FXAM_ST0) = FXAM;
DEF_ISEL(FTST_ST0) = FTST;
DEF_ISEL(FXAM) = DoFXAM;
DEF_ISEL(FTST) = DoFTST;
DEF_ISEL(FUCOM_ST0_X87) = FUCOM<RF80>;
DEF_ISEL(FUCOMP_ST0_X87) = FUCOMP<RF80>;
DEF_ISEL(FUCOMPP_ST0_ST1) = FUCOMPP;
DEF_ISEL(FUCOMPP) = DoFUCOMPP;
DEF_ISEL(FUCOMI_ST0_X87) = FUCOMI;
DEF_ISEL(FUCOMIP_ST0_X87) = FUCOMIP;
@@ -691,7 +707,7 @@ DEF_ISEL(FCOMP_ST0_MEMmem32real) = FUCOMP<MF32>;
DEF_ISEL(FCOMP_ST0_MEMm64real) = FUCOMP<MF64>;
DEF_ISEL(FCOMP_ST0_X87_DCD1) = FUCOMP<RF80>;
DEF_ISEL(FCOMP_ST0_X87_DED0) = FUCOMP<RF80>;
DEF_ISEL(FCOMPP_ST0_ST1) = FUCOMPP;
DEF_ISEL(FCOMPP) = DoFUCOMPP;
namespace {
@@ -762,26 +778,26 @@ DEF_ISEL(FLDCW_MEMmem16) = FLDCW;
namespace {
DEF_SEM(FRNDINT, RF80W dst, RF80 src) {
auto st0 = Read(src);
DEF_SEM(DoFRNDINT) {
auto st0 = Read(X87_ST0);
auto rounded = FRoundUsingMode64(st0);
// state.sw.c1 = __builtin_isgreater(FAbs(rounded), FAbs(st0)) ? 1_u8 : 0_u8;
Write(dst, rounded);
Write(X87_ST0, rounded);
return memory;
}
DEF_SEM(FYL2X, RF80 src1, RF80W dst2, RF80 src2) {
auto st0 = Read(src1);
auto st1 = Read(src2);
Write(dst2, FMul(st1, __builtin_log2(st0)));
DEF_SEM(DoFYL2X) {
auto st0 = Read(X87_ST0);
auto st1 = Read(X87_ST1);
Write(X87_ST1, FMul(st1, __builtin_log2(st0)));
(void) POP_X87_STACK();
return memory;
}
DEF_SEM(FYL2XP1, RF80 src1, RF80W dst2, RF80 src2) {
auto st0 = Read(src1);
auto st1 = Read(src2);
Write(dst2, FMul(st1, __builtin_log2(FAdd(st0, 1.0))));
DEF_SEM(DoFYL2XP1) {
auto st0 = Read(X87_ST0);
auto st1 = Read(X87_ST1);
Write(X87_ST1, FMul(st1, __builtin_log2(FAdd(st0, 1.0))));
(void) POP_X87_STACK();
return memory;
}
@@ -797,9 +813,9 @@ DEF_SEM(FFREEP, RF80) {
} // namespace
DEF_ISEL(FRNDINT_ST0) = FRNDINT;
DEF_ISEL(FYL2X_ST0_ST1) = FYL2X;
DEF_ISEL(FYL2XP1_ST0_ST1) = FYL2XP1;
DEF_ISEL(FRNDINT) = DoFRNDINT;
DEF_ISEL(FYL2X) = DoFYL2X;
DEF_ISEL(FYL2XP1) = DoFYL2XP1;
DEF_ISEL(FFREE_X87) = FFREE;
DEF_ISEL(FFREEP_X87) = FFREEP;
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_SEMANTICS_XOP_H_
#define REMILL_ARCH_X86_SEMANTICS_XOP_H_
+16 -2
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_ARCH_X86_XED_H_
#define REMILL_ARCH_X86_XED_H_
@@ -11,7 +25,7 @@
#pragma clang diagnostic ignored "-Wswitch-enum"
extern "C" {
#define XED_DLL
#include <intel/xed-interface.h>
#include <xed/xed-interface.h>
} // extern C
#pragma clang diagnostic pop
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_ABI_H_
#define REMILL_BC_ABI_H_
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_BITCODEREADERWRITER_H_
#define REMILL_BC_COMPAT_BITCODEREADERWRITER_H_
#include "remill/BC/Version.h"
#if LLVM_VERSION_NUMBER >= LLVM_VERSION(4, 0)
# include <llvm/Bitcode/BitcodeReader.h>
# include <llvm/Bitcode/BitcodeWriter.h>
#else
# include <llvm/Bitcode/ReaderWriter.h>
#endif
#endif // REMILL_BC_COMPAT_BITCODEREADERWRITER_H_
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_DEBUGINFO_H_
#define REMILL_BC_COMPAT_DEBUGINFO_H_
#include "remill/BC/Version.h"
#if LLVM_VERSION_NUMBER >= LLVM_VERSION(3, 7)
# include <llvm/IR/DebugInfoMetadata.h>
#else
# include <llvm/IR/DebugInfo.h>
#endif
#include <llvm/IR/DebugLoc.h>
#endif // REMILL_BC_COMPAT_DEBUGINFO_H_
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_GLOBALVALUE_H_
#define REMILL_BC_COMPAT_GLOBALVALUE_H_
#include "remill/BC/Version.h"
#include <llvm/IR/GlobalValue.h>
namespace remill {
inline static llvm::Type *GetValueType(llvm::GlobalValue *global) {
#if LLVM_VERSION_NUMBER < LLVM_VERSION(3, 7)
return global->getType()->getElementType();
#else
return global->getValueType();
#endif
}
} // namespace remill
#endif // REMILL_BC_COMPAT_GLOBALVALUE_H_
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_IRREADER_H_
#define REMILL_BC_COMPAT_IRREADER_H_
#include <memory>
#include "remill/BC/Version.h"
#include <llvm/IRReader/IRReader.h>
#if LLVM_VERSION_NUMBER < LLVM_VERSION(3, 6)
namespace llvm {
class Module;
template <typename ...Args>
inline static std::unique_ptr<Module> parseIRFile(Args&... args) {
return std::unique_ptr<Module>(ParseIRFile(args...));
}
} // namespace llvm
#endif
#endif // REMILL_BC_COMPAT_IRREADER_H_
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_TARGETLIBRARYINFO_H_
#define REMILL_BC_COMPAT_TARGETLIBRARYINFO_H_
#include "remill/BC/Version.h"
#if LLVM_VERSION_NUMBER >= LLVM_VERSION(3, 7)
# include <llvm/Analysis/TargetLibraryInfo.h>
#else
# include <llvm/Target/TargetLibraryInfo.h>
namespace llvm {
using TargetLibraryInfoImpl = TargetLibraryInfo;
} // namespace llvm
#endif
#endif // REMILL_BC_COMPAT_TARGETLIBRARYINFO_H_
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_COMPAT_VERIFIER_H_
#define REMILL_BC_COMPAT_VERIFIER_H_
#include "remill/BC/Version.h"
#if LLVM_VERSION_NUMBER >= LLVM_VERSION(3, 5)
# include <llvm/IR/Verifier.h>
#else
# include <llvm/Analysis/Verifier.h>
#endif
#endif // REMILL_BC_COMPAT_VERIFIER_H_
+28 -22
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>
@@ -16,7 +30,7 @@ namespace remill {
namespace {
// Find a specific function.
static llvm::Function *FindIntrinsic(const llvm::Module *module,
static llvm::Function *FindIntrinsic(llvm::Module *module,
const char *name) {
auto function = FindFunction(module, name);
CHECK(nullptr != function)
@@ -39,7 +53,7 @@ static llvm::Function *FindIntrinsic(const llvm::Module *module,
}
// Find a specific function.
static llvm::Function *FindPureIntrinsic(const llvm::Module *module,
static llvm::Function *FindPureIntrinsic(llvm::Module *module,
const char *name) {
auto function = FindIntrinsic(module, name);
@@ -49,28 +63,20 @@ static llvm::Function *FindPureIntrinsic(const llvm::Module *module,
return function;
}
// Find a specific function.
static llvm::Function *FindArgMemOnlyIntrinsic(const llvm::Module *module,
const char *name) {
auto function = FindIntrinsic(module, name);
function->addFnAttr(llvm::Attribute::ArgMemOnly);
return function;
}
} // namespace
IntrinsicTable::IntrinsicTable(const llvm::Module *module)
IntrinsicTable::IntrinsicTable(llvm::Module *module)
: error(FindIntrinsic(module, "__remill_error")),
// Control-flow.
function_call(FindArgMemOnlyIntrinsic(module, "__remill_function_call")),
function_return(FindArgMemOnlyIntrinsic(
function_call(FindIntrinsic(module, "__remill_function_call")),
function_return(FindIntrinsic(
module, "__remill_function_return")),
jump(FindArgMemOnlyIntrinsic(module, "__remill_jump")),
missing_block(FindArgMemOnlyIntrinsic(module, "__remill_missing_block")),
jump(FindIntrinsic(module, "__remill_jump")),
missing_block(FindIntrinsic(module, "__remill_missing_block")),
// OS interaction.
async_hyper_call(FindArgMemOnlyIntrinsic(
async_hyper_call(FindIntrinsic(
module, "__remill_async_hyper_call")),
// Memory access.
@@ -105,11 +111,11 @@ IntrinsicTable::IntrinsicTable(const llvm::Module *module)
atomic_begin(FindPureIntrinsic(module, "__remill_atomic_begin")),
atomic_end(FindPureIntrinsic(module, "__remill_atomic_end")),
// Optimization guides.
//
// Note: NOT pure! This is a total hack: we call an unpure function
// within a pure one so that it is not optimized out!
defer_inlining(FindIntrinsic(module, "__remill_defer_inlining")),
// // Optimization guides.
// //
// // Note: NOT pure! This is a total hack: we call an unpure function
// // within a pure one so that it is not optimized out!
// defer_inlining(FindIntrinsic(module, "__remill_defer_inlining")),
// Optimization enablers.
undefined_8(FindPureIntrinsic(module, "__remill_undefined_8")),
+18 -4
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_INTRINSICTABLE_H_
#define REMILL_BC_INTRINSICTABLE_H_
@@ -13,7 +27,7 @@ namespace remill {
class IntrinsicTable {
public:
IntrinsicTable(const llvm::Module *M);
IntrinsicTable(llvm::Module *M);
llvm::Function * const error;
@@ -55,8 +69,8 @@ class IntrinsicTable {
llvm::Function * const atomic_begin;
llvm::Function * const atomic_end;
// Optimization control.
llvm::Function * const defer_inlining;
// // Optimization control.
// llvm::Function * const defer_inlining;
// Optimization enabling.
llvm::Function *undefined_8;
+40 -380
View File
@@ -1,6 +1,19 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <functional>
@@ -17,7 +30,6 @@
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h>
@@ -26,7 +38,6 @@
#include <llvm/IR/Module.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/raw_ostream.h>
@@ -35,375 +46,26 @@
#include <llvm/Transforms/Utils/ValueMapper.h>
#include "remill/Arch/Arch.h"
#include "remill/Arch/Instruction.h"
#include "remill/BC/ABI.h"
#include "remill/BC/IntrinsicTable.h"
#include "remill/BC/Lifter.h"
#include "remill/BC/Util.h"
#include "remill/CFG/BlockHasher.h"
#include "remill/CFG/CFG.h"
#include "remill/OS/OS.h"
DEFINE_bool(add_breakpoints, false,
"Add calls to the `BREAKPOINT_INSTRUCTION` before every lifted "
"instruction. The semantics for this instruction call into a "
"breakpoint hyper call.");
namespace remill {
Lifter::Lifter(const Arch *arch_, llvm::Module *module_)
: arch(arch_),
module(module_),
pc_to_block(),
basic_block(FindFunction(module, "__remill_basic_block")),
word_type(llvm::Type::getIntNTy(
module->getContext(), arch->address_size)),
intrinsics(new IntrinsicTable(module)) {
CHECK(nullptr != basic_block)
<< "Unable to find __remill_basic_block.";
CHECK(1 == basic_block->size())
<< "Basic block template function " << basic_block->getName().str()
<< " should only have one basic block.";
EnableDeferredInlining();
}
Lifter::~Lifter(void) {
delete intrinsics;
}
namespace {
// Make sure that a function cannot be inlined by the optimizer. We use this
// as a way of ensuring that code that should be inlined later (i.e. invokes
// `__remill_defer_inlining`) definitely have the no-inline attributes set.
static void DisableInlining(llvm::Function *function) {
function->removeFnAttr(llvm::Attribute::AlwaysInline);
function->removeFnAttr(llvm::Attribute::InlineHint);
function->addFnAttr(llvm::Attribute::NoInline);
}
} // namespace
// Enable deferred inlining. The goal is to support better dead-store
// elimination for flags.
void Lifter::EnableDeferredInlining(void) {
DisableInlining(intrinsics->defer_inlining);
for (auto callers : intrinsics->defer_inlining->users()) {
if (auto call_instr = llvm::dyn_cast_or_null<llvm::CallInst>(callers)) {
auto bb = call_instr->getParent();
auto caller = bb->getParent();
DisableInlining(caller);
}
}
}
namespace {
static uint64_t GetBlockId(const cfg::Block &cfg_block) {
if (cfg_block.has_id()) {
return cfg_block.id();
} else {
return BlockHasher().HashBlock(cfg_block);
}
}
} // namespace
// Create a function for a single decoded block.
void Lifter::CreateBlock(const cfg::Block &cfg_block) {
auto id = GetBlockId(cfg_block);
auto pc = cfg_block.address();
auto id_it = id_to_block.find(id);
if (id_it != id_to_block.end()) {
pc_to_block[pc] = id_it->second;
}
auto &block_func = pc_to_block[pc];
if (!block_func) {
std::stringstream ss;
ss << "__remill_sub_" << std::hex << id;
auto func_name = ss.str();
auto func_type = basic_block->getFunctionType();
block_func = llvm::Function::Create(
func_type, llvm::GlobalValue::PrivateLinkage, ".", module);
auto block_var = new llvm::GlobalVariable(
*module, llvm::PointerType::get(func_type, 0), true,
llvm::GlobalValue::ExternalLinkage, block_func, func_name);
CHECK(block_var->getName() == func_name)
<< "Duplicate block for " << func_name;
InitFunctionAttributes(block_func);
SetBlockPC(block_var, pc);
SetBlockId(block_var, id);
id_to_block[id] = block_func;
if (cfg_block.has_name()) {
DLOG(INFO)
<< "Block at " << std::hex << pc << " has name " << cfg_block.name();
SetBlockName(block_func, cfg_block.name());
}
} else {
uint64_t other_id = 0;
if (!TryGetBlockId(block_func, other_id) || other_id != id) {
DLOG(FATAL)
<< "Duplicate cfg_block at PC " << std::hex << pc << " exists in "
<< "the CFG proto. There should only be one version of each block "
<< "in a given CFG Module.";
} else {
DLOG(ERROR)
<< "Duplicate cfg_block at PC " << std::hex << pc << " exists in "
<< "the CFG Module, but they both have the same ID.";
}
}
}
// Create a function for a single block.
llvm::Function *Lifter::GetBlock(uint64_t addr) {
auto &block_func = pc_to_block[addr];
if (!block_func) {
LOG(WARNING)
<< "Unable find block for PC " << std::hex << addr
<< " reverting to `__remill_missing_block`.";
block_func = intrinsics->missing_block;
}
return block_func;
}
// Lift the control-flow graph specified by `cfg` into this bitcode module.
void Lifter::LiftCFG(const cfg::Module *cfg_module) {
ForEachBlock(module,
[this] (uint64_t pc, uint64_t id, llvm::Function *func) {
id_to_block[id] = func;
});
for (auto &cfg_block : cfg_module->blocks()) {
CreateBlock(cfg_block);
}
LiftBlocks(cfg_module);
pc_to_block.clear();
id_to_block.clear();
}
// Lift code contained in blocks into the block methods.
void Lifter::LiftBlocks(const cfg::Module *cfg_module) {
llvm::legacy::FunctionPassManager func_pass_manager(module);
func_pass_manager.add(llvm::createCFGSimplificationPass());
func_pass_manager.add(llvm::createPromoteMemoryToRegisterPass());
func_pass_manager.add(llvm::createReassociatePass());
func_pass_manager.add(llvm::createDeadStoreEliminationPass());
func_pass_manager.add(llvm::createDeadCodeEliminationPass());
func_pass_manager.doInitialization();
for (const auto &cfg_block : cfg_module->blocks()) {
auto func = LiftBlock(cfg_block);
CHECK(!func->isDeclaration())
<< "Lifted block function " << func->getName().str()
<< " should have an implementation.";
func_pass_manager.run(*func);
}
func_pass_manager.doFinalization();
}
// Lift code contained within a single block.
llvm::Function *Lifter::LiftBlock(const cfg::Block &cfg_block) {
auto block_func = GetBlock(cfg_block.address());
if (!block_func->isDeclaration()) {
return block_func;
}
CloneBlockFunctionInto(block_func);
InstructionLifter lifter(word_type, intrinsics);
// Create a block for each instruction.
auto last_block = &block_func->back();
auto instr_addr = cfg_block.address();
Instruction *instr = nullptr;
for (const auto &cfg_instr : cfg_block.instructions()) {
CHECK(cfg_instr.address() == instr_addr)
<< "CFG Instr address " << std::hex << cfg_instr.address()
<< " doesn't match implied instruction address ("
<< std::hex << instr_addr << ") based on CFG Block structure.";
auto instr_bytes = cfg_instr.bytes();
// Check and delete the last instruction lifted.
if (instr) {
CHECK(Instruction::kCategoryNoOp == instr->category ||
Instruction::kCategoryNormal == instr->category)
<< "Predecessor of instruction at " << std::hex << instr_addr
<< " must be a normal or no-op instruction, and not one that"
<< " should end a block.";
delete instr;
instr = nullptr;
}
instr = arch->DecodeInstruction(instr_addr, instr_bytes);
DLOG_IF(WARNING, instr_bytes.size() != instr->NumBytes())
<< "Size of decoded instruction at " << std::hex << instr_addr
<< " (" << std::dec << instr->NumBytes()
<< ") doesn't match input instruction size ("
<< instr_bytes.size() << ").";
// DLOG(INFO)
// << "Lifting instruction '" << instr->Serialize();
if (auto curr_block = LiftInstruction(block_func, instr, lifter)) {
llvm::IRBuilder<> ir(last_block);
ir.CreateBr(curr_block);
last_block = curr_block;
instr_addr += instr_bytes.size();
// Unable to lift the instruction; likely because the instruction
// semantics are not implemented.
} else {
AddTerminatingTailCall(last_block, intrinsics->error);
break;
}
}
CHECK(nullptr != instr)
<< "Logic error: must lift at least one instruction.";
if (!last_block->getTerminator()) {
LiftTerminator(last_block, instr);
}
delete instr;
return block_func;
}
// Lift a single instruction into a basic block.
llvm::BasicBlock *Lifter::LiftInstruction(llvm::Function *block_func,
Instruction *instr,
InstructionLifter &lifter) {
auto &context = block_func->getContext();
auto block = llvm::BasicBlock::Create(context, "", block_func);
if (!lifter.LiftIntoBlock(instr, block)) {
block->eraseFromParent();
return nullptr;
}
return block;
}
namespace {
// Lift both targets of a conditional branch into a branch in the bitcode,
// where each side of the branch tail-calls to the functions associated with
// the lifted blocks for those branch targets.
static void LiftConditionalBranch(llvm::BasicBlock *source,
llvm::Function *dest_true,
llvm::Function *dest_false) {
auto &context = source->getContext();
auto function = source->getParent();
auto block_true = llvm::BasicBlock::Create(context, "", function);
auto block_false = llvm::BasicBlock::Create(context, "", function);
// TODO(pag): This is a bit ugly. The idea here is that, from the semantics
// code, we need a way to communicate what direction of the
// conditional branch should be followed. It turns out to be
// easiest just to write to a special variable :-)
auto branch_taken = FindVarInFunction(function, "BRANCH_TAKEN");
llvm::IRBuilder<> cond_ir(source);
auto cond_addr = cond_ir.CreateLoad(branch_taken);
auto cond = cond_ir.CreateLoad(cond_addr);
cond_ir.CreateCondBr(
cond_ir.CreateICmpEQ(
cond,
llvm::ConstantInt::get(cond->getType(), 1)),
block_true,
block_false);
AddTerminatingTailCall(block_true, dest_true);
AddTerminatingTailCall(block_false, dest_false);
}
} // namespace
// Lift the last instruction of a block as a block terminator.
void Lifter::LiftTerminator(llvm::BasicBlock *block,
const Instruction *arch_instr) {
switch (arch_instr->category) {
case Instruction::kCategoryInvalid:
AddTerminatingTailCall(block, intrinsics->async_hyper_call);
break;
case Instruction::kCategoryNormal:
case Instruction::kCategoryNoOp:
AddTerminatingTailCall(
block,
GetBlock(arch_instr->next_pc));
break;
case Instruction::kCategoryError:
AddTerminatingTailCall(block, intrinsics->error);
break;
case Instruction::kCategoryDirectJump:
AddTerminatingTailCall(
block,
GetBlock(arch_instr->branch_taken_pc));
break;
case Instruction::kCategoryIndirectJump:
AddTerminatingTailCall(block, intrinsics->jump);
break;
case Instruction::kCategoryDirectFunctionCall:
AddTerminatingTailCall(
block,
GetBlock(arch_instr->branch_taken_pc));
break;
case Instruction::kCategoryIndirectFunctionCall:
AddTerminatingTailCall(block, intrinsics->function_call);
break;
case Instruction::kCategoryFunctionReturn:
AddTerminatingTailCall(block, intrinsics->function_return);
break;
case Instruction::kCategoryConditionalBranch:
LiftConditionalBranch(
block,
GetBlock(arch_instr->branch_taken_pc),
GetBlock(arch_instr->branch_not_taken_pc));
break;
case Instruction::kCategoryAsyncHyperCall:
AddTerminatingTailCall(block, intrinsics->async_hyper_call);
break;
case Instruction::kCategoryConditionalAsyncHyperCall:
LiftConditionalBranch(
block,
intrinsics->async_hyper_call,
GetBlock(arch_instr->next_pc));
break;
}
}
namespace {
// Try to find the function that implements this semantics.
llvm::Function *GetInstructionFunction(llvm::Module *module,
const std::string &function) {
auto isel = FindGlobaVariable(module, function);
std::stringstream ss;
ss << "ISEL_" << function;
auto isel_name = ss.str();
auto isel = FindGlobaVariable(module, isel_name);
if (!isel) {
return nullptr; // Falls back on `UNIMPLEMENTED_INSTRUCTION`.
}
@@ -429,14 +91,17 @@ InstructionLifter::InstructionLifter(llvm::IntegerType *word_type_,
intrinsics(intrinsics_) {}
// Lift a single instruction into a basic block.
bool InstructionLifter::LiftIntoBlock(
LiftStatus InstructionLifter::LiftIntoBlock(
Instruction *arch_instr, llvm::BasicBlock *block) {
auto module = block->getModule();
llvm::Function *func = block->getParent();
llvm::Module *module = func->getParent();
auto isel_func = GetInstructionFunction(module, arch_instr->function);
auto status = LiftStatus::kLifted;
if (Instruction::kCategoryInvalid == arch_instr->category) {
isel_func = GetInstructionFunction(module, "INVALID_INSTRUCTION");
status = LiftStatus::kInvalid;
}
if (!isel_func) {
@@ -449,14 +114,13 @@ bool InstructionLifter::LiftIntoBlock(
LOG(ERROR)
<< "UNSUPPORTED_INSTRUCTION doesn't exist; not using it in place of "
<< arch_instr->function;
return false;
return LiftStatus::kError;
}
status = LiftStatus::kUnsupported;
arch_instr->operands.clear();
}
isel_func->addFnAttr(llvm::Attribute::ArgMemOnly);
llvm::IRBuilder<> ir(block);
auto mem_ptr = LoadMemoryPointerRef(block);
auto state_ptr = LoadStatePointer(block);
@@ -464,8 +128,9 @@ bool InstructionLifter::LiftIntoBlock(
// Begin an atomic block.
if (arch_instr->is_atomic_read_modify_write) {
std::vector<llvm::Value *> args = {ir.CreateLoad(mem_ptr)};
ir.CreateStore(
ir.CreateCall(intrinsics->atomic_begin, {ir.CreateLoad(mem_ptr)}),
ir.CreateCall(intrinsics->atomic_begin, args),
mem_ptr);
}
@@ -477,15 +142,6 @@ bool InstructionLifter::LiftIntoBlock(
args.push_back(nullptr);
args.push_back(state_ptr);
// Call out to a special 'breakpoint' instruction function, that lets us
// interpose on the machine state just before every lifted instruction.
if (FLAGS_add_breakpoints) {
ir.CreateStore(
ir.CreateCall(GetInstructionFunction(module, "BREAKPOINT_INSTRUCTION"),
args),
mem_ptr);
}
auto isel_func_type = isel_func->getFunctionType();
auto arg_num = 2U;
@@ -523,12 +179,13 @@ bool InstructionLifter::LiftIntoBlock(
// End an atomic block.
if (arch_instr->is_atomic_read_modify_write) {
std::vector<llvm::Value *> args = {ir.CreateLoad(mem_ptr)};
ir.CreateStore(
ir.CreateCall(intrinsics->atomic_end, {ir.CreateLoad(mem_ptr)}),
ir.CreateCall(intrinsics->atomic_end, args),
mem_ptr);
}
return true;
return status;
}
namespace {
@@ -583,6 +240,9 @@ static llvm::Value *LoadWordRegValOrZero(llvm::BasicBlock *block,
llvm::Value *InstructionLifter::LiftRegisterOperand(
Instruction *, llvm::BasicBlock *block,
llvm::Type *arg_type, Operand &op) {
llvm::Function *func = block->getParent();
llvm::Module *module = func->getParent();
auto &arch_reg = op.reg;
if (auto ptr_type = llvm::dyn_cast_or_null<llvm::PointerType>(arg_type)) {
@@ -602,7 +262,7 @@ llvm::Value *InstructionLifter::LiftRegisterOperand(
auto val = LoadRegValue(block, arch_reg.name);
const llvm::DataLayout data_layout(block->getModule());
const llvm::DataLayout data_layout(module);
auto val_type = val->getType();
auto val_size = data_layout.getTypeAllocSizeInBits(val_type);
auto arg_size = data_layout.getTypeAllocSizeInBits(arg_type);
+24 -95
View File
@@ -1,16 +1,22 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_LIFTER_H_
#define REMILL_BC_LIFTER_H_
#include <unordered_map>
#include <string>
#include "remill/Arch/Instruction.h"
#include "remill/BC/ABI.h"
#include "remill/BC/Util.h"
namespace llvm {
class Function;
class Module;
@@ -19,93 +25,16 @@ class IntegerType;
} // namespace llvm
namespace remill {
namespace cfg {
class Block;
class Instr;
class Module;
} // namespace cfg
class Arch;
class Instruction;
class IntrinsicTable;
class InstructionLifter;
class Operand;
// Lifts CFG files into a bitcode module. This is mostly a big bag of state
// needed for all the parts of of lifting to coordinate.
class Lifter {
public:
Lifter(const Arch *arch_, llvm::Module *module_);
~Lifter(void);
// Lift the control-flow graph specified by `cfg` into this bitcode module.
void LiftCFG(const cfg::Module *cfg);
private:
Lifter(void) = delete;
Lifter(const Lifter &) = delete;
// Enable deferred inlining. The goal is to support better dead-store
// elimination for flags.
void EnableDeferredInlining(void);
// Create a function for a single decoded block.
void CreateBlock(const cfg::Block &block);
// Create a function for a single block.
llvm::Function *GetBlock(uint64_t address);
// Lift code contained in blocks into the block methods.
void LiftBlocks(const cfg::Module *cfg);
// Lift code contained within a single block.
llvm::Function *LiftBlock(const cfg::Block &block);
// Lift the last instruction of a block as a block terminator.
void LiftTerminator(llvm::BasicBlock *block,
const Instruction *instr);
// Lift a single instruction into a basic block.
llvm::BasicBlock *LiftInstruction(llvm::Function *block,
Instruction *instr,
InstructionLifter &lifter);
// Lift an operand to an instruction.
llvm::Value *LiftOperand(llvm::BasicBlock *block,
llvm::Type *op_type,
const Operand &op);
// Lift a register operand to a value.
llvm::Value *LiftRegisterOperand(llvm::BasicBlock *block,
llvm::Type *arg_type,
const Operand::Register &reg);
// Lift an immediate operand.
llvm::Value *LiftImmediateOperand(llvm::Type *arg_type,
const Operand &op);
// Lift an indirect memory operand to a value.
llvm::Value *LiftAddressOperand(llvm::BasicBlock *block,
const Operand::Address &mem);
// Architecture of the code contained within the CFG being lifted.
const Arch * const arch;
// Module into which code is lifted.
llvm::Module * const module;
// Blocks that we've added, indexed by their entry address and their ID.
std::unordered_map<uint64_t, llvm::Function *> pc_to_block;
std::unordered_map<uint64_t, llvm::Function *> id_to_block;
// Basic block template.
llvm::Function * const basic_block;
// Machine word type for this architecture.
llvm::IntegerType * const word_type;
public:
// Set of intrinsics.
const IntrinsicTable * const intrinsics;
enum class LiftStatus {
kLifted,
kInvalid,
kUnsupported,
kError
};
// Wraps the process of lifting an instruction into a block. This resolves
@@ -119,8 +48,8 @@ class InstructionLifter {
const IntrinsicTable *intrinsics_);
// Lift a single instruction into a basic block.
virtual bool LiftIntoBlock(Instruction *instr,
llvm::BasicBlock *block);
virtual LiftStatus LiftIntoBlock(
Instruction *instr, llvm::BasicBlock *block);
// Machine word type for this architecture.
llvm::IntegerType * const word_type;
File diff suppressed because it is too large Load Diff
-33
View File
@@ -1,33 +0,0 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
#ifndef REMILL_BC_OPTIMIZER_H_
#define REMILL_BC_OPTIMIZER_H_
#include <memory>
namespace llvm {
class Function;
class Module;
} // namespace llvm
namespace remill {
class Optimizer {
public:
virtual ~Optimizer(void);
static std::unique_ptr<Optimizer> Create(llvm::Module *module_);
virtual void Optimize(void) = 0;
protected:
explicit Optimizer(llvm::Module *module_);
llvm::Module *module;
private:
Optimizer(void) = delete;
};
} // namespace remill
#endif // REMILL_BC_OPTIMIZER_H_
+91 -115
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>
@@ -13,11 +27,7 @@
#include <llvm/ADT/SmallVector.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/IR/DebugLoc.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h>
@@ -25,9 +35,6 @@
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Metadata.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/raw_ostream.h>
@@ -35,7 +42,13 @@
#include <llvm/Support/ToolOutputFile.h>
#include "remill/BC/ABI.h"
#include "remill/BC/Compat/BitcodeReaderWriter.h"
#include "remill/BC/Compat/DebugInfo.h"
#include "remill/BC/Compat/GlobalValue.h"
#include "remill/BC/Compat/IRReader.h"
#include "remill/BC/Compat/Verifier.h"
#include "remill/BC/Util.h"
#include "remill/BC/Version.h"
#include "remill/OS/FileSystem.h"
namespace remill {
@@ -76,7 +89,7 @@ llvm::CallInst *AddTerminatingTailCall(llvm::Function *source_func,
llvm::CallInst *call_target_instr = ir.CreateCall(dest_func, args);
// Make sure we tail-call from one block method to another.
call_target_instr->setTailCallKind(llvm::CallInst::TCK_MustTail);
call_target_instr->setTailCallKind(llvm::CallInst::TCK_Tail);
call_target_instr->setCallingConv(llvm::CallingConv::Fast);
ir.CreateRet(call_target_instr);
return call_target_instr;
@@ -90,8 +103,7 @@ llvm::CallInst *AddTerminatingTailCall(llvm::BasicBlock *source_block,
CHECK(nullptr != dest_func)
<< "Target function/block does not exist!";
LOG_IF(ERROR, source_block->getTerminator() ||
source_block->getTerminatingMustTailCall())
LOG_IF(ERROR, source_block->getTerminator())
<< "Block already has a terminator; not adding fall-through call to: "
<< (dest_func ? dest_func->getName().str() : "<unreachable>");
@@ -115,7 +127,7 @@ llvm::CallInst *AddTerminatingTailCall(llvm::BasicBlock *source_block,
llvm::CallInst *call_target_instr = ir.CreateCall(dest_func, args);
// Make sure we tail-call from one block method to another.
call_target_instr->setTailCallKind(llvm::CallInst::TCK_MustTail);
call_target_instr->setTailCallKind(llvm::CallInst::TCK_Tail);
call_target_instr->setCallingConv(llvm::CallingConv::Fast);
ir.CreateRet(call_target_instr);
return call_target_instr;
@@ -174,26 +186,44 @@ llvm::Value *LoadProgramCounterRef(llvm::BasicBlock *block) {
return ir.CreateLoad(FindVarInFunction(block->getParent(), "PC"));
}
// Update the program counter in the state struct with a hard-coded value.
void StoreProgramCounter(llvm::BasicBlock *block, uint64_t pc) {
auto pc_ptr = LoadProgramCounterRef(block);
auto type = llvm::dyn_cast<llvm::PointerType>(pc_ptr->getType());
(void) new llvm::StoreInst(
llvm::ConstantInt::get(type->getElementType(), pc), pc_ptr, block);
}
// Return the current memory pointer.
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block) {
llvm::IRBuilder<> ir(block);
return ir.CreateLoad(LoadMemoryPointerRef(block));
}
// Return an `llvm::Value *` that is an `i1` (bool type) representing whether
// or not a conditional branch is taken.
llvm::Value *LoadBranchTaken(llvm::BasicBlock *block) {
llvm::IRBuilder<> ir(block);
auto cond = ir.CreateLoad(ir.CreateLoad(
FindVarInFunction(block->getParent(), "BRANCH_TAKEN")));
auto true_val = llvm::ConstantInt::get(cond->getType(), 1);
return ir.CreateICmpEQ(cond, true_val);
}
// Return a reference to the memory pointer.
llvm::Value *LoadMemoryPointerRef(llvm::BasicBlock *block) {
return FindVarInFunction(block->getParent(), "MEMORY");
}
// Find a function with name `name` in the module `M`.
llvm::Function *FindFunction(const llvm::Module *module, std::string name) {
llvm::Function *FindFunction(llvm::Module *module, std::string name) {
return module->getFunction(name);
}
// Find a global variable with name `name` in the module `M`.
llvm::GlobalVariable *FindGlobaVariable(const llvm::Module *module,
llvm::GlobalVariable *FindGlobaVariable(llvm::Module *module,
std::string name) {
return module->getGlobalVariable(name);
return module->getGlobalVariable(name, true);
}
// Reads an LLVM module from a file.
@@ -207,7 +237,9 @@ llvm::Module *LoadModuleFromFile(llvm::LLVMContext *context,
CHECK(nullptr != module)
<< "Unable to parse module file: " << file_name << ".";
module->materializeAll(); // Just in case.
auto ec = module->materializeAll(); // Just in case.
CHECK(!ec)
<< "Unable to materialize everything from " << file_name;
std::string error;
llvm::raw_string_ostream error_stream(error);
@@ -235,15 +267,21 @@ void StoreModuleToFile(llvm::Module *module, std::string file_name) {
<< "Error writing module to file " << file_name << ": " << error;
}
#if LLVM_VERSION_NUMBER > LLVM_VERSION(3, 5)
std::error_code ec;
llvm::tool_output_file bc(tmp_name.c_str(), ec, llvm::sys::fs::F_RW);
CHECK(!ec)
<< "Unable to open output bitcode file for writing: " << tmp_name;
#else
llvm::tool_output_file bc(tmp_name.c_str(), error, llvm::sys::fs::F_RW);
CHECK(error.empty() && !bc.os().has_error())
<< "Unable to open output bitcode file for writing: " << tmp_name
<< ": " << error;
#endif
llvm::WriteBitcodeToFile(module, bc.os());
bc.keep();
if (!ec) {
if (!bc.os().has_error()) {
RenameFile(tmp_name, file_name);
} else {
RemoveFile(tmp_name);
@@ -290,6 +328,7 @@ std::string FindSemanticsBitcodeFile(const std::string &path,
LOG(FATAL)
<< "Cannot find path to " << arch << " semantics bitcode file.";
return "";
}
namespace {
@@ -326,28 +365,40 @@ llvm::Argument *NthArgument(llvm::Function *func, size_t index) {
return &*it;
}
// Run a callback function for every indirect block entry in a remill-lifted
// bitcode module.
void ForEachBlock(llvm::Module *module, BlockCallback on_each_function) {
for (auto &global_var : module->globals()) {
uint64_t pc = 0;
uint64_t id = 0;
if (!TryGetBlockPC(&global_var, pc)) {
// Apply a callback function to every semantics bitcode function.
void ForEachISel(llvm::Module *module, ISelCallback callback) {
for (auto &global : module->globals()) {
if (!global.hasInitializer() || !global.getName().startswith("ISEL_")) {
continue;
}
if (!TryGetBlockId(&global_var, id)) {
id = pc;
}
auto func = llvm::dyn_cast<llvm::Function>(global_var.getInitializer());
CHECK(func != nullptr)
<< "Global variable " << global_var.getName().str()
<< " should be initialized with a function.";
auto sem = llvm::dyn_cast<llvm::Function>(
global.getInitializer()->stripPointerCasts());
on_each_function(pc, id, func);
callback(&global, sem);
}
}
// Declare a lifted function of the correct type.
llvm::Function *DeclareLiftedFunction(llvm::Module *module,
const std::string &name) {
auto bb = module->getFunction("__remill_basic_block");
CHECK(nullptr != bb)
<< "Cannot declare lifted function " << name << " because the "
<< " intrinsics __remill_basic_block cannot be found.";
auto func_type = bb->getFunctionType();
auto func = llvm::dyn_cast<llvm::Function>(
module->getOrInsertFunction(name, func_type));
CHECK(nullptr != func)
<< "Could not insert function " << name << " into module";
InitFunctionAttributes(func);
return func;
}
// Clone function `source_func` into `dest_func`. This will strip out debug
// info during the clone.
void CloneFunctionInto(llvm::Function *source_func, llvm::Function *dest_func) {
@@ -360,7 +411,10 @@ void CloneFunctionInto(llvm::Function *source_func, llvm::Function *dest_func) {
dest_func->setLinkage(source_func->getLinkage());
dest_func->setVisibility(source_func->getVisibility());
dest_func->setCallingConv(source_func->getCallingConv());
#if LLVM_VERSION_NUMBER >= LLVM_VERSION(3, 6)
dest_func->setIsMaterializable(source_func->isMaterializable());
#endif
std::unordered_map<llvm::Value *, llvm::Value *> value_map;
for (llvm::Argument &old_arg : source_func->args()) {
@@ -449,12 +503,12 @@ void CloneFunctionInto(llvm::Function *source_func, llvm::Function *dest_func) {
dest_mod->getOrInsertFunction(
global_val->getName(),
llvm::dyn_cast<llvm::FunctionType>(
global_val->getValueType())));
GetValueType(global_val))));
} else if (llvm::isa<llvm::GlobalVariable>(global_val)) {
new_global_val = llvm::dyn_cast<llvm::GlobalValue>(
dest_mod->getOrInsertGlobal(
global_val->getName(), global_val->getValueType()));
global_val->getName(), GetValueType(global_val)));
} else {
LOG(FATAL)
@@ -493,86 +547,9 @@ void CloneFunctionInto(llvm::Function *source_func, llvm::Function *dest_func) {
namespace {
static bool TryGetBlockInt(llvm::GlobalObject *func, uint64_t &pc,
const char *name) {
auto md = func->getMetadata(name);
if (!md) {
return false;
}
auto val = llvm::dyn_cast<llvm::ValueAsMetadata>(md->getOperand(0).get());
if (!val) {
return false;
}
auto pc_val = llvm::dyn_cast<llvm::ConstantInt>(val->getValue());
if (!pc_val) {
return false;
}
pc = pc_val->getZExtValue();
return true;
}
static void SetBlockMeta(llvm::GlobalObject *func, const char *name, uint64_t val) {
auto &context = func->getContext();
auto int_type = llvm::Type::getInt64Ty(context);
auto const_val = llvm::ConstantInt::get(int_type, val);
auto md = llvm::ValueAsMetadata::get(const_val);
func->setMetadata(name, llvm::MDNode::get(context, md));
}
} // namespace
// Try to get the address of a block.
bool TryGetBlockPC(llvm::GlobalObject *func, uint64_t &pc) {
return TryGetBlockInt(func, pc, "pc");
}
// Try to get the ID of this block. This may be the same as the block's PC.
bool TryGetBlockId(llvm::GlobalObject *func, uint64_t &id) {
return TryGetBlockInt(func, id, "id");
}
// Try to get the ID of this block. This may be the same as the block's PC.
bool TryGetBlockName(llvm::Function *func, std::string &name) {
auto md = func->getMetadata("name");
if (!md) {
return false;
}
auto val = llvm::dyn_cast<llvm::ValueAsMetadata>(md->getOperand(0).get());
if (!val) {
return false;
}
auto name_val = llvm::dyn_cast<llvm::ConstantDataArray>(val->getValue());
if (!name_val) {
return false;
}
name = name_val->getAsString().str();
return true;
}
// Set the PC of a block.
void SetBlockPC(llvm::GlobalObject *func, uint64_t pc) {
SetBlockMeta(func, "pc", pc);
}
// Set the ID of a block.
void SetBlockId(llvm::GlobalObject *func, uint64_t id) {
SetBlockMeta(func, "id", id);
}
void SetBlockName(llvm::Function *func, const std::string &name) {
auto &context = func->getContext();
auto const_val = llvm::ConstantDataArray::getString(
context, name, false /* AddNull */);
auto addr_md = llvm::ValueAsMetadata::get(const_val);
func->setMetadata("name", llvm::MDNode::get(context, addr_md));
}
namespace {
// Initialize some attributes that are common to all newly created block
// functions. Also, give pretty names to the arguments of block functions.
static void InitBlockFunctionAttributes(llvm::Function *block_func) {
block_func->setLinkage(llvm::GlobalValue::ExternalLinkage);
block_func->setVisibility(llvm::GlobalValue::DefaultVisibility);
@@ -616,11 +593,10 @@ static void FixupBasicBlockVariables(llvm::Function *basic_block) {
// Make `func` a clone of the `__remill_basic_block` function.
void CloneBlockFunctionInto(llvm::Function *func) {
auto module = func->getParent();
llvm::Module *module = func->getParent();
auto basic_block = module->getFunction("__remill_basic_block");
CHECK(nullptr != basic_block)
<< "Unable to find __remill_basic_block in module "
<< module->getName().str();
<< "Unable to find __remill_basic_block in module";
if (!BlockHasSpecialVars(basic_block)) {
InitFunctionAttributes(basic_block);
+31 -27
View File
@@ -1,4 +1,18 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_UTIL_H_
#define REMILL_BC_UTIL_H_
@@ -55,18 +69,24 @@ llvm::Value *LoadProgramCounter(llvm::BasicBlock *block);
// Return a reference to the current program counter.
llvm::Value *LoadProgramCounterRef(llvm::BasicBlock *block);
// Update the program counter in the state struct with a hard-coded value.
void StoreProgramCounter(llvm::BasicBlock *block, uint64_t pc);
// Return the current memory pointer.
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block);
// Return a reference to the memory pointer.
llvm::Value *LoadMemoryPointerRef(llvm::BasicBlock *block);
// Return an `llvm::Value *` that is an `i1` (bool type) representing whether
// or not a conditional branch is taken.
llvm::Value *LoadBranchTaken(llvm::BasicBlock *block);
// Find a function with name `name` in the module `M`.
llvm::Function *FindFunction(const llvm::Module *M, std::string name);
llvm::Function *FindFunction(llvm::Module *M, std::string name);
// Find a global variable with name `name` in the module `M`.
llvm::GlobalVariable *FindGlobaVariable(const llvm::Module *M,
std::string name);
llvm::GlobalVariable *FindGlobaVariable(llvm::Module *M, std::string name);
// Parses and loads a bitcode file into memory.
llvm::Module *LoadModuleFromFile(llvm::LLVMContext *context,
@@ -86,11 +106,14 @@ llvm::Argument *NthArgument(llvm::Function *func, size_t index);
std::string LLVMThingToString(llvm::Value *thing);
std::string LLVMThingToString(llvm::Type *thing);
using BlockCallback = std::function<void(uint64_t, uint64_t, llvm::Function *)>;
// Apply a callback function to every semantics bitcode function.
using ISelCallback = std::function<
void(llvm::GlobalVariable *, llvm::Function *)>;
void ForEachISel(llvm::Module *module, ISelCallback callback);
// Run a callback function for every indirect block entry in a remill-lifted
// bitcode module.
void ForEachBlock(llvm::Module *module, BlockCallback callback);
// Declare a lifted function of the correct type.
llvm::Function *DeclareLiftedFunction(llvm::Module *module,
const std::string &name);
// Clone function `source_func` into `dest_func`. This will strip out debug
// info during the clone.
@@ -99,25 +122,6 @@ void ForEachBlock(llvm::Module *module, BlockCallback callback);
// `source_func` into the module of `dest_func`.
void CloneFunctionInto(llvm::Function *source_func, llvm::Function *dest_func);
// Try to get the address of a block.
bool TryGetBlockPC(llvm::GlobalObject *func, uint64_t &pc);
// Try to get the ID of this block. This may be the same as the block's PC.
bool TryGetBlockId(llvm::GlobalObject *func, uint64_t &id);
// Try to get the ID of this block. This may be the same as the block's PC.
bool TryGetBlockName(llvm::Function *func, std::string &name);
// Set the PC of a block.
void SetBlockPC(llvm::GlobalObject *func, uint64_t pc);
// Set the ID of a block.
void SetBlockId(llvm::GlobalObject *func, uint64_t id);
// Set the name of a block. This associates some high-level name, e.g. `malloc`
// with the metadata of some block function.
void SetBlockName(llvm::Function *func, const std::string &name);
// Make `func` a clone of the `__remill_basic_block` function.
void CloneBlockFunctionInto(llvm::Function *func);
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMILL_BC_VERSION_H_
#define REMILL_BC_VERSION_H_
#include <llvm/Config/llvm-config.h>
#define LLVM_VERSION(major, minor) ((major * 100) + minor)
#define LLVM_VERSION_NUMBER \
LLVM_VERSION(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR)
#if LLVM_VERSION_NUMBER < LLVM_VERSION(3, 5)
# error "Minimum supported LLVM version is 3.5"
#endif
#endif // REMILL_BC_VERSION_H_
-29
View File
@@ -1,29 +0,0 @@
/* Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved. */
#include "remill/CFG/BlockHasher.h"
#include "remill/CFG/CFG.h"
#include "third_party/murmurhash/MurmurHash2.h"
namespace remill {
BlockHasher::BlockHasher(void)
: BlockHasher(0) {}
BlockHasher::BlockHasher(uint64_t seed_)
: seed(seed_) {}
uint64_t BlockHasher::HashBlock(const cfg::Block &block) const {
std::string data;
for (const auto &inst : block.instructions()) {
auto pc = inst.address();
auto pc_ptr = reinterpret_cast<char *>(&pc);
auto &bytes = inst.bytes();
data.insert(data.end(), pc_ptr, pc_ptr + sizeof(pc));
data.insert(data.end(), bytes.begin(), bytes.end());
}
return MurmurHash64A(data.data(), data.size(), seed);
}
} // namespace remill
-35
View File
@@ -1,35 +0,0 @@
/* Copyright 2017 Peter Goodman (peter@trailofbits.com), all rights reserved. */
#ifndef REMILL_CFG_BLOCKHASHER_H_
#define REMILL_CFG_BLOCKHASHER_H_
#include <cstdint>
#include <string>
namespace remill {
namespace cfg {
class Block;
} // namespace cfg
// Used to create a position- and data-dependent hash of a basic block. This
// is part of the block versioning scheme to handle self-modifying code. The
// seed of the hasher should be a hash of some region of executable code.
//
// The reason we want a hash is so that we can identify blocks in a way that
// is representative of their content and location, as opposed to just being
// represented by their program counters.
class BlockHasher {
public:
BlockHasher(void);
explicit BlockHasher(uint64_t seed_);
uint64_t HashBlock(const cfg::Block &block) const;
const uint64_t seed;
};
} // namespace remill
#endif // REMILL_CFG_BLOCKHASHER_H_
-30
View File
@@ -1,30 +0,0 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
#include <fstream>
#include <glog/logging.h>
#include "remill/CFG/CFG.h"
namespace remill {
const cfg::Module *ReadCFG(std::string cfg_file_name) {
GOOGLE_PROTOBUF_VERIFY_VERSION;
std::ifstream cfg(cfg_file_name);
CHECK(cfg.good()) << "Invalid CFG file: " << cfg_file_name;
auto cfg_pb = new cfg::Module;
auto parsed = cfg_pb->ParseFromIstream(&cfg);
CHECK(parsed)
<< "Unable to parse CFG file: " << cfg_file_name
<< " with error " << cfg_pb->DebugString();
return cfg_pb;
}
} // namespace remill
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include "generated/CFG/CFG.pb.cc"
#pragma clang diagnostic pop
-26
View File
@@ -1,26 +0,0 @@
/* Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. */
#ifndef REMILL_CFG_CFG_H_
#define REMILL_CFG_CFG_H_
#include <string>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include "generated/CFG/CFG.pb.h"
#pragma clang diagnostic pop
class Module;
namespace llvm {
class Module;
} // namespace llvm
namespace remill {
class Arch;
const cfg::Module *ReadCFG(std::string cfg_file_name);
} // namespace remill
#endif // REMILL_CFG_CFG_H_
-23
View File
@@ -1,23 +0,0 @@
// Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved.
package remill.cfg;
message Instr {
required bytes bytes = 1;
required uint64 address = 2;
}
// A block has an ID that can be distinct from its address. The idea here is
// that the block should represent a position- and content dependent hash of
// the block. This scheme permits multiple blocks at the same address to exist
// (e.g. to model runtime code modification).
message Block {
optional string name = 1;
optional uint64 id = 2;
required uint64 address = 3;
repeated Instr instructions = 4;
}
message Module {
repeated Block blocks = 1;
}
+15 -1
View File
@@ -1,4 +1,18 @@
/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <glog/logging.h>

Some files were not shown because too many files have changed in this diff Show More