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.
@@ -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
- const Function* llvmfunc_def = LLVMUtil::getDefFunForMultipleModule(called_llvmfunc);
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
- For a more detailed explanation of the Function declaration and definition mapping relationships and how External APIs are handled,
849
- please refer to the SVF Wiki: https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c
850
-
851
- Table 1
852
- | ------- | ----------------- | --------------- | ----------------- | ----------- |
853
- | | AppDef | AppDecl | ExtDef | ExtDecl |
854
- | ------- | ----------------- | --------------- | ----------------- | ----------- |
855
- | AppDef | X | FunDefToDeclsMap| FunDeclToDefMap | X |
856
- | ------- | ----------------- | --------------- | ----------------- | ----------- |
857
- | AppDecl | FunDeclToDefMap | X | FunDeclToDefMap | X |
858
- | ------- | ----------------- | --------------- | ----------------- | ----------- |
859
- | ExtDef | FunDefToDeclsMap | FunDefToDeclsMap| X | X |
860
- | ------- | ----------------- | --------------- | ----------------- | ----------- |
861
- | ExtDecl | FunDeclToDefMap | X | X | ExtFuncsVec |
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*> funDecls, funDefs, extFuncs, overwriteExtFuncs;
913
- OrderedSet<string> declNames, defNames, intersectNames;
914
- typedef Map<string, const Function*> NameToFunDefMapTy;
915
- typedef Map<string, Set<const Function*>> NameToFunDeclsMapTy;
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
- funDecls.insert(&fun);
929
- declNames.insert(fun.getName().str());
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
- // Find overwrite functions in extapi.bc
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
- funDecls.insert(&fun);
969
- declNames.insert(fun.getName().str());
912
+ appFunDecls.insert(&fun);
913
+ appFuncDeclNames.insert(fun.getName().str());
970
914
  }
971
915
  else
972
916
  {
973
- funDefs.insert(&fun);
974
- defNames.insert(fun.getName().str());
917
+ appFunDefs.insert(&fun);
918
+ appFuncDefNames.insert(fun.getName().str());
975
919
  }
976
920
  }
977
921
  }
978
922
  }
979
- // Find the intersectNames
923
+
924
+ // Find the intersectNames between appFuncDefNames and externalFunDefNames
980
925
  std::set_intersection(
981
- declNames.begin(), declNames.end(), defNames.begin(), defNames.end(),
926
+ appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
982
927
  std::inserter(intersectNames, intersectNames.end()));
983
928
 
984
- ///// name to def map
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
- string funName = fdef->getName().str();
989
- if (intersectNames.find(funName) != intersectNames.end())
931
+ assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
932
+
933
+ if (appFunToReplace)
990
934
  {
991
- nameToFunDefMap.emplace(std::move(funName), fdef);
935
+ appModule = appFunToReplace->getParent();
992
936
  }
993
- }
994
-
995
- ///// name to decls map
996
- NameToFunDeclsMapTy nameToFunDeclsMap;
997
- for (const Function* fdecl : funDecls)
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
- // pair with key funName will be created automatically if it does
1003
- // not exist
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
- /// Fun decl --> def
1009
- for (const Function* fdecl : funDecls)
965
+ /// App Func decl -> SVF extern Func def
966
+ for (const Function* appFunDecl : appFunDecls)
1010
967
  {
1011
- string funName = fdecl->getName().str();
1012
- NameToFunDefMapTy::iterator mit;
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
- FunDeclToDefMap[fdecl] = mit->second;
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
- /// Fun def --> decls
1021
- for (const Function* fdef : funDefs)
990
+ /// Overwrite
991
+ /// App Func def -> SVF extern Func def
992
+ for (string sameFuncDef: intersectNames)
1022
993
  {
1023
- string funName = fdef->getName().str();
1024
- if (intersectNames.find(funName) == intersectNames.end())
1025
- continue;
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
- std::vector<const Function*>& decls = FunDefToDeclsMap[fdef];
1031
- const auto& declsSet = mit->second;
1032
- // Reserve space for decls to avoid more than 1 reallocation
1033
- decls.reserve(decls.size() + declsSet.size());
999
+ FunctionType *appFuncDefType = appFuncDef->getFunctionType();
1000
+ FunctionType *extFuncDefType = extFuncDef->getFunctionType();
1001
+ if (appFuncDefType != extFuncDefType)
1002
+ continue;
1034
1003
 
1035
- for (const Function* decl : declsSet)
1004
+ auto it = ExtFun2Annotations.find(sameFuncDef);
1005
+ if (it != ExtFun2Annotations.end())
1036
1006
  {
1037
- decls.push_back(decl);
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
- /// App Func decl -> SVF extern Func def
1042
- for (const Function* fdecl : funDecls)
1030
+ auto linkFunctions = [&](Function* caller, Function* callee)
1043
1031
  {
1044
- std::string declName = LLVMUtil::restoreFuncName(fdecl->getName().str());
1045
- for (const Function* extfun : extFuncs)
1032
+ for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
1046
1033
  {
1047
- if (extfun->getName().str().compare(declName) == 0)
1034
+ Instruction *inst = &*I;
1035
+
1036
+ if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
1048
1037
  {
1049
- // AppDecl -> ExtDef in Table 1
1050
- FunDeclToDefMap[fdecl] = extfun;
1051
- // ExtDef -> AppDecl in Table 1
1052
- std::vector<const Function*>& decls = FunDefToDeclsMap[extfun];
1053
- decls.push_back(fdecl);
1054
- // Keep all called functions in extfun
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
- /// Overwrite
1064
- /// App Func def -> SVF extern Func def
1065
- for (const Function* appfunc : funDefs)
1048
+ std::function<void(const Function*, Function*)> cloneAndLinkFunction;
1049
+ cloneAndLinkFunction = [&](const Function* extFunToClone, Function* appClonedFun)
1066
1050
  {
1067
- std::string appfuncName = LLVMUtil::restoreFuncName(appfunc->getName().str());
1068
- for (const Function* owfunc : overwriteExtFuncs)
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
- if (appfuncName.compare(owfunc->getName().str()) == 0)
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
- Type* returnType1 = appfunc->getReturnType();
1073
- Type* returnType2 = owfunc->getReturnType();
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
- if (appfunc->arg_size() != owfunc->arg_size())
1086
- continue;
1075
+ Function* clonedFunction = cloneAndReplaceFunction(extFunToClone, nullptr, appModule, cloneBody);
1087
1076
 
1088
- bool argMismatch = false;
1089
- Function::const_arg_iterator argIter1 = appfunc->arg_begin();
1090
- Function::const_arg_iterator argIter2 = owfunc->arg_begin();
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
- // Check if the parameters types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*.
1097
- if (!(argType1 == argType2 || (argType1->isPointerTy() && argType2->isPointerTy())))
1098
- {
1099
- argMismatch = true;
1100
- break;
1101
- }
1102
- argIter1++;
1103
- argIter2++;
1104
- }
1105
- if (argMismatch)
1106
- continue;
1107
-
1108
- Function* fun = const_cast<Function*>(appfunc);
1109
- Module* mod = fun->getParent();
1110
- FunctionType* funType = fun->getFunctionType();
1111
- std::string funName = fun->getName().str();
1112
- // Replace app function definition with declaration
1113
- Function* declaration = Function::Create(funType, GlobalValue::ExternalLinkage, funName, mod);
1114
- fun->replaceAllUsesWith(declaration);
1115
- fun->eraseFromParent();
1116
- declaration->setName(funName);
1117
- // AppDef -> ExtDef in Table 1, AppDef has been changed to AppDecl
1118
- FunDeclToDefMap[declaration] = owfunc;
1119
- // ExtDef -> AppDef in Table 1
1120
- std::vector<const Function*>& decls = FunDefToDeclsMap[owfunc];
1121
- decls.push_back(declaration);
1122
- // Keep all called functions in owfunc
1123
- // ExtDecl -> ExtDecl in Table 1
1124
- std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(owfunc);
1125
- ExtFuncsVec.insert(ExtFuncsVec.end(), calledFunctions.begin(), calledFunctions.end());
1126
- break;
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(LLVMUtil::getDefFunForMultipleModule(func)));
1227
+ svffun->setDefFunForMultipleModule(getSVFFunction(func));
1242
1228
  }
1243
1229
 
1244
1230
  svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));