Skip to content

Commit

Permalink
Merge branch 'master' into 0821
Browse files Browse the repository at this point in the history
  • Loading branch information
bjjwwang authored Aug 21, 2023
2 parents 2361399 + 0c18f85 commit 3c1a9e3
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .config.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
#define CONFIG_H_IN

#define PROJECT_PATH "@CMAKE_CURRENT_SOURCE_DIR@"
#define EXTAPI_PATH PROJECT_PATH "/@CMAKE_BUILD_TYPE@-build/include/Util"
#define EXTAPI_PATH PROJECT_PATH "/@CMAKE_BUILD_TYPE@-build/svf-llvm"

#endif
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ install(
# Compile extapi.c to extapi.bc
find_path(LLVM_CLANG_DIR NAMES clang 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/lib/Util/extapi.c -o ${PROJECT_BINARY_DIR}/include/Util/extapi.bc
DEPENDS ${PROJECT_SOURCE_DIR}/svf/lib/Util/extapi.c
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
)
50 changes: 26 additions & 24 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ void LLVMModuleSet::loadExtAPIModules()
Err.print("SVFModuleLoader", llvm::errs());
abort();
}
// The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
// The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
// Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
modules.insert(modules.begin(), *mod);
owned_modules.insert(owned_modules.begin(),std::move(mod));
Expand Down Expand Up @@ -729,7 +729,7 @@ void LLVMModuleSet::addSVFMain()
}

/*
For a more detailed explanation of the Function declaration and definition mapping relationships and how External APIs are handled,
For a more detailed explanation of the Function declaration and definition mapping relationships and how External APIs are handled,
please refer to the SVF Wiki: https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c
Table 1
Expand All @@ -750,44 +750,44 @@ void LLVMModuleSet::addSVFMain()
The app function definition will be changed to an app function declaration.
Then, put the app function declaration and its corresponding Ext function definition into FunDeclToDefMap/FunDefToDeclsMap.
------------------------------------------------------
AppDef -> ExtDef (overwrite):
AppDef -> ExtDef (overwrite):
For example,
App function:
App function:
char* foo(char *a, char *b){return a;}
Ext function:
Ext function:
__attribute__((annotate("OVERWRITE")))
char* foo(char *a, char *b){return b;}
When SVF handles the foo function in the App module,
the definition of
When SVF handles the foo function in the App module,
the definition of
foo: char* foo(char *a, char *b){return a;}
will be changed to a declaration
foo: char* foo(char *a, char *b);
Then,
foo: char* foo(char *a, char *b);
Then,
foo: char* foo(char *a, char *b);
and
__attribute__((annotate("OVERWRITE")))
char* foo(char *a, char *b){return b;}
will be put into FunDeclToDefMap
------------------------------------------------------
ExtDef -> AppDef (overwrite):
ExtDef -> AppDef (overwrite):
__attribute__((annotate("OVERWRITE")))
char* foo(char *a, char *b){return b;}
char* foo(char *a, char *b){return b;}
and
foo: char* foo(char *a, char *b);
are put into FunDefToDeclsMap;
------------------------------------------------------
In principle, all functions in extapi.c have bodies (definitions), but some functions (those starting with "sse_")
In principle, all functions in extapi.c have bodies (definitions), but some functions (those starting with "sse_")
have only function declarations without definitions. ExtFuncsVec is used to record function declarations starting with "sse_" that are used.
ExtDecl -> ExtDecl:
For example,
App function:
For example,
App function:
foo(){call memcpy();}
Ext function:
Ext function:
declare sse_check_overflow();
memcpy(){sse_check_overflow();}
sse_check_overflow() used in the Ext function but not in the App function.
sse_check_overflow should be kept in ExtFuncsVec.
*/
Expand All @@ -808,11 +808,13 @@ void LLVMModuleSet::buildFunToFunMap()
{
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) {
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()) {
if (it != annotations.end())
{
overwriteExtFuncs.insert(&fun);
}
if (fun.getName().str() == "main") {
Expand Down Expand Up @@ -924,10 +926,10 @@ void LLVMModuleSet::buildFunToFunMap()
// ExtDecl -> ExtDecl in Table 1
ExtFuncsVec = LLVMUtil::getCalledFunctions(extfun);
}
}
}
}

/// Overwrite
/// Overwrite
/// App Func def -> SVF extern Func def
for (const Function* appfunc : funDefs)
{
Expand All @@ -950,7 +952,7 @@ void LLVMModuleSet::buildFunToFunMap()
std::vector<const Function*>& decls = FunDefToDeclsMap[owfunc];
decls.push_back(declaration);
// Keep all called functions in owfunc
// ExtDecl -> ExtDecl in Table 1
// ExtDecl -> ExtDecl in Table 1
ExtFuncsVec = LLVMUtil::getCalledFunctions(owfunc);
}
}
Expand Down
22 changes: 11 additions & 11 deletions svf-llvm/lib/LLVMUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,17 +474,17 @@ std::vector<std::string> LLVMUtil::getFunAnnotations(const Function* fun)
continue;

ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
if (data->isString())
if (data->isString())
{
std::string annotation = data->getAsString().str();
if (!annotation.empty())
if (!annotation.empty())
annotations.push_back(annotation);
}
}
return annotations;
}

void LLVMUtil::removeFunAnnotations(std::vector<Function*>& removedFuncList)
void LLVMUtil::removeFunAnnotations(std::vector<Function*>& removedFuncList)
{
if (removedFuncList.empty())
return; // No functions to remove annotations in extapi.bc module
Expand All @@ -499,14 +499,14 @@ void LLVMUtil::removeFunAnnotations(std::vector<Function*>& removedFuncList)
return;

std::vector<Constant*> newAnnotations;
for (unsigned i = 0; i < ca->getNumOperands(); ++i)
for (unsigned i = 0; i < ca->getNumOperands(); ++i)
{
ConstantStruct* structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
if (structAn == nullptr)
continue;

ConstantExpr* expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0));
if (expr == nullptr || expr->getOpcode() != Instruction::BitCast)
if (expr == nullptr || expr->getOpcode() != Instruction::BitCast)
{
// Keep the annotation if it's not created using BitCast
newAnnotations.push_back(structAn);
Expand All @@ -529,13 +529,13 @@ void LLVMUtil::removeFunAnnotations(std::vector<Function*>& removedFuncList)

// Check if a global variable with the name llvm.global.annotations already exists
GlobalVariable* existingGlobal = module->getGlobalVariable("llvm.global.annotations");
if (existingGlobal)
if (existingGlobal)
// Rename the existing llvm.global.annotations to llvm.global.annotations_old
existingGlobal->setName("llvm.global.annotations_old");

// Create a new global variable with the updated annotations
GlobalVariable* newGlobal = new GlobalVariable(*module, newCA->getType(), glob->isConstant(),
glob->getLinkage(), newCA, "llvm.global.annotations", glob, glob->getThreadLocalMode());
glob->getLinkage(), newCA, "llvm.global.annotations", glob, glob->getThreadLocalMode());

// Copy other properties from the old global variable to the new one
newGlobal->setSection(glob->getSection());
Expand All @@ -546,15 +546,15 @@ void LLVMUtil::removeFunAnnotations(std::vector<Function*>& removedFuncList)
}

/// Get all called funcions in a parent function
std::vector<const Function *> LLVMUtil::getCalledFunctions(const Function *F)
std::vector<const Function *> LLVMUtil::getCalledFunctions(const Function *F)
{
std::vector<const Function *> calledFunctions;
for (const Instruction &I : instructions(F))
for (const Instruction &I : instructions(F))
{
if (const CallBase *callInst = SVFUtil::dyn_cast<CallBase>(&I))
if (const CallBase *callInst = SVFUtil::dyn_cast<CallBase>(&I))
{
Function *calledFunction = callInst->getCalledFunction();
if (calledFunction)
if (calledFunction)
{
calledFunctions.push_back(calledFunction);
std::vector<const Function *> nestedCalledFunctions = getCalledFunctions(calledFunction);
Expand Down
4 changes: 2 additions & 2 deletions svf-llvm/lib/SVFIRExtAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
{
NodeID dummy = pag->addDummyValNode();
AccessPath ap1(0);
addNormalGepEdge(getValueNode(cs->getArgOperand(0)), dummy, ap1);
addNormalGepEdge(getValueNode(cs->getArgOperand(0)), dummy, ap1);
AccessPath ap2(0);
addNormalGepEdge(dummy, getValueNode(cs), ap2);
addNormalGepEdge(dummy, getValueNode(cs), ap2);
}
else if(svfCallee->getName().compare("dlsym") == 0)
{
Expand Down
File renamed without changes.
17 changes: 9 additions & 8 deletions svf/lib/Util/ExtAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::stri
{
assert(fun && "Null SVFFunction* pointer");
const std::vector<std::string>& annotations = fun->getAnnotations();
for (const std::string& annotation : annotations)
if (annotation.find(funcAnnotation) != std::string::npos)
for (const std::string& annotation : annotations)
if (annotation.find(funcAnnotation) != std::string::npos)
return annotation;
return "";
}

bool ExtAPI::hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation)
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)
if (annotation.find(funcAnnotation) != std::string::npos)
for (const std::string& annotation : annotations)
if (annotation.find(funcAnnotation) != std::string::npos)
return true;
return false;
}
}

// Does (F) have a static var X (unavailable to us) that its return points to?
bool ExtAPI::has_static(const SVFFunction* F)
Expand Down Expand Up @@ -106,8 +106,9 @@ s32_t ExtAPI::get_alloc_arg_pos(const SVFFunction* F)
assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");

std::string number;
for (char c : allocArg) {
if (isdigit(c))
for (char c : allocArg)
{
if (isdigit(c))
number.push_back(c);
}
assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_ARG + number)?");
Expand Down

0 comments on commit 3c1a9e3

Please sign in to comment.