From bdbae401abbc35b0247730419b6d3297745256d6 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Tue, 19 Dec 2023 15:59:45 +0100 Subject: [PATCH 01/15] Modified CMakeLists.txt to take whether or not to disable RTTI & exception handling from LLVM's configuration, rather than hardcoding --- CMakeLists.txt | 85 +++++++++++++++++++++++++++++++++++++---- svf-llvm/CMakeLists.txt | 52 ++----------------------- 2 files changed, 81 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a115b82c4..51e3d81e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,15 +5,77 @@ project("SVF") configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h) -# We need to match the build environment for LLVM: In particular, we need C++14 -# and the -fno-rtti flag +# Match configuration used to build LLVM (match C++ standard; match +# runtime typing information (RTTI); match exception handling; etc) +if(COMMAND add_llvm_library) + message(STATUS "Detected in-tree build configuration; skipping LLVM fetching") + set(IN_SOURCE_BUILD 1) +else() + message(STATUS "Detected out-of-tree build configuration; fetching LLVM") + + find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR} $ENV{LLVM_DIR}) + message(STATUS "LLVM STATUS: + Version ${LLVM_PACKAGE_VERSION} + Definitions ${LLVM_DEFINITIONS} + Includes ${LLVM_INCLUDE_DIRS} + Libraries ${LLVM_LIBRARY_DIRS} + Targets ${LLVM_TARGETS_TO_BUILD} + Build type ${LLVM_BUILD_TYPE} + Exceptions ${LLVM_ENABLE_EH} + RTTI ${LLVM_ENABLE_RTTI} + Dynamic lib ${LLVM_LINK_LLVM_DYLIB}" + ) + + if("${LLVM_PACKAGE_VERSION_MAJOR}" VERSION_GREATER "15") + message(FATAL_ERROR "Unsupported LLVM version (need <= 15.0.7; got ${LLVM_PACKAGE_VERSION})") + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT ${LLVM_BUILD_TYPE} STREQUAL "Debug") + message(FATAL_ERROR "Got build type 'Debug' but LLVM is not built in Debug mode!") + endif() + + if(NOT LLVM_ENABLE_EH) + message(STATUS "Building SVF without exception handling") + add_compile_options("-fno-exceptions") + endif() + + if(NOT LLVM_ENABLE_RTTI) + message(STATUS "Building SVF without RTII") + add_compile_options("-fno-rtti") + endif() + + # Load the LLVM definitions & include directories + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + + if(NOT ${LLVM_LINK_LLVM_DYLIB}) + message(STATUS "Linking to separate LLVM static libraries") + llvm_map_components_to_libnames( + llvm_libs + analysis + bitwriter + core + instcombine + instrumentation + ipo + irreader + linker + scalaropts + support + target + transformutils) + else() + message(STATUS "Linking to LLVM dynamic shared library object") + set(llvm_libs LLVM) + endif() + + # Make the "add_llvm_library()" command available + include(AddLLVM) +endif() + +# Set C++ standard; use C++14 as LLVM 15 defaults to that (doesn't need to match) set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -# add -std=gnu++14 set(CMAKE_CXX_EXTENSIONS ON) - -add_compile_options("-fno-rtti") -add_compile_options("-fno-exceptions") +set(CMAKE_CXX_STANDARD_REQUIRED ON) # Treat compiler warnings as errors add_compile_options("-Werror" "-Wall") @@ -80,11 +142,18 @@ endif() add_subdirectory(svf) add_subdirectory(svf-llvm) +include(GNUInstallDirs) +install( + TARGETS SvfCore SvfLLVM + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) install( DIRECTORY ${PROJECT_SOURCE_DIR}/svf/include/ ${PROJECT_SOURCE_DIR}/svf-llvm/include/ COMPONENT devel - DESTINATION include/svf + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/include/svf FILES_MATCHING PATTERN "**/*.h") diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index a583840e1..3e9d97e82 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -1,56 +1,12 @@ -# To support both in- and out-of-source builds, we check for the presence of the -# add_llvm_loadable_module command. - if this command is not present, we are -# building out-of-source -if(NOT COMMAND add_llvm_library) - find_package(LLVM REQUIRED CONFIG HINTS "${LLVM_DIR}") - set(LLVM_DIR ${LLVM_BINARY_DIR} PARENT_SCOPE) - - message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") - message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") - - if(NOT LLVM_ENABLE_RTTI) - add_compile_options("-fno-rtti") - message(STATUS "Disable RTTI") - endif() - - if(NOT LLVM_ENABLE_EH) - add_compile_options("-fno-exceptions") - message(STATUS "Disable exceptions") - endif() - - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") - include(AddLLVM) - - add_definitions(${LLVM_DEFINITIONS}) - # include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) - - if(LLVM_LINK_LLVM_DYLIB) - set(llvm_libs LLVM) - else() - llvm_map_components_to_libnames( - llvm_libs - analysis - bitwriter - core - instcombine - instrumentation - ipo - irreader - linker - scalaropts - support - target - transformutils) - endif() -else() - set(IN_SOURCE_BUILD 1) -endif() - # SVF-LLVM contains LLVM Libs file(GLOB SVFLLVM_SOURCES lib/*.cpp) add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) + target_include_directories(SvfLLVM SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) +target_link_directories(SvfLLVM PUBLIC ${LLVM_LIBRARY_DIRS}) +target_compile_definitions(SvfLLVM PUBLIC ${LLVM_DEFINITIONS}) + target_include_directories(SvfLLVM PUBLIC include) target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) From 395974241bb2b3062493f0d74536078b506442a7 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 09:48:51 +0100 Subject: [PATCH 02/15] Fixed setting of C++ standard and removed requirement for LLVM to be built in debug-mode when SVF is being built in debug-mode --- CMakeLists.txt | 32 +++++++++++++++++++++----------- svf/CMakeLists.txt | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51e3d81e7..c744375be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ else() find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR} $ENV{LLVM_DIR}) message(STATUS "LLVM STATUS: - Version ${LLVM_PACKAGE_VERSION} + Version ${LLVM_VERSION} Definitions ${LLVM_DEFINITIONS} Includes ${LLVM_INCLUDE_DIRS} Libraries ${LLVM_LIBRARY_DIRS} @@ -26,12 +26,9 @@ else() Dynamic lib ${LLVM_LINK_LLVM_DYLIB}" ) - if("${LLVM_PACKAGE_VERSION_MAJOR}" VERSION_GREATER "15") - message(FATAL_ERROR "Unsupported LLVM version (need <= 15.0.7; got ${LLVM_PACKAGE_VERSION})") - endif() - if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT ${LLVM_BUILD_TYPE} STREQUAL "Debug") - message(FATAL_ERROR "Got build type 'Debug' but LLVM is not built in Debug mode!") + message(NOTICE "Building SVF in debug-mode but LLVM was not built in debug-mode; " + "debug information could be incomplete when using SVF from LLVM") endif() if(NOT LLVM_ENABLE_EH) @@ -70,12 +67,25 @@ else() # Make the "add_llvm_library()" command available include(AddLLVM) -endif() -# Set C++ standard; use C++14 as LLVM 15 defaults to that (doesn't need to match) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_EXTENSIONS ON) -set(CMAKE_CXX_STANDARD_REQUIRED ON) + # Set the default C++ standard used to build SVF; LLVM versions up to version 6 defaulted to C++98, + # and up to (and including) version 15 the default was C++14. From versions 16 and onwards, the + # default C++ standard has been C++17. Build SVF with C++14 unless the LLVM version is below 6. + if (LLVM_VERSION_MAJOR VERSION_LESS 6) + set(CMAKE_CXX_STANDARD 98) + message(STATUS "Got LLVM version ${LLVM_VERSION}; using C++ standard: ${CMAKE_CXX_STANDARD}") + elseif(LLVM_VERSION_MAJOR VERSION_LESS 16) + set(CMAKE_CXX_STANDARD 14) + message(STATUS "Got LLVM version ${LLVM_VERSION}; using C++ standard: ${CMAKE_CXX_STANDARD}") + else() + message(FATAL_ERROR "Found unsupported LLVM version; need <= 15, got: ${LLVM_VERSION}") + endif() + + # Always enable extensions and require a compiler that supports at least the set C++ standard + set(CMAKE_CXX_EXTENSIONS ON) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + +endif() # Treat compiler warnings as errors add_compile_options("-Werror" "-Wall") diff --git a/svf/CMakeLists.txt b/svf/CMakeLists.txt index 605db56d8..204904112 100644 --- a/svf/CMakeLists.txt +++ b/svf/CMakeLists.txt @@ -1,6 +1,6 @@ # Due to a mutual dependencies, all the sub projects of the SVG are merged here -# Otherwise it is impossible to load the dependencies in opt. -# NOTE: if the SVF should be linked into opt, we should probably use the +# Otherwise it is impossible to load the dependencies in opt. +# NOTE: if the SVF should be linked into opt, we should probably use the # individual sub projects here, rather than the combined project. file( From 2c574c63f5a0a297f841e190384fafb374e8288a Mon Sep 17 00:00:00 2001 From: shuangxiang kan <18550887212@163.com> Date: Mon, 18 Dec 2023 13:32:32 +1100 Subject: [PATCH 03/15] Fix matching parameters and return values for "OVERWRITE" functions and add some new functions sepcfications in extapi.c --- svf-llvm/lib/LLVMModule.cpp | 36 +++++++++++++++ svf-llvm/lib/extapi.c | 88 ++++++++++++++++++++++++++++++++++--- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index e803b9aed..70980ffbf 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -979,6 +979,42 @@ void LLVMModuleSet::buildFunToFunMap() { if (appfunc->getName().str().compare(owfunc->getName().str()) == 0) { + Type* returnType1 = appfunc->getReturnType(); + Type* returnType2 = owfunc->getReturnType(); + + // Check if the return types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*. + if (!(returnType1 == returnType2 || + (returnType1->isPointerTy() && returnType2->isPointerTy() && + (returnType1->getPointerElementType()->isIntegerTy(8) || returnType2->getPointerElementType()->isIntegerTy(8))))) + { + continue; + } + + if (appfunc->arg_size() != owfunc->arg_size()) + continue; + + bool argMismatch = false; + Function::const_arg_iterator argIter1 = appfunc->arg_begin(); + Function::const_arg_iterator argIter2 = owfunc->arg_begin(); + while (argIter1 != appfunc->arg_end() && argIter2 != owfunc->arg_end()) + { + Type* argType1 = argIter1->getType(); + Type* argType2 = argIter2->getType(); + + // Check if the parameters types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*. + if (!(argType1 == argType2 || + (argType1->isPointerTy() && argType2->isPointerTy() && + (argType1->getPointerElementType()->isIntegerTy(8) || argType2->getPointerElementType()->isIntegerTy(8))))) + { + argMismatch = true; + break; + } + argIter1++; + argIter2++; + } + if (argMismatch) + continue; + Function* fun = const_cast(appfunc); Module* mod = fun->getParent(); FunctionType* funType = fun->getFunctionType(); diff --git a/svf-llvm/lib/extapi.c b/svf-llvm/lib/extapi.c index d0c640ad6..4ffa70032 100644 --- a/svf-llvm/lib/extapi.c +++ b/svf-llvm/lib/extapi.c @@ -459,16 +459,20 @@ void* safexrealloc() return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) + char *strtok(char *str, const char *delim) { - return NULL; + return str; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char *strtok_r(char *str, const char *delim, char **saveptr) { - return NULL; + return str; +} + +char* strsep(char** stringp, const char* delim) +{ + return *stringp; } __attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) @@ -727,11 +731,26 @@ char *fgets(char *str, int n, void *stream) return str; } +char *fgets_unlocked(char *str, int n, void *stream) +{ + return str; +} + +char* gets(char *str) +{ + return str; +} + void *memchr(const void *str, int c, unsigned long n) { return (void *)str; } +void *memrchr(const void *str, int c, unsigned long n) +{ + return (void *)str; +} + void * mremap(void * old_address, unsigned long old_size, unsigned long new_size, int flags) { return old_address; @@ -742,6 +761,26 @@ char *strchr(const char *str, int c) return (char *)str; } +char *__strchrnull(const char *s, int c) +{ + return (char *)s; +} + +char *strcasestr(const char *haystack, const char *needle) +{ + return (char *)haystack; +} + +char* index(const char *s, int c) +{ + return (char *)s; +} + +char* rindex(const char *s, int c) +{ + return (char *)s; +} + char *strerror_r(int errnum, char *buf, unsigned long buflen) { return buf; @@ -888,18 +927,36 @@ double strtod(const char *str, char **endptr) return 0.0; } +double strtod_l(const char *str, char **endptr, void *loc) +{ + *endptr = (char *)str; + return 0.0; +} + float strtof(const char *nptr, char **endptr) { *endptr = (char *)nptr; return 0.0; } +float strtof_l(const char *nptr, char **endptr, void *loc) +{ + *endptr = (char *)nptr; + return 0.0; +} + long int strtol(const char *str, char **endptr, int base) { *endptr = (char *)str; return 0; } +long long strtoll(const char *str, char **endptr, int base) +{ + *endptr = (char *)str; + return 0; +} + long double strtold(const char* str, char** endptr) { *endptr = (char *)str; @@ -912,6 +969,27 @@ unsigned long int strtoul(const char *str, char **endptr, int base) return 0; } +unsigned long long strtoull(const char *str, char **endptr, int base) +{ + *endptr = (char *)str; + return 0; +} + +char *gcvt(double x, int ndigit, char *buf) +{ + return buf; +} + +void *memmem(const void *haystack, unsigned long haystacklen, const void *needle, unsigned long needlelen) +{ + return (void *)haystack; +} + +char* ctime_r(const char *timer, char *buf) +{ + return buf; +} + int readdir_r(void *__restrict__dir, void *__restrict__entry, void **__restrict__result) { __restrict__entry = *__restrict__result; @@ -997,7 +1075,7 @@ char * bind_textdomain_codeset(const char * domainname, const char * codeset) char *ctermid(char *s) { - return STATIC_OBJECT; + return s; } char * dcgettext(const char * domainname, const char * msgid, int category) From c24615f8187230276f43345a005586b5a8b26869 Mon Sep 17 00:00:00 2001 From: shuangxiang kan <18550887212@163.com> Date: Mon, 18 Dec 2023 18:42:32 +1100 Subject: [PATCH 04/15] Remove getPointerElementType() The getPointerElementType will be deprecated in future versions of LLVM. Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if the arguments and return values are of the void * type. --- svf-llvm/lib/LLVMModule.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 70980ffbf..03e60077c 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -982,10 +982,12 @@ void LLVMModuleSet::buildFunToFunMap() Type* returnType1 = appfunc->getReturnType(); Type* returnType2 = owfunc->getReturnType(); - // Check if the return types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*. - if (!(returnType1 == returnType2 || - (returnType1->isPointerTy() && returnType2->isPointerTy() && - (returnType1->getPointerElementType()->isIntegerTy(8) || returnType2->getPointerElementType()->isIntegerTy(8))))) + // Check if the return types are compatible: + // (1) The types are exactly the same, + // (2) Both are pointer types, and at least one of them is a void*. + // Note that getPointerElementType() will be deprecated in the future versions of LLVM. + // Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if it is a void * type. + if (!(returnType1 == returnType2 || (returnType1->isPointerTy() && returnType2->isPointerTy()))) { continue; } @@ -1002,9 +1004,7 @@ void LLVMModuleSet::buildFunToFunMap() Type* argType2 = argIter2->getType(); // Check if the parameters types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*. - if (!(argType1 == argType2 || - (argType1->isPointerTy() && argType2->isPointerTy() && - (argType1->getPointerElementType()->isIntegerTy(8) || argType2->getPointerElementType()->isIntegerTy(8))))) + if (!(argType1 == argType2 || (argType1->isPointerTy() && argType2->isPointerTy()))) { argMismatch = true; break; From 8f01b0e5f6ad3d68fbb0f6c398001a5cb22c78d2 Mon Sep 17 00:00:00 2001 From: GitHub Actions Build Date: Mon, 18 Dec 2023 08:04:52 +0000 Subject: [PATCH 05/15] SVF code formatter --- svf-llvm/lib/LLVMModule.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 03e60077c..55a9a6b63 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -982,10 +982,10 @@ void LLVMModuleSet::buildFunToFunMap() Type* returnType1 = appfunc->getReturnType(); Type* returnType2 = owfunc->getReturnType(); - // Check if the return types are compatible: - // (1) The types are exactly the same, + // Check if the return types are compatible: + // (1) The types are exactly the same, // (2) Both are pointer types, and at least one of them is a void*. - // Note that getPointerElementType() will be deprecated in the future versions of LLVM. + // Note that getPointerElementType() will be deprecated in the future versions of LLVM. // Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if it is a void * type. if (!(returnType1 == returnType2 || (returnType1->isPointerTy() && returnType2->isPointerTy()))) { @@ -994,7 +994,7 @@ void LLVMModuleSet::buildFunToFunMap() if (appfunc->arg_size() != owfunc->arg_size()) continue; - + bool argMismatch = false; Function::const_arg_iterator argIter1 = appfunc->arg_begin(); Function::const_arg_iterator argIter2 = owfunc->arg_begin(); From 9ef3df01bf59572542eaab2e6b9ad2c6386bafb5 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Tue, 19 Dec 2023 16:01:33 +0100 Subject: [PATCH 06/15] Take LLVMContext object from module used to build SVFModule rather than forcing unique_ptr to avoid erronous garbage collection clearing LLVM internal objects when SVF is used from within an LLVM pass --- svf-llvm/include/SVF-LLVM/LLVMModule.h | 12 +++--- svf-llvm/lib/LLVMModule.cpp | 54 ++++++++++++++++++-------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/svf-llvm/include/SVF-LLVM/LLVMModule.h b/svf-llvm/include/SVF-LLVM/LLVMModule.h index b8174c16a..005debf6f 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMModule.h +++ b/svf-llvm/include/SVF-LLVM/LLVMModule.h @@ -67,7 +67,7 @@ class LLVMModuleSet static bool preProcessed; SymbolTableInfo* symInfo; SVFModule* svfModule; ///< Borrowed from singleton SVFModule::svfModule - std::unique_ptr cxts; + std::unique_ptr owned_ctx; std::vector> owned_modules; std::vector> modules; @@ -111,8 +111,10 @@ class LLVMModuleSet llvmModuleSet = nullptr; } - // The parameter of context should be the llvm context of the mod, the llvm context of mod and extapi module should be the same - static SVFModule* buildSVFModule(Module& mod, std::unique_ptr context); + // Build an SVF module from a given LLVM Module instance (for use e.g. in a LLVM pass) + static SVFModule* buildSVFModule(Module& mod); + + // Build an SVF module from the bitcode files provided in `moduleNameVec` static SVFModule* buildSVFModule(const std::vector& moduleNameVec); inline SVFModule* getSVFModule() @@ -357,8 +359,8 @@ class LLVMModuleSet std::vector getLLVMGlobalFunctions(const GlobalVariable* global); void loadModules(const std::vector& moduleNameVec); - // The llvm context of app module and extapi module should be the same - void loadExtAPIModules(std::unique_ptr context = nullptr); + // Loads ExtAPI bitcode file; uses LLVMContext made while loading module bitcode files or from Module + void loadExtAPIModules(); void addSVFMain(); void createSVFDataStructure(); diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 55a9a6b63..c786638e8 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -73,19 +73,18 @@ bool LLVMModuleSet::preProcessed = false; LLVMModuleSet::LLVMModuleSet() : symInfo(SymbolTableInfo::SymbolInfo()), - svfModule(SVFModule::getSVFModule()), cxts(nullptr) + svfModule(SVFModule::getSVFModule()) { } -SVFModule* LLVMModuleSet::buildSVFModule(Module &mod, std::unique_ptr context) +SVFModule* LLVMModuleSet::buildSVFModule(Module &mod) { LLVMModuleSet* mset = getLLVMModuleSet(); double startSVFModuleTime = SVFStat::getClk(true); SVFModule::getSVFModule()->setModuleIdentifier(mod.getModuleIdentifier()); - mset->modules.emplace_back(mod); - mset->loadExtAPIModules(std::move(context)); - + mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()` + mset->loadExtAPIModules(); // Uses context from module through `this->getContext()` mset->build(); double endSVFModuleTime = SVFStat::getClk(true); SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime)/TIMEINTERVAL; @@ -101,8 +100,8 @@ SVFModule* LLVMModuleSet::buildSVFModule(const std::vector &moduleN LLVMModuleSet* mset = getLLVMModuleSet(); - mset->loadModules(moduleNameVec); - mset->loadExtAPIModules(); + mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()` + mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()` if (!moduleNameVec.empty()) { @@ -507,9 +506,11 @@ void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) SVFModule::setPagFromTXT(Options::Graphtxt()); // - // To avoid the following type bugs (t1 != t3) when parsing multiple modules, - // We should use only one LLVMContext object for multiple modules in the same thread. - // No such problem if only one module is processed by SVF. + // LLVMContext objects separate global LLVM settings (from which e.g. types are + // derived); multiple LLVMContext objects can coexist and each context can "own" + // multiple modules (modules can only have one context). Mixing contexts can lead + // to unintended inequalities, such as the following: + // // ------------------------------------------------------------------ // LLVMContext ctxa,ctxb; // IntegerType * t1 = IntegerType::get(ctxa,32); @@ -521,7 +522,16 @@ void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) // assert(t1 != t3); // ------------------------------------------------------------------ // - cxts = std::make_unique(); + // When loading bytecode files, SVF will use the same LLVMContext object for all + // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as + // well, which *must* be loaded using the same LLVMContext object. Hence, when + // loading modules from bitcode files, a new LLVMContext is created (using a + // `std::unique_ptr` type to ensure automatic garbage collection). + // + // This garbage collection should be avoided when building an SVF module from an LLVM + // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()` + + owned_ctx = std::make_unique(); for (const std::string& moduleName : moduleNameVec) { @@ -532,7 +542,7 @@ void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) } SMDiagnostic Err; - std::unique_ptr mod = parseIRFile(moduleName, Err, *cxts); + std::unique_ptr mod = parseIRFile(moduleName, Err, *owned_ctx); if (mod == nullptr) { SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n"; @@ -544,8 +554,21 @@ void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) } } -void LLVMModuleSet::loadExtAPIModules(std::unique_ptr context) +void LLVMModuleSet::loadExtAPIModules() { + // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that + // the same LLVMContext object is used to load this bitcode file as is used by the other modules + // being analysed. + // When the modules are loaded from bitcode files (i.e. passing filenames to files containing + // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading + // the modules in `loadModules()`, which populates this->modules and this->owned_modules. + // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass), + // the context should be retrieved from the module itself (note that the garbage collection from + // `std::unique_ptr LLVMModuleSet::owned_ctx` should be avoided in this case). This + // function populates only this->modules. + // In both cases, fetching the context from the main LLVM module (through `getContext`) works + assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!"); + // Load external API module (extapi.bc) if (!ExtAPI::getExtAPI()->getExtBcPath().empty()) { @@ -556,10 +579,7 @@ void LLVMModuleSet::loadExtAPIModules(std::unique_ptr context) abort(); } SMDiagnostic Err; - assert(!(cxts == nullptr && context == nullptr) && "Before loading extapi module, at least one LLVMContext should be initialized !!!"); - if (context != nullptr) - cxts = std::move(context); - std::unique_ptr mod = parseIRFile(extModuleName, Err, *cxts); + std::unique_ptr mod = parseIRFile(extModuleName, Err, getContext()); if (mod == nullptr) { SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n"; From ca5632c816a2cba84c4eae8ae72511d499e09809 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 09:58:16 +0100 Subject: [PATCH 07/15] Replaced fatal error for LLVM versions greater than 15 with a warning to cater to future LLVM 16 support --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c744375be..1c77713aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,9 @@ else() set(CMAKE_CXX_STANDARD 14) message(STATUS "Got LLVM version ${LLVM_VERSION}; using C++ standard: ${CMAKE_CXX_STANDARD}") else() - message(FATAL_ERROR "Found unsupported LLVM version; need <= 15, got: ${LLVM_VERSION}") + set(CMAKE_CXX_STANDARD 17) + message(WARNING "Found unsupported LLVM version (got version ${LLVM_VERSION}; currently supported " + "versions are up to 15); using C++ standard: ${CMAKE_CXX_STANDARD}") endif() # Always enable extensions and require a compiler that supports at least the set C++ standard From 58a4ffc7000b2b8c87b267fa27e4770d904c4726 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 10:16:24 +0100 Subject: [PATCH 08/15] Switched adding LLVM definitions, link directories, and include directories from only to `SvfLLVM` to global additions so that modules defined after `SvfLLVM` or in its subdirectories automatically inherit/can find LLVM as well --- CMakeLists.txt | 3 --- svf-llvm/CMakeLists.txt | 9 ++++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c77713aa..ddfab673b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,9 +41,6 @@ else() add_compile_options("-fno-rtti") endif() - # Load the LLVM definitions & include directories - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - if(NOT ${LLVM_LINK_LLVM_DYLIB}) message(STATUS "Linking to separate LLVM static libraries") llvm_map_components_to_libnames( diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 3e9d97e82..097ec1fdd 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -3,9 +3,12 @@ file(GLOB SVFLLVM_SOURCES lib/*.cpp) add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) -target_include_directories(SvfLLVM SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) -target_link_directories(SvfLLVM PUBLIC ${LLVM_LIBRARY_DIRS}) -target_compile_definitions(SvfLLVM PUBLIC ${LLVM_DEFINITIONS}) +# Set the LLVM header and library paths; note that this does not link the LLVM library itself but +# makes it (and the LLVM headers) available for all modules defined hereafter/in subdirectories +separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) target_include_directories(SvfLLVM PUBLIC include) target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) From af15d889d4461a91939fb635bfe2c5bf1d4021ec Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 11:01:35 +0100 Subject: [PATCH 09/15] Switched to CMake-recommended way of linking libraries (through `target_link_libraries()`); linked SvfCore and SvfLLVM for tools; LLVM link directory should be added to rpath for tools --- svf-llvm/CMakeLists.txt | 8 +++----- svf-llvm/tools/CFL/CMakeLists.txt | 8 +++++++- svf-llvm/tools/DDA/CMakeLists.txt | 8 +++++++- svf-llvm/tools/Example/CMakeLists.txt | 8 +++++++- svf-llvm/tools/LLVM2SVF/CMakeLists.txt | 8 +++++++- svf-llvm/tools/MTA/CMakeLists.txt | 8 +++++++- svf-llvm/tools/SABER/CMakeLists.txt | 8 +++++++- svf-llvm/tools/WPA/CMakeLists.txt | 8 +++++++- 8 files changed, 52 insertions(+), 12 deletions(-) diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 097ec1fdd..e829dfae5 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -3,12 +3,10 @@ file(GLOB SVFLLVM_SOURCES lib/*.cpp) add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) -# Set the LLVM header and library paths; note that this does not link the LLVM library itself but -# makes it (and the LLVM headers) available for all modules defined hereafter/in subdirectories separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) -include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) -link_directories(${LLVM_LIBRARY_DIRS}) -add_definitions(${LLVM_DEFINITIONS}) +target_include_directories(SvfLLVM SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) +target_link_directories(SvfLLVM PUBLIC ${LLVM_LIBRARY_DIRS}) +target_compile_definitions(SvfLLVM PUBLIC ${LLVM_DEFINITIONS}) target_include_directories(SvfLLVM PUBLIC include) target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) diff --git a/svf-llvm/tools/CFL/CMakeLists.txt b/svf-llvm/tools/CFL/CMakeLists.txt index 96010e2f8..1fe366a04 100644 --- a/svf-llvm/tools/CFL/CMakeLists.txt +++ b/svf-llvm/tools/CFL/CMakeLists.txt @@ -3,7 +3,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(cfl cfl.cpp) - target_link_libraries(cfl SvfLLVM ${llvm_libs}) + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(cfl PUBLIC include) + target_include_directories(cfl SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(cfl PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(cfl PUBLIC ${LLVM_DEFINITIONS}) + + target_link_libraries(cfl SvfCore SvfLLVM) set_target_properties(cfl PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/DDA/CMakeLists.txt b/svf-llvm/tools/DDA/CMakeLists.txt index e5294d5ab..63a233db8 100644 --- a/svf-llvm/tools/DDA/CMakeLists.txt +++ b/svf-llvm/tools/DDA/CMakeLists.txt @@ -3,7 +3,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(dvf dda.cpp) - target_link_libraries(dvf SvfLLVM ${llvm_libs}) + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(dvf PUBLIC include) + target_include_directories(dvf SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(dvf PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(dvf PUBLIC ${LLVM_DEFINITIONS}) + + target_link_libraries(dvf SvfCore SvfLLVM) set_target_properties(dvf PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/Example/CMakeLists.txt b/svf-llvm/tools/Example/CMakeLists.txt index 7ab9f42df..af3446d85 100644 --- a/svf-llvm/tools/Example/CMakeLists.txt +++ b/svf-llvm/tools/Example/CMakeLists.txt @@ -3,7 +3,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(svf-ex svf-ex.cpp) - target_link_libraries(svf-ex SvfLLVM ${llvm_libs}) + target_link_libraries(svf-ex SvfCore SvfLLVM) + + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(svf-ex PUBLIC include) + target_include_directories(svf-ex SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(svf-ex PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(svf-ex PUBLIC ${LLVM_DEFINITIONS}) set_target_properties(svf-ex PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt index 38418aa5f..4ff4e9413 100644 --- a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt +++ b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt @@ -3,7 +3,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(llvm2svf llvm2svf.cpp) - target_link_libraries(llvm2svf SvfLLVM ${llvm_libs}) + target_link_libraries(llvm2svf SvfCore SvfLLVM) + + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(llvm2svf PUBLIC include) + target_include_directories(llvm2svf SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(llvm2svf PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(llvm2svf PUBLIC ${LLVM_DEFINITIONS}) set_target_properties(llvm2svf PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/MTA/CMakeLists.txt b/svf-llvm/tools/MTA/CMakeLists.txt index 568827946..dd9792fbf 100644 --- a/svf-llvm/tools/MTA/CMakeLists.txt +++ b/svf-llvm/tools/MTA/CMakeLists.txt @@ -5,7 +5,13 @@ else() add_executable(mta mta.cpp LockResultValidator.cpp MTAResultValidator.cpp MTAAnnotator.cpp) - target_link_libraries(mta SvfLLVM ${llvm_libs}) + target_link_libraries(mta SvfCore SvfLLVM) + + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(mta PUBLIC include) + target_include_directories(mta SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(mta PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(mta PUBLIC ${LLVM_DEFINITIONS}) set_target_properties(mta PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/SABER/CMakeLists.txt b/svf-llvm/tools/SABER/CMakeLists.txt index ece9c72ec..2b723c2d2 100644 --- a/svf-llvm/tools/SABER/CMakeLists.txt +++ b/svf-llvm/tools/SABER/CMakeLists.txt @@ -3,7 +3,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(saber saber.cpp) - target_link_libraries(saber SvfLLVM ${llvm_libs}) + target_link_libraries(saber SvfCore SvfLLVM) + + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(saber PUBLIC include) + target_include_directories(saber SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(saber PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(saber PUBLIC ${LLVM_DEFINITIONS}) set_target_properties(saber PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/svf-llvm/tools/WPA/CMakeLists.txt b/svf-llvm/tools/WPA/CMakeLists.txt index 16aa12926..5ecc414f3 100644 --- a/svf-llvm/tools/WPA/CMakeLists.txt +++ b/svf-llvm/tools/WPA/CMakeLists.txt @@ -6,7 +6,13 @@ if(DEFINED IN_SOURCE_BUILD) else() add_executable(wpa wpa.cpp) - target_link_libraries(wpa SvfLLVM ${llvm_libs} Threads::Threads) + target_link_libraries(wpa SvfCore SvfLLVM Threads::Threads) + + separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) + target_include_directories(wpa PUBLIC include) + target_include_directories(wpa SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) + target_link_directories(wpa PUBLIC ${LLVM_LIBRARY_DIRS}) + target_compile_definitions(wpa PUBLIC ${LLVM_DEFINITIONS}) set_target_properties(wpa PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) From 3f51410c255874847eb5329f49fec25f11f9ed37 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 13:30:51 +0100 Subject: [PATCH 10/15] Add the tools through `add_llvm_executable`; modify build/setup scripts to also include the installed LLVM/Z3 instances in $LD_LIBRARY_PATH (same for compiled SVF libraries) --- CMakeLists.txt | 86 ++------------------------ build.sh | 5 +- setup.sh | 12 +++- svf-llvm/CMakeLists.txt | 75 +++++++++++++++++++--- svf-llvm/tools/CFL/CMakeLists.txt | 18 +----- svf-llvm/tools/CMakeLists.txt | 16 ----- svf-llvm/tools/DDA/CMakeLists.txt | 18 +----- svf-llvm/tools/Example/CMakeLists.txt | 18 +----- svf-llvm/tools/LLVM2SVF/CMakeLists.txt | 18 +----- svf-llvm/tools/MTA/CMakeLists.txt | 20 +----- svf-llvm/tools/SABER/CMakeLists.txt | 18 +----- svf-llvm/tools/WPA/CMakeLists.txt | 18 +----- 12 files changed, 101 insertions(+), 221 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddfab673b..a6678d49f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,89 +2,15 @@ cmake_minimum_required(VERSION 3.13.4) project("SVF") +message(STATUS "Using CMake with generator: ${CMAKE_GENERATOR}") + configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h) -# Match configuration used to build LLVM (match C++ standard; match -# runtime typing information (RTTI); match exception handling; etc) -if(COMMAND add_llvm_library) - message(STATUS "Detected in-tree build configuration; skipping LLVM fetching") - set(IN_SOURCE_BUILD 1) -else() - message(STATUS "Detected out-of-tree build configuration; fetching LLVM") - - find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR} $ENV{LLVM_DIR}) - message(STATUS "LLVM STATUS: - Version ${LLVM_VERSION} - Definitions ${LLVM_DEFINITIONS} - Includes ${LLVM_INCLUDE_DIRS} - Libraries ${LLVM_LIBRARY_DIRS} - Targets ${LLVM_TARGETS_TO_BUILD} - Build type ${LLVM_BUILD_TYPE} - Exceptions ${LLVM_ENABLE_EH} - RTTI ${LLVM_ENABLE_RTTI} - Dynamic lib ${LLVM_LINK_LLVM_DYLIB}" - ) - - if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT ${LLVM_BUILD_TYPE} STREQUAL "Debug") - message(NOTICE "Building SVF in debug-mode but LLVM was not built in debug-mode; " - "debug information could be incomplete when using SVF from LLVM") - endif() - - if(NOT LLVM_ENABLE_EH) - message(STATUS "Building SVF without exception handling") - add_compile_options("-fno-exceptions") - endif() - - if(NOT LLVM_ENABLE_RTTI) - message(STATUS "Building SVF without RTII") - add_compile_options("-fno-rtti") - endif() - - if(NOT ${LLVM_LINK_LLVM_DYLIB}) - message(STATUS "Linking to separate LLVM static libraries") - llvm_map_components_to_libnames( - llvm_libs - analysis - bitwriter - core - instcombine - instrumentation - ipo - irreader - linker - scalaropts - support - target - transformutils) - else() - message(STATUS "Linking to LLVM dynamic shared library object") - set(llvm_libs LLVM) - endif() - - # Make the "add_llvm_library()" command available - include(AddLLVM) - - # Set the default C++ standard used to build SVF; LLVM versions up to version 6 defaulted to C++98, - # and up to (and including) version 15 the default was C++14. From versions 16 and onwards, the - # default C++ standard has been C++17. Build SVF with C++14 unless the LLVM version is below 6. - if (LLVM_VERSION_MAJOR VERSION_LESS 6) - set(CMAKE_CXX_STANDARD 98) - message(STATUS "Got LLVM version ${LLVM_VERSION}; using C++ standard: ${CMAKE_CXX_STANDARD}") - elseif(LLVM_VERSION_MAJOR VERSION_LESS 16) - set(CMAKE_CXX_STANDARD 14) - message(STATUS "Got LLVM version ${LLVM_VERSION}; using C++ standard: ${CMAKE_CXX_STANDARD}") - else() - set(CMAKE_CXX_STANDARD 17) - message(WARNING "Found unsupported LLVM version (got version ${LLVM_VERSION}; currently supported " - "versions are up to 15); using C++ standard: ${CMAKE_CXX_STANDARD}") - endif() - - # Always enable extensions and require a compiler that supports at least the set C++ standard - set(CMAKE_CXX_EXTENSIONS ON) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - -endif() +# Build SVF with C++ standard C++17 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_EXTENSIONS ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # Treat compiler warnings as errors add_compile_options("-Werror" "-Wall") diff --git a/build.sh b/build.sh index 933a22438..b9c6c0579 100755 --- a/build.sh +++ b/build.sh @@ -205,7 +205,10 @@ if [[ ! -d "$Z3_DIR" ]]; then export Z3_DIR="$SVFHOME/$Z3Home" fi -export PATH=$LLVM_DIR/bin:$PATH +# Add LLVM & Z3 to $PATH and $LD_LIBRARY_PATH (prepend so that selected instances will be used first) +export PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH +export LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:$LD_LIBRARY_PATH + echo "LLVM_DIR=$LLVM_DIR" echo "Z3_DIR=$Z3_DIR" diff --git a/setup.sh b/setup.sh index 16e0c487b..6c80c608b 100755 --- a/setup.sh +++ b/setup.sh @@ -65,6 +65,12 @@ fi Build="${PTAOBJTY}-build" -export PATH=$LLVM_DIR/bin:$PATH -PTABIN=$SVF_DIR/$Build/bin -export PATH=$PTABIN:$PATH +# Add LLVM & Z3 to $PATH and $LD_LIBRARY_PATH (prepend so that selected instances will be used first) +export PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH +export LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:$LD_LIBRARY_PATH + +# Add compiled SVF binaries dir to $PATH +export PATH=$SVF_DIR/$Build/bin:$PATH + +# Add compiled library directories to $LD_LIBRARY_PATH +export LD_LIBRARY_PATH=$SVF_DIR/$Build/svf:$SVF_DIR/$Build/svf-llvm:$LD_LIBRARY_PATH diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index e829dfae5..3438d9078 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -1,17 +1,78 @@ # SVF-LLVM contains LLVM Libs file(GLOB SVFLLVM_SOURCES lib/*.cpp) -add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) +find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR} $ENV{LLVM_DIR}) +message(STATUS "LLVM STATUS: + Version ${LLVM_VERSION} + Definitions ${LLVM_DEFINITIONS} + Includes ${LLVM_INCLUDE_DIRS} + Libraries ${LLVM_LIBRARY_DIRS} + Targets ${LLVM_TARGETS_TO_BUILD} + Build type ${LLVM_BUILD_TYPE} + Exceptions ${LLVM_ENABLE_EH} + RTTI ${LLVM_ENABLE_RTTI} + Dynamic lib ${LLVM_LINK_LLVM_DYLIB}" +) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT ${LLVM_BUILD_TYPE} STREQUAL "Debug") + message(NOTICE "Building SVF in debug-mode but LLVM was not built in debug-mode; " + "debug information could be incomplete when using SVF from LLVM") +endif() + +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) + +if(NOT LLVM_ENABLE_EH) + message(STATUS "Building SVF-llvm without exception handling") + add_compile_options("-fno-exceptions") +endif() -separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) -target_include_directories(SvfLLVM SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) -target_link_directories(SvfLLVM PUBLIC ${LLVM_LIBRARY_DIRS}) -target_compile_definitions(SvfLLVM PUBLIC ${LLVM_DEFINITIONS}) +if(NOT LLVM_ENABLE_RTTI) + message(STATUS "Building SVF-llvm without RTII") + add_compile_options("-fno-rtti") +endif() + +if(LLVM_LINK_LLVM_DYLIB) + message(STATUS "Linking to LLVM dynamic shared library object") + set(llvm_libs LLVM) + + # Set which components to include in the dynamic library to include the new SvfLLVM + if (LLVM_DYLIB_COMPONENTS) + message(STATUS "Appending SvfLLVM to LLVM dynamic library components") + list(APPEND LLVM_DYLIB_COMPONENTS SvfLLVM) + else() + message(STATUS "Adding all;SvfLLVM to LLVM dynamic library components (was unset)") + set(LLVM_DYLIB_COMPONENTS all;SvfLLVM) + endif() +else() + message(STATUS "Linking to separate LLVM static libraries") + llvm_map_components_to_libnames( + llvm_libs + analysis + bitwriter + core + instcombine + instrumentation + ipo + irreader + linker + scalaropts + support + target + transformutils) +endif() + +# Make the "add_llvm_library()" command available and configure LLVM/CMake +list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") +include(AddLLVM) +add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) target_include_directories(SvfLLVM PUBLIC include) -target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) +target_link_libraries(SvfLLVM PUBLIC ${Z3_LIBRARIES} SvfCore) -if(DEFINED IN_SOURCE_BUILD) +# Add intrinsics_gen target if we're building as part of LLVM source build +if(TARGET intrinsics_gen) add_dependencies(SvfLLVM intrinsics_gen) endif() diff --git a/svf-llvm/tools/CFL/CMakeLists.txt b/svf-llvm/tools/CFL/CMakeLists.txt index 1fe366a04..8eddef867 100644 --- a/svf-llvm/tools/CFL/CMakeLists.txt +++ b/svf-llvm/tools/CFL/CMakeLists.txt @@ -1,16 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(cfl cfl.cpp) -else() - add_executable(cfl cfl.cpp) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(cfl PUBLIC include) - target_include_directories(cfl SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(cfl PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(cfl PUBLIC ${LLVM_DEFINITIONS}) - - target_link_libraries(cfl SvfCore SvfLLVM) - - set_target_properties(cfl PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(cfl cfl.cpp) +target_link_libraries(cfl PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/CMakeLists.txt b/svf-llvm/tools/CMakeLists.txt index 5474ed0a9..1b7d9b578 100644 --- a/svf-llvm/tools/CMakeLists.txt +++ b/svf-llvm/tools/CMakeLists.txt @@ -1,19 +1,3 @@ -if(DEFINED IN_SOURCE_BUILD) - set(LLVM_LINK_COMPONENTS - BitWriter - Core - IPO - IrReader - InstCombine - Instrumentation - Target - Linker - Analysis - ScalarOpts - Support - SvfLLVM) -endif() - add_subdirectory(SABER) add_subdirectory(WPA) add_subdirectory(Example) diff --git a/svf-llvm/tools/DDA/CMakeLists.txt b/svf-llvm/tools/DDA/CMakeLists.txt index 63a233db8..eb75800c7 100644 --- a/svf-llvm/tools/DDA/CMakeLists.txt +++ b/svf-llvm/tools/DDA/CMakeLists.txt @@ -1,16 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(dvf dda.cpp) -else() - add_executable(dvf dda.cpp) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(dvf PUBLIC include) - target_include_directories(dvf SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(dvf PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(dvf PUBLIC ${LLVM_DEFINITIONS}) - - target_link_libraries(dvf SvfCore SvfLLVM) - - set_target_properties(dvf PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(dvf dda.cpp) +target_link_libraries(dvf PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/Example/CMakeLists.txt b/svf-llvm/tools/Example/CMakeLists.txt index af3446d85..d841bced3 100644 --- a/svf-llvm/tools/Example/CMakeLists.txt +++ b/svf-llvm/tools/Example/CMakeLists.txt @@ -1,16 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(svf-ex svf-ex.cpp) -else() - add_executable(svf-ex svf-ex.cpp) - - target_link_libraries(svf-ex SvfCore SvfLLVM) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(svf-ex PUBLIC include) - target_include_directories(svf-ex SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(svf-ex PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(svf-ex PUBLIC ${LLVM_DEFINITIONS}) - - set_target_properties(svf-ex PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(svf-ex svf-ex.cpp) +target_link_libraries(svf-ex PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt index 4ff4e9413..162a1149a 100644 --- a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt +++ b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt @@ -1,16 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(llvm2svf llvm2svf.cpp) -else() - add_executable(llvm2svf llvm2svf.cpp) - - target_link_libraries(llvm2svf SvfCore SvfLLVM) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(llvm2svf PUBLIC include) - target_include_directories(llvm2svf SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(llvm2svf PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(llvm2svf PUBLIC ${LLVM_DEFINITIONS}) - - set_target_properties(llvm2svf PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() \ No newline at end of file +add_llvm_executable(llvm2svf llvm2svf.cpp) +target_link_libraries(llvm2svf PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/MTA/CMakeLists.txt b/svf-llvm/tools/MTA/CMakeLists.txt index dd9792fbf..abe518329 100644 --- a/svf-llvm/tools/MTA/CMakeLists.txt +++ b/svf-llvm/tools/MTA/CMakeLists.txt @@ -1,18 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(mta mta.cpp LockResultValidator.cpp MTAResultValidator.cpp - MTAAnnotator.cpp) -else() - add_executable(mta mta.cpp LockResultValidator.cpp MTAResultValidator.cpp - MTAAnnotator.cpp) - - target_link_libraries(mta SvfCore SvfLLVM) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(mta PUBLIC include) - target_include_directories(mta SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(mta PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(mta PUBLIC ${LLVM_DEFINITIONS}) - - set_target_properties(mta PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(mta mta.cpp LockResultValidator.cpp MTAResultValidator.cpp MTAAnnotator.cpp) +target_link_libraries(mta PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/SABER/CMakeLists.txt b/svf-llvm/tools/SABER/CMakeLists.txt index 2b723c2d2..c865f00f2 100644 --- a/svf-llvm/tools/SABER/CMakeLists.txt +++ b/svf-llvm/tools/SABER/CMakeLists.txt @@ -1,16 +1,2 @@ -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(saber saber.cpp) -else() - add_executable(saber saber.cpp) - - target_link_libraries(saber SvfCore SvfLLVM) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(saber PUBLIC include) - target_include_directories(saber SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(saber PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(saber PUBLIC ${LLVM_DEFINITIONS}) - - set_target_properties(saber PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(saber saber.cpp) +target_link_libraries(saber PUBLIC SvfLLVM) diff --git a/svf-llvm/tools/WPA/CMakeLists.txt b/svf-llvm/tools/WPA/CMakeLists.txt index 5ecc414f3..944dbba4a 100644 --- a/svf-llvm/tools/WPA/CMakeLists.txt +++ b/svf-llvm/tools/WPA/CMakeLists.txt @@ -1,19 +1,5 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -if(DEFINED IN_SOURCE_BUILD) - add_llvm_tool(wpa wpa.cpp) -else() - add_executable(wpa wpa.cpp) - - target_link_libraries(wpa SvfCore SvfLLVM Threads::Threads) - - separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) - target_include_directories(wpa PUBLIC include) - target_include_directories(wpa SYSTEM PUBLIC ${LLVM_INCLUDE_DIRS}) - target_link_directories(wpa PUBLIC ${LLVM_LIBRARY_DIRS}) - target_compile_definitions(wpa PUBLIC ${LLVM_DEFINITIONS}) - - set_target_properties(wpa PROPERTIES RUNTIME_OUTPUT_DIRECTORY - ${CMAKE_BINARY_DIR}/bin) -endif() +add_llvm_executable(wpa wpa.cpp) +target_link_libraries(wpa PUBLIC SvfLLVM Threads::Threads) From d0a1b83e20a53fd843933662417b689e7e75358d Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 13:46:09 +0100 Subject: [PATCH 11/15] Apparently this is not the case for older CMake versions; explicitly link LLVM libraries to avoid undefined symbols --- CMakeLists.txt | 5 ----- svf-llvm/CMakeLists.txt | 7 ++++++- svf-llvm/tools/CFL/CMakeLists.txt | 2 +- svf-llvm/tools/CMakeLists.txt | 5 +++++ svf-llvm/tools/DDA/CMakeLists.txt | 2 +- svf-llvm/tools/Example/CMakeLists.txt | 2 +- svf-llvm/tools/LLVM2SVF/CMakeLists.txt | 2 +- svf-llvm/tools/MTA/CMakeLists.txt | 2 +- svf-llvm/tools/SABER/CMakeLists.txt | 2 +- svf-llvm/tools/WPA/CMakeLists.txt | 2 +- svf/CMakeLists.txt | 6 ++++++ 11 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6678d49f..9c88d4811 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,6 @@ message(STATUS "Using CMake with generator: ${CMAKE_GENERATOR}") configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h) -# Build SVF with C++ standard C++17 -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_EXTENSIONS ON) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - # Treat compiler warnings as errors add_compile_options("-Werror" "-Wall") diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 3438d9078..4ab41c21e 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -69,7 +69,12 @@ include(AddLLVM) add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) target_include_directories(SvfLLVM PUBLIC include) -target_link_libraries(SvfLLVM PUBLIC ${Z3_LIBRARIES} SvfCore) +target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) + +# Build SVF with C++ standard C++17 +set_property(TARGET SvfLLVM PROPERTY CXX_STANDARD 17) +set_property(TARGET SvfLLVM PROPERTY CXX_EXTENSIONS ON) +set_property(TARGET SvfLLVM PROPERTY CXX_STANDARD_REQUIRED ON) # Add intrinsics_gen target if we're building as part of LLVM source build if(TARGET intrinsics_gen) diff --git a/svf-llvm/tools/CFL/CMakeLists.txt b/svf-llvm/tools/CFL/CMakeLists.txt index 8eddef867..4bde7bce6 100644 --- a/svf-llvm/tools/CFL/CMakeLists.txt +++ b/svf-llvm/tools/CFL/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(cfl cfl.cpp) -target_link_libraries(cfl PUBLIC SvfLLVM) +target_link_libraries(cfl PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/CMakeLists.txt b/svf-llvm/tools/CMakeLists.txt index 1b7d9b578..db98c40d8 100644 --- a/svf-llvm/tools/CMakeLists.txt +++ b/svf-llvm/tools/CMakeLists.txt @@ -5,3 +5,8 @@ add_subdirectory(DDA) add_subdirectory(MTA) add_subdirectory(CFL) add_subdirectory(LLVM2SVF) + +# Build SvfLLVM tools with C++ standard C++17 +set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_STANDARD 17) +set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_EXTENSIONS ON) +set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/svf-llvm/tools/DDA/CMakeLists.txt b/svf-llvm/tools/DDA/CMakeLists.txt index eb75800c7..c54858043 100644 --- a/svf-llvm/tools/DDA/CMakeLists.txt +++ b/svf-llvm/tools/DDA/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(dvf dda.cpp) -target_link_libraries(dvf PUBLIC SvfLLVM) +target_link_libraries(dvf PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/Example/CMakeLists.txt b/svf-llvm/tools/Example/CMakeLists.txt index d841bced3..996491f40 100644 --- a/svf-llvm/tools/Example/CMakeLists.txt +++ b/svf-llvm/tools/Example/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(svf-ex svf-ex.cpp) -target_link_libraries(svf-ex PUBLIC SvfLLVM) +target_link_libraries(svf-ex PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt index 162a1149a..e838dc05f 100644 --- a/svf-llvm/tools/LLVM2SVF/CMakeLists.txt +++ b/svf-llvm/tools/LLVM2SVF/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(llvm2svf llvm2svf.cpp) -target_link_libraries(llvm2svf PUBLIC SvfLLVM) +target_link_libraries(llvm2svf PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/MTA/CMakeLists.txt b/svf-llvm/tools/MTA/CMakeLists.txt index abe518329..0508d95cf 100644 --- a/svf-llvm/tools/MTA/CMakeLists.txt +++ b/svf-llvm/tools/MTA/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(mta mta.cpp LockResultValidator.cpp MTAResultValidator.cpp MTAAnnotator.cpp) -target_link_libraries(mta PUBLIC SvfLLVM) +target_link_libraries(mta PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/SABER/CMakeLists.txt b/svf-llvm/tools/SABER/CMakeLists.txt index c865f00f2..2ebc80e33 100644 --- a/svf-llvm/tools/SABER/CMakeLists.txt +++ b/svf-llvm/tools/SABER/CMakeLists.txt @@ -1,2 +1,2 @@ add_llvm_executable(saber saber.cpp) -target_link_libraries(saber PUBLIC SvfLLVM) +target_link_libraries(saber PUBLIC ${llvm_libs} SvfLLVM) diff --git a/svf-llvm/tools/WPA/CMakeLists.txt b/svf-llvm/tools/WPA/CMakeLists.txt index 944dbba4a..4a99b53a3 100644 --- a/svf-llvm/tools/WPA/CMakeLists.txt +++ b/svf-llvm/tools/WPA/CMakeLists.txt @@ -2,4 +2,4 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_llvm_executable(wpa wpa.cpp) -target_link_libraries(wpa PUBLIC SvfLLVM Threads::Threads) +target_link_libraries(wpa PUBLIC ${llvm_libs} SvfLLVM Threads::Threads) diff --git a/svf/CMakeLists.txt b/svf/CMakeLists.txt index 204904112..0c0c86eb5 100644 --- a/svf/CMakeLists.txt +++ b/svf/CMakeLists.txt @@ -20,4 +20,10 @@ file( lib/WPA/*.cpp) add_library(SvfCore ${SVF_CORE_SOURCES}) + +# Build SVF with C++ standard C++17 +set_property(TARGET SvfCore PROPERTY CXX_STANDARD 17) +set_property(TARGET SvfCore PROPERTY CXX_EXTENSIONS ON) +set_property(TARGET SvfCore PROPERTY CXX_STANDARD_REQUIRED ON) + target_link_libraries(SvfCore PUBLIC ${Z3_LIBRARIES}) From 1fd01becf94de270c67f6f037cf41c727ca00a87 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Wed, 20 Dec 2023 13:59:35 +0100 Subject: [PATCH 12/15] Tests require specific output directory for tools --- svf-llvm/tools/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/svf-llvm/tools/CMakeLists.txt b/svf-llvm/tools/CMakeLists.txt index db98c40d8..89dda6a78 100644 --- a/svf-llvm/tools/CMakeLists.txt +++ b/svf-llvm/tools/CMakeLists.txt @@ -7,6 +7,8 @@ add_subdirectory(CFL) add_subdirectory(LLVM2SVF) # Build SvfLLVM tools with C++ standard C++17 -set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_STANDARD 17) -set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_EXTENSIONS ON) -set_property(TARGET cfl dvf svf-ex llvm2svf mta saber wpa PROPERTY CXX_STANDARD_REQUIRED ON) +set_target_properties(cfl dvf svf-ex llvm2svf mta saber wpa + PROPERTIES CXX_STANDARD 17 + CXX_EXTENSIONS ON + CXX_STANDARD_REQUIRED ON + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) From 97d624db01e653b7f82b4392f52dcc2bb8448277 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Fri, 22 Dec 2023 18:36:31 +0100 Subject: [PATCH 13/15] Updated CMake build system to install correctly; moved more LLVM-only variables to the CMakeLists.txt script in svf-llm/; modified generated configuration variables in config.h (and updated ExtAPI.h/ExtAPI.cpp accordingly); removed unnecessary exports from build script; added additional configuration information to config.h --- .config.in | 19 ++++++++++-- CMakeLists.txt | 38 ++++++++++-------------- build.sh | 4 +-- svf-llvm/CMakeLists.txt | 55 +++++++++++++++++++++++++++++++---- svf-llvm/tools/CMakeLists.txt | 8 +++++ svf/CMakeLists.txt | 13 +++++++++ svf/include/Util/ExtAPI.h | 2 -- svf/lib/Util/ExtAPI.cpp | 45 ++++++++++++++++++---------- 8 files changed, 133 insertions(+), 51 deletions(-) diff --git a/.config.in b/.config.in index a10763202..e381f1435 100644 --- a/.config.in +++ b/.config.in @@ -1,8 +1,21 @@ #ifndef CONFIG_H_IN #define CONFIG_H_IN -#define PROJECT_PATH "@CMAKE_CURRENT_SOURCE_DIR@" -#define BUILD_TYPE "@CMAKE_BUILD_TYPE@-build" -#define EXTAPI_DIR PROJECT_PATH "/@CMAKE_BUILD_TYPE@-build/svf-llvm" +// Directory structure of SVF build +#define SVF_ROOT "@CMAKE_CURRENT_SOURCE_DIR@" +#define SVF_BUILD_DIR "@CMAKE_CURRENT_BINARY_DIR@" +#define SVF_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@" +#define SVF_BIN_DIR SVF_INSTALL_DIR "/bin" +#define SVF_LIB_DIR SVF_INSTALL_DIR "/lib" +#define SVF_INCLUDE_DIR SVF_INSTALL_DIR "/include" +#define SVF_EXTAPI_DIR SVF_INCLUDE_DIR "/SVF-LLVM" +#define SVF_EXTAPI_BC SVF_EXTAPI_DIR "/extapi.bc" + +// Build properties of current SVF build +#define SVF_BUILD_TYPE "@CMAKE_BUILD_TYPE@" +#cmakedefine SVF_ASSERT_MODE +#cmakedefine SVF_COVERAGE +#cmakedefine SVF_SANITIZE "@SVF_SANITIZE@" + #endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c88d4811..4042bc13b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,7 @@ project("SVF") message(STATUS "Using CMake with generator: ${CMAKE_GENERATOR}") -configure_file(${PROJECT_SOURCE_DIR}/.config.in - ${PROJECT_BINARY_DIR}/include/Util/config.h) +configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h) # Treat compiler warnings as errors add_compile_options("-Werror" "-Wall") @@ -72,27 +71,20 @@ endif() add_subdirectory(svf) add_subdirectory(svf-llvm) +# Whether RTTI/Exceptions are enabled currently depends on whether the LLVM instance used to build +# SVF had them enabled; since the LLVM instance is found in the "svf-llvm" subdirectory, it sets the +# below variables in its parent directory (i.e. for this CMakeLists.txt) so check them here +if(SVF_NO_RTTI) + add_compile_options("-fno-rtti") +endif() + +if(SVF_NO_EH) + add_compile_options("-fno-exceptions") +endif() + +# Install generated configuration header (see `configure_file()`) to top-level include dir of SVF include(GNUInstallDirs) install( - TARGETS SvfCore SvfLLVM - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + FILES ${PROJECT_BINARY_DIR}/include/Util/config.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf/Util ) -install( - DIRECTORY ${PROJECT_SOURCE_DIR}/svf/include/ - ${PROJECT_SOURCE_DIR}/svf-llvm/include/ - COMPONENT devel - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/include/svf - FILES_MATCHING - PATTERN "**/*.h") - -# Compile extapi.c to extapi.bc -find_path(LLVM_CLANG_DIR - NAMES clang llvm - HINTS ${LLVM_DIR} ENV LLVM_DIR - PATH_SUFFIXES bin) -add_custom_target(extapi_ir ALL - COMMAND ${LLVM_CLANG_DIR}/clang -w -S -c -Xclang -disable-O0-optnone -fno-discard-value-names -emit-llvm ${PROJECT_SOURCE_DIR}/svf-llvm/lib/extapi.c -o ${PROJECT_BINARY_DIR}/svf-llvm/extapi.bc - DEPENDS ${PROJECT_SOURCE_DIR}/svf-llvm/lib/extapi.c -) \ No newline at end of file diff --git a/build.sh b/build.sh index b9c6c0579..87e9666be 100755 --- a/build.sh +++ b/build.sh @@ -206,8 +206,8 @@ if [[ ! -d "$Z3_DIR" ]]; then fi # Add LLVM & Z3 to $PATH and $LD_LIBRARY_PATH (prepend so that selected instances will be used first) -export PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH -export LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:$LD_LIBRARY_PATH +PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH +LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:$LD_LIBRARY_PATH echo "LLVM_DIR=$LLVM_DIR" echo "Z3_DIR=$Z3_DIR" diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 4ab41c21e..55676d58e 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -24,13 +24,13 @@ link_directories(${LLVM_LIBRARY_DIRS}) add_definitions(${LLVM_DEFINITIONS}) if(NOT LLVM_ENABLE_EH) - message(STATUS "Building SVF-llvm without exception handling") - add_compile_options("-fno-exceptions") + message(STATUS "Building SVF without exception handling") + set(SVF_NO_RTTI ON PARENT_SCOPE) # Set for parent scope because this needs to be set in top-level CMakeLists.txt endif() if(NOT LLVM_ENABLE_RTTI) - message(STATUS "Building SVF-llvm without RTII") - add_compile_options("-fno-rtti") + message(STATUS "Building SVF without RTTI") + set(SVF_NO_EH ON PARENT_SCOPE) # Set for parent scope because this needs to be set in top-level CMakeLists.txt endif() if(LLVM_LINK_LLVM_DYLIB) @@ -60,7 +60,8 @@ else() scalaropts support target - transformutils) + transformutils +) endif() # Make the "add_llvm_library()" command available and configure LLVM/CMake @@ -82,3 +83,47 @@ if(TARGET intrinsics_gen) endif() add_subdirectory(tools) + +# Compile extapi.c to extapi.bc +set(EXTAPI_TO_BC_FLAGS + "-w" + "-S" + "-c" + "-Xclang" + "-disable-O0-optnone" + "-fno-discard-value-names" + "-emit-llvm" + "${CMAKE_CURRENT_LIST_DIR}/lib/extapi.c" + "-o" + "${CMAKE_BINARY_DIR}/svf-llvm/extapi.bc" +) +find_program(LLVM_CLANG + NAMES clang + HINTS ${LLVM_BINARY_DIR} + PATH_SUFFIXES bin + REQUIRED +) +add_custom_target(extapi_ir ALL + COMMAND ${LLVM_CLANG} ${EXTAPI_TO_BC_FLAGS} + DEPENDS ${CMAKE_CURRENT_LIST_DIR}/lib/extapi.c +) + +# Install the headers (as a subdirectory of the main SVF include) and the compiled library binaries +include(GNUInstallDirs) +install( + TARGETS SvfLLVM + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install( + FILES ${CMAKE_BINARY_DIR}/svf-llvm/extapi.bc + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf/SVF-LLVM +) +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf + FILES_MATCHING + PATTERN "**/*.h" +) + diff --git a/svf-llvm/tools/CMakeLists.txt b/svf-llvm/tools/CMakeLists.txt index 89dda6a78..eb728ac2e 100644 --- a/svf-llvm/tools/CMakeLists.txt +++ b/svf-llvm/tools/CMakeLists.txt @@ -12,3 +12,11 @@ set_target_properties(cfl dvf svf-ex llvm2svf mta saber wpa CXX_EXTENSIONS ON CXX_STANDARD_REQUIRED ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +include(GNUInstallDirs) +install( + TARGETS cfl dvf svf-ex llvm2svf mta saber wpa + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/svf/CMakeLists.txt b/svf/CMakeLists.txt index 0c0c86eb5..3d7abcf4d 100644 --- a/svf/CMakeLists.txt +++ b/svf/CMakeLists.txt @@ -27,3 +27,16 @@ set_property(TARGET SvfCore PROPERTY CXX_EXTENSIONS ON) set_property(TARGET SvfCore PROPERTY CXX_STANDARD_REQUIRED ON) target_link_libraries(SvfCore PUBLIC ${Z3_LIBRARIES}) + +include(GNUInstallDirs) +install( + TARGETS SvfCore + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf + FILES_MATCHING + PATTERN "**/*.h") diff --git a/svf/include/Util/ExtAPI.h b/svf/include/Util/ExtAPI.h index af5d145cf..f2715a9c0 100644 --- a/svf/include/Util/ExtAPI.h +++ b/svf/include/Util/ExtAPI.h @@ -38,8 +38,6 @@ /// For a more detailed explanation of how External APIs are handled in SVF, please refer to the SVF Wiki: https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c -#define DEFAULT_EXTAPI_BC_PATH "/svf-llvm/extapi.bc" // Default path to extapi.bc through the SVF build method(e.g. source ./build.sh) - namespace SVF { diff --git a/svf/lib/Util/ExtAPI.cpp b/svf/lib/Util/ExtAPI.cpp index 05adb5377..b05d361a3 100644 --- a/svf/lib/Util/ExtAPI.cpp +++ b/svf/lib/Util/ExtAPI.cpp @@ -30,6 +30,8 @@ #include "Util/ExtAPI.h" #include "Util/SVFUtil.h" #include "Util/Options.h" +#include "Util/config.h" +#include #include using namespace SVF; @@ -115,42 +117,53 @@ static std::string getFilePath(const std::string& path) if (!bcFilePath.empty() && bcFilePath.back() != '/') bcFilePath.push_back('/'); - bcFilePath.append(BUILD_TYPE).append(DEFAULT_EXTAPI_BC_PATH); + bcFilePath.append(SVF_BUILD_TYPE "-build").append("/svf-llvm/extapi.bc"); return bcFilePath; } // Get extapi.bc path std::string ExtAPI::getExtBcPath() { - // Five default ways to get extapi.bc path - // 1. Set extapi.bc path through setExtBcPath() method - // 2. Set extapi.bc path through the "-extapi = PATH_TO_EXTAPIFILE" option - // 3. Default path: "SVF_IR_PATH/CMAKE_BUILD_TYPE-build/svf-llvm/extapi.bc" - // 4. From $SVF_DIR - // 5. From "npm root"(If SVF is installed via npm) + // Default ways of retrieving extapi.bc (in order of precedence): + // 1. Set `path/to/extapi.bc` through `setExtBcPath()` + // 2. Set `path/to/extapi.bc` through the command line argument `-extapi=path/to/extapi.bc` + // 3. Get location generated by CMakeLists.txt from `config.h` header file (if SVF was installed) + // 4. Get location in build tree based from `config.h` header file (if SVF was only built) + // 5. Get location based on environment variable $ENV{SVF_DIR} + // 6. Search for `extapi.bc` from root directory for npm installation (iff SVF installed through npm) + + // 1. Set `path/to/extapi.bc` through `setExtBcPath()` if (!extBcPath.empty()) return extBcPath; - // 2. Set extapi.bc path through the "-extapi = PATH_TO_EXTAPIFILE" option + // 2. Set `path/to/extapi.bc` through the command line argument `-extapi=path/to/extapi.bc` if (setExtBcPath(Options::ExtAPIPath())) return extBcPath; - // 3. Default path: "SVF_IR_PATH/CMAKE_BUILD_TYPE-build/svf-llvm/extapi.bc" - if (setExtBcPath(std::string(EXTAPI_DIR) + "/extapi.bc")) + // 3. Get location generated by CMakeLists.txt from `config.h` header file (if SVF was installed) + if (setExtBcPath(SVF_EXTAPI_BC)) // Full path is available (for custom file names) + return extBcPath; + if (setExtBcPath(SVF_EXTAPI_DIR "/extapi.bc")) // Based on directory & default filename + return extBcPath; + + // 4. Get location in build tree based from `config.h` header file (if SVF was only built) + if (setExtBcPath(SVF_BUILD_DIR "/svf-llvm/extapi.bc")) return extBcPath; - // 4. From $SVF_DIR + // 5. Get location based on environment variable $ENV{SVF_DIR} if (setExtBcPath(getFilePath("SVF_DIR"))) return extBcPath; - // 5. From "npm root"(If SVF is installed via npm) + // 6. Search for `extapi.bc` from root directory for npm installation (iff SVF installed through npm) if (setExtBcPath(getFilePath("npm root"))) return extBcPath; - SVFUtil::errs() << "No extapi.bc found at " << extBcPath << " in getExtBcPath() !!!" << "\n" - << "You can specify extapi.bc path in two ways:" << "\n" - << "1. Set it via the command line using -extapi=/path_to_extapi;" << "\n" - << "2. Use the API setExtBcPath(). Please note that setExtBcPath() should be used before buildSVFModule().\n"; + SVFUtil::errs() << "ERROR: Failed to find \"extapi.bc\" LLVM bitcode file in " << extBcPath << std::endl + << "To override the default locations for \"extapi.bc\", you can:" << std::endl + << "\t1. Use the command line argument \"-extapi=path/to/extapi.bc\"" << std::endl + << "\t2. Use the \"setExtBcPath()\" function *BEFORE* calling \"buildSVFModule()\"" << std::endl + << "\t3. Override the paths in \"svf/Util/config.h\" (WARNING: will be overwritten when " + << "rebuilding SVF (generated by CMakeLists.txt))" << std::endl; abort(); } From d85eacb63282547be06771e8012f397367ef16a3 Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Thu, 28 Dec 2023 12:06:01 +0100 Subject: [PATCH 14/15] Removed repetitive setting of C++ standard to top-level CMakeLists.txt script; removed target-specific setting of C++ standard --- CMakeLists.txt | 7 ++++++- svf-llvm/CMakeLists.txt | 5 ----- svf-llvm/tools/CMakeLists.txt | 10 +++++----- svf/CMakeLists.txt | 5 ----- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4042bc13b..08e9cfbdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,12 @@ message(STATUS "Using CMake with generator: ${CMAKE_GENERATOR}") configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h) # Treat compiler warnings as errors -add_compile_options("-Werror" "-Wall") +add_compile_options("-Werror" "-Wall" "-Wno-deprecated-declarations") + +# Build SVF with C++ standard C++17 +set(CXX_STANDARD 17) +set(CXX_EXTENSIONS ON) +set(CXX_STANDARD_REQUIRED ON) # Keep assertions enabled if requested option(SVF_ENABLE_ASSERTIONS "Always enable assertions") diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 55676d58e..45d2c1ffd 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -72,11 +72,6 @@ add_llvm_library(SvfLLVM ${SVFLLVM_SOURCES}) target_include_directories(SvfLLVM PUBLIC include) target_link_libraries(SvfLLVM PUBLIC ${llvm_libs} ${Z3_LIBRARIES} SvfCore) -# Build SVF with C++ standard C++17 -set_property(TARGET SvfLLVM PROPERTY CXX_STANDARD 17) -set_property(TARGET SvfLLVM PROPERTY CXX_EXTENSIONS ON) -set_property(TARGET SvfLLVM PROPERTY CXX_STANDARD_REQUIRED ON) - # Add intrinsics_gen target if we're building as part of LLVM source build if(TARGET intrinsics_gen) add_dependencies(SvfLLVM intrinsics_gen) diff --git a/svf-llvm/tools/CMakeLists.txt b/svf-llvm/tools/CMakeLists.txt index eb728ac2e..8ea5ff6fa 100644 --- a/svf-llvm/tools/CMakeLists.txt +++ b/svf-llvm/tools/CMakeLists.txt @@ -7,11 +7,11 @@ add_subdirectory(CFL) add_subdirectory(LLVM2SVF) # Build SvfLLVM tools with C++ standard C++17 -set_target_properties(cfl dvf svf-ex llvm2svf mta saber wpa - PROPERTIES CXX_STANDARD 17 - CXX_EXTENSIONS ON - CXX_STANDARD_REQUIRED ON - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set_target_properties( + cfl dvf svf-ex llvm2svf mta saber wpa + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) include(GNUInstallDirs) install( diff --git a/svf/CMakeLists.txt b/svf/CMakeLists.txt index 3d7abcf4d..d9087c506 100644 --- a/svf/CMakeLists.txt +++ b/svf/CMakeLists.txt @@ -21,11 +21,6 @@ file( add_library(SvfCore ${SVF_CORE_SOURCES}) -# Build SVF with C++ standard C++17 -set_property(TARGET SvfCore PROPERTY CXX_STANDARD 17) -set_property(TARGET SvfCore PROPERTY CXX_EXTENSIONS ON) -set_property(TARGET SvfCore PROPERTY CXX_STANDARD_REQUIRED ON) - target_link_libraries(SvfCore PUBLIC ${Z3_LIBRARIES}) include(GNUInstallDirs) From 1f54a147f4de95115dc6322e594e9bf4f0ba91ef Mon Sep 17 00:00:00 2001 From: Johannes Blaser Date: Thu, 28 Dec 2023 12:10:27 +0100 Subject: [PATCH 15/15] FIX: Replaced setting `CXX_STANDARD` (and related) with `CMAKE_CXX_STANDARD` --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08e9cfbdc..aecd62d20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,9 @@ configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Ut add_compile_options("-Werror" "-Wall" "-Wno-deprecated-declarations") # Build SVF with C++ standard C++17 -set(CXX_STANDARD 17) -set(CXX_EXTENSIONS ON) -set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_EXTENSIONS ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # Keep assertions enabled if requested option(SVF_ENABLE_ASSERTIONS "Always enable assertions")