Skip to content

Commit

Permalink
Merge branch 'SVF-tools:master' into update-from-master-0615-WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonZhongZexin authored Sep 3, 2023
2 parents 358f474 + 14a54d3 commit 55a80a7
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 20 deletions.
1 change: 1 addition & 0 deletions .github/workflows/svf-lib_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ jobs:
cp -rf $GITHUB_WORKSPACE/svf/include SVF-${osVersion}/svf
cp -rf $GITHUB_WORKSPACE/svf-llvm/include SVF-${osVersion}/svf-llvm
cp -f $GITHUB_WORKSPACE/Release-build/svf-llvm/libSvfLLVM.a SVF-${osVersion}/Release-build/svf-llvm/libSvfLLVM.a
cp -f $GITHUB_WORKSPACE/Release-build/svf-llvm/extapi.bc SVF-${osVersion}/Release-build/svf-llvm/extapi.bc
cp -f $GITHUB_WORKSPACE/Release-build/svf/libSvfCore.a SVF-${osVersion}/Release-build/svf/libSvfCore.a
cp -rf $GITHUB_WORKSPACE/Release-build/include SVF-${osVersion}/Release-build
git add .
Expand Down
17 changes: 16 additions & 1 deletion svf-llvm/include/SVF-LLVM/LLVMModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,25 @@ class LLVMModuleSet
SVFOtherValue* getSVFOtherValue(const Value* ov);

/// Remove unused function in extapi.bc module
bool isUsedExtFunction(Function* func)
bool isCalledExtFunction(Function* func)
{
/// check if a llvm Function is called.
auto isCalledFunction = [](llvm::Function* F)
{
for (auto& use : F->uses())
{
llvm::User* user = use.getUser();

if (llvm::isa<llvm::CallBase>(user))
{
return true;
}
}
return false;
};
/// if this function func defined in extapi.bc but never used in application code (without any corresponding declared functions).
if (func->getParent()->getName().str() == Options::ExtAPIInput()
&& !isCalledFunction(func)
&& func->getName().str() != "svf__main"
&& FunDefToDeclsMap.find(func) == FunDefToDeclsMap.end()
&& std::find(ExtFuncsVec.begin(), ExtFuncsVec.end(), func) == ExtFuncsVec.end())
Expand Down
49 changes: 36 additions & 13 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,26 +153,36 @@ void LLVMModuleSet::createSVFDataStructure()
{
getSVFType(IntegerType::getInt8Ty(getContext()));
// Functions need to be retrieved in the order of insertion
std::vector<const Function*> candidateFuncs;
// candidateDefs is the vector for all used defined functions
// candidateDecls is the vector for all used declared functions
std::vector<const Function*> candidateDefs, candidateDecls;
for (Module& mod : modules)
{
std::vector<Function*> removedFuncList;
/// Function
for (Function& func : mod.functions())
{
if (isUsedExtFunction(&func))
if (isCalledExtFunction(&func))
{
removedFuncList.push_back(&func);
}
else if (func.isDeclaration())
{
candidateDecls.push_back(&func);
}
else
{
candidateFuncs.push_back(&func);
candidateDefs.push_back(&func);
}
}
/// Remove unused functions and annotations in extapi.bc
LLVMUtil::removeUnusedFuncsAndAnnotations(removedFuncList);
}
for (const Function* func: candidateFuncs)
for (const Function* func: candidateDefs)
{
createSVFFunction(func);
}
for (const Function* func: candidateDecls)
{
createSVFFunction(func);
}
Expand Down Expand Up @@ -790,24 +800,37 @@ void LLVMModuleSet::buildFunToFunMap()
OrderedSet<string> declNames, defNames, intersectNames;
typedef Map<string, const Function*> NameToFunDefMapTy;
typedef Map<string, Set<const Function*>> NameToFunDeclsMapTy;

for (Module& mod : modules)
{
// extapi.bc functions
if (mod.getName().str() == Options::ExtAPIInput())
{
for (const Function& fun : mod.functions())
{
extFuncs.insert(&fun);
// Find overwrite functions in extapi.bc
std::vector<std::string> annotations = LLVMUtil::getFunAnnotations(&fun);
auto it = std::find_if(annotations.begin(), annotations.end(), [&](const std::string& annotation)
// there is main declaration in ext bc, it should be mapped to
// main definition in app bc.
if (fun.getName().str() == "main")
{
return annotation.find("OVERWRITE") != std::string::npos;
});
if (it != annotations.end())
funDecls.insert(&fun);
declNames.insert(fun.getName().str());
}
else
{
overwriteExtFuncs.insert(&fun);
extFuncs.insert(&fun);
// Find overwrite functions in extapi.bc
std::vector<std::string> annotations =
LLVMUtil::getFunAnnotations(&fun);
auto it =
std::find_if(annotations.begin(), annotations.end(),
[&](const std::string& annotation)
{
return annotation.find("OVERWRITE") !=
std::string::npos;
});
if (it != annotations.end())
{
overwriteExtFuncs.insert(&fun);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions svf/include/Graphs/VFGNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ class VFGNode : public GenericVFGNodeTy
{

public:
/// 24 kinds of ICFG node
/// 25 kinds of ICFG node
/// Gep represents offset edge for field sensitivity
enum VFGNodeK
{
Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, Branch, TPhi, TIntraPhi, TInterPhi,
MPhi, MIntraPhi, MInterPhi, FRet, ARet, AParm, FParm,
FunRet, APIN, APOUT, FPIN, FPOUT, NPtr, DummyVProp
APIN, APOUT, FPIN, FPOUT, NPtr, DummyVProp
};

typedef VFGEdge::VFGEdgeSetTy::iterator iterator;
Expand Down
5 changes: 5 additions & 0 deletions svf/include/Util/ExtAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

/// 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"

namespace SVF
{

Expand All @@ -55,6 +57,9 @@ class ExtAPI

static void destory();

// Get extapi.bc file path
std::string getExtBcPath();

// Get the annotation of (F)
std::string getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation);

Expand Down
2 changes: 1 addition & 1 deletion svf/include/WPA/AndersenPWC.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AndersenSCD : public Andersen
{
if (scdAndersen == nullptr)
{
new AndersenSCD(_pag);
scdAndersen = new AndersenSCD(_pag);
scdAndersen->analyze();
return scdAndersen;
}
Expand Down
11 changes: 9 additions & 2 deletions svf/lib/MemoryModel/AccessPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,15 @@ APOffset AccessPath::computeConstantOffset() const
else
{
APOffset offset = op->getSExtValue();
u32_t flattenOffset = SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type, offset);
totalConstOffset += flattenOffset;
if (offset >= 0)
{
u32_t flattenOffset =
SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type,
offset);
totalConstOffset += flattenOffset;
}
else
totalConstOffset += offset;
}
}
return totalConstOffset;
Expand Down
73 changes: 73 additions & 0 deletions svf/lib/Util/ExtAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
*/

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

using namespace SVF;

Expand All @@ -51,6 +53,77 @@ void ExtAPI::destory()
}
}

// Get environment variables $SVF_DIR and "npm root" through popen() method
static std::string GetStdoutFromCommand(const std::string& command)
{
char buffer[128];
std::string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe)
{
return "popen failed!";
}
// read till end of process:
while (!feof(pipe))
{
// use buffer to read and add to result
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
// remove "\n"
result.erase(remove(result.begin(), result.end(), '\n'), result.end());
return result;
}

// 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)
{
int os_flag = 1;
// 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
// Mac os
if (os_flag == 1)
{
bcFilePath.append("/svf-lib/SVF-osx");
}
}

if (bcFilePath.back() != '/')
bcFilePath.push_back('/');
bcFilePath.append(EXTAPI_BC_PATH);
return bcFilePath;
}

// Get extapi.bc path
std::string ExtAPI::getExtBcPath()
{
struct stat statbuf;
std::string bcFilePath = std::string(EXTAPI_PATH) + "/extapi.bc";
if (!stat(bcFilePath.c_str(), &statbuf))
return bcFilePath;

bcFilePath = getFilePath("echo $SVF_DIR");
if (!stat(bcFilePath.c_str(), &statbuf))
return bcFilePath;

bcFilePath = getFilePath("npm root");
if (!stat(bcFilePath.c_str(), &statbuf))
return bcFilePath;

SVFUtil::errs() << "No extpai.bc found at " << bcFilePath << " for getExtAPI(); set $SVF_DIR first!\n";
abort();
}

std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation)
{
assert(fun && "Null SVFFunction* pointer");
Expand Down
3 changes: 2 additions & 1 deletion svf/lib/Util/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Util/Options.h"
#include "Util/CommandLine.h"
#include "Util/ExtAPI.h"

namespace SVF
{
Expand Down Expand Up @@ -772,7 +773,7 @@ const Option<bool> Options::VtableInSVFIR(

//WPAPass.cpp
const Option<std::string> Options::ExtAPIInput(
"extapi", "External API extapi.bc", std::string(EXTAPI_PATH) + "/extapi.bc"
"extapi", "External API extapi.bc", ExtAPI::getExtAPI()->getExtBcPath()
);

const Option<bool> Options::AnderSVFG(
Expand Down

0 comments on commit 55a80a7

Please sign in to comment.