svf-tools 1.0.987 → 1.0.989
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/AE/Svfexe/AEDetector.h +15 -2
- package/svf/include/AE/Svfexe/AbsExtAPI.h +147 -0
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +25 -92
- package/svf/include/SVFIR/SVFValue.h +0 -11
- package/svf/include/Util/ExtAPI.h +10 -0
- package/svf/include/Util/SVFUtil.h +1 -7
- package/svf/lib/AE/Svfexe/AEDetector.cpp +108 -28
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +765 -0
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +24 -797
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
- package/svf/lib/Util/ExtAPI.cpp +33 -10
- package/svf/lib/Util/SVFUtil.cpp +0 -15
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -58
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +10 -19
- package/svf-llvm/lib/CHGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +216 -230
- package/svf-llvm/lib/LLVMUtil.cpp +32 -228
- package/svf-llvm/lib/ObjTypeInference.cpp +2 -2
- package/svf-llvm/lib/SVFIRBuilder.cpp +0 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +5 -6
- package/svf-llvm/lib/extapi.c +0 -1
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
#include "MSSA/SVFGBuilder.h"
|
|
40
40
|
#include "llvm/Support/FileSystem.h"
|
|
41
41
|
#include "SVF-LLVM/ObjTypeInference.h"
|
|
42
|
+
#include "llvm/Transforms/Utils/Cloning.h"
|
|
42
43
|
|
|
43
44
|
using namespace std;
|
|
44
45
|
using namespace SVF;
|
|
@@ -159,7 +160,6 @@ void LLVMModuleSet::build()
|
|
|
159
160
|
|
|
160
161
|
buildFunToFunMap();
|
|
161
162
|
buildGlobalDefToRepMap();
|
|
162
|
-
removeUnusedExtAPIs();
|
|
163
163
|
|
|
164
164
|
if (Options::SVFMain())
|
|
165
165
|
addSVFMain();
|
|
@@ -202,6 +202,13 @@ void LLVMModuleSet::createSVFDataStructure()
|
|
|
202
202
|
createSVFFunction(func);
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
// Store annotations of functions in extapi.bc
|
|
206
|
+
for (const auto& pair : ExtFun2Annotations)
|
|
207
|
+
{
|
|
208
|
+
const SVFFunction* svffun = getSVFFunction(pair.first);
|
|
209
|
+
ExtAPI::getExtAPI()->setExtFuncAnnotations(svffun, pair.second);
|
|
210
|
+
}
|
|
211
|
+
|
|
205
212
|
/// then traverse candidate sets
|
|
206
213
|
for (const Module& mod : modules)
|
|
207
214
|
{
|
|
@@ -243,8 +250,6 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
|
|
|
243
250
|
func->isDeclaration(), LLVMUtil::isIntrinsicFun(func),
|
|
244
251
|
func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo);
|
|
245
252
|
svfModule->addFunctionSet(svfFunc);
|
|
246
|
-
if (ExtFun2Annotations.find(func) != ExtFun2Annotations.end())
|
|
247
|
-
svfFunc->setAnnotations(ExtFun2Annotations[func]);
|
|
248
253
|
addFunctionMap(func, svfFunc);
|
|
249
254
|
|
|
250
255
|
for (const Argument& arg : func->args())
|
|
@@ -353,8 +358,7 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func)
|
|
|
353
358
|
auto called_llvmval = call->getCalledOperand()->stripPointerCasts();
|
|
354
359
|
if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
|
|
355
360
|
{
|
|
356
|
-
|
|
357
|
-
SVFFunction* callee = getSVFFunction(llvmfunc_def);
|
|
361
|
+
SVFFunction* callee = getSVFFunction(called_llvmfunc);
|
|
358
362
|
svfcall->setCalledOperand(callee);
|
|
359
363
|
}
|
|
360
364
|
else
|
|
@@ -839,294 +843,295 @@ void LLVMModuleSet::collectExtFunAnnotations(const Module* mod)
|
|
|
839
843
|
{
|
|
840
844
|
std::string annotation = data->getAsString().str();
|
|
841
845
|
if (!annotation.empty())
|
|
842
|
-
ExtFun2Annotations[fun].push_back(annotation);
|
|
846
|
+
ExtFun2Annotations[fun->getName().str()].push_back(annotation);
|
|
843
847
|
}
|
|
844
848
|
}
|
|
845
849
|
}
|
|
846
850
|
|
|
847
851
|
/*
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
When a user wants to use functions in extapi.c to overwrite the functions defined in the app code, two relationships, "AppDef -> ExtDef" and "ExtDef -> AppDef," are used.
|
|
865
|
-
Use Ext function definition to override the App function definition (Ext function with "__attribute__((annotate("OVERWRITE")))" in extapi.c).
|
|
866
|
-
The app function definition will be changed to an app function declaration.
|
|
867
|
-
Then, put the app function declaration and its corresponding Ext function definition into FunDeclToDefMap/FunDefToDeclsMap.
|
|
868
|
-
------------------------------------------------------
|
|
869
|
-
AppDef -> ExtDef (overwrite):
|
|
870
|
-
For example,
|
|
871
|
-
App function:
|
|
872
|
-
char* foo(char *a, char *b){return a;}
|
|
873
|
-
Ext function:
|
|
874
|
-
__attribute__((annotate("OVERWRITE")))
|
|
875
|
-
char* foo(char *a, char *b){return b;}
|
|
876
|
-
|
|
877
|
-
When SVF handles the foo function in the App module,
|
|
878
|
-
the definition of
|
|
879
|
-
foo: char* foo(char *a, char *b){return a;}
|
|
880
|
-
will be changed to a declaration
|
|
881
|
-
foo: char* foo(char *a, char *b);
|
|
882
|
-
Then,
|
|
883
|
-
foo: char* foo(char *a, char *b);
|
|
884
|
-
and
|
|
885
|
-
__attribute__((annotate("OVERWRITE")))
|
|
886
|
-
char* foo(char *a, char *b){return b;}
|
|
887
|
-
will be put into FunDeclToDefMap
|
|
888
|
-
------------------------------------------------------
|
|
889
|
-
ExtDef -> AppDef (overwrite):
|
|
890
|
-
__attribute__((annotate("OVERWRITE")))
|
|
891
|
-
char* foo(char *a, char *b){return b;}
|
|
892
|
-
and
|
|
893
|
-
foo: char* foo(char *a, char *b);
|
|
894
|
-
are put into FunDefToDeclsMap;
|
|
895
|
-
------------------------------------------------------
|
|
896
|
-
In principle, all functions in extapi.c have bodies (definitions), but some functions (those starting with "sse_")
|
|
897
|
-
have only function declarations without definitions. ExtFuncsVec is used to record function declarations starting with "sse_" that are used.
|
|
898
|
-
|
|
899
|
-
ExtDecl -> ExtDecl:
|
|
900
|
-
For example,
|
|
901
|
-
App function:
|
|
902
|
-
foo(){call memcpy();}
|
|
903
|
-
Ext function:
|
|
904
|
-
declare sse_check_overflow();
|
|
905
|
-
memcpy(){sse_check_overflow();}
|
|
906
|
-
|
|
907
|
-
sse_check_overflow() used in the Ext function but not in the App function.
|
|
908
|
-
sse_check_overflow should be kept in ExtFuncsVec.
|
|
852
|
+
There are three types of functions(definitions) in extapi.c:
|
|
853
|
+
1. (Fun_Overwrite): Functions with "OVERWRITE" annotion:
|
|
854
|
+
These functions are used to replace the corresponding function definitions in the application.
|
|
855
|
+
2. (Fun_Annotation): Functions with annotation(s) but without "OVERWRITE" annotation:
|
|
856
|
+
These functions are used to tell SVF to do special processing, like malloc().
|
|
857
|
+
3. (Fun_Noraml): Functions without any annotation:
|
|
858
|
+
These functions are used to replace the corresponding function declarations in the application.
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
We will iterate over declarations (appFunDecl) and definitons (appFunDef) of functions in the application and extapi.c to do the following clone or replace operations:
|
|
862
|
+
1. appFuncDecl --> Fun_Normal: Clone the Fun_Overwrite and replace the appFuncDecl in application.
|
|
863
|
+
2. appFuncDecl --> Fun_Annotation: Move the annotions on Fun_Annotation to appFuncDecl in application.
|
|
864
|
+
|
|
865
|
+
3. appFunDef --> Fun_Overwrite: Clone the Fun_Overwrite and overwrite the appFunDef in application.
|
|
866
|
+
4. appFunDef --> Fun_Annotation: Replace the appFunDef with appFunDecl and move the annotions to appFunDecl in application
|
|
909
867
|
*/
|
|
910
868
|
void LLVMModuleSet::buildFunToFunMap()
|
|
911
869
|
{
|
|
912
|
-
Set<const Function*>
|
|
913
|
-
OrderedSet<string>
|
|
914
|
-
|
|
915
|
-
|
|
870
|
+
Set<const Function*> appFunDecls, appFunDefs, extFuncs, clonedFuncs;
|
|
871
|
+
OrderedSet<string> appFuncDeclNames, appFuncDefNames, extFunDefNames, intersectNames;
|
|
872
|
+
Map<const Function*, const Function*> extFuncs2ClonedFuncs;
|
|
873
|
+
Module* appModule = nullptr;
|
|
874
|
+
Module* extModule = nullptr;
|
|
875
|
+
|
|
916
876
|
for (Module& mod : modules)
|
|
917
877
|
{
|
|
918
878
|
// extapi.bc functions
|
|
919
879
|
if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
|
|
920
880
|
{
|
|
921
881
|
collectExtFunAnnotations(&mod);
|
|
882
|
+
extModule = &mod;
|
|
922
883
|
for (const Function& fun : mod.functions())
|
|
923
884
|
{
|
|
924
885
|
// there is main declaration in ext bc, it should be mapped to
|
|
925
886
|
// main definition in app bc.
|
|
926
887
|
if (fun.getName().str() == "main")
|
|
927
888
|
{
|
|
928
|
-
|
|
929
|
-
|
|
889
|
+
appFunDecls.insert(&fun);
|
|
890
|
+
appFuncDeclNames.insert(fun.getName().str());
|
|
930
891
|
}
|
|
931
892
|
/// Keep svf_main() function and all the functions called in svf_main()
|
|
932
893
|
else if (fun.getName().str() == "svf__main")
|
|
933
894
|
{
|
|
934
895
|
ExtFuncsVec.push_back(&fun);
|
|
935
|
-
// Get all called functions in svf_main()
|
|
936
|
-
std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(&fun);
|
|
937
|
-
ExtFuncsVec.insert(ExtFuncsVec.end(), calledFunctions.begin(), calledFunctions.end());
|
|
938
896
|
}
|
|
939
897
|
else
|
|
940
898
|
{
|
|
941
899
|
extFuncs.insert(&fun);
|
|
942
|
-
|
|
943
|
-
if (ExtFun2Annotations.find(&fun) != ExtFun2Annotations.end())
|
|
944
|
-
{
|
|
945
|
-
std::vector<std::string> annotations = ExtFun2Annotations[&fun];
|
|
946
|
-
auto it =
|
|
947
|
-
std::find_if(annotations.begin(), annotations.end(),
|
|
948
|
-
[&](const std::string& annotation)
|
|
949
|
-
{
|
|
950
|
-
return annotation.find("OVERWRITE") !=
|
|
951
|
-
std::string::npos;
|
|
952
|
-
});
|
|
953
|
-
if (it != annotations.end())
|
|
954
|
-
{
|
|
955
|
-
overwriteExtFuncs.insert(&fun);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
900
|
+
extFunDefNames.insert(fun.getName().str());
|
|
958
901
|
}
|
|
959
902
|
}
|
|
960
903
|
}
|
|
961
904
|
else
|
|
962
905
|
{
|
|
906
|
+
appModule = &mod;
|
|
963
907
|
/// app functions
|
|
964
908
|
for (const Function& fun : mod.functions())
|
|
965
909
|
{
|
|
966
910
|
if (fun.isDeclaration())
|
|
967
911
|
{
|
|
968
|
-
|
|
969
|
-
|
|
912
|
+
appFunDecls.insert(&fun);
|
|
913
|
+
appFuncDeclNames.insert(fun.getName().str());
|
|
970
914
|
}
|
|
971
915
|
else
|
|
972
916
|
{
|
|
973
|
-
|
|
974
|
-
|
|
917
|
+
appFunDefs.insert(&fun);
|
|
918
|
+
appFuncDefNames.insert(fun.getName().str());
|
|
975
919
|
}
|
|
976
920
|
}
|
|
977
921
|
}
|
|
978
922
|
}
|
|
979
|
-
|
|
923
|
+
|
|
924
|
+
// Find the intersectNames between appFuncDefNames and externalFunDefNames
|
|
980
925
|
std::set_intersection(
|
|
981
|
-
|
|
926
|
+
appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
|
|
982
927
|
std::inserter(intersectNames, intersectNames.end()));
|
|
983
928
|
|
|
984
|
-
|
|
985
|
-
NameToFunDefMapTy nameToFunDefMap;
|
|
986
|
-
for (const Function* fdef : funDefs)
|
|
929
|
+
auto cloneAndReplaceFunction = [&](const Function* extFunToClone, Function* appFunToReplace, Module* appModule, bool cloneBody) -> Function*
|
|
987
930
|
{
|
|
988
|
-
|
|
989
|
-
|
|
931
|
+
assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
|
|
932
|
+
|
|
933
|
+
if (appFunToReplace)
|
|
990
934
|
{
|
|
991
|
-
|
|
935
|
+
appModule = appFunToReplace->getParent();
|
|
992
936
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
string funName = fdecl->getName().str();
|
|
1000
|
-
if (intersectNames.find(funName) != intersectNames.end())
|
|
937
|
+
// Create a new function with the same signature as extFunToClone
|
|
938
|
+
Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
|
|
939
|
+
// Map the arguments of the new function to the arguments of extFunToClone
|
|
940
|
+
llvm::ValueToValueMapTy valueMap;
|
|
941
|
+
Function::arg_iterator destArg = clonedFunction->arg_begin();
|
|
942
|
+
for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
|
|
1001
943
|
{
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
1004
|
-
nameToFunDeclsMap[std::move(funName)].insert(fdecl);
|
|
944
|
+
destArg->setName(srcArg->getName()); // Copy the name of the original argument
|
|
945
|
+
valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
|
|
1005
946
|
}
|
|
1006
|
-
|
|
947
|
+
if (cloneBody)
|
|
948
|
+
{
|
|
949
|
+
// Clone the body of extFunToClone into clonedFunction
|
|
950
|
+
llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
|
|
951
|
+
CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
|
|
952
|
+
}
|
|
953
|
+
if (appFunToReplace)
|
|
954
|
+
{
|
|
955
|
+
// Replace all uses of appFunToReplace with clonedFunction
|
|
956
|
+
appFunToReplace->replaceAllUsesWith(clonedFunction);
|
|
957
|
+
std::string oldFunctionName = appFunToReplace->getName().str();
|
|
958
|
+
// Delete the old function
|
|
959
|
+
appFunToReplace->eraseFromParent();
|
|
960
|
+
clonedFunction->setName(oldFunctionName);
|
|
961
|
+
}
|
|
962
|
+
return clonedFunction;
|
|
963
|
+
};
|
|
1007
964
|
|
|
1008
|
-
///
|
|
1009
|
-
for (const Function*
|
|
965
|
+
/// App Func decl -> SVF extern Func def
|
|
966
|
+
for (const Function* appFunDecl : appFunDecls)
|
|
1010
967
|
{
|
|
1011
|
-
string
|
|
1012
|
-
|
|
1013
|
-
if (intersectNames.find(funName) != intersectNames.end() &&
|
|
1014
|
-
(mit = nameToFunDefMap.find(funName)) != nameToFunDefMap.end())
|
|
968
|
+
std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
|
|
969
|
+
for (const Function* extFun : extFuncs)
|
|
1015
970
|
{
|
|
1016
|
-
|
|
971
|
+
if (extFun->getName().str().compare(appFunDeclName) == 0)
|
|
972
|
+
{
|
|
973
|
+
auto it = ExtFun2Annotations.find(extFun->getName().str());
|
|
974
|
+
// Without annotations, this function is normal function with useful function body
|
|
975
|
+
if (it == ExtFun2Annotations.end())
|
|
976
|
+
{
|
|
977
|
+
Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
|
|
978
|
+
extFuncs2ClonedFuncs[extFun] = clonedFunction;
|
|
979
|
+
clonedFuncs.insert(clonedFunction);
|
|
980
|
+
}
|
|
981
|
+
else
|
|
982
|
+
{
|
|
983
|
+
ExtFuncsVec.push_back(appFunDecl);
|
|
984
|
+
}
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
1017
987
|
}
|
|
1018
988
|
}
|
|
1019
989
|
|
|
1020
|
-
///
|
|
1021
|
-
|
|
990
|
+
/// Overwrite
|
|
991
|
+
/// App Func def -> SVF extern Func def
|
|
992
|
+
for (string sameFuncDef: intersectNames)
|
|
1022
993
|
{
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
NameToFunDeclsMapTy::iterator mit = nameToFunDeclsMap.find(funName);
|
|
1027
|
-
if (mit == nameToFunDeclsMap.end())
|
|
994
|
+
Function* appFuncDef = appModule->getFunction(sameFuncDef);
|
|
995
|
+
Function* extFuncDef = extModule->getFunction(sameFuncDef);
|
|
996
|
+
if (appFuncDef == nullptr || extFuncDef == nullptr)
|
|
1028
997
|
continue;
|
|
1029
998
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
999
|
+
FunctionType *appFuncDefType = appFuncDef->getFunctionType();
|
|
1000
|
+
FunctionType *extFuncDefType = extFuncDef->getFunctionType();
|
|
1001
|
+
if (appFuncDefType != extFuncDefType)
|
|
1002
|
+
continue;
|
|
1034
1003
|
|
|
1035
|
-
|
|
1004
|
+
auto it = ExtFun2Annotations.find(sameFuncDef);
|
|
1005
|
+
if (it != ExtFun2Annotations.end())
|
|
1036
1006
|
{
|
|
1037
|
-
|
|
1007
|
+
std::vector<std::string> annotations = it->second;
|
|
1008
|
+
if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
|
|
1009
|
+
{
|
|
1010
|
+
Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
|
|
1011
|
+
extFuncs2ClonedFuncs[extFuncDef] = clonedFunction;
|
|
1012
|
+
clonedFuncs.insert(clonedFunction);
|
|
1013
|
+
}
|
|
1014
|
+
else
|
|
1015
|
+
{
|
|
1016
|
+
if (annotations.size() >= 2)
|
|
1017
|
+
{
|
|
1018
|
+
for (const auto& annotation : annotations)
|
|
1019
|
+
{
|
|
1020
|
+
if(annotation.find("OVERWRITE") != std::string::npos)
|
|
1021
|
+
{
|
|
1022
|
+
assert(false && "overwrite and other annotations cannot co-exist");
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1038
1027
|
}
|
|
1039
1028
|
}
|
|
1040
1029
|
|
|
1041
|
-
|
|
1042
|
-
for (const Function* fdecl : funDecls)
|
|
1030
|
+
auto linkFunctions = [&](Function* caller, Function* callee)
|
|
1043
1031
|
{
|
|
1044
|
-
|
|
1045
|
-
for (const Function* extfun : extFuncs)
|
|
1032
|
+
for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
|
|
1046
1033
|
{
|
|
1047
|
-
|
|
1034
|
+
Instruction *inst = &*I;
|
|
1035
|
+
|
|
1036
|
+
if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
|
|
1048
1037
|
{
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
// ExtDecl -> ExtDecl in Table 1
|
|
1056
|
-
std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extfun);
|
|
1057
|
-
ExtFuncsVec.insert(ExtFuncsVec.end(), calledFunctions.begin(), calledFunctions.end());
|
|
1058
|
-
break;
|
|
1038
|
+
Function *calledFunc = callInst->getCalledFunction();
|
|
1039
|
+
|
|
1040
|
+
if (calledFunc && calledFunc->getName() == callee->getName())
|
|
1041
|
+
{
|
|
1042
|
+
callInst->setCalledFunction(callee);
|
|
1043
|
+
}
|
|
1059
1044
|
}
|
|
1060
1045
|
}
|
|
1061
|
-
}
|
|
1046
|
+
};
|
|
1062
1047
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
for (const Function* appfunc : funDefs)
|
|
1048
|
+
std::function<void(const Function*, Function*)> cloneAndLinkFunction;
|
|
1049
|
+
cloneAndLinkFunction = [&](const Function* extFunToClone, Function* appClonedFun)
|
|
1066
1050
|
{
|
|
1067
|
-
|
|
1068
|
-
|
|
1051
|
+
if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
|
|
1052
|
+
return;
|
|
1053
|
+
|
|
1054
|
+
Module* appModule = appClonedFun->getParent();
|
|
1055
|
+
// Check if the function already exists in the parent module
|
|
1056
|
+
if (appModule->getFunction(extFunToClone->getName()))
|
|
1069
1057
|
{
|
|
1070
|
-
|
|
1058
|
+
// The function already exists, no need to clone, but need to link it with the caller
|
|
1059
|
+
Function* func = appModule->getFunction(extFunToClone->getName());
|
|
1060
|
+
linkFunctions(appClonedFun, func);
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
// Decide whether to clone the function body based on ExtFun2Annotations
|
|
1064
|
+
bool cloneBody = true;
|
|
1065
|
+
auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
|
|
1066
|
+
if (it != ExtFun2Annotations.end())
|
|
1067
|
+
{
|
|
1068
|
+
std::vector<std::string> annotations = it->second;
|
|
1069
|
+
if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
|
|
1071
1070
|
{
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
// Check if the return types are compatible:
|
|
1076
|
-
// (1) The types are exactly the same,
|
|
1077
|
-
// (2) Both are pointer types, and at least one of them is a void*.
|
|
1078
|
-
// Note that getPointerElementType() will be deprecated in the future versions of LLVM.
|
|
1079
|
-
// Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if it is a void * type.
|
|
1080
|
-
if (!(returnType1 == returnType2 || (returnType1->isPointerTy() && returnType2->isPointerTy())))
|
|
1081
|
-
{
|
|
1082
|
-
continue;
|
|
1083
|
-
}
|
|
1071
|
+
cloneBody = false;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1084
1074
|
|
|
1085
|
-
|
|
1086
|
-
continue;
|
|
1075
|
+
Function* clonedFunction = cloneAndReplaceFunction(extFunToClone, nullptr, appModule, cloneBody);
|
|
1087
1076
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
while (argIter1 != appfunc->arg_end() && argIter2 != owfunc->arg_end())
|
|
1092
|
-
{
|
|
1093
|
-
Type* argType1 = argIter1->getType();
|
|
1094
|
-
Type* argType2 = argIter2->getType();
|
|
1077
|
+
clonedFuncs.insert(clonedFunction);
|
|
1078
|
+
// Add the cloned function to ExtFuncsVec for further processing
|
|
1079
|
+
ExtFuncsVec.push_back(clonedFunction);
|
|
1095
1080
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1081
|
+
linkFunctions(appClonedFun, clonedFunction);
|
|
1082
|
+
|
|
1083
|
+
std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
|
|
1084
|
+
|
|
1085
|
+
for (const auto& calledFunction : calledFunctions)
|
|
1086
|
+
{
|
|
1087
|
+
cloneAndLinkFunction(calledFunction, clonedFunction);
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
// Recursive clone called functions
|
|
1092
|
+
for (const auto& pair : extFuncs2ClonedFuncs)
|
|
1093
|
+
{
|
|
1094
|
+
Function* extFun = const_cast<Function*>(pair.first);
|
|
1095
|
+
Function* clonedExtFun = const_cast<Function*>(pair.second);
|
|
1096
|
+
std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
|
|
1097
|
+
|
|
1098
|
+
for (const auto& extCalledFun : extCalledFuns)
|
|
1099
|
+
{
|
|
1100
|
+
cloneAndLinkFunction(extCalledFun, clonedExtFun);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
|
|
1105
|
+
Fun2AnnoMap newFun2AnnoMap;
|
|
1106
|
+
for (const Function* extFun : ExtFuncsVec)
|
|
1107
|
+
{
|
|
1108
|
+
std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
|
|
1109
|
+
auto it = ExtFun2Annotations.find(name);
|
|
1110
|
+
if (it != ExtFun2Annotations.end())
|
|
1111
|
+
{
|
|
1112
|
+
std::string newKey = name;
|
|
1113
|
+
if (name != extFun->getName().str())
|
|
1114
|
+
{
|
|
1115
|
+
newKey = extFun->getName().str();
|
|
1127
1116
|
}
|
|
1117
|
+
newFun2AnnoMap.insert({newKey, it->second});
|
|
1128
1118
|
}
|
|
1129
1119
|
}
|
|
1120
|
+
ExtFun2Annotations.swap(newFun2AnnoMap);
|
|
1121
|
+
|
|
1122
|
+
// Remove ExtAPI module from modules
|
|
1123
|
+
auto it = std::find_if(modules.begin(), modules.end(),
|
|
1124
|
+
[&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
|
|
1125
|
+
{
|
|
1126
|
+
return &moduleRef.get() == extModule;
|
|
1127
|
+
});
|
|
1128
|
+
|
|
1129
|
+
if (it != modules.end())
|
|
1130
|
+
{
|
|
1131
|
+
size_t index = std::distance(modules.begin(), it);
|
|
1132
|
+
modules.erase(it);
|
|
1133
|
+
owned_modules.erase(owned_modules.begin() + index);
|
|
1134
|
+
}
|
|
1130
1135
|
}
|
|
1131
1136
|
|
|
1132
1137
|
void LLVMModuleSet::buildGlobalDefToRepMap()
|
|
@@ -1171,25 +1176,6 @@ void LLVMModuleSet::buildGlobalDefToRepMap()
|
|
|
1171
1176
|
}
|
|
1172
1177
|
}
|
|
1173
1178
|
|
|
1174
|
-
void LLVMModuleSet::removeUnusedExtAPIs()
|
|
1175
|
-
{
|
|
1176
|
-
Set<Function*> removedFuncList;
|
|
1177
|
-
for (Module& mod : modules)
|
|
1178
|
-
{
|
|
1179
|
-
if (mod.getName().str() != ExtAPI::getExtAPI()->getExtBcPath())
|
|
1180
|
-
continue;
|
|
1181
|
-
for (Function& func : mod.functions())
|
|
1182
|
-
{
|
|
1183
|
-
if (isCalledExtFunction(&func))
|
|
1184
|
-
{
|
|
1185
|
-
removedFuncList.insert(&func);
|
|
1186
|
-
ExtFun2Annotations.erase(&func);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
LLVMUtil::removeUnusedFuncsAndAnnotationsAndGlobalVariables(removedFuncList);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
1179
|
// Dump modules to files
|
|
1194
1180
|
void LLVMModuleSet::dumpModulesToFile(const std::string& suffix)
|
|
1195
1181
|
{
|
|
@@ -1238,7 +1224,7 @@ void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue)
|
|
|
1238
1224
|
const Function* func = SVFUtil::cast<Function>(val);
|
|
1239
1225
|
svffun->setIsNotRet(LLVMUtil::functionDoesNotRet(func));
|
|
1240
1226
|
svffun->setIsUncalledFunction(LLVMUtil::isUncalledFunction(func));
|
|
1241
|
-
svffun->setDefFunForMultipleModule(getSVFFunction(
|
|
1227
|
+
svffun->setDefFunForMultipleModule(getSVFFunction(func));
|
|
1242
1228
|
}
|
|
1243
1229
|
|
|
1244
1230
|
svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));
|