Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the extapi.bc path not found issue #1212

Merged
merged 2 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .config.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 7 additions & 1 deletion svf/include/Util/ExtAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "DEFUALT"


namespace SVF
{
Expand All @@ -49,6 +49,9 @@ class ExtAPI

static ExtAPI *extOp;

// extapi.bc file path
static std::string extBcPath;

ExtAPI() = default;

public:
Expand All @@ -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();

Expand Down
1 change: 1 addition & 0 deletions svf/include/Util/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class Options
static const Option<bool> VtableInSVFIR;

// WPAPass.cpp
static const Option<std::string> ExtAPIPath;
static const Option<bool> AnderSVFG;
static const Option<bool> SABERFULLSVFG;
static const Option<bool> PrintAliases;
Expand Down
88 changes: 58 additions & 30 deletions svf/lib/Util/ExtAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@

#include "Util/ExtAPI.h"
#include "Util/SVFUtil.h"
#include "Util/Options.h"
#include <sys/stat.h>

using namespace SVF;

ExtAPI* ExtAPI::extOp = nullptr;
std::string ExtAPI::extBcPath = "";

ExtAPI* ExtAPI::getExtAPI()
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;

Copy link
Contributor

@251 251 Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simplify that function and make it much faster:

  1. add a short circuit in the beginning:
if (!extBcPath.empty())
    return extBcPath;
  1. just assemble the paths via getenv, getFilePath, ... as below but than forward them to setExtBcPath and do the stat call there once (and not for every call to that function)

This should also remove the code duplication.

// 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<std::string>& 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 "";
Expand All @@ -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<std::string>& 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;
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions svf/lib/Util/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,13 @@ const Option<bool> Options::VtableInSVFIR(
false
);

//WPAPass.cpp
const Option<std::string> Options::ExtAPIPath(
"extapi",
"External API extapi.bc",
""
);

const Option<bool> Options::AnderSVFG(
"svfg",
"Generate SVFG after Andersen's Analysis",
Expand Down