arkanalyzer 1.0.39 → 1.0.41
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/config/arkanalyzer.json +6 -2
- package/lib/Config.d.ts +1 -0
- package/lib/Config.d.ts.map +1 -1
- package/lib/Scene.d.ts +6 -5
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +36 -18
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +3 -4
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +7 -8
- package/lib/callgraph/model/CallGraph.d.ts +5 -5
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
- package/lib/callgraph/model/CallGraph.js +18 -21
- package/lib/callgraph/model/CallSite.d.ts +16 -6
- package/lib/callgraph/model/CallSite.d.ts.map +1 -1
- package/lib/callgraph/model/CallSite.js +48 -8
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +0 -1
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts.map +1 -1
- package/lib/callgraph/model/builder/CallGraphBuilder.js +0 -8
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +3 -6
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +6 -29
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +6 -15
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +61 -85
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +2 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +12 -8
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts +10 -3
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.js +20 -5
- package/lib/callgraph/pointerAnalysis/context/Context.d.ts +69 -0
- package/lib/callgraph/pointerAnalysis/context/Context.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/context/Context.js +202 -0
- package/lib/callgraph/pointerAnalysis/context/ContextItem.d.ts +40 -0
- package/lib/callgraph/pointerAnalysis/context/ContextItem.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/context/ContextItem.js +99 -0
- package/lib/callgraph/pointerAnalysis/context/ContextSelector.d.ts +46 -0
- package/lib/callgraph/pointerAnalysis/context/ContextSelector.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/context/ContextSelector.js +138 -0
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +11 -1
- package/lib/core/base/Local.js +1 -1
- package/lib/core/common/ArkIRTransformer.d.ts +2 -0
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +90 -0
- package/lib/core/common/ArkValueTransformer.d.ts +1 -1
- package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkValueTransformer.js +48 -33
- package/lib/core/common/Builtin.d.ts.map +1 -1
- package/lib/core/common/Builtin.js +2 -2
- package/lib/core/common/DummyMainCreater.js +1 -1
- package/lib/core/common/IRInference.d.ts +1 -0
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +60 -44
- package/lib/core/common/ModelUtils.d.ts +1 -0
- package/lib/core/common/ModelUtils.d.ts.map +1 -1
- package/lib/core/common/ModelUtils.js +7 -0
- package/lib/core/common/SdkUtils.d.ts +14 -1
- package/lib/core/common/SdkUtils.d.ts.map +1 -1
- package/lib/core/common/SdkUtils.js +118 -24
- package/lib/core/common/TypeInference.d.ts +2 -1
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +21 -12
- package/lib/core/common/ValueUtil.d.ts +1 -0
- package/lib/core/common/ValueUtil.d.ts.map +1 -1
- package/lib/core/common/ValueUtil.js +7 -0
- package/lib/core/graph/BaseExplicitGraph.d.ts +1 -0
- package/lib/core/graph/BaseExplicitGraph.d.ts.map +1 -1
- package/lib/core/graph/BaseExplicitGraph.js +3 -0
- package/lib/core/graph/Scc.js +1 -1
- package/lib/core/graph/builder/CfgBuilder.d.ts +2 -0
- package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/CfgBuilder.js +59 -7
- package/lib/core/model/ArkImport.js +1 -1
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +8 -2
- package/lib/core/model/builder/ArkClassBuilder.js +21 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +2 -2
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +2 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -4
- package/lib/save/JsonPrinter.d.ts +1 -0
- package/lib/save/JsonPrinter.d.ts.map +1 -1
- package/lib/save/JsonPrinter.js +15 -5
- package/lib/save/arkir/ArkIRMethodPrinter.d.ts.map +1 -1
- package/lib/save/arkir/ArkIRMethodPrinter.js +13 -5
- package/lib/save/source/SourceBody.d.ts +1 -1
- package/lib/save/source/SourceBody.d.ts.map +1 -1
- package/lib/save/source/SourceBody.js +3 -2
- package/lib/save/source/SourceStmt.d.ts.map +1 -1
- package/lib/save/source/SourceStmt.js +12 -4
- package/lib/save/source/SourceTransformer.d.ts +3 -3
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +11 -10
- package/lib/transformer/StaticSingleAssignmentFormer.js +1 -1
- package/package.json +7 -7
- package/lib/callgraph/pointerAnalysis/Context.d.ts +0 -38
- package/lib/callgraph/pointerAnalysis/Context.d.ts.map +0 -1
- package/lib/callgraph/pointerAnalysis/Context.js +0 -154
|
@@ -47,11 +47,12 @@ const Local_1 = require("../../core/base/Local");
|
|
|
47
47
|
const Type_1 = require("../../core/base/Type");
|
|
48
48
|
const Constant_1 = require("../../core/base/Constant");
|
|
49
49
|
const Statistics_1 = require("../common/Statistics");
|
|
50
|
-
const Context_1 = require("./Context");
|
|
51
50
|
const Pag_1 = require("./Pag");
|
|
52
51
|
const TSConst_1 = require("../../core/common/TSConst");
|
|
53
52
|
const PTAUtils_1 = require("./PTAUtils");
|
|
54
53
|
const PointerAnalysisConfig_1 = require("./PointerAnalysisConfig");
|
|
54
|
+
const Context_1 = require("./context/Context");
|
|
55
|
+
const ContextSelector_1 = require("./context/ContextSelector");
|
|
55
56
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
|
|
56
57
|
class CSFuncID {
|
|
57
58
|
constructor(cid, fid) {
|
|
@@ -61,15 +62,12 @@ class CSFuncID {
|
|
|
61
62
|
}
|
|
62
63
|
exports.CSFuncID = CSFuncID;
|
|
63
64
|
class PagBuilder {
|
|
64
|
-
constructor(p, cg, s,
|
|
65
|
+
constructor(p, cg, s, config) {
|
|
65
66
|
this.handledFunc = new Set();
|
|
66
67
|
this.worklist = [];
|
|
67
68
|
// TODO: change string to hash value
|
|
68
69
|
this.staticField2UniqInstanceMap = new Map();
|
|
69
70
|
this.instanceField2UniqInstanceMap = new Map();
|
|
70
|
-
this.cid2ThisRefPtMap = new Map();
|
|
71
|
-
this.cid2ThisRefMap = new Map();
|
|
72
|
-
this.cid2ThisLocalMap = new Map();
|
|
73
71
|
this.sdkMethodReturnValueMap = new Map();
|
|
74
72
|
// record the SDK API param, and create fake Values
|
|
75
73
|
this.methodParamValueMap = new Map();
|
|
@@ -83,11 +81,25 @@ class PagBuilder {
|
|
|
83
81
|
this.retriggerNodesList = new Set();
|
|
84
82
|
this.pag = p;
|
|
85
83
|
this.cg = cg;
|
|
86
|
-
this.scale =
|
|
84
|
+
this.scale = config.analysisScale;
|
|
87
85
|
this.funcPags = new Map();
|
|
88
|
-
this.ctx = new Context_1.KLimitedContextSensitive(kLimit);
|
|
89
86
|
this.scene = s;
|
|
90
87
|
this.pagStat = new Statistics_1.PAGStat();
|
|
88
|
+
let kLimit = config.kLimit;
|
|
89
|
+
switch (config.contextType) {
|
|
90
|
+
case PointerAnalysisConfig_1.ContextType.CallSite:
|
|
91
|
+
this.ctxSelector = new ContextSelector_1.KCallSiteContextSelector(kLimit);
|
|
92
|
+
break;
|
|
93
|
+
case PointerAnalysisConfig_1.ContextType.Obj:
|
|
94
|
+
this.ctxSelector = new ContextSelector_1.KObjContextSelector(kLimit);
|
|
95
|
+
break;
|
|
96
|
+
case PointerAnalysisConfig_1.ContextType.Func:
|
|
97
|
+
this.ctxSelector = new ContextSelector_1.KFuncContextSelector(kLimit);
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
this.ctxSelector = new ContextSelector_1.KCallSiteContextSelector(kLimit);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
91
103
|
}
|
|
92
104
|
buildFuncPagAndAddToWorklist(cs) {
|
|
93
105
|
if (this.worklist.includes(cs)) {
|
|
@@ -109,12 +121,12 @@ class PagBuilder {
|
|
|
109
121
|
buildForEntries(funcIDs) {
|
|
110
122
|
this.worklist = [];
|
|
111
123
|
funcIDs.forEach(funcID => {
|
|
112
|
-
let cid = this.
|
|
124
|
+
let cid = this.ctxSelector.emptyContext(funcID);
|
|
113
125
|
let csFuncID = new CSFuncID(cid, funcID);
|
|
114
126
|
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
115
127
|
});
|
|
116
128
|
this.handleReachable();
|
|
117
|
-
this.globalThisPagNode = this.getOrNewGlobalThisNode(
|
|
129
|
+
this.globalThisPagNode = this.getOrNewGlobalThisNode(ContextSelector_1.emptyID);
|
|
118
130
|
this.pag.addPagEdge(this.globalThisPagNode, this.globalThisPagNode, Pag_1.PagEdgeKind.Copy);
|
|
119
131
|
}
|
|
120
132
|
handleReachable() {
|
|
@@ -131,7 +143,7 @@ class PagBuilder {
|
|
|
131
143
|
}
|
|
132
144
|
build() {
|
|
133
145
|
for (let funcID of this.cg.getEntries()) {
|
|
134
|
-
let cid = this.
|
|
146
|
+
let cid = this.ctxSelector.emptyContext(funcID);
|
|
135
147
|
let csFuncID = new CSFuncID(cid, funcID);
|
|
136
148
|
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
137
149
|
this.handleReachable();
|
|
@@ -193,12 +205,12 @@ class PagBuilder {
|
|
|
193
205
|
});
|
|
194
206
|
return;
|
|
195
207
|
}
|
|
196
|
-
let dycs = this.cg.
|
|
208
|
+
let dycs = this.cg.getDynCallSiteByStmt(stmt);
|
|
197
209
|
if (dycs) {
|
|
198
210
|
this.addToDynamicCallSite(fpag, dycs);
|
|
199
211
|
}
|
|
200
212
|
else {
|
|
201
|
-
logger.error(`can not find
|
|
213
|
+
logger.error(`can not find callSite by stmt: ${stmt.toString()}`);
|
|
202
214
|
}
|
|
203
215
|
}
|
|
204
216
|
processExternalScopeValue(value, funcID) {
|
|
@@ -322,9 +334,10 @@ class PagBuilder {
|
|
|
322
334
|
}
|
|
323
335
|
/// add Copy edges interprocedural
|
|
324
336
|
addCallsEdgesFromFuncPag(funcPag, cid) {
|
|
337
|
+
var _a, _b;
|
|
325
338
|
for (let cs of funcPag.getNormalCallSites()) {
|
|
326
339
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
327
|
-
let calleeCid = this.
|
|
340
|
+
let calleeCid = this.ctxSelector.selectContext(cid, cs, ContextSelector_1.emptyID, cs.calleeFuncID);
|
|
328
341
|
let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
|
|
329
342
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
330
343
|
this.addStaticPagCallReturnEdge(cs, cid, calleeCid);
|
|
@@ -338,19 +351,18 @@ class PagBuilder {
|
|
|
338
351
|
if (calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.constructor || calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.intrinsic) {
|
|
339
352
|
let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID));
|
|
340
353
|
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
341
|
-
|
|
342
|
-
let baseNodeID = baseNode.getID();
|
|
343
|
-
this.addThisRefCallEdge(baseNodeID, cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID);
|
|
354
|
+
this.addThisRefCallEdge(cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID);
|
|
344
355
|
}
|
|
345
356
|
else {
|
|
346
357
|
logger.error(`constructor or intrinsic func is static ${ivkExpr.toString()}`);
|
|
347
358
|
}
|
|
348
359
|
}
|
|
360
|
+
this.cg.addDirectOrSpecialCallEdge((_a = this.cg.getArkMethodByFuncID(cs.callerFuncID)) === null || _a === void 0 ? void 0 : _a.getSignature(), (_b = this.cg.getArkMethodByFuncID(cs.calleeFuncID)) === null || _b === void 0 ? void 0 : _b.getSignature(), cs.callStmt);
|
|
349
361
|
}
|
|
350
362
|
return true;
|
|
351
363
|
}
|
|
352
364
|
addDynamicCallSite(funcPag, funcID, cid) {
|
|
353
|
-
// add dyn
|
|
365
|
+
// add dyn callSite in funcpag to base node
|
|
354
366
|
for (let cs of funcPag.getDynamicCallSites()) {
|
|
355
367
|
let invokeExpr = cs.callStmt.getInvokeExpr();
|
|
356
368
|
let base;
|
|
@@ -443,8 +455,8 @@ class PagBuilder {
|
|
|
443
455
|
if (this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
444
456
|
return srcNodes;
|
|
445
457
|
}
|
|
446
|
-
let
|
|
447
|
-
let
|
|
458
|
+
let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
|
|
459
|
+
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
|
|
448
460
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
449
461
|
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, baseClassPTNode, calleeCid));
|
|
450
462
|
continue;
|
|
@@ -522,7 +534,7 @@ class PagBuilder {
|
|
|
522
534
|
srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode));
|
|
523
535
|
// Pass base's pts to callee's this pointer
|
|
524
536
|
if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
525
|
-
let srcBaseNode = this.addThisRefCallEdge(
|
|
537
|
+
let srcBaseNode = this.addThisRefCallEdge(cid, ivkExpr.getBase(), callee, calleeCid, staticCS.callerFuncID);
|
|
526
538
|
if (srcBaseNode !== -1) {
|
|
527
539
|
srcNodes.push(srcBaseNode);
|
|
528
540
|
}
|
|
@@ -536,7 +548,7 @@ class PagBuilder {
|
|
|
536
548
|
if (!(thisValue instanceof Local_1.Local)) {
|
|
537
549
|
return srcNodes;
|
|
538
550
|
}
|
|
539
|
-
this.addThisRefCallEdge(
|
|
551
|
+
this.addThisRefCallEdge(ptNode.getOriginCid(), thisValue, callee, calleeCid, staticCS.callerFuncID);
|
|
540
552
|
}
|
|
541
553
|
return srcNodes;
|
|
542
554
|
}
|
|
@@ -576,7 +588,7 @@ class PagBuilder {
|
|
|
576
588
|
break;
|
|
577
589
|
case PTAUtils_1.BuiltApiType.FunctionBind:
|
|
578
590
|
/**
|
|
579
|
-
* clone the function node and add the this pointer, origin
|
|
591
|
+
* clone the function node and add the this pointer, origin callSite, args offset to it
|
|
580
592
|
* let f = function.bind(thisArg, arg1, arg2, ...)
|
|
581
593
|
* f();
|
|
582
594
|
*/
|
|
@@ -616,7 +628,7 @@ class PagBuilder {
|
|
|
616
628
|
handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
617
629
|
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
618
630
|
srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args, staticCS.callStmt, cid, calleeCid, 1));
|
|
619
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes,
|
|
631
|
+
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
620
632
|
}
|
|
621
633
|
handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
622
634
|
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
@@ -626,7 +638,7 @@ class PagBuilder {
|
|
|
626
638
|
}
|
|
627
639
|
let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args[1]);
|
|
628
640
|
srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0));
|
|
629
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes,
|
|
641
|
+
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
630
642
|
}
|
|
631
643
|
handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes) {
|
|
632
644
|
let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode);
|
|
@@ -641,9 +653,9 @@ class PagBuilder {
|
|
|
641
653
|
srcNode.setArgsOffset(1);
|
|
642
654
|
srcNode.setOriginCid(cid);
|
|
643
655
|
}
|
|
644
|
-
addThisEdge(staticCS, cid, realCallee, srcNodes,
|
|
656
|
+
addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid) {
|
|
645
657
|
if (!(staticCS.args[0] instanceof Constant_1.NullConstant) && !realCallee.isStatic()) {
|
|
646
|
-
let srcNodeID = this.addThisRefCallEdge(
|
|
658
|
+
let srcNodeID = this.addThisRefCallEdge(cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID);
|
|
647
659
|
if (srcNodeID !== -1) {
|
|
648
660
|
srcNodes.push(srcNodeID);
|
|
649
661
|
}
|
|
@@ -701,8 +713,8 @@ class PagBuilder {
|
|
|
701
713
|
logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`);
|
|
702
714
|
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
703
715
|
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
704
|
-
let
|
|
705
|
-
let
|
|
716
|
+
let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
|
|
717
|
+
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, ContextSelector_1.emptyID, staticCS.calleeFuncID);
|
|
706
718
|
let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
|
|
707
719
|
srcNodes.push(...staticSrcNodes);
|
|
708
720
|
}
|
|
@@ -740,8 +752,8 @@ class PagBuilder {
|
|
|
740
752
|
}
|
|
741
753
|
return reAnalyzeNodes;
|
|
742
754
|
}
|
|
743
|
-
addThisRefCallEdge(
|
|
744
|
-
let thisRefNodeID = this.recordThisRefNode(
|
|
755
|
+
addThisRefCallEdge(cid, baseLocal, callee, calleeCid, callerFunID) {
|
|
756
|
+
let thisRefNodeID = this.recordThisRefNode(callee, calleeCid);
|
|
745
757
|
if (thisRefNodeID === -1) {
|
|
746
758
|
return -1;
|
|
747
759
|
}
|
|
@@ -763,7 +775,7 @@ class PagBuilder {
|
|
|
763
775
|
this.pag.addPagEdge(this.pag.getNode(srcNodeId), thisRefNode, Pag_1.PagEdgeKind.This);
|
|
764
776
|
return srcNodeId;
|
|
765
777
|
}
|
|
766
|
-
recordThisRefNode(
|
|
778
|
+
recordThisRefNode(callee, calleeCid) {
|
|
767
779
|
var _a;
|
|
768
780
|
if (!callee || !callee.getCfg()) {
|
|
769
781
|
logger.error(`callee is null`);
|
|
@@ -771,25 +783,22 @@ class PagBuilder {
|
|
|
771
783
|
}
|
|
772
784
|
let thisAssignStmt = (_a = callee
|
|
773
785
|
.getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().filter(s => s instanceof Stmt_1.ArkAssignStmt && s.getRightOp() instanceof Ref_1.ArkThisRef);
|
|
774
|
-
let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt
|
|
786
|
+
let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt[0]).getRightOp();
|
|
775
787
|
if (!thisPtr) {
|
|
776
788
|
throw new Error('Can not get this ptr');
|
|
777
789
|
}
|
|
778
|
-
|
|
779
|
-
this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode);
|
|
780
|
-
let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr);
|
|
781
|
-
thisRefNode.addPTNode(baseClassPTNode);
|
|
790
|
+
let thisRefNode = this.getOrNewPagNode(calleeCid, thisPtr);
|
|
782
791
|
return thisRefNode.getID();
|
|
783
792
|
}
|
|
784
793
|
/*
|
|
785
794
|
* Add copy edges from arguments to parameters
|
|
786
|
-
* ret edges from return values to
|
|
795
|
+
* ret edges from return values to callSite
|
|
787
796
|
* Return src node
|
|
788
797
|
*/
|
|
789
798
|
addStaticPagCallEdge(cs, callerCid, calleeCid, ptNode) {
|
|
790
799
|
var _a, _b, _c, _d;
|
|
791
800
|
if (!calleeCid) {
|
|
792
|
-
calleeCid = this.
|
|
801
|
+
calleeCid = this.ctxSelector.selectContext(callerCid, cs, ptNode ? ptNode.getID() : ContextSelector_1.emptyID, cs.calleeFuncID);
|
|
793
802
|
}
|
|
794
803
|
let srcNodes = [];
|
|
795
804
|
// Add reachable
|
|
@@ -845,8 +854,8 @@ class PagBuilder {
|
|
|
845
854
|
}
|
|
846
855
|
// add args to parameters edges
|
|
847
856
|
for (let i = offset; i <= args.length; i++) {
|
|
848
|
-
let arg = args
|
|
849
|
-
let param = params
|
|
857
|
+
let arg = args[i];
|
|
858
|
+
let param = params[i - offset];
|
|
850
859
|
if (!arg || !param) {
|
|
851
860
|
return srcNodes;
|
|
852
861
|
}
|
|
@@ -872,7 +881,7 @@ class PagBuilder {
|
|
|
872
881
|
// container value is the base value of callstmt, its points-to is PagNewContainerExprNode
|
|
873
882
|
let srcNodes = [];
|
|
874
883
|
let containerValue = callStmt.getInvokeExpr().getBase();
|
|
875
|
-
let param = params
|
|
884
|
+
let param = params[0];
|
|
876
885
|
if (!containerValue || !param) {
|
|
877
886
|
return srcNodes;
|
|
878
887
|
}
|
|
@@ -924,7 +933,7 @@ class PagBuilder {
|
|
|
924
933
|
}
|
|
925
934
|
addStaticPagCallReturnEdge(cs, callerCid, calleeCid) {
|
|
926
935
|
if (!calleeCid) {
|
|
927
|
-
calleeCid = this.
|
|
936
|
+
calleeCid = this.ctxSelector.selectContext(callerCid, cs, ContextSelector_1.emptyID, cs.calleeFuncID);
|
|
928
937
|
}
|
|
929
938
|
let srcNodes = [];
|
|
930
939
|
// Add reachable
|
|
@@ -990,7 +999,7 @@ class PagBuilder {
|
|
|
990
999
|
}
|
|
991
1000
|
// add args to parameters edges
|
|
992
1001
|
for (let i = 0; i < argNum; i++) {
|
|
993
|
-
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b
|
|
1002
|
+
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b[i];
|
|
994
1003
|
let paramValue;
|
|
995
1004
|
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
996
1005
|
// TODO: cannot find value
|
|
@@ -1019,7 +1028,7 @@ class PagBuilder {
|
|
|
1019
1028
|
dstPagNode.setSdkParam();
|
|
1020
1029
|
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
1021
1030
|
// create new DynCallSite
|
|
1022
|
-
let sdkParamCallSite =
|
|
1031
|
+
let sdkParamCallSite = this.cg.getCallSiteManager().newDynCallSite(sdkParamInvokeStmt, undefined, undefined, funcID);
|
|
1023
1032
|
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
1024
1033
|
}
|
|
1025
1034
|
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
@@ -1028,55 +1037,19 @@ class PagBuilder {
|
|
|
1028
1037
|
return srcNodes;
|
|
1029
1038
|
}
|
|
1030
1039
|
getOrNewPagNode(cid, v, s) {
|
|
1031
|
-
if (v instanceof Ref_1.ArkThisRef) {
|
|
1032
|
-
return this.getOrNewThisRefNode(cid, v);
|
|
1033
|
-
}
|
|
1034
|
-
// this local is also not uniq!!!
|
|
1035
|
-
// remove below block once this issue fixed
|
|
1036
1040
|
// globalThis process can not be removed while all `globalThis` ref is the same Value
|
|
1037
|
-
if (v instanceof Local_1.Local) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
else if (v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
|
|
1042
|
-
// globalThis node has no cid
|
|
1043
|
-
return this.getOrNewGlobalThisNode(-1);
|
|
1044
|
-
}
|
|
1041
|
+
if (v instanceof Local_1.Local && v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
|
|
1042
|
+
// globalThis node has no cid
|
|
1043
|
+
return this.getOrNewGlobalThisNode(-1);
|
|
1045
1044
|
}
|
|
1046
1045
|
if (v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef) {
|
|
1047
1046
|
v = this.getRealInstanceRef(v);
|
|
1048
1047
|
}
|
|
1049
1048
|
return this.pag.getOrNewNode(cid, v, s);
|
|
1050
1049
|
}
|
|
1051
|
-
/**
|
|
1052
|
-
* return ThisRef PAG node according to cid, a cid has a unique ThisRef node
|
|
1053
|
-
* @param cid: current contextID
|
|
1054
|
-
*/
|
|
1055
|
-
getOrNewThisRefNode(cid, v) {
|
|
1056
|
-
let thisRefNodeID = this.cid2ThisRefMap.get(cid);
|
|
1057
|
-
if (!thisRefNodeID) {
|
|
1058
|
-
thisRefNodeID = -1;
|
|
1059
|
-
}
|
|
1060
|
-
let thisRefNode = this.pag.getOrNewThisRefNode(thisRefNodeID, v);
|
|
1061
|
-
this.cid2ThisRefMap.set(cid, thisRefNode.getID());
|
|
1062
|
-
return thisRefNode;
|
|
1063
|
-
}
|
|
1064
|
-
// TODO: remove it once this local not uniq issue is fixed
|
|
1065
|
-
getOrNewThisLoalNode(cid, v, s) {
|
|
1066
|
-
let thisLocalNodeID = this.cid2ThisLocalMap.get(cid);
|
|
1067
|
-
if (thisLocalNodeID) {
|
|
1068
|
-
return this.pag.getNode(thisLocalNodeID);
|
|
1069
|
-
}
|
|
1070
|
-
let thisNode = this.pag.getOrNewNode(cid, v, s);
|
|
1071
|
-
this.cid2ThisLocalMap.set(cid, thisNode.getID());
|
|
1072
|
-
return thisNode;
|
|
1073
|
-
}
|
|
1074
1050
|
getOrNewGlobalThisNode(cid) {
|
|
1075
1051
|
return this.pag.getOrNewNode(cid, this.getGlobalThisValue());
|
|
1076
1052
|
}
|
|
1077
|
-
getUniqThisLocalNode(cid) {
|
|
1078
|
-
return this.cid2ThisLocalMap.get(cid);
|
|
1079
|
-
}
|
|
1080
1053
|
/**
|
|
1081
1054
|
* search the storage map to get propertyNode with given storage and propertyFieldName
|
|
1082
1055
|
* @param storage storage type: AppStorage, LocalStorage etc.
|
|
@@ -1475,7 +1448,7 @@ class PagBuilder {
|
|
|
1475
1448
|
var _a;
|
|
1476
1449
|
funcPag.addDynamicCallSite(cs);
|
|
1477
1450
|
this.pagStat.numDynamicCall++;
|
|
1478
|
-
logger.trace('[add dynamic
|
|
1451
|
+
logger.trace('[add dynamic callSite] ' + cs.callStmt.toString() + ': ' + ((_a = cs.callStmt.getCfg()) === null || _a === void 0 ? void 0 : _a.getDeclaringMethod().getSignature().toString()));
|
|
1479
1452
|
}
|
|
1480
1453
|
setPtForNode(node, pts) {
|
|
1481
1454
|
if (!pts) {
|
|
@@ -1571,7 +1544,7 @@ class PagBuilder {
|
|
|
1571
1544
|
let srcFunc = (_c = src.getDeclaringStmt()) === null || _c === void 0 ? void 0 : _c.getCfg().getDeclaringMethod();
|
|
1572
1545
|
if (srcFunc) {
|
|
1573
1546
|
let srcFuncID = this.cg.getCallGraphNodeByMethod(srcFunc.getSignature()).getID();
|
|
1574
|
-
let cid = this.
|
|
1547
|
+
let cid = this.ctxSelector.emptyContext(funcID);
|
|
1575
1548
|
let csFuncID = new CSFuncID(cid, srcFuncID);
|
|
1576
1549
|
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
1577
1550
|
}
|
|
@@ -1696,5 +1669,8 @@ class PagBuilder {
|
|
|
1696
1669
|
});
|
|
1697
1670
|
return usedValuesInArray;
|
|
1698
1671
|
}
|
|
1672
|
+
getContextSelector() {
|
|
1673
|
+
return this.ctxSelector;
|
|
1674
|
+
}
|
|
1699
1675
|
}
|
|
1700
1676
|
exports.PagBuilder = PagBuilder;
|
|
@@ -25,6 +25,7 @@ export declare class PointerAnalysis extends AbstractAnalysis {
|
|
|
25
25
|
start(): void;
|
|
26
26
|
private postProcess;
|
|
27
27
|
getPTD(): DiffPTData<NodeID, NodeID, IPtsCollection<NodeID>>;
|
|
28
|
+
getPag(): Pag;
|
|
28
29
|
getStat(): string;
|
|
29
30
|
protected preProcessMethod(funcID: FuncID): CallSite[];
|
|
30
31
|
setEntries(fIds: FuncID[]): void;
|
|
@@ -47,7 +48,7 @@ export declare class PointerAnalysis extends AbstractAnalysis {
|
|
|
47
48
|
private propagate;
|
|
48
49
|
/**
|
|
49
50
|
* 1. 记录被更新的节点(记录cid, nodeid)
|
|
50
|
-
* 2. ( PAGLocalNode记录
|
|
51
|
+
* 2. ( PAGLocalNode记录callSite(cid, value唯一)),通过1种的nodeID查询Node,拿到CallSite
|
|
51
52
|
* 3. 在addDynamicCall里对传入指针过滤(已处理指针和未处理指针)
|
|
52
53
|
*/
|
|
53
54
|
private onTheFlyDynamicCallSolve;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PointerAnalysis.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysis.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAG5D,OAAO,EAAE,SAAS,EAAiB,QAAQ,EAAe,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAa,IAAI,EAAe,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAI5C,OAAO,EAAE,GAAG,EAAgF,MAAM,OAAO,CAAC;AAE1G,OAAO,EAAE,qBAAqB,EAAoB,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAIvD,qBAAa,eAAgB,SAAQ,gBAAgB;IACjD,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAqD;IAChE,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAAY;IAE5B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB;IAU1E,MAAM,CAAC,8BAA8B,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe;IAuB3G,MAAM,CAAC,wBAAwB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe;IAgB7G,SAAS,CAAC,IAAI,IAAI,IAAI;IAYf,KAAK,IAAI,IAAI;IAMpB,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"PointerAnalysis.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysis.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAG5D,OAAO,EAAE,SAAS,EAAiB,QAAQ,EAAe,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAa,IAAI,EAAe,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAI5C,OAAO,EAAE,GAAG,EAAgF,MAAM,OAAO,CAAC;AAE1G,OAAO,EAAE,qBAAqB,EAAoB,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAIvD,qBAAa,eAAgB,SAAQ,gBAAgB;IACjD,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAqD;IAChE,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAAY;IAE5B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB;IAU1E,MAAM,CAAC,8BAA8B,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe;IAuB3G,MAAM,CAAC,wBAAwB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe;IAgB7G,SAAS,CAAC,IAAI,IAAI,IAAI;IAYf,KAAK,IAAI,IAAI;IAMpB,OAAO,CAAC,WAAW;IAiBZ,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAI5D,MAAM,IAAI,GAAG;IAIb,OAAO,IAAI,MAAM;IAQxB,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE;IAK/C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAIvC,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,eAAe;IAkDvB,OAAO,CAAC,kBAAkB;IA6B1B,OAAO,CAAC,mBAAmB;IA4B3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,SAAS;IAoBjB;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACI,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,GAAG,OAAO;IAmCrD,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,GAAG,OAAO;IAItD,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IA6BhD,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,cAAc;IA2Cf,cAAc,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAI9C,SAAS,CAAC,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,GAAG,QAAQ,EAAE;IAIlE,iBAAiB,IAAI,MAAM,EAAE;IAI7B,eAAe,IAAI,MAAM,EAAE;IAI3B,YAAY,IAAI,qBAAqB;IAI5C,OAAO,CAAC,sBAAsB;IA8BvB,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAU9G"}
|
|
@@ -61,7 +61,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
|
|
|
61
61
|
super(s, cg);
|
|
62
62
|
this.pag = p;
|
|
63
63
|
this.ptd = new PtsDS_1.DiffPTData(config.ptsCollectionCtor);
|
|
64
|
-
this.pagBuilder = new PagBuilder_1.PagBuilder(this.pag, this.cg, s, config
|
|
64
|
+
this.pagBuilder = new PagBuilder_1.PagBuilder(this.pag, this.cg, s, config);
|
|
65
65
|
this.cgBuilder = new CallGraphBuilder_1.CallGraphBuilder(this.cg, s);
|
|
66
66
|
this.ptaStat = new Statistics_1.PTAStat(this);
|
|
67
67
|
this.config = config;
|
|
@@ -125,13 +125,17 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
|
|
|
125
125
|
this.pag.dump(path_1.default.join(this.config.outputDirectory, 'ptaEnd_pag.dot'));
|
|
126
126
|
this.cg.dump(path_1.default.join(this.config.outputDirectory, 'cgEnd.dot'));
|
|
127
127
|
}
|
|
128
|
-
if (this.config.
|
|
128
|
+
if (this.config.debug) {
|
|
129
129
|
this.dumpUnhandledFunctions();
|
|
130
|
+
this.pagBuilder.getContextSelector().dump(this.config.outputDirectory, this.cg);
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
getPTD() {
|
|
133
134
|
return this.ptd;
|
|
134
135
|
}
|
|
136
|
+
getPag() {
|
|
137
|
+
return this.pag;
|
|
138
|
+
}
|
|
135
139
|
getStat() {
|
|
136
140
|
let ret = this.cg.getStat();
|
|
137
141
|
ret += '\n' + this.pagBuilder.getStat();
|
|
@@ -348,7 +352,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
|
|
|
348
352
|
}
|
|
349
353
|
/**
|
|
350
354
|
* 1. 记录被更新的节点(记录cid, nodeid)
|
|
351
|
-
* 2. ( PAGLocalNode记录
|
|
355
|
+
* 2. ( PAGLocalNode记录callSite(cid, value唯一)),通过1种的nodeID查询Node,拿到CallSite
|
|
352
356
|
* 3. 在addDynamicCall里对传入指针过滤(已处理指针和未处理指针)
|
|
353
357
|
*/
|
|
354
358
|
onTheFlyDynamicCallSolve() {
|
|
@@ -377,13 +381,13 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
|
|
|
377
381
|
logger.warn(`node ${node.getID()} has no related dynamic call site`);
|
|
378
382
|
return changed;
|
|
379
383
|
}
|
|
380
|
-
logger.info(`[process dynamic
|
|
381
|
-
dynCallSites.forEach(
|
|
384
|
+
logger.info(`[process dynamic callSite] node ${node.getID()}`);
|
|
385
|
+
dynCallSites.forEach(dynCallSite => {
|
|
382
386
|
for (let pt of pts) {
|
|
383
|
-
let srcNodes = this.pagBuilder.addDynamicCallEdge(
|
|
387
|
+
let srcNodes = this.pagBuilder.addDynamicCallEdge(dynCallSite, pt, node.getCid());
|
|
384
388
|
changed = this.addToReanalyze(srcNodes) || changed;
|
|
385
389
|
}
|
|
386
|
-
processedCallSites.add(
|
|
390
|
+
processedCallSites.add(dynCallSite);
|
|
387
391
|
});
|
|
388
392
|
return changed;
|
|
389
393
|
}
|
|
@@ -394,7 +398,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
|
|
|
394
398
|
logger.warn(`node ${node.getID()} has no related unknown call site`);
|
|
395
399
|
return changed;
|
|
396
400
|
}
|
|
397
|
-
logger.info(`[process unknown
|
|
401
|
+
logger.info(`[process unknown callSite] node ${node.getID()}`);
|
|
398
402
|
unknownCallSites.forEach(unknownCallSite => {
|
|
399
403
|
for (let pt of pts) {
|
|
400
404
|
let srcNodes = this.pagBuilder.addDynamicCallEdge(unknownCallSite, pt, node.getCid());
|
|
@@ -4,18 +4,25 @@ export declare enum PtaAnalysisScale {
|
|
|
4
4
|
WholeProgram = 0,
|
|
5
5
|
MethodLevel = 1
|
|
6
6
|
}
|
|
7
|
+
export declare enum ContextType {
|
|
8
|
+
CallSite = 0,
|
|
9
|
+
Obj = 1,
|
|
10
|
+
Func = 2
|
|
11
|
+
}
|
|
7
12
|
export declare class PointerAnalysisConfig {
|
|
8
13
|
private static instance;
|
|
9
14
|
kLimit: number;
|
|
15
|
+
contextType: ContextType;
|
|
10
16
|
outputDirectory: string;
|
|
11
17
|
detectTypeDiff: boolean;
|
|
12
18
|
dotDump: boolean;
|
|
13
|
-
|
|
19
|
+
debug: boolean;
|
|
14
20
|
analysisScale: PtaAnalysisScale;
|
|
15
21
|
ptsCollectionType: PtsCollectionType;
|
|
16
22
|
ptsCollectionCtor: new () => IPtsCollection<NodeID>;
|
|
17
|
-
constructor(kLimit: number, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean,
|
|
18
|
-
static
|
|
23
|
+
constructor(kLimit: number, contextType: ContextType, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, debug?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType);
|
|
24
|
+
static dispose(): void;
|
|
25
|
+
static create(kLimit: number, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, debug?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType, contextType?: ContextType): PointerAnalysisConfig;
|
|
19
26
|
static getInstance(): PointerAnalysisConfig;
|
|
20
27
|
}
|
|
21
28
|
//# sourceMappingURL=PointerAnalysisConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PointerAnalysisConfig.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA2B,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,oBAAY,gBAAgB;IACxB,YAAY,IAAI;IAChB,WAAW,IAAI;CAClB;AAED,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAwB;IAExC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"PointerAnalysisConfig.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA2B,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,oBAAY,gBAAgB;IACxB,YAAY,IAAI;IAChB,WAAW,IAAI;CAClB;AAED,oBAAY,WAAW;IACnB,QAAQ,IAAI;IACZ,GAAG,IAAI;IACP,IAAI,IAAI;CACX;AAED,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAwB;IAExC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,gBAAgB,CAAC;IAChC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,UAAU,cAAc,CAAC,MAAM,CAAC,CAAC;gBAOvD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,KAAK,GAAE,OAAe,EACtB,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB;WAyBvB,OAAO,IAAI,IAAI;WASf,MAAM,CAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,KAAK,GAAE,OAAe,EACtB,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB,EACjC,WAAW,GAAE,WAA8B,GAC5C,qBAAqB;WAiBV,WAAW,IAAI,qBAAqB;CAMrD"}
|
|
@@ -37,7 +37,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
37
37
|
return result;
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.PointerAnalysisConfig = exports.PtaAnalysisScale = void 0;
|
|
40
|
+
exports.PointerAnalysisConfig = exports.ContextType = exports.PtaAnalysisScale = void 0;
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const PtsDS_1 = require("./PtsDS");
|
|
43
43
|
var PtaAnalysisScale;
|
|
@@ -45,12 +45,18 @@ var PtaAnalysisScale;
|
|
|
45
45
|
PtaAnalysisScale[PtaAnalysisScale["WholeProgram"] = 0] = "WholeProgram";
|
|
46
46
|
PtaAnalysisScale[PtaAnalysisScale["MethodLevel"] = 1] = "MethodLevel";
|
|
47
47
|
})(PtaAnalysisScale = exports.PtaAnalysisScale || (exports.PtaAnalysisScale = {}));
|
|
48
|
+
var ContextType;
|
|
49
|
+
(function (ContextType) {
|
|
50
|
+
ContextType[ContextType["CallSite"] = 0] = "CallSite";
|
|
51
|
+
ContextType[ContextType["Obj"] = 1] = "Obj";
|
|
52
|
+
ContextType[ContextType["Func"] = 2] = "Func";
|
|
53
|
+
})(ContextType = exports.ContextType || (exports.ContextType = {}));
|
|
48
54
|
class PointerAnalysisConfig {
|
|
49
55
|
/*
|
|
50
56
|
* Note: DO NOT use `new PointerAnalysisConfig` to initialize ptaconfig
|
|
51
57
|
* Use PointerAnalysisConfig.create() for singleton pattern
|
|
52
58
|
*/
|
|
53
|
-
constructor(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false,
|
|
59
|
+
constructor(kLimit, contextType, outputDirectory, detectTypeDiff = false, dotDump = false, debug = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set) {
|
|
54
60
|
if (kLimit > 5) {
|
|
55
61
|
throw new Error('K Limit too large');
|
|
56
62
|
}
|
|
@@ -58,20 +64,29 @@ class PointerAnalysisConfig {
|
|
|
58
64
|
this.outputDirectory = outputDirectory;
|
|
59
65
|
this.detectTypeDiff = detectTypeDiff;
|
|
60
66
|
this.dotDump = dotDump;
|
|
61
|
-
this.
|
|
67
|
+
this.debug = debug;
|
|
62
68
|
this.analysisScale = analysisScale;
|
|
63
69
|
this.ptsCollectionType = ptsCoType;
|
|
64
70
|
this.ptsCollectionCtor = (0, PtsDS_1.createPtsCollectionCtor)(ptsCoType);
|
|
71
|
+
this.contextType = contextType;
|
|
65
72
|
if (!fs.existsSync(outputDirectory)) {
|
|
66
73
|
fs.mkdirSync(outputDirectory, { recursive: true });
|
|
67
74
|
}
|
|
68
75
|
}
|
|
76
|
+
/*
|
|
77
|
+
* Set static field to be null, then all related objects could be freed by GC.
|
|
78
|
+
* Class PointerAnalysisConfig has been exported by ArkAnalyzer, the dispose method should be called by users themselves before free this class.
|
|
79
|
+
*/
|
|
80
|
+
static dispose() {
|
|
81
|
+
// @ts-expect-error: only be used to free the memory
|
|
82
|
+
this.instance = null;
|
|
83
|
+
}
|
|
69
84
|
/*
|
|
70
85
|
* Create Singleton instance
|
|
71
86
|
* The instance can be created multi-times and be overwrited
|
|
72
87
|
*/
|
|
73
|
-
static create(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false,
|
|
74
|
-
PointerAnalysisConfig.instance = new PointerAnalysisConfig(kLimit, outputDirectory, detectTypeDiff, dotDump,
|
|
88
|
+
static create(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false, debug = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set, contextType = ContextType.Func) {
|
|
89
|
+
PointerAnalysisConfig.instance = new PointerAnalysisConfig(kLimit, contextType, outputDirectory, detectTypeDiff, dotDump, debug, analysisScale, ptsCoType);
|
|
75
90
|
return PointerAnalysisConfig.instance;
|
|
76
91
|
}
|
|
77
92
|
/*
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { CallGraph } from '../../model/CallGraph';
|
|
2
|
+
import { ContextItemManager } from './ContextItem';
|
|
3
|
+
export type ContextID = number;
|
|
4
|
+
export declare const DUMMY_CID = 0;
|
|
5
|
+
/**
|
|
6
|
+
* An abstract base class representing a context in pointer analysis.
|
|
7
|
+
* A context is an immutable sequence of context elements (represented by their IDs).
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class Context {
|
|
10
|
+
protected contextElems: number[];
|
|
11
|
+
constructor(contextElems?: number[]);
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new empty context instance.
|
|
14
|
+
* This static method must be called on a concrete subclass.
|
|
15
|
+
* @example CallSiteContext.newEmpty()
|
|
16
|
+
*/
|
|
17
|
+
static newEmpty<T extends Context>(this: new () => T): T;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new context instance from an array of element IDs.
|
|
20
|
+
* This static method must be called on a concrete subclass.
|
|
21
|
+
* @param contextElems An array of ContextItem IDs.
|
|
22
|
+
* @example CallSiteContext.new([1, 2])
|
|
23
|
+
*/
|
|
24
|
+
static new<T extends Context>(this: new (elems: number[]) => T, contextElems: number[]): T;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new k-limited context by prepending a new element to an old context.
|
|
27
|
+
* The returned instance has the same type as the `oldCtx`.
|
|
28
|
+
* @param oldCtx The previous context instance.
|
|
29
|
+
* @param elem The ID of the new element to add.
|
|
30
|
+
* @param k The maximum length limit for the context.
|
|
31
|
+
*/
|
|
32
|
+
static newKLimitedContext<T extends Context>(oldCtx: T, elem: number, k: number): T;
|
|
33
|
+
/**
|
|
34
|
+
* Truncates an existing context to a specified k-limit.
|
|
35
|
+
* The returned instance has the same type as `ctx`.
|
|
36
|
+
* @param ctx The context instance to truncate.
|
|
37
|
+
* @param k The maximum length limit for the context.
|
|
38
|
+
*/
|
|
39
|
+
static kLimitedContext<T extends Context>(ctx: T, k: number): T;
|
|
40
|
+
length(): number;
|
|
41
|
+
get(index: number): number;
|
|
42
|
+
toString(): string;
|
|
43
|
+
abstract append(callSiteID: number, elementID: number, k: number, m: ContextItemManager): Context;
|
|
44
|
+
abstract dump(m: ContextItemManager, cg: CallGraph): string;
|
|
45
|
+
}
|
|
46
|
+
export declare class CallSiteContext extends Context {
|
|
47
|
+
append(callSiteID: number, calleeFunc: number, k: number, m: ContextItemManager): CallSiteContext;
|
|
48
|
+
dump(m: ContextItemManager, cg: CallGraph): string;
|
|
49
|
+
}
|
|
50
|
+
export declare class ObjContext extends Context {
|
|
51
|
+
append(callSiteID: number, objId: number, k: number, m: ContextItemManager): ObjContext;
|
|
52
|
+
dump(m: ContextItemManager, cg: CallGraph): string;
|
|
53
|
+
}
|
|
54
|
+
export declare class FuncContext extends Context {
|
|
55
|
+
append(callSiteID: number, funcId: number, k: number, m: ContextItemManager): FuncContext;
|
|
56
|
+
dump(m: ContextItemManager, cg: CallGraph): string;
|
|
57
|
+
}
|
|
58
|
+
export declare class ContextCache {
|
|
59
|
+
private contextList;
|
|
60
|
+
private contextToIDMap;
|
|
61
|
+
constructor();
|
|
62
|
+
getOrNewContextID(context: Context): ContextID;
|
|
63
|
+
updateContext(id: ContextID, newContext: Context, oldContext: Context): boolean;
|
|
64
|
+
getContextID(context: Context): ContextID | undefined;
|
|
65
|
+
getContext(id: number): Context | undefined;
|
|
66
|
+
getContextList(): Context[];
|
|
67
|
+
dump(m: ContextItemManager, cg: CallGraph): string;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=Context.d.ts.map
|