diff --git a/.config.in b/.config.in index f9ecec3fe..a10763202 100644 --- a/.config.in +++ b/.config.in @@ -2,6 +2,7 @@ #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" #endif diff --git a/svf/include/Util/ExtAPI.h b/svf/include/Util/ExtAPI.h index 2692dab1f..a5f0ec90a 100644 --- a/svf/include/Util/ExtAPI.h +++ b/svf/include/Util/ExtAPI.h @@ -38,7 +38,7 @@ /// 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 EXTAPI_BC_PATH "Release-build/svf-llvm/extapi.bc" +#define DEFUALT_EXTAPI_BC_PATH "/svf-llvm/extapi.bc" // Default path to extapi.bc through the SVF build method(e.g. source ./build.sh) namespace SVF { @@ -49,6 +49,9 @@ class ExtAPI static ExtAPI *extOp; + // extapi.bc file path + static std::string extBcPath; + ExtAPI() = default; public: @@ -57,6 +60,9 @@ class ExtAPI static void destory(); + // Set extapi.bc file path + static void setExtBcPath(const std::string& path); + // Get extapi.bc file path std::string getExtBcPath(); diff --git a/svf/include/Util/Options.h b/svf/include/Util/Options.h index d911bb0b4..d52a1793d 100644 --- a/svf/include/Util/Options.h +++ b/svf/include/Util/Options.h @@ -248,6 +248,7 @@ class Options static const Option VtableInSVFIR; // WPAPass.cpp + static const Option ExtAPIPath; static const Option AnderSVFG; static const Option SABERFULLSVFG; static const Option PrintAliases; diff --git a/svf/lib/Util/ExtAPI.cpp b/svf/lib/Util/ExtAPI.cpp index f919fd94d..22dbe0689 100644 --- a/svf/lib/Util/ExtAPI.cpp +++ b/svf/lib/Util/ExtAPI.cpp @@ -29,11 +29,13 @@ #include "Util/ExtAPI.h" #include "Util/SVFUtil.h" +#include "Util/Options.h" #include using namespace SVF; ExtAPI* ExtAPI::extOp = nullptr; +std::string ExtAPI::extBcPath = ""; ExtAPI* ExtAPI::getExtAPI() { @@ -53,6 +55,12 @@ void ExtAPI::destory() } } +// Set extapi.bc file path +void ExtAPI::setExtBcPath(const std::string& path) +{ + extBcPath = path; +} + // Get environment variables $SVF_DIR and "npm root" through popen() method static std::string GetStdoutFromCommand(const std::string& command) { @@ -80,55 +88,77 @@ static std::string GetStdoutFromCommand(const std::string& command) // Get extapi.bc file path in npm static std::string getFilePath(const std::string& path) { - std::string bcFilePath = GetStdoutFromCommand(path); - if (path.compare("npm root") == 0) + std::string bcFilePath = ""; + if (path.compare("SVF_DIR") == 0) { - int os_flag = 1; + bcFilePath = getenv("SVF_DIR"); + } + else if (path.compare("npm root") == 0) + { + bcFilePath = GetStdoutFromCommand(path); // SVF installed via npm needs to determine the type of operating // system, otherwise the extapi.bc path may not be found. #ifdef linux // Linux os - os_flag = 0; bcFilePath.append("/svf-lib/SVF-linux"); -#endif +#else // Mac os - if (os_flag == 1) - { - bcFilePath.append("/svf-lib/SVF-osx"); - } + bcFilePath.append("/svf-lib/SVF-osx"); +#endif } - if (bcFilePath.back() != '/') + if (!bcFilePath.empty() && bcFilePath.back() != '/') bcFilePath.push_back('/'); - bcFilePath.append(EXTAPI_BC_PATH); + bcFilePath.append(BUILD_TYPE).append(DEFUALT_EXTAPI_BC_PATH); return bcFilePath; } // Get extapi.bc path std::string ExtAPI::getExtBcPath() { - struct stat statbuf; - std::string bcFilePath = std::string(EXTAPI_DIR) + "/extapi.bc"; - if (!stat(bcFilePath.c_str(), &statbuf)) - return bcFilePath; - - bcFilePath = getFilePath("echo $SVF_DIR"); - if (!stat(bcFilePath.c_str(), &statbuf)) - return bcFilePath; + // 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) - bcFilePath = getFilePath("npm root"); - if (!stat(bcFilePath.c_str(), &statbuf)) - return bcFilePath; - - SVFUtil::errs() << "No extapi.bc found at " << bcFilePath << " for getExtAPI(); The default path for extapi.bc is: SVF_IR_PATH/CMAKE_BUILD_TYPE-build/svf-llvm/extapi.bc !\n"; + struct stat statbuf; + // 1. Set extapi.bc path through setExtBcPath() method + if (!extBcPath.empty() && !stat(extBcPath.c_str(), &statbuf)) + return extBcPath; + + // 2. Set extapi.bc path through the "-extapi = PATH_TO_EXTAPIFILE" option + extBcPath = Options::ExtAPIPath(); + if (!extBcPath.empty() && !stat(extBcPath.c_str(), &statbuf)) + return extBcPath; + + // 3. Default path: "SVF_IR_PATH/CMAKE_BUILD_TYPE-build/svf-llvm/extapi.bc" + extBcPath = std::string(EXTAPI_DIR) + "/extapi.bc"; + if (!stat(extBcPath.c_str(), &statbuf)) + return extBcPath; + + // 4. From $SVF_DIR + extBcPath = getFilePath("SVF_DIR"); + if (!stat(extBcPath.c_str(), &statbuf)) + return extBcPath; + + // 5. From "npm root"(If SVF is installed via npm) + extBcPath = getFilePath("npm root"); + if (!stat(extBcPath.c_str(), &statbuf)) + 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"; abort(); } std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation) { assert(fun && "Null SVFFunction* pointer"); - const std::vector& annotations = fun->getAnnotations(); - for (const std::string& annotation : annotations) + for (const std::string& annotation : fun->getAnnotations()) if (annotation.find(funcAnnotation) != std::string::npos) return annotation; return ""; @@ -137,8 +167,7 @@ std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::stri bool ExtAPI::hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation) { assert(fun && "Null SVFFunction* pointer"); - const std::vector& annotations = fun->getAnnotations(); - for (const std::string& annotation : annotations) + for (const std::string& annotation : fun->getAnnotations()) if (annotation.find(funcAnnotation) != std::string::npos) return true; return false; @@ -168,8 +197,7 @@ bool ExtAPI::is_arg_alloc(const SVFFunction* F) // Get the position of argument which holds the new object s32_t ExtAPI::get_alloc_arg_pos(const SVFFunction* F) { - std::string s = "ALLOC_ARG"; - std::string allocArg = getExtFuncAnnotation(F, s); + std::string allocArg = getExtFuncAnnotation(F, "ALLOC_ARG"); assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!"); std::string number; diff --git a/svf/lib/Util/Options.cpp b/svf/lib/Util/Options.cpp index 685ea8744..a8deae843 100644 --- a/svf/lib/Util/Options.cpp +++ b/svf/lib/Util/Options.cpp @@ -770,6 +770,13 @@ const Option Options::VtableInSVFIR( false ); +//WPAPass.cpp +const Option Options::ExtAPIPath( + "extapi", + "External API extapi.bc", + "" +); + const Option Options::AnderSVFG( "svfg", "Generate SVFG after Andersen's Analysis",