svf-tools 1.0.683 → 1.0.685
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.685",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -546,7 +546,7 @@ inline IntervalValue operator%(const IntervalValue &lhs,
|
|
|
546
546
|
else
|
|
547
547
|
{
|
|
548
548
|
NumericLiteral n_ub = max(abs(lhs.lb()), abs(lhs.ub()));
|
|
549
|
-
NumericLiteral d_ub = max(abs(rhs.lb()), rhs.ub() - 1
|
|
549
|
+
NumericLiteral d_ub = max(abs(rhs.lb()), rhs.ub()) - 1;
|
|
550
550
|
NumericLiteral ub = min(n_ub, d_ub);
|
|
551
551
|
|
|
552
552
|
if (lhs.lb().getNumeral() < 0)
|
|
@@ -592,7 +592,7 @@ inline IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
592
592
|
return IntervalValue(1, 1);
|
|
593
593
|
// lhs[1,2] rhs[3,4]
|
|
594
594
|
}
|
|
595
|
-
else if (lhs.ub().geq(rhs.lb()))
|
|
595
|
+
else if (!lhs.ub().geq(rhs.lb()))
|
|
596
596
|
{
|
|
597
597
|
return IntervalValue(0, 0);
|
|
598
598
|
}
|
|
@@ -758,6 +758,7 @@ cJSON* jsonCreateString(const char* str)
|
|
|
758
758
|
cJSON* jsonCreateIndex(size_t index)
|
|
759
759
|
{
|
|
760
760
|
constexpr size_t maxPreciseIntInDouble = (1ull << 53);
|
|
761
|
+
(void)maxPreciseIntInDouble; // silence unused warning
|
|
761
762
|
assert(index <= maxPreciseIntInDouble);
|
|
762
763
|
return cJSON_CreateNumber(index);
|
|
763
764
|
}
|
|
@@ -1099,7 +1100,7 @@ cJSON* SVFIRWriter::toJson(const SVFModule* module)
|
|
|
1099
1100
|
cJSON* values = jsonCreateArray();
|
|
1100
1101
|
for (size_t i = 1; i <= svfModuleWriter.svfValuePool.size(); ++i)
|
|
1101
1102
|
{
|
|
1102
|
-
cJSON* value =
|
|
1103
|
+
cJSON* value = contentToJson(svfModuleWriter.svfValuePool.getPtr(i));
|
|
1103
1104
|
jsonAddItemToArray(values, value);
|
|
1104
1105
|
}
|
|
1105
1106
|
jsonAddItemToObject(root, "values", values);
|
|
@@ -1107,7 +1108,7 @@ cJSON* SVFIRWriter::toJson(const SVFModule* module)
|
|
|
1107
1108
|
cJSON* types = jsonCreateArray();
|
|
1108
1109
|
for (size_t i = 1; i <= svfModuleWriter.svfTypePool.size(); ++i)
|
|
1109
1110
|
{
|
|
1110
|
-
cJSON* type =
|
|
1111
|
+
cJSON* type = contentToJson(svfModuleWriter.svfTypePool.getPtr(i));
|
|
1111
1112
|
jsonAddItemToArray(types, type);
|
|
1112
1113
|
}
|
|
1113
1114
|
jsonAddItemToObject(root, "types", types);
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
* Author: Xiaokang Fan
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
#include "Util/Options.h"
|
|
31
30
|
#include <queue>
|
|
31
|
+
#include <algorithm>
|
|
32
|
+
#include "Util/Options.h"
|
|
32
33
|
#include "SVFIR/SVFModule.h"
|
|
33
34
|
#include "SVFIR/SVFModuleRW.h"
|
|
34
35
|
#include "Util/SVFUtil.h"
|
|
@@ -95,7 +96,7 @@ SVFModule* LLVMModuleSet::buildSVFModule(Module &mod)
|
|
|
95
96
|
double endSVFModuleTime = SVFStat::getClk(true);
|
|
96
97
|
SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime)/TIMEINTERVAL;
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
buildSymbolTable();
|
|
99
100
|
|
|
100
101
|
return svfModule.get();
|
|
101
102
|
}
|
|
@@ -118,12 +119,12 @@ SVFModule* LLVMModuleSet::buildSVFModule(const std::vector<std::string> &moduleN
|
|
|
118
119
|
double endSVFModuleTime = SVFStat::getClk(true);
|
|
119
120
|
SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime)/TIMEINTERVAL;
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
buildSymbolTable();
|
|
122
123
|
|
|
123
124
|
return svfModule.get();
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
void LLVMModuleSet::
|
|
127
|
+
void LLVMModuleSet::buildSymbolTable() const
|
|
127
128
|
{
|
|
128
129
|
double startSymInfoTime = SVFStat::getClk(true);
|
|
129
130
|
if (!SVFModule::pagReadFromTXT())
|
|
@@ -134,7 +135,8 @@ void LLVMModuleSet::build_symbol_table() const
|
|
|
134
135
|
builder.buildMemModel(svfModule.get());
|
|
135
136
|
}
|
|
136
137
|
double endSymInfoTime = SVFStat::getClk(true);
|
|
137
|
-
SVFStat::timeOfBuildingSymbolTable =
|
|
138
|
+
SVFStat::timeOfBuildingSymbolTable =
|
|
139
|
+
(endSymInfoTime - startSymInfoTime) / TIMEINTERVAL;
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
void LLVMModuleSet::build()
|
|
@@ -158,67 +160,79 @@ void LLVMModuleSet::createSVFDataStructure()
|
|
|
158
160
|
for (Module& mod : modules)
|
|
159
161
|
{
|
|
160
162
|
/// Function
|
|
161
|
-
for (
|
|
163
|
+
for (const Function& func : mod.functions())
|
|
162
164
|
{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
SVFFunction* svfFunc = new SVFFunction(
|
|
166
|
+
func.getName().str(), getSVFType(func.getType()),
|
|
167
|
+
SVFUtil::cast<SVFFunctionType>(
|
|
168
|
+
getSVFType(func.getFunctionType())),
|
|
169
|
+
func.isDeclaration(), LLVMUtil::isIntrinsicFun(&func),
|
|
170
|
+
func.hasAddressTaken(), func.isVarArg(), new SVFLoopAndDomInfo);
|
|
166
171
|
svfModule->addFunctionSet(svfFunc);
|
|
167
|
-
addFunctionMap(func,svfFunc);
|
|
172
|
+
addFunctionMap(&func, svfFunc);
|
|
168
173
|
|
|
169
|
-
for (
|
|
174
|
+
for (const Argument& arg : func.args())
|
|
170
175
|
{
|
|
171
|
-
|
|
172
|
-
|
|
176
|
+
SVFArgument* svfarg = new SVFArgument(
|
|
177
|
+
arg.getName().str(), getSVFType(arg.getType()), svfFunc,
|
|
178
|
+
arg.getArgNo(), LLVMUtil::isArgOfUncalledFunction(&arg));
|
|
173
179
|
svfFunc->addArgument(svfarg);
|
|
174
|
-
addArgumentMap(arg,svfarg);
|
|
180
|
+
addArgumentMap(&arg, svfarg);
|
|
175
181
|
}
|
|
176
182
|
|
|
177
|
-
for (
|
|
183
|
+
for (const BasicBlock& bb : func)
|
|
178
184
|
{
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
SVFBasicBlock* svfBB = new SVFBasicBlock(
|
|
186
|
+
bb.getName().str(), getSVFType(bb.getType()), svfFunc);
|
|
181
187
|
svfFunc->addBasicBlock(svfBB);
|
|
182
|
-
addBasicBlockMap(bb,svfBB);
|
|
183
|
-
for (
|
|
188
|
+
addBasicBlockMap(&bb, svfBB);
|
|
189
|
+
for (const Instruction& inst : bb)
|
|
184
190
|
{
|
|
185
|
-
const Instruction* inst = &*iit;
|
|
186
191
|
SVFInstruction* svfInst = nullptr;
|
|
187
|
-
if(const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
|
|
192
|
+
if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
|
|
188
193
|
{
|
|
189
|
-
if(LLVMUtil::isVirtualCallSite(call))
|
|
190
|
-
svfInst = new SVFVirtualCallInst(
|
|
194
|
+
if (LLVMUtil::isVirtualCallSite(call))
|
|
195
|
+
svfInst = new SVFVirtualCallInst(
|
|
196
|
+
call->getName().str(),
|
|
197
|
+
getSVFType(call->getType()), svfBB,
|
|
198
|
+
call->getFunctionType()->isVarArg(),
|
|
199
|
+
inst.isTerminator());
|
|
191
200
|
else
|
|
192
|
-
svfInst = new SVFCallInst(
|
|
201
|
+
svfInst = new SVFCallInst(
|
|
202
|
+
call->getName().str(),
|
|
203
|
+
getSVFType(call->getType()), svfBB,
|
|
204
|
+
call->getFunctionType()->isVarArg(),
|
|
205
|
+
inst.isTerminator());
|
|
193
206
|
}
|
|
194
207
|
else
|
|
195
208
|
{
|
|
196
|
-
svfInst = new SVFInstruction(
|
|
209
|
+
svfInst = new SVFInstruction(
|
|
210
|
+
inst.getName().str(), getSVFType(inst.getType()),
|
|
211
|
+
svfBB, inst.isTerminator(),
|
|
212
|
+
SVFUtil::isa<ReturnInst>(inst));
|
|
197
213
|
}
|
|
198
214
|
svfBB->addInstruction(svfInst);
|
|
199
|
-
addInstructionMap(inst,svfInst);
|
|
215
|
+
addInstructionMap(&inst, svfInst);
|
|
200
216
|
}
|
|
201
217
|
}
|
|
202
218
|
}
|
|
203
219
|
|
|
204
220
|
/// GlobalVariable
|
|
205
|
-
for (
|
|
206
|
-
eit = mod.global_end(); it != eit; ++it)
|
|
221
|
+
for (const GlobalVariable& global : mod.globals())
|
|
207
222
|
{
|
|
208
|
-
|
|
209
|
-
|
|
223
|
+
SVFGlobalValue* svfglobal = new SVFGlobalValue(
|
|
224
|
+
global.getName().str(), getSVFType(global.getType()));
|
|
210
225
|
svfModule->addGlobalSet(svfglobal);
|
|
211
|
-
addGlobalValueMap(global,svfglobal);
|
|
226
|
+
addGlobalValueMap(&global, svfglobal);
|
|
212
227
|
}
|
|
213
228
|
|
|
214
229
|
/// GlobalAlias
|
|
215
|
-
for (
|
|
216
|
-
eit = mod.alias_end(); it != eit; ++it)
|
|
230
|
+
for (const GlobalAlias& alias : mod.aliases())
|
|
217
231
|
{
|
|
218
|
-
|
|
219
|
-
|
|
232
|
+
SVFGlobalValue* svfalias = new SVFGlobalValue(
|
|
233
|
+
alias.getName().str(), getSVFType(alias.getType()));
|
|
220
234
|
svfModule->addAliasSet(svfalias);
|
|
221
|
-
addGlobalValueMap(alias,svfalias);
|
|
235
|
+
addGlobalValueMap(&alias, svfalias);
|
|
222
236
|
}
|
|
223
237
|
}
|
|
224
238
|
}
|
|
@@ -228,15 +242,14 @@ void LLVMModuleSet::initSVFFunction()
|
|
|
228
242
|
for (Module& mod : modules)
|
|
229
243
|
{
|
|
230
244
|
/// Function
|
|
231
|
-
for (
|
|
245
|
+
for (const Function& f : mod.functions())
|
|
232
246
|
{
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
initSVFBasicBlock(f);
|
|
247
|
+
SVFFunction* svffun = getSVFFunction(&f);
|
|
248
|
+
initSVFBasicBlock(&f);
|
|
236
249
|
|
|
237
|
-
if (SVFUtil::isExtCall(svffun)
|
|
250
|
+
if (!SVFUtil::isExtCall(svffun))
|
|
238
251
|
{
|
|
239
|
-
initDomTree(svffun, f);
|
|
252
|
+
initDomTree(svffun, &f);
|
|
240
253
|
}
|
|
241
254
|
}
|
|
242
255
|
}
|
|
@@ -554,36 +567,34 @@ std::vector<const Function* > LLVMModuleSet::getLLVMGlobalFunctions(const Global
|
|
|
554
567
|
|
|
555
568
|
void LLVMModuleSet::addSVFMain()
|
|
556
569
|
{
|
|
557
|
-
std::vector<const Function
|
|
558
|
-
std::vector<const Function
|
|
559
|
-
Function*
|
|
570
|
+
std::vector<const Function*> ctor_funcs;
|
|
571
|
+
std::vector<const Function*> dtor_funcs;
|
|
572
|
+
Function* orgMain = 0;
|
|
560
573
|
Module* mainMod = nullptr;
|
|
561
574
|
|
|
562
575
|
for (Module &mod : modules)
|
|
563
576
|
{
|
|
564
577
|
// Collect ctor and dtor functions
|
|
565
|
-
for (
|
|
578
|
+
for (const GlobalVariable& global : mod.globals())
|
|
566
579
|
{
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
if (global->getName().equals(SVF_GLOBAL_CTORS) &&
|
|
570
|
-
global->hasInitializer())
|
|
580
|
+
if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
|
|
571
581
|
{
|
|
572
|
-
ctor_funcs = getLLVMGlobalFunctions(global);
|
|
582
|
+
ctor_funcs = getLLVMGlobalFunctions(&global);
|
|
573
583
|
}
|
|
574
|
-
else if (global
|
|
575
|
-
global->hasInitializer())
|
|
584
|
+
else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
|
|
576
585
|
{
|
|
577
|
-
dtor_funcs = getLLVMGlobalFunctions(global);
|
|
586
|
+
dtor_funcs = getLLVMGlobalFunctions(&global);
|
|
578
587
|
}
|
|
579
588
|
}
|
|
580
589
|
|
|
581
590
|
// Find main function
|
|
582
591
|
for (auto &func : mod)
|
|
583
592
|
{
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
593
|
+
auto funName = func.getName();
|
|
594
|
+
|
|
595
|
+
assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
|
|
596
|
+
|
|
597
|
+
if (funName.equals("main"))
|
|
587
598
|
{
|
|
588
599
|
orgMain = &func;
|
|
589
600
|
mainMod = &mod;
|
|
@@ -597,10 +608,10 @@ void LLVMModuleSet::addSVFMain()
|
|
|
597
608
|
(ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
|
|
598
609
|
{
|
|
599
610
|
assert(mainMod && "Module with main function not found.");
|
|
600
|
-
Module
|
|
611
|
+
Module& M = *mainMod;
|
|
601
612
|
// char **
|
|
602
|
-
Type*
|
|
603
|
-
Type*
|
|
613
|
+
Type* i8ptr2 = PointerType::getInt8PtrTy(M.getContext())->getPointerTo();
|
|
614
|
+
Type* i32 = IntegerType::getInt32Ty(M.getContext());
|
|
604
615
|
// define void @svf.main(i32, i8**, i8**)
|
|
605
616
|
#if (LLVM_VERSION_MAJOR >= 9)
|
|
606
617
|
FunctionCallee svfmainFn = M.getOrInsertFunction(
|
|
@@ -621,7 +632,7 @@ void LLVMModuleSet::addSVFMain()
|
|
|
621
632
|
IRBuilder Builder(block);
|
|
622
633
|
// emit "call void @ctor()". ctor_funcs is sorted so the functions are
|
|
623
634
|
// emitted in the order of priority
|
|
624
|
-
for(auto
|
|
635
|
+
for (auto& ctor : ctor_funcs)
|
|
625
636
|
{
|
|
626
637
|
auto target = M.getOrInsertFunction(
|
|
627
638
|
ctor->getName(),
|
|
@@ -632,18 +643,15 @@ void LLVMModuleSet::addSVFMain()
|
|
|
632
643
|
// main() should be called after all ctor functions and before dtor
|
|
633
644
|
// functions.
|
|
634
645
|
Function::arg_iterator arg_it = svfmain->arg_begin();
|
|
635
|
-
Value*
|
|
646
|
+
Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
|
|
636
647
|
size_t cnt = orgMain->arg_size();
|
|
637
648
|
assert(cnt <= 3 && "Too many arguments for main()");
|
|
638
|
-
Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args,args + cnt));
|
|
649
|
+
Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
|
|
639
650
|
// emit "call void @dtor()". dtor_funcs is sorted so the functions are
|
|
640
651
|
// emitted in the order of priority
|
|
641
|
-
for (auto
|
|
652
|
+
for (auto& dtor : dtor_funcs)
|
|
642
653
|
{
|
|
643
|
-
auto target = M.getOrInsertFunction(
|
|
644
|
-
dtor->getName(),
|
|
645
|
-
Type::getVoidTy(M.getContext())
|
|
646
|
-
);
|
|
654
|
+
auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
|
|
647
655
|
Builder.CreateCall(target);
|
|
648
656
|
}
|
|
649
657
|
// return;
|
|
@@ -662,107 +670,79 @@ void LLVMModuleSet::buildFunToFunMap()
|
|
|
662
670
|
for (Module& mod : modules)
|
|
663
671
|
{
|
|
664
672
|
/// Function
|
|
665
|
-
for (
|
|
673
|
+
for (const Function& fun : mod.functions())
|
|
666
674
|
{
|
|
667
|
-
|
|
668
|
-
if (fun->isDeclaration())
|
|
675
|
+
if (fun.isDeclaration())
|
|
669
676
|
{
|
|
670
|
-
funDecls.insert(fun);
|
|
671
|
-
declNames.insert(fun
|
|
677
|
+
funDecls.insert(&fun);
|
|
678
|
+
declNames.insert(fun.getName().str());
|
|
672
679
|
}
|
|
673
680
|
else
|
|
674
681
|
{
|
|
675
|
-
funDefs.insert(fun);
|
|
676
|
-
defNames.insert(fun
|
|
682
|
+
funDefs.insert(&fun);
|
|
683
|
+
defNames.insert(fun.getName().str());
|
|
677
684
|
}
|
|
678
685
|
}
|
|
679
686
|
}
|
|
680
687
|
// Find the intersectNames
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
while (declIter != declNames.end() && defIter != defNames.end())
|
|
685
|
-
{
|
|
686
|
-
if (*declIter < *defIter)
|
|
687
|
-
{
|
|
688
|
-
declIter++;
|
|
689
|
-
}
|
|
690
|
-
else
|
|
691
|
-
{
|
|
692
|
-
if (!(*defIter < *declIter))
|
|
693
|
-
{
|
|
694
|
-
intersectNames.insert(*declIter);
|
|
695
|
-
declIter++;
|
|
696
|
-
}
|
|
697
|
-
defIter++;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
688
|
+
std::set_intersection(
|
|
689
|
+
declNames.begin(), declNames.end(), defNames.begin(), defNames.end(),
|
|
690
|
+
std::inserter(intersectNames, intersectNames.end()));
|
|
700
691
|
|
|
701
692
|
///// name to def map
|
|
702
693
|
NameToFunDefMapTy nameToFunDefMap;
|
|
703
|
-
for (
|
|
704
|
-
eit = funDefs.end(); it != eit; ++it)
|
|
694
|
+
for (const Function* fdef : funDefs)
|
|
705
695
|
{
|
|
706
|
-
const Function* fdef = *it;
|
|
707
696
|
string funName = fdef->getName().str();
|
|
708
|
-
if (intersectNames.find(funName)
|
|
709
|
-
|
|
710
|
-
|
|
697
|
+
if (intersectNames.find(funName) != intersectNames.end())
|
|
698
|
+
{
|
|
699
|
+
nameToFunDefMap.emplace(std::move(funName), fdef);
|
|
700
|
+
}
|
|
711
701
|
}
|
|
712
702
|
|
|
713
703
|
///// name to decls map
|
|
714
704
|
NameToFunDeclsMapTy nameToFunDeclsMap;
|
|
715
|
-
for (
|
|
716
|
-
eit = funDecls.end(); it != eit; ++it)
|
|
705
|
+
for (const Function* fdecl : funDecls)
|
|
717
706
|
{
|
|
718
|
-
const Function* fdecl = *it;
|
|
719
707
|
string funName = fdecl->getName().str();
|
|
720
|
-
if (intersectNames.find(funName)
|
|
721
|
-
continue;
|
|
722
|
-
NameToFunDeclsMapTy::iterator mit = nameToFunDeclsMap.find(funName);
|
|
723
|
-
if (mit == nameToFunDeclsMap.end())
|
|
724
|
-
{
|
|
725
|
-
Set<const Function*> decls;
|
|
726
|
-
decls.insert(fdecl);
|
|
727
|
-
nameToFunDeclsMap[funName] = decls;
|
|
728
|
-
}
|
|
729
|
-
else
|
|
708
|
+
if (intersectNames.find(funName) != intersectNames.end())
|
|
730
709
|
{
|
|
731
|
-
|
|
732
|
-
|
|
710
|
+
// pair with key funName will be created automatically if it does
|
|
711
|
+
// not exist
|
|
712
|
+
nameToFunDeclsMap[std::move(funName)].insert(fdecl);
|
|
733
713
|
}
|
|
734
714
|
}
|
|
735
715
|
|
|
736
716
|
/// Fun decl --> def
|
|
737
|
-
for (
|
|
738
|
-
eit = funDecls.end(); it != eit; ++it)
|
|
717
|
+
for (const Function* fdecl : funDecls)
|
|
739
718
|
{
|
|
740
|
-
const Function* fdecl = *it;
|
|
741
719
|
string funName = fdecl->getName().str();
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
720
|
+
NameToFunDefMapTy::iterator mit;
|
|
721
|
+
if (intersectNames.find(funName) != intersectNames.end() &&
|
|
722
|
+
(mit = nameToFunDefMap.find(funName)) != nameToFunDefMap.end())
|
|
723
|
+
{
|
|
724
|
+
FunDeclToDefMap[fdecl] = mit->second;
|
|
725
|
+
}
|
|
748
726
|
}
|
|
749
727
|
|
|
750
728
|
/// Fun def --> decls
|
|
751
|
-
for (
|
|
752
|
-
eit = funDefs.end(); it != eit; ++it)
|
|
729
|
+
for (const Function* fdef : funDefs)
|
|
753
730
|
{
|
|
754
|
-
const Function* fdef = *it;
|
|
755
731
|
string funName = fdef->getName().str();
|
|
756
732
|
if (intersectNames.find(funName) == intersectNames.end())
|
|
757
733
|
continue;
|
|
758
734
|
NameToFunDeclsMapTy::iterator mit = nameToFunDeclsMap.find(funName);
|
|
759
735
|
if (mit == nameToFunDeclsMap.end())
|
|
760
736
|
continue;
|
|
737
|
+
|
|
761
738
|
std::vector<const Function*>& decls = FunDefToDeclsMap[fdef];
|
|
762
|
-
|
|
763
|
-
|
|
739
|
+
const auto& declsSet = mit->second;
|
|
740
|
+
// Reserve space for decls to avoid more than 1 reallocation
|
|
741
|
+
decls.reserve(decls.size() + declsSet.size());
|
|
742
|
+
|
|
743
|
+
for (const Function* decl : declsSet)
|
|
764
744
|
{
|
|
765
|
-
decls.push_back(
|
|
745
|
+
decls.push_back(decl);
|
|
766
746
|
}
|
|
767
747
|
}
|
|
768
748
|
}
|
|
@@ -774,35 +754,22 @@ void LLVMModuleSet::buildGlobalDefToRepMap()
|
|
|
774
754
|
for (Module &mod : modules)
|
|
775
755
|
{
|
|
776
756
|
// Collect ctor and dtor functions
|
|
777
|
-
for (
|
|
757
|
+
for (GlobalVariable& global : mod.globals())
|
|
778
758
|
{
|
|
779
|
-
|
|
780
|
-
if (global->hasPrivateLinkage())
|
|
759
|
+
if (global.hasPrivateLinkage())
|
|
781
760
|
continue;
|
|
782
|
-
string name = global
|
|
761
|
+
string name = global.getName().str();
|
|
783
762
|
if (name.empty())
|
|
784
763
|
continue;
|
|
785
|
-
|
|
786
|
-
if (mit == nameToGlobalsMap.end())
|
|
787
|
-
{
|
|
788
|
-
Set<GlobalVariable*> globals;
|
|
789
|
-
globals.insert(global);
|
|
790
|
-
nameToGlobalsMap[name] = globals;
|
|
791
|
-
}
|
|
792
|
-
else
|
|
793
|
-
{
|
|
794
|
-
Set<GlobalVariable*> &globals = mit->second;
|
|
795
|
-
globals.insert(global);
|
|
796
|
-
}
|
|
764
|
+
nameToGlobalsMap[std::move(name)].insert(&global);
|
|
797
765
|
}
|
|
798
766
|
}
|
|
799
767
|
|
|
800
|
-
for (
|
|
801
|
-
eit = nameToGlobalsMap.end(); it != eit; ++it)
|
|
768
|
+
for (const auto& pair : nameToGlobalsMap)
|
|
802
769
|
{
|
|
803
|
-
Set<GlobalVariable*> &globals =
|
|
770
|
+
const Set<GlobalVariable*> &globals = pair.second;
|
|
804
771
|
|
|
805
|
-
auto repIt =
|
|
772
|
+
const auto repIt =
|
|
806
773
|
std::find_if(globals.begin(), globals.end(),
|
|
807
774
|
[](GlobalVariable* g)
|
|
808
775
|
{
|
|
@@ -815,12 +782,17 @@ void LLVMModuleSet::buildGlobalDefToRepMap()
|
|
|
815
782
|
: (assert(!globals.empty() && "Empty global set"),
|
|
816
783
|
*globals.begin());
|
|
817
784
|
|
|
818
|
-
for (Set<GlobalVariable*>::
|
|
785
|
+
for (Set<GlobalVariable*>::const_iterator sit = globals.begin(),
|
|
819
786
|
seit = globals.end(); sit != seit; ++sit)
|
|
820
787
|
{
|
|
821
788
|
GlobalVariable *cur = *sit;
|
|
822
789
|
GlobalDefToRepMap[cur] = rep;
|
|
823
790
|
}
|
|
791
|
+
|
|
792
|
+
for (const GlobalVariable* cur : globals)
|
|
793
|
+
{
|
|
794
|
+
GlobalDefToRepMap[cur] = rep;
|
|
795
|
+
}
|
|
824
796
|
}
|
|
825
797
|
}
|
|
826
798
|
|
|
@@ -48,7 +48,9 @@ MemObj* SymbolTableBuilder::createBlkObj(SymID symId)
|
|
|
48
48
|
assert(symInfo->isBlkObj(symId));
|
|
49
49
|
assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
|
|
50
50
|
LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet();
|
|
51
|
-
MemObj* obj =
|
|
51
|
+
MemObj* obj =
|
|
52
|
+
new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
|
|
53
|
+
IntegerType::get(llvmset->getContext(), 32))));
|
|
52
54
|
symInfo->objMap[symId] = obj;
|
|
53
55
|
return obj;
|
|
54
56
|
}
|
|
@@ -58,7 +60,9 @@ MemObj* SymbolTableBuilder::createConstantObj(SymID symId)
|
|
|
58
60
|
assert(symInfo->isConstantObj(symId));
|
|
59
61
|
assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
|
|
60
62
|
LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet();
|
|
61
|
-
MemObj* obj =
|
|
63
|
+
MemObj* obj =
|
|
64
|
+
new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
|
|
65
|
+
IntegerType::get(llvmset->getContext(), 32))));
|
|
62
66
|
symInfo->objMap[symId] = obj;
|
|
63
67
|
return obj;
|
|
64
68
|
}
|
|
@@ -90,64 +94,63 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule)
|
|
|
90
94
|
for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
|
|
91
95
|
{
|
|
92
96
|
// Add symbols for all the globals .
|
|
93
|
-
for (
|
|
97
|
+
for (const GlobalVariable& gv : M.globals())
|
|
94
98
|
{
|
|
95
|
-
collectSym(
|
|
99
|
+
collectSym(&gv);
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
// Add symbols for all the global aliases
|
|
99
|
-
for (
|
|
103
|
+
for (const GlobalAlias& ga : M.aliases())
|
|
100
104
|
{
|
|
101
|
-
collectSym(
|
|
102
|
-
collectSym(
|
|
105
|
+
collectSym(&ga);
|
|
106
|
+
collectSym(ga.getAliasee());
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
// Add symbols for all of the functions and the instructions in them.
|
|
106
|
-
for (
|
|
110
|
+
for (const Function& fun : M.functions())
|
|
107
111
|
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
collectVararg(fun);
|
|
112
|
+
collectSym(&fun);
|
|
113
|
+
collectRet(&fun);
|
|
114
|
+
if (fun.getFunctionType()->isVarArg())
|
|
115
|
+
collectVararg(&fun);
|
|
113
116
|
|
|
114
117
|
// Add symbols for all formal parameters.
|
|
115
|
-
for (
|
|
116
|
-
I != E; ++I)
|
|
118
|
+
for (const Argument& arg : fun.args())
|
|
117
119
|
{
|
|
118
|
-
collectSym(
|
|
120
|
+
collectSym(&arg);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
// collect and create symbols inside the function body
|
|
122
|
-
for (
|
|
124
|
+
for (const Instruction& inst : instructions(fun))
|
|
123
125
|
{
|
|
124
|
-
|
|
125
|
-
collectSym(inst);
|
|
126
|
+
collectSym(&inst);
|
|
126
127
|
|
|
127
128
|
// initialization for some special instructions
|
|
128
129
|
//{@
|
|
129
|
-
if (const StoreInst
|
|
130
|
+
if (const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
|
|
130
131
|
{
|
|
131
132
|
collectSym(st->getPointerOperand());
|
|
132
133
|
collectSym(st->getValueOperand());
|
|
133
134
|
}
|
|
134
|
-
else if (const LoadInst
|
|
135
|
+
else if (const LoadInst* ld =
|
|
136
|
+
SVFUtil::dyn_cast<LoadInst>(&inst))
|
|
135
137
|
{
|
|
136
138
|
collectSym(ld->getPointerOperand());
|
|
137
139
|
}
|
|
138
|
-
else if (const AllocaInst
|
|
140
|
+
else if (const AllocaInst* alloc =
|
|
141
|
+
SVFUtil::dyn_cast<AllocaInst>(&inst))
|
|
139
142
|
{
|
|
140
143
|
collectSym(alloc->getArraySize());
|
|
141
144
|
}
|
|
142
|
-
else if (const PHINode
|
|
145
|
+
else if (const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
|
|
143
146
|
{
|
|
144
147
|
for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
|
|
145
148
|
{
|
|
146
149
|
collectSym(phi->getIncomingValue(i));
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
|
-
else if (const GetElementPtrInst
|
|
150
|
-
|
|
152
|
+
else if (const GetElementPtrInst* gep =
|
|
153
|
+
SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
|
|
151
154
|
{
|
|
152
155
|
collectSym(gep->getPointerOperand());
|
|
153
156
|
for (u32_t i = 0; i < gep->getNumOperands(); ++i)
|
|
@@ -155,61 +158,67 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule)
|
|
|
155
158
|
collectSym(gep->getOperand(i));
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
|
-
else if (const SelectInst
|
|
161
|
+
else if (const SelectInst* sel =
|
|
162
|
+
SVFUtil::dyn_cast<SelectInst>(&inst))
|
|
159
163
|
{
|
|
160
164
|
collectSym(sel->getTrueValue());
|
|
161
165
|
collectSym(sel->getFalseValue());
|
|
162
166
|
collectSym(sel->getCondition());
|
|
163
167
|
}
|
|
164
|
-
else if (const BinaryOperator
|
|
168
|
+
else if (const BinaryOperator* binary =
|
|
169
|
+
SVFUtil::dyn_cast<BinaryOperator>(&inst))
|
|
165
170
|
{
|
|
166
171
|
for (u32_t i = 0; i < binary->getNumOperands(); i++)
|
|
167
172
|
collectSym(binary->getOperand(i));
|
|
168
173
|
}
|
|
169
|
-
else if (const UnaryOperator
|
|
174
|
+
else if (const UnaryOperator* unary =
|
|
175
|
+
SVFUtil::dyn_cast<UnaryOperator>(&inst))
|
|
170
176
|
{
|
|
171
177
|
for (u32_t i = 0; i < unary->getNumOperands(); i++)
|
|
172
178
|
collectSym(unary->getOperand(i));
|
|
173
179
|
}
|
|
174
|
-
else if (const CmpInst
|
|
180
|
+
else if (const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
|
|
175
181
|
{
|
|
176
182
|
for (u32_t i = 0; i < cmp->getNumOperands(); i++)
|
|
177
183
|
collectSym(cmp->getOperand(i));
|
|
178
184
|
}
|
|
179
|
-
else if (const CastInst
|
|
185
|
+
else if (const CastInst* cast =
|
|
186
|
+
SVFUtil::dyn_cast<CastInst>(&inst))
|
|
180
187
|
{
|
|
181
188
|
collectSym(cast->getOperand(0));
|
|
182
189
|
}
|
|
183
|
-
else if (const ReturnInst
|
|
190
|
+
else if (const ReturnInst* ret =
|
|
191
|
+
SVFUtil::dyn_cast<ReturnInst>(&inst))
|
|
184
192
|
{
|
|
185
|
-
if(ret->getReturnValue())
|
|
193
|
+
if (ret->getReturnValue())
|
|
186
194
|
collectSym(ret->getReturnValue());
|
|
187
195
|
}
|
|
188
|
-
else if (const BranchInst
|
|
196
|
+
else if (const BranchInst* br =
|
|
197
|
+
SVFUtil::dyn_cast<BranchInst>(&inst))
|
|
189
198
|
{
|
|
190
199
|
Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
|
|
191
200
|
collectSym(opnd);
|
|
192
201
|
}
|
|
193
|
-
else if (const SwitchInst
|
|
202
|
+
else if (const SwitchInst* sw =
|
|
203
|
+
SVFUtil::dyn_cast<SwitchInst>(&inst))
|
|
194
204
|
{
|
|
195
205
|
collectSym(sw->getCondition());
|
|
196
206
|
}
|
|
197
|
-
else if (isNonInstricCallSite(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(inst)))
|
|
207
|
+
else if (isNonInstricCallSite(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&inst)))
|
|
198
208
|
{
|
|
199
209
|
|
|
200
|
-
const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
|
|
210
|
+
const CallBase* cs = LLVMUtil::getLLVMCallSite(&inst);
|
|
201
211
|
for (u32_t i = 0; i < cs->arg_size(); i++)
|
|
202
212
|
{
|
|
203
213
|
collectSym(cs->getArgOperand(i));
|
|
204
214
|
}
|
|
205
|
-
// Calls to inline asm need to be added as well because the
|
|
206
|
-
// referenced anywhere else.
|
|
207
|
-
const Value
|
|
215
|
+
// Calls to inline asm need to be added as well because the
|
|
216
|
+
// callee isn't referenced anywhere else.
|
|
217
|
+
const Value* Callee = cs->getCalledOperand();
|
|
208
218
|
collectSym(Callee);
|
|
209
219
|
|
|
210
|
-
//TODO handle inlineAsm
|
|
211
|
-
///if (SVFUtil::isa<InlineAsm>(Callee))
|
|
212
|
-
|
|
220
|
+
// TODO handle inlineAsm
|
|
221
|
+
/// if (SVFUtil::isa<InlineAsm>(Callee))
|
|
213
222
|
}
|
|
214
223
|
//@}
|
|
215
224
|
}
|
|
@@ -233,7 +242,9 @@ void SymbolTableBuilder::collectSVFTypeInfo(const Value* val)
|
|
|
233
242
|
}
|
|
234
243
|
if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
|
|
235
244
|
{
|
|
236
|
-
for (bridge_gep_iterator
|
|
245
|
+
for (bridge_gep_iterator
|
|
246
|
+
gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
|
|
247
|
+
ge = bridge_gep_end(SVFUtil::cast<User>(val));
|
|
237
248
|
gi != ge; ++gi)
|
|
238
249
|
{
|
|
239
250
|
const Type* gepTy = *gi;
|
|
@@ -245,12 +256,16 @@ void SymbolTableBuilder::collectSVFTypeInfo(const Value* val)
|
|
|
245
256
|
/*!
|
|
246
257
|
* Collect symbols, including value and object syms
|
|
247
258
|
*/
|
|
248
|
-
void SymbolTableBuilder::collectSym(const Value
|
|
259
|
+
void SymbolTableBuilder::collectSym(const Value* val)
|
|
249
260
|
{
|
|
250
261
|
|
|
251
262
|
//TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
|
|
252
263
|
|
|
253
|
-
DBOUT(DMemModel,
|
|
264
|
+
DBOUT(DMemModel,
|
|
265
|
+
outs()
|
|
266
|
+
<< "collect sym from ##"
|
|
267
|
+
<< LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->toString()
|
|
268
|
+
<< " \n");
|
|
254
269
|
//TODO handle constant expression value here??
|
|
255
270
|
handleCE(val);
|
|
256
271
|
|
|
@@ -270,14 +285,15 @@ void SymbolTableBuilder::collectSym(const Value *val)
|
|
|
270
285
|
/*!
|
|
271
286
|
* Get value sym, if not available create a new one
|
|
272
287
|
*/
|
|
273
|
-
void SymbolTableBuilder::collectVal(const Value
|
|
288
|
+
void SymbolTableBuilder::collectVal(const Value* val)
|
|
274
289
|
{
|
|
275
290
|
// collect and record special sym here
|
|
276
291
|
if (LLVMUtil::isNullPtrSym(val) || LLVMUtil::isBlackholeSym(val))
|
|
277
292
|
{
|
|
278
293
|
return;
|
|
279
294
|
}
|
|
280
|
-
SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find(
|
|
295
|
+
SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find(
|
|
296
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val));
|
|
281
297
|
if (iter == symInfo->valSymMap.end())
|
|
282
298
|
{
|
|
283
299
|
// create val sym and sym type
|
|
@@ -298,10 +314,11 @@ void SymbolTableBuilder::collectVal(const Value *val)
|
|
|
298
314
|
/*!
|
|
299
315
|
* Get memory object sym, if not available create a new one
|
|
300
316
|
*/
|
|
301
|
-
void SymbolTableBuilder::collectObj(const Value
|
|
317
|
+
void SymbolTableBuilder::collectObj(const Value* val)
|
|
302
318
|
{
|
|
303
319
|
val = LLVMUtil::getGlobalRep(val);
|
|
304
|
-
SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find(
|
|
320
|
+
SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find(
|
|
321
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val));
|
|
305
322
|
if (iter == symInfo->objSymMap.end())
|
|
306
323
|
{
|
|
307
324
|
SVFValue* svfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val);
|
|
@@ -321,7 +338,9 @@ void SymbolTableBuilder::collectObj(const Value *val)
|
|
|
321
338
|
outs() << "create a new obj sym " << id << "\n");
|
|
322
339
|
|
|
323
340
|
// create a memory object
|
|
324
|
-
MemObj* mem =
|
|
341
|
+
MemObj* mem =
|
|
342
|
+
new MemObj(id, createObjTypeInfo(val),
|
|
343
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val));
|
|
325
344
|
assert(symInfo->objMap.find(id) == symInfo->objMap.end());
|
|
326
345
|
symInfo->objMap[id] = mem;
|
|
327
346
|
}
|
|
@@ -331,47 +350,51 @@ void SymbolTableBuilder::collectObj(const Value *val)
|
|
|
331
350
|
/*!
|
|
332
351
|
* Create unique return sym, if not available create a new one
|
|
333
352
|
*/
|
|
334
|
-
void SymbolTableBuilder::collectRet(const Function
|
|
353
|
+
void SymbolTableBuilder::collectRet(const Function* val)
|
|
335
354
|
{
|
|
336
|
-
const SVFFunction* svffun =
|
|
337
|
-
|
|
355
|
+
const SVFFunction* svffun =
|
|
356
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val);
|
|
357
|
+
SymbolTableInfo::FunToIDMapTy::iterator iter =
|
|
358
|
+
symInfo->returnSymMap.find(svffun);
|
|
338
359
|
if (iter == symInfo->returnSymMap.end())
|
|
339
360
|
{
|
|
340
361
|
SymID id = NodeIDAllocator::get()->allocateValueId();
|
|
341
362
|
symInfo->returnSymMap.insert(std::make_pair(svffun, id));
|
|
342
|
-
DBOUT(DMemModel,
|
|
343
|
-
outs() << "create a return sym " << id << "\n");
|
|
363
|
+
DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
|
|
344
364
|
}
|
|
345
365
|
}
|
|
346
366
|
|
|
347
367
|
/*!
|
|
348
368
|
* Create vararg sym, if not available create a new one
|
|
349
369
|
*/
|
|
350
|
-
void SymbolTableBuilder::collectVararg(const Function
|
|
370
|
+
void SymbolTableBuilder::collectVararg(const Function* val)
|
|
351
371
|
{
|
|
352
|
-
const SVFFunction* svffun =
|
|
353
|
-
|
|
372
|
+
const SVFFunction* svffun =
|
|
373
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val);
|
|
374
|
+
SymbolTableInfo::FunToIDMapTy::iterator iter =
|
|
375
|
+
symInfo->varargSymMap.find(svffun);
|
|
354
376
|
if (iter == symInfo->varargSymMap.end())
|
|
355
377
|
{
|
|
356
378
|
SymID id = NodeIDAllocator::get()->allocateValueId();
|
|
357
379
|
symInfo->varargSymMap.insert(std::make_pair(svffun, id));
|
|
358
|
-
DBOUT(DMemModel,
|
|
359
|
-
outs() << "create a vararg sym " << id << "\n");
|
|
380
|
+
DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
|
|
360
381
|
}
|
|
361
382
|
}
|
|
362
383
|
|
|
363
|
-
|
|
364
384
|
/*!
|
|
365
385
|
* Handle constant expression
|
|
366
386
|
*/
|
|
367
|
-
void SymbolTableBuilder::handleCE(const Value
|
|
387
|
+
void SymbolTableBuilder::handleCE(const Value* val)
|
|
368
388
|
{
|
|
369
389
|
if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
|
|
370
390
|
{
|
|
371
391
|
if (const ConstantExpr* ce = isGepConstantExpr(ref))
|
|
372
392
|
{
|
|
373
|
-
DBOUT(DMemModelCE,
|
|
374
|
-
|
|
393
|
+
DBOUT(DMemModelCE, outs() << "handle constant expression "
|
|
394
|
+
<< LLVMModuleSet::getLLVMModuleSet()
|
|
395
|
+
->getSVFValue(ref)
|
|
396
|
+
->toString()
|
|
397
|
+
<< "\n");
|
|
375
398
|
collectVal(ce);
|
|
376
399
|
|
|
377
400
|
// handle the recursive constant express case
|
|
@@ -384,8 +407,11 @@ void SymbolTableBuilder::handleCE(const Value *val)
|
|
|
384
407
|
}
|
|
385
408
|
else if (const ConstantExpr* ce = isCastConstantExpr(ref))
|
|
386
409
|
{
|
|
387
|
-
DBOUT(DMemModelCE,
|
|
388
|
-
|
|
410
|
+
DBOUT(DMemModelCE, outs() << "handle constant expression "
|
|
411
|
+
<< LLVMModuleSet::getLLVMModuleSet()
|
|
412
|
+
->getSVFValue(ref)
|
|
413
|
+
->toString()
|
|
414
|
+
<< "\n");
|
|
389
415
|
collectVal(ce);
|
|
390
416
|
collectVal(ce->getOperand(0));
|
|
391
417
|
// handle the recursive constant express case
|
|
@@ -394,8 +420,11 @@ void SymbolTableBuilder::handleCE(const Value *val)
|
|
|
394
420
|
}
|
|
395
421
|
else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
|
|
396
422
|
{
|
|
397
|
-
DBOUT(DMemModelCE,
|
|
398
|
-
|
|
423
|
+
DBOUT(DMemModelCE, outs() << "handle constant expression "
|
|
424
|
+
<< LLVMModuleSet::getLLVMModuleSet()
|
|
425
|
+
->getSVFValue(ref)
|
|
426
|
+
->toString()
|
|
427
|
+
<< "\n");
|
|
399
428
|
collectVal(ce);
|
|
400
429
|
collectVal(ce->getOperand(0));
|
|
401
430
|
collectVal(ce->getOperand(1));
|
|
@@ -407,14 +436,14 @@ void SymbolTableBuilder::handleCE(const Value *val)
|
|
|
407
436
|
handleCE(ce->getOperand(2));
|
|
408
437
|
}
|
|
409
438
|
// if we meet a int2ptr, then it points-to black hole
|
|
410
|
-
else if (const ConstantExpr
|
|
439
|
+
else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref))
|
|
411
440
|
{
|
|
412
441
|
collectVal(int2Ptrce);
|
|
413
442
|
}
|
|
414
|
-
else if (const ConstantExpr
|
|
443
|
+
else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref))
|
|
415
444
|
{
|
|
416
445
|
collectVal(ptr2Intce);
|
|
417
|
-
const Constant
|
|
446
|
+
const Constant* opnd = ptr2Intce->getOperand(0);
|
|
418
447
|
handleCE(opnd);
|
|
419
448
|
}
|
|
420
449
|
else if (isTruncConstantExpr(ref) || isCmpConstantExpr(ref))
|
|
@@ -437,8 +466,8 @@ void SymbolTableBuilder::handleCE(const Value *val)
|
|
|
437
466
|
}
|
|
438
467
|
else
|
|
439
468
|
{
|
|
440
|
-
|
|
441
|
-
|
|
469
|
+
assert(!SVFUtil::isa<ConstantExpr>(val) &&
|
|
470
|
+
"we don't handle all other constant expression for now!");
|
|
442
471
|
collectVal(ref);
|
|
443
472
|
}
|
|
444
473
|
}
|
|
@@ -447,7 +476,7 @@ void SymbolTableBuilder::handleCE(const Value *val)
|
|
|
447
476
|
/*!
|
|
448
477
|
* Handle global constant expression
|
|
449
478
|
*/
|
|
450
|
-
void SymbolTableBuilder::handleGlobalCE(const GlobalVariable
|
|
479
|
+
void SymbolTableBuilder::handleGlobalCE(const GlobalVariable* G)
|
|
451
480
|
{
|
|
452
481
|
assert(G);
|
|
453
482
|
|
|
@@ -455,30 +484,25 @@ void SymbolTableBuilder::handleGlobalCE(const GlobalVariable *G)
|
|
|
455
484
|
const Type* T = G->getValueType();
|
|
456
485
|
bool is_array = 0;
|
|
457
486
|
//An array is considered a single variable of its type.
|
|
458
|
-
while (const ArrayType
|
|
487
|
+
while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
|
|
459
488
|
{
|
|
460
489
|
T = AT->getElementType();
|
|
461
|
-
is_array =
|
|
490
|
+
is_array = true;
|
|
462
491
|
}
|
|
463
492
|
|
|
464
493
|
if (SVFUtil::isa<StructType>(T))
|
|
465
494
|
{
|
|
466
495
|
//A struct may be used in constant GEP expr.
|
|
467
|
-
for (
|
|
468
|
-
it != ie; ++it)
|
|
496
|
+
for (const User* user : G->users())
|
|
469
497
|
{
|
|
470
|
-
handleCE(
|
|
498
|
+
handleCE(user);
|
|
471
499
|
}
|
|
472
500
|
}
|
|
473
|
-
else
|
|
501
|
+
else if (is_array)
|
|
474
502
|
{
|
|
475
|
-
|
|
503
|
+
for (const User* user : G->users())
|
|
476
504
|
{
|
|
477
|
-
|
|
478
|
-
G->user_end(); it != ie; ++it)
|
|
479
|
-
{
|
|
480
|
-
handleCE(*it);
|
|
481
|
-
}
|
|
505
|
+
handleCE(user);
|
|
482
506
|
}
|
|
483
507
|
}
|
|
484
508
|
|
|
@@ -491,12 +515,12 @@ void SymbolTableBuilder::handleGlobalCE(const GlobalVariable *G)
|
|
|
491
515
|
/*!
|
|
492
516
|
* Handle global variable initialization
|
|
493
517
|
*/
|
|
494
|
-
void SymbolTableBuilder::handleGlobalInitializerCE(const Constant
|
|
518
|
+
void SymbolTableBuilder::handleGlobalInitializerCE(const Constant* C)
|
|
495
519
|
{
|
|
496
520
|
|
|
497
521
|
if (C->getType()->isSingleValueType())
|
|
498
522
|
{
|
|
499
|
-
if (const ConstantExpr
|
|
523
|
+
if (const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
|
|
500
524
|
{
|
|
501
525
|
handleCE(E);
|
|
502
526
|
}
|
|
@@ -521,9 +545,10 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant *C)
|
|
|
521
545
|
}
|
|
522
546
|
else if(const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
|
|
523
547
|
{
|
|
524
|
-
if(Options::ModelConsts())
|
|
548
|
+
if (Options::ModelConsts())
|
|
525
549
|
{
|
|
526
|
-
if(const ConstantDataSequential* seq =
|
|
550
|
+
if (const ConstantDataSequential* seq =
|
|
551
|
+
SVFUtil::dyn_cast<ConstantDataSequential>(data))
|
|
527
552
|
{
|
|
528
553
|
for(u32_t i = 0; i < seq->getNumElements(); i++)
|
|
529
554
|
{
|
|
@@ -533,8 +558,9 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant *C)
|
|
|
533
558
|
}
|
|
534
559
|
else
|
|
535
560
|
{
|
|
536
|
-
assert(
|
|
537
|
-
|
|
561
|
+
assert(
|
|
562
|
+
(SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
|
|
563
|
+
"Single value type data should have been handled!");
|
|
538
564
|
}
|
|
539
565
|
}
|
|
540
566
|
}
|
|
@@ -547,9 +573,9 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant *C)
|
|
|
547
573
|
/*
|
|
548
574
|
* Initial the memory object here
|
|
549
575
|
*/
|
|
550
|
-
ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value
|
|
576
|
+
ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val)
|
|
551
577
|
{
|
|
552
|
-
const PointerType
|
|
578
|
+
const PointerType* refTy = nullptr;
|
|
553
579
|
|
|
554
580
|
const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
|
|
555
581
|
|
|
@@ -566,7 +592,9 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value *val)
|
|
|
566
592
|
if (refTy)
|
|
567
593
|
{
|
|
568
594
|
Type* objTy = getPtrElementType(refTy);
|
|
569
|
-
ObjTypeInfo* typeInfo = new ObjTypeInfo(
|
|
595
|
+
ObjTypeInfo* typeInfo = new ObjTypeInfo(
|
|
596
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFType(objTy),
|
|
597
|
+
Options::MaxFieldLimit());
|
|
570
598
|
initTypeInfo(typeInfo,val, objTy);
|
|
571
599
|
return typeInfo;
|
|
572
600
|
}
|
|
@@ -575,9 +603,11 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value *val)
|
|
|
575
603
|
writeWrnMsg("try to create an object with a non-pointer type.");
|
|
576
604
|
writeWrnMsg(val->getName().str());
|
|
577
605
|
writeWrnMsg("(" + LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->getSourceLoc() + ")");
|
|
578
|
-
if(isConstantObjSym(val))
|
|
606
|
+
if (isConstantObjSym(val))
|
|
579
607
|
{
|
|
580
|
-
ObjTypeInfo* typeInfo = new ObjTypeInfo(
|
|
608
|
+
ObjTypeInfo* typeInfo = new ObjTypeInfo(
|
|
609
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFType(val->getType()),
|
|
610
|
+
0);
|
|
581
611
|
initTypeInfo(typeInfo,val, val->getType());
|
|
582
612
|
return typeInfo;
|
|
583
613
|
}
|
|
@@ -595,33 +625,37 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value *val)
|
|
|
595
625
|
void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val)
|
|
596
626
|
{
|
|
597
627
|
|
|
598
|
-
const PointerType
|
|
628
|
+
const PointerType* refty = SVFUtil::dyn_cast<PointerType>(val->getType());
|
|
599
629
|
assert(refty && "this value should be a pointer type!");
|
|
600
630
|
Type* elemTy = getPtrElementType(refty);
|
|
601
631
|
bool isPtrObj = false;
|
|
602
632
|
// Find the inter nested array element
|
|
603
|
-
while (const ArrayType
|
|
633
|
+
while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
|
|
604
634
|
{
|
|
605
635
|
elemTy = AT->getElementType();
|
|
606
|
-
if(elemTy->isPointerTy())
|
|
636
|
+
if (elemTy->isPointerTy())
|
|
607
637
|
isPtrObj = true;
|
|
608
|
-
if(SVFUtil::isa<GlobalVariable>(val) &&
|
|
609
|
-
|
|
638
|
+
if (SVFUtil::isa<GlobalVariable>(val) &&
|
|
639
|
+
SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
|
|
640
|
+
SVFUtil::isa<ConstantArray>(
|
|
641
|
+
SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
|
|
610
642
|
typeinfo->setFlag(ObjTypeInfo::CONST_ARRAY_OBJ);
|
|
611
643
|
else
|
|
612
644
|
typeinfo->setFlag(ObjTypeInfo::VAR_ARRAY_OBJ);
|
|
613
645
|
}
|
|
614
|
-
if (const StructType
|
|
646
|
+
if (const StructType* ST = SVFUtil::dyn_cast<StructType>(elemTy))
|
|
615
647
|
{
|
|
616
|
-
const std::vector<const SVFType*>& flattenFields =
|
|
617
|
-
|
|
618
|
-
|
|
648
|
+
const std::vector<const SVFType*>& flattenFields =
|
|
649
|
+
getOrAddSVFTypeInfo(ST)->getFlattenFieldTypes();
|
|
650
|
+
isPtrObj |= std::any_of(flattenFields.begin(), flattenFields.end(),
|
|
651
|
+
[](const SVFType* ty)
|
|
619
652
|
{
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
653
|
+
return ty->isPointerTy();
|
|
654
|
+
});
|
|
655
|
+
if (SVFUtil::isa<GlobalVariable>(val) &&
|
|
656
|
+
SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
|
|
657
|
+
SVFUtil::isa<ConstantStruct>(
|
|
658
|
+
SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
|
|
625
659
|
typeinfo->setFlag(ObjTypeInfo::CONST_STRUCT_OBJ);
|
|
626
660
|
else
|
|
627
661
|
typeinfo->setFlag(ObjTypeInfo::VAR_STRUCT_OBJ);
|
|
@@ -643,7 +677,8 @@ void SymbolTableBuilder::analyzeHeapObjType(ObjTypeInfo* typeinfo, const Value*
|
|
|
643
677
|
if(const Value* castUse = getUniqueUseViaCastInst(val))
|
|
644
678
|
{
|
|
645
679
|
typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ);
|
|
646
|
-
typeinfo->resetTypeForHeapStaticObj(
|
|
680
|
+
typeinfo->resetTypeForHeapStaticObj(
|
|
681
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFType(castUse->getType()));
|
|
647
682
|
analyzeObjType(typeinfo,castUse);
|
|
648
683
|
}
|
|
649
684
|
else
|
|
@@ -661,7 +696,8 @@ void SymbolTableBuilder::analyzeStaticObjType(ObjTypeInfo* typeinfo, const Value
|
|
|
661
696
|
if(const Value* castUse = getUniqueUseViaCastInst(val))
|
|
662
697
|
{
|
|
663
698
|
typeinfo->setFlag(ObjTypeInfo::STATIC_OBJ);
|
|
664
|
-
typeinfo->resetTypeForHeapStaticObj(
|
|
699
|
+
typeinfo->resetTypeForHeapStaticObj(
|
|
700
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFType(castUse->getType()));
|
|
665
701
|
analyzeObjType(typeinfo,castUse);
|
|
666
702
|
}
|
|
667
703
|
else
|
|
@@ -674,7 +710,8 @@ void SymbolTableBuilder::analyzeStaticObjType(ObjTypeInfo* typeinfo, const Value
|
|
|
674
710
|
/*!
|
|
675
711
|
* Initialize the type info of an object
|
|
676
712
|
*/
|
|
677
|
-
void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
|
|
713
|
+
void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
|
|
714
|
+
const Type* objTy)
|
|
678
715
|
{
|
|
679
716
|
|
|
680
717
|
u32_t objSize = 1;
|
|
@@ -704,13 +741,19 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, c
|
|
|
704
741
|
analyzeObjType(typeinfo,val);
|
|
705
742
|
objSize = getObjSize(objTy);
|
|
706
743
|
}
|
|
707
|
-
else if (SVFUtil::isa<Instruction>(val) &&
|
|
744
|
+
else if (SVFUtil::isa<Instruction>(val) &&
|
|
745
|
+
isHeapAllocExtCall(
|
|
746
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(
|
|
747
|
+
SVFUtil::cast<Instruction>(val))))
|
|
708
748
|
{
|
|
709
749
|
analyzeHeapObjType(typeinfo,val);
|
|
710
750
|
// Heap object, label its field as infinite here
|
|
711
751
|
objSize = typeinfo->getMaxFieldOffsetLimit();
|
|
712
752
|
}
|
|
713
|
-
else if (SVFUtil::isa<Instruction>(val) &&
|
|
753
|
+
else if (SVFUtil::isa<Instruction>(val) &&
|
|
754
|
+
isStaticExtCall(
|
|
755
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(
|
|
756
|
+
SVFUtil::cast<Instruction>(val))))
|
|
714
757
|
{
|
|
715
758
|
analyzeStaticObjType(typeinfo,val);
|
|
716
759
|
// static object allocated before main, label its field as infinite here
|