Skip to content

Commit 3a16ad4

Browse files
Peter Goodmanartemdinaburgekilmer
authored
CMake improvements and refactor of __remill_basic_block (#447)
* Append project name to the check_git target to fix compound builds (#446) * Change the way we get registers for __remill_basic_block so that it's the Arch class of the target that actually populates the function, and isn't based on reverse-engineering what's visible in the function as compiled by llvm * Renamed a cmake var to reduce likelihood of conflicts, and tries to make sure remill only links against static llvm libraries * Fix instruction dominance issues * Minor fix on the type of PC on x86 * Added new implementation (in Arch.cpp) of the AArch64 __remill_basic_block function Co-authored-by: Artem Dinaburg <[email protected]> Co-authored-by: Eric Kilmer <[email protected]>
1 parent 5f74c38 commit 3a16ad4

28 files changed

+1372
-1679
lines changed

CMakeLists.txt

Lines changed: 193 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ include(CTest)
3030
if (LLVM_Z3_INSTALL_DIR)
3131
find_package(Z3 4.7.1)
3232
set(need_z3 TRUE)
33-
elseif(DEFINED ENV{TRAILOFBITS_LIBRARIES})
34-
set(LLVM_Z3_INSTALL_DIR "$ENV{TRAILOFBITS_LIBRARIES}/z3")
33+
elseif(DEFINED CXX_COMMON_REPOSITORY_ROOT)
34+
set(LLVM_Z3_INSTALL_DIR "${CXX_COMMON_REPOSITORY_ROOT}/z3")
3535
set(need_z3 TRUE)
3636
else()
3737
set(need_z3 FALSE)
@@ -67,38 +67,80 @@ endif()
6767
# libraries
6868
#
6969

70+
# LLVM
7071
find_package(LLVM REQUIRED CONFIG HINTS ${FINDPACKAGE_LLVM_HINTS})
7172

7273
string(REPLACE "." ";" LLVM_VERSION_LIST ${LLVM_PACKAGE_VERSION})
7374
list(GET LLVM_VERSION_LIST 0 LLVM_MAJOR_VERSION)
7475
list(GET LLVM_VERSION_LIST 1 LLVM_MINOR_VERSION)
7576

76-
set(LLVM_LIBRARIES
77-
LLVMCore LLVMAnalysis LLVMSupport LLVMipo LLVMIRReader
78-
LLVMBitReader LLVMBitWriter LLVMTransformUtils LLVMScalarOpts
79-
LLVMLTO
77+
add_library(thirdparty_llvm INTERFACE)
78+
target_include_directories(thirdparty_llvm SYSTEM INTERFACE
79+
${LLVM_INCLUDE_DIRS}
80+
)
81+
target_compile_definitions(thirdparty_llvm INTERFACE
82+
${LLVM_DEFINITIONS}
83+
)
84+
85+
# Go find only the static libraries of LLVM, and link against those.
86+
foreach(LLVM_LIB IN LISTS LLVM_AVAILABLE_LIBS)
87+
get_target_property(LLVM_LIB_TYPE ${LLVM_LIB} TYPE)
88+
if(LLVM_LIB_TYPE STREQUAL "STATIC_LIBRARY")
89+
list(APPEND LLVM_LIBRARIES "${LLVM_LIB}")
90+
endif()
91+
endforeach()
92+
93+
# These are out-of-order in `LLVM_AVAILABLE_LIBS` and should always be last.
94+
list(REMOVE_ITEM LLVM_LIBRARIES LLVMMC LLVMCore LLVMSupport)
95+
list(APPEND LLVM_LIBRARIES LLVMMC LLVMCore LLVMSupport)
96+
message(WARNING "Libraries: ${LLVM_LIBRARIES}")
97+
98+
99+
target_link_libraries(thirdparty_llvm INTERFACE
100+
${LLVM_LIBRARIES}
80101
)
81102

82-
list(APPEND PROJECT_LIBRARIES ${LLVM_LIBRARIES})
83-
list(APPEND PROJECT_DEFINITIONS ${LLVM_DEFINITIONS})
84-
list(APPEND PROJECT_INCLUDEDIRECTORIES ${LLVM_INCLUDE_DIRS})
103+
# Microsoft Z3
104+
add_library(thirdparty_z3 INTERFACE)
105+
if(Z3_FOUND)
106+
target_include_directories(thirdparty_z3 SYSTEM INTERFACE
107+
${Z3_INCLUDE_DIR}
108+
)
109+
target_link_libraries(thirdparty_z3 INTERFACE
110+
${Z3_LIBRARIES}
111+
)
112+
endif()
85113

86-
# xed
114+
# Intel XED
87115
find_package(XED REQUIRED)
88-
list(APPEND PROJECT_LIBRARIES ${XED_LIBRARIES})
89-
list(APPEND PROJECT_INCLUDEDIRECTORIES ${XED_INCLUDE_DIRS})
116+
add_library(thirdparty_xed INTERFACE)
117+
target_include_directories(thirdparty_xed SYSTEM INTERFACE
118+
${XED_INCLUDE_DIRS}
119+
)
120+
target_link_libraries(thirdparty_xed INTERFACE
121+
${XED_LIBRARIES}
122+
)
90123

91-
# google log module
124+
# Google glog module
92125
find_package(glog REQUIRED)
93-
list(APPEND PROJECT_LIBRARIES glog::glog)
126+
add_library(thirdparty_glog INTERFACE)
127+
target_link_libraries(thirdparty_glog INTERFACE
128+
glog::glog
129+
)
94130

95-
# gflags
131+
# Google gflags
96132
find_package(gflags REQUIRED)
97-
list(APPEND PROJECT_LIBRARIES gflags)
133+
add_library(thirdparty_gflags INTERFACE)
134+
target_link_libraries(thirdparty_gflags INTERFACE
135+
gflags
136+
)
98137

99-
# windows sdk
138+
# Windows SDK
139+
add_library(thirdparty_win32 INTERFACE)
100140
if(DEFINED WIN32)
101-
list(APPEND PROJECT_LIBRARIES "Kernel32.lib")
141+
target_link_libraries(thirdparty_win32 INTERFACE
142+
"Kernel32.lib"
143+
)
102144
endif()
103145

104146
#
@@ -122,14 +164,10 @@ endif()
122164
set(REMILL_BUILD_SEMANTICS_DIR_X86 "${CMAKE_CURRENT_BINARY_DIR}/remill/Arch/X86/Runtime/")
123165
set(REMILL_BUILD_SEMANTICS_DIR_AARCH64 "${CMAKE_CURRENT_BINARY_DIR}/remill/Arch/AArch64/Runtime/")
124166

125-
list(APPEND PROJECT_DEFINITIONS "REMILL_INSTALL_SEMANTICS_DIR=\"${REMILL_INSTALL_SEMANTICS_DIR}/\"")
126-
list(APPEND PROJECT_DEFINITIONS "REMILL_BUILD_SEMANTICS_DIR_X86=\"${REMILL_BUILD_SEMANTICS_DIR_X86}\"")
127-
list(APPEND PROJECT_DEFINITIONS "REMILL_BUILD_SEMANTICS_DIR_AARCH64=\"${REMILL_BUILD_SEMANTICS_DIR_AARCH64}\"")
128-
129167
# verion data
130168
add_subdirectory(remill/Version)
131169

132-
add_library(${PROJECT_NAME} STATIC
170+
add_library(remill STATIC
133171
remill/Arch/AArch64/Arch.cpp
134172
remill/Arch/AArch64/Decode.cpp
135173
remill/Arch/AArch64/Extract.cpp
@@ -151,14 +189,102 @@ add_library(${PROJECT_NAME} STATIC
151189
remill/OS/OS.cpp
152190
)
153191

154-
set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)
192+
set_property(TARGET remill PROPERTY POSITION_INDEPENDENT_CODE ON)
193+
set(THIRDPARTY_LIBRARY_LIST thirdparty_z3 thirdparty_llvm thirdparty_xed thirdparty_glog thirdparty_gflags)
155194

156195
# add everything as public.
157-
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_LIBRARIES} RemillVersion)
158-
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
159-
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${PROJECT_INCLUDEDIRECTORIES})
160-
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_DEFINITIONS} ${GLOBAL_DEFINITIONS})
161-
target_compile_options(${PROJECT_NAME} PUBLIC ${GLOBAL_CXXFLAGS})
196+
197+
if(UNIX AND NOT APPLE)
198+
#For Linux builds, group LLVM libraries into a single group
199+
# that avoids frustrating library ordering issues
200+
set(LINKER_START_GROUP "-Wl,--start-group")
201+
set(LINKER_END_GROUP "-Wl,--end-group")
202+
else()
203+
set(LINKER_START_GROUP "")
204+
set(LINKER_END_GROUP "")
205+
endif()
206+
207+
208+
target_link_libraries(remill LINK_PUBLIC
209+
${LINKER_START_GROUP} ${THIRDPARTY_LIBRARY_LIST} ${LINKER_END_GROUP}
210+
RemillVersion
211+
)
212+
213+
target_include_directories(remill PUBLIC ${CMAKE_SOURCE_DIR})
214+
215+
if(WIN32)
216+
# warnings and compiler settings
217+
target_compile_options(remill PUBLIC
218+
/MD /nologo /W3 /EHsc /wd4141 /wd4146 /wd4180 /wd4244
219+
/wd4258 /wd4267 /wd4291 /wd4345 /wd4351 /wd4355 /wd4456
220+
/wd4457 /wd4458 /wd4459 /wd4503 /wd4624 /wd4722 /wd4800
221+
/wd4100 /wd4127 /wd4512 /wd4505 /wd4610 /wd4510 /wd4702
222+
/wd4245 /wd4706 /wd4310 /wd4701 /wd4703 /wd4389 /wd4611
223+
/wd4805 /wd4204 /wd4577 /wd4091 /wd4592 /wd4324
224+
)
225+
226+
target_compile_definitions(remill PUBLIC
227+
_CRT_SECURE_NO_DEPRECATE
228+
_CRT_SECURE_NO_WARNINGS
229+
_CRT_NONSTDC_NO_DEPRECATE
230+
_CRT_NONSTDC_NO_WARNINGS
231+
_SCL_SECURE_NO_DEPRECATE
232+
_SCL_SECURE_NO_WARNINGS
233+
GOOGLE_PROTOBUF_NO_RTTI
234+
)
235+
236+
else()
237+
# warnings and compiler settings
238+
target_compile_options(remill PUBLIC
239+
-Wall -Wextra -Wno-unused-parameter -Wno-c++98-compat
240+
-Wno-unreachable-code-return -Wno-nested-anon-types
241+
-Wno-extended-offsetof
242+
-Wno-variadic-macros -Wno-return-type-c-linkage
243+
-Wno-c99-extensions -Wno-ignored-attributes -Wno-unused-local-typedef
244+
-Wno-unknown-pragmas -Wno-unknown-warning-option -fPIC
245+
-fno-omit-frame-pointer -fvisibility-inlines-hidden
246+
-fno-asynchronous-unwind-tables
247+
)
248+
249+
# Clang-specific warnings/error options
250+
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
251+
target_compile_options(remill PUBLIC
252+
-Wgnu-alignof-expression -Wno-gnu-anonymous-struct -Wno-gnu-designator
253+
-Wno-gnu-zero-variadic-macro-arguments -Wno-gnu-statement-expression
254+
-fno-aligned-allocation
255+
)
256+
endif()
257+
258+
# debug symbols
259+
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
260+
target_compile_options(remill PUBLIC
261+
-gdwarf-2 -g3
262+
)
263+
endif()
264+
265+
# optimization flags and definitions
266+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
267+
target_compile_options(remill PUBLIC
268+
-O0
269+
)
270+
target_compile_definitions(remill PUBLIC
271+
"DEBUG"
272+
)
273+
else()
274+
target_compile_options(remill PUBLIC
275+
-O2
276+
)
277+
target_compile_definitions(remill PUBLIC
278+
"NDEBUG"
279+
)
280+
endif()
281+
endif()
282+
283+
target_compile_definitions(remill PUBLIC
284+
"REMILL_INSTALL_SEMANTICS_DIR=\"${REMILL_INSTALL_SEMANTICS_DIR}/\""
285+
"REMILL_BUILD_SEMANTICS_DIR_X86=\"${REMILL_BUILD_SEMANTICS_DIR_X86}\""
286+
"REMILL_BUILD_SEMANTICS_DIR_AARCH64=\"${REMILL_BUILD_SEMANTICS_DIR_AARCH64}\""
287+
)
162288

163289
#
164290
# Also install clang, libllvm and llvm-link
@@ -234,7 +360,7 @@ endfunction()
234360
set(INSTALLED_CLANG_NAME "remill-clang-${REMILL_LLVM_VERSION}${executable_extension}")
235361
set(INSTALLED_LLVMLINK_NAME "remill-llvm-link-${REMILL_LLVM_VERSION}${executable_extension}")
236362

237-
if("${LIBRARY_REPOSITORY_ROOT}" STREQUAL "" OR NOT EXISTS "${LIBRARY_REPOSITORY_ROOT}/llvm")
363+
if("${CXX_COMMON_REPOSITORY_ROOT}" STREQUAL "" OR NOT EXISTS "${CXX_COMMON_REPOSITORY_ROOT}/llvm")
238364
set(INSTALLED_LIBLLVM_NAME "${dynamic_lib_prefix}LLVM-${REMILL_LLVM_VERSION}.${dynamic_lib_extension}")
239365

240366
# system binaries are not built statically, so we need to fix the rpath
@@ -268,10 +394,10 @@ if("${LIBRARY_REPOSITORY_ROOT}" STREQUAL "" OR NOT EXISTS "${LIBRARY_REPOSITORY_
268394
else()
269395
# The executable in our binary repository are statically built, meaning that we don't need
270396
# to change the rpath
271-
InstallExternalTarget("ext_clang" "${LIBRARY_REPOSITORY_ROOT}/llvm/bin/clang${executable_extension}"
397+
InstallExternalTarget("ext_clang" "${CXX_COMMON_REPOSITORY_ROOT}/llvm/bin/clang${executable_extension}"
272398
"${install_folder}/bin" "${INSTALLED_CLANG_NAME}")
273399

274-
InstallExternalTarget("ext_llvmlink" "${LIBRARY_REPOSITORY_ROOT}/llvm/bin/llvm-link${executable_extension}"
400+
InstallExternalTarget("ext_llvmlink" "${CXX_COMMON_REPOSITORY_ROOT}/llvm/bin/llvm-link${executable_extension}"
275401
"${install_folder}/bin" "${INSTALLED_LLVMLINK_NAME}")
276402
endif()
277403

@@ -282,9 +408,42 @@ install(TARGETS "${PROJECT_NAME}"
282408

283409
set(REMILL_LIBRARY_LOCATION "${install_folder}/lib/libremill.a")
284410
set(REMILL_INCLUDE_LOCATION "${install_folder}/include")
411+
get_target_property(REMILL_COMPILE_OPTIONS remill COMPILE_OPTIONS)
412+
get_target_property(REMILL_COMPILE_DEFINITIONS remill COMPILE_DEFINITIONS)
413+
414+
GetTargetTree(THIRDPARTY_LIBRARIES ${THIRDPARTY_LIBRARY_LIST})
415+
GetPublicIncludeFolders(THIRDPARTY_INCLUDE_DIRECTORIES ${THIRDPARTY_LIBRARIES})
416+
foreach(THIRDPARTY_LIB IN LISTS THIRDPARTY_LIBRARIES)
417+
string(SUBSTRING "${THIRDPARTY_LIB}" 0 1 THIRDPARTY_LIB_PREFIX)
418+
if(TARGET ${THIRDPARTY_LIB})
419+
get_target_property(THIRDPARTY_LIB_TYPE ${THIRDPARTY_LIB} TYPE)
420+
if(THIRDPARTY_LIB_TYPE STREQUAL "STATIC_LIBRARY" OR THIRDPARTY_LIB_TYPE STREQUAL "SHARED_LIBRARY")
421+
list(APPEND THIRDPARTY_LIBRARY_FILES "$${}<TARGET_FILE:${THIRDPARTY_LIB}>")
422+
endif()
423+
elseif("${THIRDPARTY_LIB_PREFIX}" STREQUAL "$${}")
424+
# E.g. $<LINK_ONLY:...>
425+
else()
426+
list(APPEND THIRDPARTY_LIBRARY_FILES "${THIRDPARTY_LIB}")
427+
endif()
428+
endforeach()
429+
430+
list(REMOVE_DUPLICATES THIRDPARTY_LIBRARY_FILES)
431+
if(NOT "x{$LINKER_START_GROUP}x" STREQUAL "xx")
432+
list(INSERT THIRDPARTY_LIBRARY_FILES 0 "${LINKER_START_GROUP}")
433+
list(APPEND THIRDPARTY_LIBRARY_FILES "${LINKER_END_GROUP}")
434+
endif()
435+
436+
# First do the basic substitutions.
285437
configure_file(
286438
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/remillConfig.cmake.in"
287-
"${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
439+
"${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake.pregen"
440+
@ONLY
441+
)
442+
443+
# Then expand the generator expressions added to `THIRDPARTY_LIBRARY_FILES`.
444+
file(GENERATE
445+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
446+
INPUT "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake.pregen"
288447
)
289448

290449
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/remillConfig.cmake"
@@ -316,6 +475,7 @@ install(FILES
316475
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/Attributes.h"
317476
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/BitcodeReaderWriter.h"
318477
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/CallingConvention.h"
478+
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/CTypes.h"
319479
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/DataLayout.h"
320480
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/DebugInfo.h"
321481
"${CMAKE_CURRENT_SOURCE_DIR}/remill/BC/Compat/Error.h"

cmake/BCCompiler.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ set(DEFAULT_BC_COMPILER_FLAGS
1717
-ffreestanding -fno-common -fno-builtin -fno-exceptions -fno-rtti
1818
-fno-asynchronous-unwind-tables -Wno-unneeded-internal-declaration
1919
-Wno-unused-function -Wgnu-inline-cpp-without-extern -std=c++14
20+
-Wno-pass-failed=transform-warning
2021
${EXTRA_BC_SYSROOT}
2122
)
2223

cmake/git_watcher.cmake

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,18 @@ function(GetGitState _working_dir)
158158

159159
RunGitCommand(show -s "--format=%s" ${object})
160160
if(exit_code EQUAL 0)
161+
string(REPLACE "\"" "\\\"" output "${output}")
161162
set(ENV{GIT_COMMIT_SUBJECT} "${output}")
162163
endif()
163164

164165
RunGitCommand(show -s "--format=%b" ${object})
165166
if(exit_code EQUAL 0)
166167
if(output)
167168
# Escape line breaks in the commit message.
168-
string(REPLACE "\r\n" "\\r\\n\\\r\n" safe ${output})
169+
string(REPLACE "\r\n" "\\r\\n\\\r\n" safe "${output}")
169170
if(safe STREQUAL output)
170171
# Didn't have windows lines - try unix lines.
171-
string(REPLACE "\n" "\\n\\\n" safe ${output})
172+
string(REPLACE "\n" "\\n\\\n" safe "${output}")
172173
endif()
173174
else()
174175
# There was no commit body - set the safe string to empty.

cmake/remillConfig.cmake.in

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,28 @@ cmake_minimum_required(VERSION 3.2)
1616

1717
if(NOT TARGET remill)
1818
if(WIN32)
19-
set(REMILL_LIBRARY_LOCATION "${CMAKE_INSTALL_PREFIX}/remill/lib/remill.lib")
20-
set(REMILL_INCLUDE_LOCATION "${CMAKE_INSTALL_PREFIX}/remill/include")
19+
set(REMILL_LIBRARY_LOCATION "@CMAKE_INSTALL_PREFIX@/remill/lib/remill.lib")
20+
set(REMILL_INCLUDE_LOCATION "@CMAKE_INSTALL_PREFIX@/remill/include")
2121
else()
22-
set(REMILL_LIBRARY_LOCATION "${CMAKE_INSTALL_PREFIX}/lib/libremill.a")
23-
set(REMILL_INCLUDE_LOCATION "${CMAKE_INSTALL_PREFIX}/include")
22+
set(REMILL_LIBRARY_LOCATION "@CMAKE_INSTALL_PREFIX@/lib/libremill.a")
23+
set(REMILL_INCLUDE_LOCATION "@CMAKE_INSTALL_PREFIX@/include")
2424
endif()
2525

26-
add_library(remill STATIC IMPORTED)
27-
set_property(TARGET remill PROPERTY IMPORTED_LOCATION "${REMILL_LIBRARY_LOCATION}")
28-
target_include_directories(remill INTERFACE "${REMILL_INCLUDE_LOCATION}")
26+
if(NOT "x@CXX_COMMON_REPOSITORY_ROOT@x" STREQUAL "xx")
27+
set(CXX_COMMON_REPOSITORY_ROOT "@CXX_COMMON_REPOSITORY_ROOT@")
28+
endif()
2929

30-
target_compile_definitions(remill INTERFACE "REMILL_INSTALL_SEMANTICS_DIR=\"${REMILL_INSTALL_SEMANTICS_DIR}\"")
31-
target_compile_definitions(remill INTERFACE "REMILL_BUILD_SEMANTICS_DIR_X86=\"${REMILL_INSTALL_SEMANTICS_DIR}\"")
32-
target_compile_definitions(remill INTERFACE "REMILL_BUILD_SEMANTICS_DIR_AARCH64=\"${REMILL_INSTALL_SEMANTICS_DIR}\"")
30+
set(LLVM_MAJOR_VERSION @LLVM_MAJOR_VERSION@)
31+
set(LLVM_MINOR_VERSION @LLVM_MINOR_VERSION@)
32+
set(REMILL_LLVM_VERSION "@LLVM_MAJOR_VERSION@.@LLVM_MINOR_VERSION@")
33+
34+
add_library(remill STATIC IMPORTED)
35+
set_property(TARGET remill PROPERTY IMPORTED_LOCATION "@REMILL_LIBRARY_LOCATION@")
36+
target_include_directories(remill INTERFACE @THIRDPARTY_INCLUDE_DIRECTORIES@)
37+
target_include_directories(remill INTERFACE @REMILL_INCLUDE_LOCATION@)
38+
target_compile_options(remill INTERFACE @REMILL_COMPILE_OPTIONS@)
39+
target_compile_definitions(remill INTERFACE @REMILL_COMPILE_DEFINITIONS@)
40+
target_link_libraries(remill INTERFACE @THIRDPARTY_LIBRARY_FILES@)
3341

3442
# Add a dummy 'semantics' target to satisfy the protobuf generator
3543
add_custom_target(semantics)

0 commit comments

Comments
 (0)