arkanalyzer 1.0.6 → 1.0.8
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 +8 -0
- package/docs/IR2ts-stmt.md +81 -0
- package/docs/IR2ts.md +82 -0
- package/lib/Config.d.ts +29 -1
- package/lib/Config.d.ts.map +1 -1
- package/lib/Config.js +44 -11
- package/lib/Scene.d.ts +152 -9
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +233 -66
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +2 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.js +14 -7
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +2 -4
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +2 -3
- package/lib/callgraph/common/Statistics.js +1 -1
- package/lib/callgraph/model/BaseGraph.js +2 -2
- package/lib/callgraph/model/CallGraph.d.ts +3 -2
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
- package/lib/callgraph/model/CallGraph.js +23 -14
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +2 -2
- package/lib/callgraph/model/builder/CallGraphBuilder.js +3 -3
- package/lib/callgraph/pointerAnalysis/Context.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Context.js +0 -1
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +36 -9
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +130 -37
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +34 -5
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +479 -126
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +6 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +107 -45
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PtsDS.js +0 -2
- package/lib/core/base/Constant.d.ts +37 -5
- package/lib/core/base/Constant.d.ts.map +1 -1
- package/lib/core/base/Constant.js +58 -8
- package/lib/core/base/Expr.d.ts +98 -13
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +295 -127
- package/lib/core/base/Local.d.ts +70 -5
- package/lib/core/base/Local.d.ts.map +1 -1
- package/lib/core/base/Local.js +77 -4
- package/lib/core/base/Ref.d.ts +79 -5
- package/lib/core/base/Ref.d.ts.map +1 -1
- package/lib/core/base/Ref.js +143 -38
- package/lib/core/base/Stmt.d.ts +126 -12
- package/lib/core/base/Stmt.d.ts.map +1 -1
- package/lib/core/base/Stmt.js +135 -28
- package/lib/core/base/Type.d.ts +11 -2
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +47 -42
- package/lib/core/base/Value.d.ts +24 -2
- package/lib/core/base/Value.d.ts.map +1 -1
- package/lib/core/common/ArkError.d.ts +15 -0
- package/lib/core/common/ArkError.d.ts.map +1 -0
- package/lib/core/common/ArkError.js +28 -0
- package/lib/core/common/ArkIRTransformer.d.ts +12 -5
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +90 -45
- package/lib/core/common/BodyBuilder.d.ts +2 -0
- package/lib/core/common/BodyBuilder.d.ts.map +1 -1
- package/lib/core/common/BodyBuilder.js +5 -2
- package/lib/core/common/Builtin.js +1 -1
- package/lib/core/common/CfgBuilder.d.ts +12 -7
- package/lib/core/common/CfgBuilder.d.ts.map +1 -1
- package/lib/core/common/CfgBuilder.js +336 -140
- package/lib/core/common/Const.d.ts +15 -10
- package/lib/core/common/Const.d.ts.map +1 -1
- package/lib/core/common/Const.js +18 -11
- package/lib/core/common/DummyMainCreater.d.ts +5 -4
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +43 -28
- package/lib/core/common/EtsConst.d.ts +1 -0
- package/lib/core/common/EtsConst.d.ts.map +1 -1
- package/lib/core/common/EtsConst.js +2 -1
- package/lib/core/common/ExprUseReplacer.js +8 -8
- package/lib/core/common/IRUtils.d.ts +7 -0
- package/lib/core/common/IRUtils.d.ts.map +1 -1
- package/lib/core/common/IRUtils.js +34 -2
- 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 +39 -36
- package/lib/core/common/RefUseReplacer.js +3 -3
- package/lib/core/common/StmtUseReplacer.js +4 -4
- package/lib/core/common/TSConst.d.ts +10 -3
- package/lib/core/common/TSConst.d.ts.map +1 -1
- package/lib/core/common/TSConst.js +11 -4
- package/lib/core/common/TypeInference.d.ts +8 -2
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +222 -90
- package/lib/core/common/ValueUtil.d.ts +0 -4
- package/lib/core/common/ValueUtil.d.ts.map +1 -1
- package/lib/core/common/ValueUtil.js +10 -27
- package/lib/core/common/VisibleValue.js +1 -1
- package/lib/core/dataflow/DataflowProblem.d.ts +1 -0
- package/lib/core/dataflow/DataflowProblem.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowProblem.js +4 -4
- package/lib/core/dataflow/DataflowSolver.d.ts +20 -16
- package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowSolver.js +67 -78
- package/lib/core/dataflow/TiantAnalysis.d.ts +1 -0
- package/lib/core/dataflow/TiantAnalysis.d.ts.map +1 -1
- package/lib/core/dataflow/TiantAnalysis.js +42 -28
- package/lib/core/dataflow/UndefinedVariable.d.ts +15 -1
- package/lib/core/dataflow/UndefinedVariable.d.ts.map +1 -1
- package/lib/core/dataflow/UndefinedVariable.js +122 -76
- package/lib/core/dataflow/Util.d.ts +5 -1
- package/lib/core/dataflow/Util.d.ts.map +1 -1
- package/lib/core/dataflow/Util.js +43 -22
- package/lib/core/graph/BasicBlock.d.ts +72 -0
- package/lib/core/graph/BasicBlock.d.ts.map +1 -1
- package/lib/core/graph/BasicBlock.js +165 -3
- package/lib/core/graph/Cfg.d.ts +30 -1
- package/lib/core/graph/Cfg.d.ts.map +1 -1
- package/lib/core/graph/Cfg.js +131 -11
- package/lib/core/graph/DominanceFinder.js +7 -7
- package/lib/core/graph/DominanceTree.js +4 -4
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ViewTreeBuilder.js +6 -5
- package/lib/core/model/ArkBaseModel.d.ts +59 -0
- package/lib/core/model/ArkBaseModel.d.ts.map +1 -0
- package/lib/core/model/ArkBaseModel.js +271 -0
- package/lib/core/model/ArkBody.d.ts +3 -9
- package/lib/core/model/ArkBody.d.ts.map +1 -1
- package/lib/core/model/ArkBody.js +3 -14
- package/lib/core/model/ArkClass.d.ts +107 -13
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +152 -54
- package/lib/core/model/ArkExport.d.ts +8 -7
- package/lib/core/model/ArkExport.d.ts.map +1 -1
- package/lib/core/model/ArkExport.js +16 -18
- package/lib/core/model/ArkField.d.ts +16 -13
- package/lib/core/model/ArkField.d.ts.map +1 -1
- package/lib/core/model/ArkField.js +18 -62
- package/lib/core/model/ArkFile.d.ts +42 -0
- package/lib/core/model/ArkFile.d.ts.map +1 -1
- package/lib/core/model/ArkFile.js +58 -0
- package/lib/core/model/ArkImport.d.ts +9 -7
- package/lib/core/model/ArkImport.d.ts.map +1 -1
- package/lib/core/model/ArkImport.js +11 -12
- package/lib/core/model/ArkMetadata.d.ts +20 -0
- package/lib/core/model/ArkMetadata.d.ts.map +1 -0
- package/lib/core/model/ArkMetadata.js +44 -0
- package/lib/core/model/ArkMethod.d.ts +195 -17
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +363 -46
- package/lib/core/model/ArkNamespace.d.ts +6 -8
- package/lib/core/model/ArkNamespace.d.ts.map +1 -1
- package/lib/core/model/ArkNamespace.js +16 -20
- package/lib/core/model/ArkSignature.d.ts +41 -0
- package/lib/core/model/ArkSignature.d.ts.map +1 -1
- package/lib/core/model/ArkSignature.js +76 -19
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +60 -49
- package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkExportBuilder.js +12 -6
- package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkFieldBuilder.js +13 -9
- package/lib/core/model/builder/ArkFileBuilder.js +1 -3
- package/lib/core/model/builder/ArkImportBuilder.d.ts +2 -1
- package/lib/core/model/builder/ArkImportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkImportBuilder.js +16 -13
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +3 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +105 -45
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkNamespaceBuilder.js +4 -5
- package/lib/core/model/builder/builderUtils.d.ts +2 -1
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +63 -43
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -3
- package/lib/save/ArkStream.js +1 -1
- package/lib/save/DotPrinter.d.ts.map +1 -1
- package/lib/save/DotPrinter.js +1 -15
- package/lib/save/GraphPrinter.d.ts.map +1 -1
- package/lib/save/GraphPrinter.js +4 -2
- package/lib/save/JsonPrinter.js +5 -5
- package/lib/save/ViewTreePrinter.d.ts +16 -0
- package/lib/save/ViewTreePrinter.d.ts.map +1 -0
- package/lib/save/ViewTreePrinter.js +130 -0
- package/lib/save/source/SourceBase.d.ts +2 -2
- package/lib/save/source/SourceBase.d.ts.map +1 -1
- package/lib/save/source/SourceBase.js +6 -13
- package/lib/save/source/SourceBody.d.ts.map +1 -1
- package/lib/save/source/SourceBody.js +27 -14
- package/lib/save/source/SourceClass.d.ts.map +1 -1
- package/lib/save/source/SourceClass.js +12 -8
- package/lib/save/source/SourceField.d.ts.map +1 -1
- package/lib/save/source/SourceField.js +6 -2
- package/lib/save/source/SourceMethod.d.ts.map +1 -1
- package/lib/save/source/SourceMethod.js +10 -3
- package/lib/save/source/SourceModule.d.ts.map +1 -1
- package/lib/save/source/SourceModule.js +16 -10
- package/lib/save/source/SourceNamespace.d.ts.map +1 -1
- package/lib/save/source/SourceNamespace.js +4 -0
- package/lib/save/source/SourceStmt.d.ts +1 -1
- package/lib/save/source/SourceStmt.d.ts.map +1 -1
- package/lib/save/source/SourceStmt.js +37 -25
- package/lib/save/source/SourceTransformer.d.ts +6 -0
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +82 -51
- package/lib/save/source/SourceUtils.d.ts.map +1 -1
- package/lib/save/source/SourceUtils.js +12 -11
- package/lib/transformer/StaticSingleAssignmentFormer.js +3 -3
- package/lib/utils/CfgStructualAnalysis.d.ts +1 -0
- package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -1
- package/lib/utils/CfgStructualAnalysis.js +103 -72
- package/lib/utils/callGraphUtils.d.ts.map +1 -1
- package/lib/utils/callGraphUtils.js +7 -10
- package/lib/utils/crypto_utils.d.ts +6 -0
- package/lib/utils/crypto_utils.d.ts.map +1 -0
- package/lib/utils/crypto_utils.js +57 -0
- package/lib/utils/entryMethodUtils.d.ts.map +1 -1
- package/lib/utils/entryMethodUtils.js +27 -26
- package/lib/utils/getAllFiles.d.ts +1 -1
- package/lib/utils/getAllFiles.d.ts.map +1 -1
- package/lib/utils/getAllFiles.js +4 -5
- package/lib/utils/logger.js +2 -2
- package/package.json +3 -2
|
@@ -51,6 +51,7 @@ const Context_1 = require("./Context");
|
|
|
51
51
|
const Pag_1 = require("./Pag");
|
|
52
52
|
const PtsDS_1 = require("./PtsDS");
|
|
53
53
|
const TSConst_1 = require("../../core/common/TSConst");
|
|
54
|
+
const Const_1 = require("../../core/common/Const");
|
|
54
55
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
|
|
55
56
|
class CSFuncID {
|
|
56
57
|
constructor(cid, fid) {
|
|
@@ -70,10 +71,15 @@ class PagBuilder {
|
|
|
70
71
|
this.cid2ThisRefMap = new Map();
|
|
71
72
|
this.cid2ThisLocalMap = new Map();
|
|
72
73
|
this.sdkMethodReturnValueMap = new Map();
|
|
74
|
+
// record the SDK API param, and create fake Values
|
|
75
|
+
this.sdkMethodParamValueMap = new Map();
|
|
76
|
+
this.fakeSdkMethodParamDeclaringStmt = new Stmt_1.ArkAssignStmt(new Local_1.Local(""), new Local_1.Local(""));
|
|
73
77
|
this.funcHandledThisRound = new Set();
|
|
74
78
|
this.updatedNodesThisRound = new Map();
|
|
75
79
|
this.singletonFuncMap = new Map();
|
|
80
|
+
this.globalThisValue = new Local_1.Local(TSConst_1.GLOBAL_THIS);
|
|
76
81
|
this.storagePropertyMap = new Map();
|
|
82
|
+
this.externalScopeVariableMap = new Map();
|
|
77
83
|
this.pag = p;
|
|
78
84
|
this.cg = cg;
|
|
79
85
|
this.funcPags = new Map;
|
|
@@ -106,9 +112,11 @@ class PagBuilder {
|
|
|
106
112
|
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
107
113
|
});
|
|
108
114
|
this.handleReachable();
|
|
115
|
+
this.globalThisPagNode = this.getOrNewGlobalThisNode(-1);
|
|
116
|
+
this.pag.addPagEdge(this.globalThisPagNode, this.globalThisPagNode, Pag_1.PagEdgeKind.Copy);
|
|
109
117
|
}
|
|
110
118
|
handleReachable() {
|
|
111
|
-
if (this.worklist.length
|
|
119
|
+
if (this.worklist.length === 0) {
|
|
112
120
|
return false;
|
|
113
121
|
}
|
|
114
122
|
this.funcHandledThisRound.clear();
|
|
@@ -131,38 +139,45 @@ class PagBuilder {
|
|
|
131
139
|
if (this.funcPags.has(funcID)) {
|
|
132
140
|
return false;
|
|
133
141
|
}
|
|
134
|
-
let fpag = new Pag_1.FuncPag();
|
|
135
142
|
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
136
143
|
if (arkMethod == null) {
|
|
137
|
-
//throw new Error("function ID");
|
|
138
144
|
return false;
|
|
139
145
|
}
|
|
140
146
|
let cfg = arkMethod.getCfg();
|
|
141
147
|
if (!cfg) {
|
|
148
|
+
this.buildSDKFuncPag(funcID);
|
|
142
149
|
return false;
|
|
143
150
|
}
|
|
144
151
|
logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`);
|
|
152
|
+
let fpag = new Pag_1.FuncPag();
|
|
145
153
|
for (let stmt of cfg.getStmts()) {
|
|
146
154
|
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
155
|
+
this.handleValueFromExternalScope(stmt.getRightOp(), funcID);
|
|
147
156
|
// Add non-call edges
|
|
148
157
|
let kind = this.getEdgeKindForAssignStmt(stmt);
|
|
149
|
-
if (kind
|
|
158
|
+
if (kind !== Pag_1.PagEdgeKind.Unknown) {
|
|
150
159
|
fpag.addInternalEdge(stmt, kind);
|
|
151
160
|
continue;
|
|
152
161
|
}
|
|
153
162
|
// handle call
|
|
154
|
-
let
|
|
155
|
-
if (
|
|
163
|
+
let ivkExpr = stmt.getInvokeExpr();
|
|
164
|
+
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
156
165
|
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
157
166
|
if (cs) {
|
|
158
167
|
// direct call is already existing in CG
|
|
168
|
+
// TODO: API Invoke stmt has anonymous method param, how to add these param into callee
|
|
159
169
|
fpag.addNormalCallSite(cs);
|
|
170
|
+
if (ivkExpr.getMethodSignature().getDeclaringClassSignature()
|
|
171
|
+
.getDeclaringFileSignature().getFileName() === Const_1.UNKNOWN_FILE_NAME) {
|
|
172
|
+
fpag.addUnknownCallSite(cs);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
160
175
|
}
|
|
161
176
|
else {
|
|
162
177
|
throw new Error('Can not find static callsite');
|
|
163
178
|
}
|
|
164
179
|
}
|
|
165
|
-
else if (
|
|
180
|
+
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr || ivkExpr instanceof Expr_1.ArkPtrInvokeExpr) {
|
|
166
181
|
let ptcs = this.cg.getDynCallsiteByStmt(stmt);
|
|
167
182
|
if (ptcs) {
|
|
168
183
|
this.addToDynamicCallSite(fpag, ptcs);
|
|
@@ -174,7 +189,14 @@ class PagBuilder {
|
|
|
174
189
|
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
175
190
|
if (cs) {
|
|
176
191
|
// direct call or constructor call is already existing in CG
|
|
177
|
-
|
|
192
|
+
// TODO: some ptr invoke stmt is recognized as Static invoke in tests/resources/callgraph/funPtrTest1/fnPtrTest4.ts
|
|
193
|
+
// TODO: instance invoke(ptr invoke)
|
|
194
|
+
if (this.cg.isUnknownMethod(cs.calleeFuncID)) {
|
|
195
|
+
fpag.addUnknownCallSite(cs);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
fpag.addNormalCallSite(cs);
|
|
199
|
+
}
|
|
178
200
|
continue;
|
|
179
201
|
}
|
|
180
202
|
let dycs = this.cg.getDynCallsiteByStmt(stmt);
|
|
@@ -193,24 +215,51 @@ class PagBuilder {
|
|
|
193
215
|
this.pagStat.numTotalFunction++;
|
|
194
216
|
return true;
|
|
195
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* will not create real funcPag, only create param values
|
|
220
|
+
*/
|
|
221
|
+
buildSDKFuncPag(funcID) {
|
|
222
|
+
var _a;
|
|
223
|
+
// check if SDK method
|
|
224
|
+
let cgNode = this.cg.getNode(funcID);
|
|
225
|
+
if (!cgNode.isSdkMethod()) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
let args = (_a = this.cg.getArkMethodByFuncID(funcID)) === null || _a === void 0 ? void 0 : _a.getParameters();
|
|
229
|
+
if (!args) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
let paramArr = [];
|
|
233
|
+
args.forEach((arg) => {
|
|
234
|
+
let argInstance = new Local_1.Local(arg.getName(), arg.getType());
|
|
235
|
+
argInstance.setDeclaringStmt(this.fakeSdkMethodParamDeclaringStmt);
|
|
236
|
+
paramArr.push(argInstance);
|
|
237
|
+
});
|
|
238
|
+
this.sdkMethodParamValueMap.set(funcID, paramArr);
|
|
239
|
+
}
|
|
196
240
|
buildPagFromFuncPag(funcID, cid) {
|
|
241
|
+
var _a;
|
|
197
242
|
let funcPag = this.funcPags.get(funcID);
|
|
198
|
-
if (funcPag
|
|
199
|
-
//throw new Error("No Func PAG is found for #" + funcID);
|
|
243
|
+
if (funcPag === undefined) {
|
|
200
244
|
return;
|
|
201
245
|
}
|
|
202
246
|
if (this.handledFunc.has(`${cid}-${funcID}`)) {
|
|
203
247
|
return;
|
|
204
248
|
}
|
|
205
249
|
this.addEdgesFromFuncPag(funcPag, cid);
|
|
250
|
+
let interFuncPag = (_a = this.interFuncPags) === null || _a === void 0 ? void 0 : _a.get(funcID);
|
|
251
|
+
if (interFuncPag) {
|
|
252
|
+
this.addEdgesFromInterFuncPag(interFuncPag, cid);
|
|
253
|
+
}
|
|
206
254
|
this.addCallsEdgesFromFuncPag(funcPag, cid);
|
|
207
|
-
this.addDynamicCallSite(funcPag);
|
|
255
|
+
this.addDynamicCallSite(funcPag, funcID);
|
|
256
|
+
this.addUnknownCallSite(funcPag, funcID);
|
|
208
257
|
this.handledFunc.add(`${cid}-${funcID}`);
|
|
209
258
|
}
|
|
210
259
|
/// Add Pag Nodes and Edges in function
|
|
211
260
|
addEdgesFromFuncPag(funcPag, cid) {
|
|
212
261
|
let inEdges = funcPag.getInternalEdges();
|
|
213
|
-
if (inEdges
|
|
262
|
+
if (inEdges === undefined) {
|
|
214
263
|
return false;
|
|
215
264
|
}
|
|
216
265
|
for (let e of inEdges) {
|
|
@@ -227,17 +276,17 @@ class PagBuilder {
|
|
|
227
276
|
/// add Copy edges interprocedural
|
|
228
277
|
addCallsEdgesFromFuncPag(funcPag, cid) {
|
|
229
278
|
for (let cs of funcPag.getNormalCallSites()) {
|
|
279
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
230
280
|
let calleeCid = this.ctx.getOrNewContext(cid, cs.calleeFuncID, true);
|
|
231
281
|
let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
|
|
232
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
233
282
|
// process the Storage API(Static)
|
|
234
283
|
if (!this.processStorage(cs, calleeCGNode, cid)) {
|
|
235
284
|
// If not Storage API, process normal edge
|
|
236
285
|
this.addStaticPagCallEdge(cs, cid, calleeCid);
|
|
237
286
|
}
|
|
238
287
|
// Add edge to thisRef for special calls
|
|
239
|
-
if (calleeCGNode.getKind()
|
|
240
|
-
calleeCGNode.getKind()
|
|
288
|
+
if (calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.constructor ||
|
|
289
|
+
calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.intrinsic) {
|
|
241
290
|
let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID));
|
|
242
291
|
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
243
292
|
let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase());
|
|
@@ -285,13 +334,21 @@ class PagBuilder {
|
|
|
285
334
|
return false;
|
|
286
335
|
}
|
|
287
336
|
processStorageSetOrCreate(cs, cid) {
|
|
288
|
-
let
|
|
337
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
338
|
+
if (!propertyStr) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
let propertyName = propertyStr;
|
|
289
342
|
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
290
343
|
let storageObj = cs.args[1];
|
|
291
344
|
this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
|
|
292
345
|
}
|
|
293
346
|
processStorageLink(cs, cid) {
|
|
294
|
-
let
|
|
347
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
348
|
+
if (!propertyStr) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
let propertyName = propertyStr;
|
|
295
352
|
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
296
353
|
let leftOp = cs.callStmt.getLeftOp();
|
|
297
354
|
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
@@ -302,7 +359,11 @@ class PagBuilder {
|
|
|
302
359
|
this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
|
|
303
360
|
}
|
|
304
361
|
processStorageProp(cs, cid) {
|
|
305
|
-
let
|
|
362
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
363
|
+
if (!propertyStr) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
let propertyName = propertyStr;
|
|
306
367
|
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
307
368
|
let leftOp = cs.callStmt.getLeftOp();
|
|
308
369
|
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
@@ -312,19 +373,31 @@ class PagBuilder {
|
|
|
312
373
|
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
313
374
|
}
|
|
314
375
|
processStorageSet(cs, cid) {
|
|
315
|
-
let
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
let
|
|
319
|
-
|
|
376
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
377
|
+
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
378
|
+
let base = ivkExpr.getBase();
|
|
379
|
+
let baseNode = this.pag.getOrNewNode(cid, base);
|
|
380
|
+
if (baseNode.isStorageLinked()) {
|
|
381
|
+
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
382
|
+
this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
386
|
+
// TODO: process AppStorage.set()
|
|
320
387
|
}
|
|
321
388
|
}
|
|
322
389
|
processStorageGet(cs, cid) {
|
|
390
|
+
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
323
393
|
let leftOp = cs.callStmt.getLeftOp();
|
|
324
394
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
325
395
|
let propertyName;
|
|
326
396
|
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
327
|
-
|
|
397
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
398
|
+
if (propertyStr) {
|
|
399
|
+
propertyName = propertyStr;
|
|
400
|
+
}
|
|
328
401
|
}
|
|
329
402
|
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
330
403
|
let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
|
|
@@ -332,19 +405,44 @@ class PagBuilder {
|
|
|
332
405
|
propertyName = baseNode.getStorage().PropertyName;
|
|
333
406
|
}
|
|
334
407
|
}
|
|
335
|
-
// TODO: should not new node
|
|
336
408
|
let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
337
409
|
if (!propertyNode) {
|
|
338
410
|
return;
|
|
339
411
|
}
|
|
340
412
|
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
341
413
|
}
|
|
342
|
-
|
|
414
|
+
getPropertyName(value) {
|
|
415
|
+
if (value instanceof Local_1.Local) {
|
|
416
|
+
let type = value.getType();
|
|
417
|
+
if (type instanceof Type_1.StringType) {
|
|
418
|
+
return type.getName();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else if (value instanceof Constant_1.Constant) {
|
|
422
|
+
return value.getValue();
|
|
423
|
+
}
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
addDynamicCallSite(funcPag, funcID) {
|
|
343
427
|
// add dyn callsite in funcpag to base node
|
|
344
428
|
for (let cs of funcPag.getDynamicCallSites()) {
|
|
345
|
-
let
|
|
429
|
+
let invokeExpr = cs.callStmt.getInvokeExpr();
|
|
430
|
+
let base;
|
|
431
|
+
if (invokeExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
432
|
+
base = invokeExpr.getBase();
|
|
433
|
+
}
|
|
434
|
+
else if (invokeExpr instanceof Expr_1.ArkPtrInvokeExpr) {
|
|
435
|
+
base = invokeExpr.getFuncPtrLocal();
|
|
436
|
+
}
|
|
346
437
|
// TODO: check base under different cid
|
|
347
438
|
let baseNodeIDs = this.pag.getNodesByValue(base);
|
|
439
|
+
if (!baseNodeIDs) {
|
|
440
|
+
// bind the call site to export base
|
|
441
|
+
let interProceduralLocal = this.getSourceValueFromExternalScope(base, funcID);
|
|
442
|
+
if (interProceduralLocal) {
|
|
443
|
+
baseNodeIDs = this.pag.getNodesByValue(interProceduralLocal);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
348
446
|
if (!baseNodeIDs) {
|
|
349
447
|
logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
|
|
350
448
|
continue;
|
|
@@ -358,63 +456,114 @@ class PagBuilder {
|
|
|
358
456
|
}
|
|
359
457
|
}
|
|
360
458
|
}
|
|
459
|
+
addUnknownCallSite(funcPag, funcID) {
|
|
460
|
+
var _a;
|
|
461
|
+
let method = this.cg.getArkMethodByFuncID(funcID);
|
|
462
|
+
if (!method) {
|
|
463
|
+
throw new Error(`can not find ArkMethod by FuncID ${funcID}`);
|
|
464
|
+
}
|
|
465
|
+
let locals = (_a = method.getBody()) === null || _a === void 0 ? void 0 : _a.getLocals();
|
|
466
|
+
funcPag.getUnknownCallSites().forEach((unknownCallSite) => {
|
|
467
|
+
var _a;
|
|
468
|
+
let calleeName = (_a = unknownCallSite.callStmt.getInvokeExpr()) === null || _a === void 0 ? void 0 : _a.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
469
|
+
let base = locals.get(calleeName);
|
|
470
|
+
if (base) {
|
|
471
|
+
let baseNodeIDs = this.pag.getNodesByValue(base);
|
|
472
|
+
if (!baseNodeIDs) {
|
|
473
|
+
logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
for (let nodeID of baseNodeIDs.values()) {
|
|
477
|
+
let node = this.pag.getNode(nodeID);
|
|
478
|
+
if (!(node instanceof Pag_1.PagLocalNode)) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
node.addRelatedUnknownCallSite(unknownCallSite);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}
|
|
361
486
|
addDynamicCallEdge(cs, baseClassPTNode, cid) {
|
|
362
487
|
let srcNodes = [];
|
|
363
488
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
364
|
-
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
365
489
|
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
366
490
|
let value = ptNode.getValue();
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
let callee = null;
|
|
371
|
-
if (value instanceof Expr_1.ArkNewExpr) {
|
|
372
|
-
// get class signature
|
|
373
|
-
let clsSig = value.getType().getClassSignature();
|
|
374
|
-
let cls;
|
|
375
|
-
cls = this.scene.getClass(clsSig);
|
|
376
|
-
while (!callee && cls) {
|
|
377
|
-
callee = cls.getMethodWithName(calleeName);
|
|
378
|
-
cls = cls.getSuperClass();
|
|
379
|
-
}
|
|
491
|
+
let callees = this.getDynamicCallee(ptNode, value, ivkExpr, cs);
|
|
492
|
+
for (let callee of callees) {
|
|
380
493
|
if (!callee) {
|
|
381
|
-
|
|
494
|
+
continue;
|
|
382
495
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
496
|
+
// get caller and callee CG node, add param and return value PAG edge
|
|
497
|
+
let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature());
|
|
498
|
+
let callerNode = this.cg.getNode(cs.callerFuncID);
|
|
499
|
+
if (!callerNode) {
|
|
500
|
+
throw new Error("Can not get caller method node");
|
|
501
|
+
}
|
|
502
|
+
// update call graph
|
|
503
|
+
// TODO: movo to cgbuilder
|
|
504
|
+
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
505
|
+
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
506
|
+
let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
|
|
507
|
+
let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
|
|
508
|
+
let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
|
|
509
|
+
srcNodes.push(...staticSrcNodes);
|
|
510
|
+
// Pass base's pts to callee's this pointer
|
|
511
|
+
if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
512
|
+
let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
|
|
513
|
+
srcNodes.push(srcBaseNode);
|
|
514
|
+
}
|
|
391
515
|
}
|
|
392
516
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
517
|
+
return srcNodes;
|
|
518
|
+
}
|
|
519
|
+
getDynamicCallee(ptNode, value, ivkExpr, cs) {
|
|
520
|
+
let callee = [];
|
|
521
|
+
if (ptNode instanceof Pag_1.PagFuncNode) {
|
|
522
|
+
// function ptr invoke
|
|
523
|
+
let tempCallee = this.scene.getMethod(ptNode.getMethod());
|
|
524
|
+
if (!callee) {
|
|
525
|
+
return callee;
|
|
526
|
+
}
|
|
527
|
+
callee.push(tempCallee);
|
|
397
528
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
529
|
+
else {
|
|
530
|
+
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
531
|
+
// instance method invoke
|
|
532
|
+
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
533
|
+
return callee;
|
|
534
|
+
}
|
|
535
|
+
let tempCallee;
|
|
536
|
+
// try to get callee by MethodSignature
|
|
537
|
+
if (value instanceof Expr_1.ArkNewExpr) {
|
|
538
|
+
// get class signature
|
|
539
|
+
let clsSig = value.getType().getClassSignature();
|
|
540
|
+
let cls;
|
|
541
|
+
cls = this.scene.getClass(clsSig);
|
|
542
|
+
while (!tempCallee && cls) {
|
|
543
|
+
tempCallee = cls.getMethodWithName(calleeName);
|
|
544
|
+
cls = cls.getSuperClass();
|
|
545
|
+
}
|
|
546
|
+
if (!tempCallee) {
|
|
547
|
+
tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (!tempCallee && cs.args) {
|
|
551
|
+
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
552
|
+
// return empty node when {o_2} come in
|
|
553
|
+
// try to get callee by anonymous method in param
|
|
554
|
+
for (let arg of cs.args) {
|
|
555
|
+
// TODO: anonymous method param and return value pointer pass
|
|
556
|
+
let argType = arg.getType();
|
|
557
|
+
if (argType instanceof Type_1.FunctionType) {
|
|
558
|
+
callee.push(this.scene.getMethod(argType.getMethodSignature()));
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else if (tempCallee) {
|
|
563
|
+
callee.push(tempCallee);
|
|
415
564
|
}
|
|
416
565
|
}
|
|
417
|
-
return
|
|
566
|
+
return callee;
|
|
418
567
|
}
|
|
419
568
|
addUpdatedNode(nodeID, diffPT) {
|
|
420
569
|
var _a;
|
|
@@ -451,7 +600,7 @@ class PagBuilder {
|
|
|
451
600
|
else {
|
|
452
601
|
callees.push(callee);
|
|
453
602
|
}
|
|
454
|
-
if (callees.length
|
|
603
|
+
if (callees.length === 0) {
|
|
455
604
|
return srcNodes;
|
|
456
605
|
}
|
|
457
606
|
callees.forEach(callee => {
|
|
@@ -460,7 +609,7 @@ class PagBuilder {
|
|
|
460
609
|
throw new Error("Can not get caller method node");
|
|
461
610
|
}
|
|
462
611
|
if (this.processStorage(cs, dstCGNode, cid)) {
|
|
463
|
-
if (ivkExpr.getArgs().length
|
|
612
|
+
if (ivkExpr.getArgs().length !== 0) {
|
|
464
613
|
// for AppStorage.set() instance invoke, add obj to reanalyze list
|
|
465
614
|
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
466
615
|
srcNodes.push(argsNode.getID());
|
|
@@ -489,26 +638,29 @@ class PagBuilder {
|
|
|
489
638
|
const diffCallSites = new Set(Array.from(callSites).filter(item => !processedCallSites.has(item)));
|
|
490
639
|
diffCallSites.forEach((cs) => {
|
|
491
640
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
641
|
+
if (!(ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr)) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
492
644
|
// Get local of base class
|
|
493
645
|
let base = ivkExpr.getBase();
|
|
494
646
|
// TODO: remove this after multiple this local fixed
|
|
495
647
|
base = this.getRealThisLocal(base, cs.callerFuncID);
|
|
496
648
|
// Get PAG nodes for this base's local
|
|
497
649
|
let ctx2NdMap = this.pag.getNodesByValue(base);
|
|
498
|
-
if (ctx2NdMap) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
650
|
+
if (!ctx2NdMap) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
for (let [cid] of ctx2NdMap.entries()) {
|
|
654
|
+
reAnalyzeNodes.push(...this.handleUnkownDynamicCall(cs, cid));
|
|
502
655
|
}
|
|
503
656
|
});
|
|
504
657
|
}
|
|
505
658
|
return reAnalyzeNodes;
|
|
506
659
|
}
|
|
507
660
|
addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, callerFunID) {
|
|
508
|
-
//let thisPtr = callee.getThisInstance();
|
|
509
661
|
var _a;
|
|
510
662
|
if (!callee || !callee.getCfg()) {
|
|
511
|
-
|
|
663
|
+
logger.error(`callee is null`);
|
|
512
664
|
return -1;
|
|
513
665
|
}
|
|
514
666
|
let thisAssignStmt = (_a = callee.getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().filter(s => s instanceof Stmt_1.ArkAssignStmt && s.getRightOp() instanceof Ref_1.ArkThisRef);
|
|
@@ -523,6 +675,14 @@ class PagBuilder {
|
|
|
523
675
|
let srcBaseLocal = ivkExpr.getBase();
|
|
524
676
|
srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID);
|
|
525
677
|
let srcNodeId = this.pag.hasCtxNode(cid, srcBaseLocal);
|
|
678
|
+
if (!srcNodeId) {
|
|
679
|
+
// this check is for export local and closure use
|
|
680
|
+
// replace the invoke base, because its origin base has no pag node
|
|
681
|
+
let interProceduralLocal = this.getSourceValueFromExternalScope(srcBaseLocal, callerFunID);
|
|
682
|
+
if (interProceduralLocal) {
|
|
683
|
+
srcNodeId = this.pag.hasCtxNode(cid, interProceduralLocal);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
526
686
|
if (!srcNodeId) {
|
|
527
687
|
throw new Error('Can not get base node');
|
|
528
688
|
}
|
|
@@ -545,35 +705,10 @@ class PagBuilder {
|
|
|
545
705
|
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
546
706
|
if (!calleeMethod) {
|
|
547
707
|
// TODO: check if nodes need to delete
|
|
548
|
-
// this.cg.removeCallGraphNode(cs.calleeFuncID)
|
|
549
708
|
return srcNodes;
|
|
550
709
|
}
|
|
551
|
-
if (calleeNode.
|
|
552
|
-
|
|
553
|
-
// TODO: add new array type
|
|
554
|
-
if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
555
|
-
return srcNodes;
|
|
556
|
-
}
|
|
557
|
-
// check fake heap object exists or not
|
|
558
|
-
let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
|
|
559
|
-
if (!cidMap) {
|
|
560
|
-
cidMap = new Map();
|
|
561
|
-
}
|
|
562
|
-
let newExpr = cidMap.get(calleeCid);
|
|
563
|
-
if (!newExpr) {
|
|
564
|
-
if (returnType instanceof Type_1.ClassType) {
|
|
565
|
-
newExpr = new Expr_1.ArkNewExpr(returnType);
|
|
566
|
-
}
|
|
567
|
-
// } else if (returnType instanceof ArrayType) {
|
|
568
|
-
// TODO: check how to transform array type 2 newArrayExpr
|
|
569
|
-
// newExpr = new ArkNewArrayExpr(returnType.getBaseType(), )
|
|
570
|
-
// }
|
|
571
|
-
}
|
|
572
|
-
cidMap.set(calleeCid, newExpr);
|
|
573
|
-
this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
|
|
574
|
-
let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
|
|
575
|
-
let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
|
|
576
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
|
|
710
|
+
if (calleeNode.isSdkMethod()) {
|
|
711
|
+
srcNodes.push(...this.addSDKMethodPagCallEdge(cs, callerCid, calleeCid));
|
|
577
712
|
return srcNodes;
|
|
578
713
|
}
|
|
579
714
|
if (!calleeMethod.getCfg()) {
|
|
@@ -584,7 +719,6 @@ class PagBuilder {
|
|
|
584
719
|
// callee cid will updated if callee is singleton
|
|
585
720
|
calleeCid = calleeCS.cid;
|
|
586
721
|
// TODO: getParameterInstances's performance is not good. Need to refactor
|
|
587
|
-
//let params = calleeMethod.getParameterInstances();
|
|
588
722
|
let params = calleeMethod.getCfg().getStmts()
|
|
589
723
|
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
590
724
|
.map(stmt => stmt.getRightOp());
|
|
@@ -595,7 +729,6 @@ class PagBuilder {
|
|
|
595
729
|
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
596
730
|
let param = params.at(i);
|
|
597
731
|
// TODO: param type should be ArkParameterRef?
|
|
598
|
-
//if (arg && param && param instanceof ArkParameterRef) {
|
|
599
732
|
if (arg && param) {
|
|
600
733
|
if (arg instanceof Constant_1.Constant) {
|
|
601
734
|
continue;
|
|
@@ -629,7 +762,7 @@ class PagBuilder {
|
|
|
629
762
|
continue;
|
|
630
763
|
}
|
|
631
764
|
else if (retValue instanceof Expr_1.AbstractExpr) {
|
|
632
|
-
|
|
765
|
+
logger.debug(retValue);
|
|
633
766
|
continue;
|
|
634
767
|
}
|
|
635
768
|
else {
|
|
@@ -639,6 +772,86 @@ class PagBuilder {
|
|
|
639
772
|
}
|
|
640
773
|
return srcNodes;
|
|
641
774
|
}
|
|
775
|
+
addSDKMethodPagCallEdge(cs, callerCid, calleeCid) {
|
|
776
|
+
let srcNodes = [];
|
|
777
|
+
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
778
|
+
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
779
|
+
if (!calleeMethod) {
|
|
780
|
+
return srcNodes;
|
|
781
|
+
}
|
|
782
|
+
if (!this.sdkMethodParamValueMap.has(calleeNode.getID())) {
|
|
783
|
+
this.buildSDKFuncPag(calleeNode.getID());
|
|
784
|
+
}
|
|
785
|
+
this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod);
|
|
786
|
+
srcNodes.push(...this.addSDKMethodParamPagEdge(cs, callerCid, calleeCid, calleeNode.getID()));
|
|
787
|
+
return srcNodes;
|
|
788
|
+
}
|
|
789
|
+
addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod) {
|
|
790
|
+
let returnType = calleeMethod.getReturnType();
|
|
791
|
+
if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
// check fake heap object exists or not
|
|
795
|
+
let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
|
|
796
|
+
if (!cidMap) {
|
|
797
|
+
cidMap = new Map();
|
|
798
|
+
}
|
|
799
|
+
let newExpr = cidMap.get(calleeCid);
|
|
800
|
+
if (!newExpr) {
|
|
801
|
+
if (returnType instanceof Type_1.ClassType) {
|
|
802
|
+
newExpr = new Expr_1.ArkNewExpr(returnType);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
cidMap.set(calleeCid, newExpr);
|
|
806
|
+
this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
|
|
807
|
+
let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
|
|
808
|
+
let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
|
|
809
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
|
|
810
|
+
}
|
|
811
|
+
addSDKMethodParamPagEdge(cs, callerCid, calleeCid, funcID) {
|
|
812
|
+
var _a, _b;
|
|
813
|
+
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
814
|
+
let srcNodes = [];
|
|
815
|
+
if (argNum) {
|
|
816
|
+
// add args to parameters edges
|
|
817
|
+
for (let i = 0; i < argNum; i++) {
|
|
818
|
+
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
819
|
+
let paramValue;
|
|
820
|
+
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
821
|
+
// TODO: cannot find value
|
|
822
|
+
paramValue = this.sdkMethodParamValueMap.get(funcID)[i];
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
if (arg && paramValue) {
|
|
828
|
+
// Get or create new PAG node for argument and parameter
|
|
829
|
+
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
830
|
+
let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
|
|
831
|
+
if (dstPagNode instanceof Pag_1.PagLocalNode) {
|
|
832
|
+
// set the fake param Value in PagLocalNode
|
|
833
|
+
/**
|
|
834
|
+
* TODO: !!!
|
|
835
|
+
* some API param is in the form of anonymous method:
|
|
836
|
+
* component/common.d.ts
|
|
837
|
+
* declare function animateTo(value: AnimateParam, event: () => void): void;
|
|
838
|
+
*
|
|
839
|
+
* this param fake Value will create PagFuncNode rather than PagLocalNode
|
|
840
|
+
* when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
|
|
841
|
+
*/
|
|
842
|
+
dstPagNode.setSdkParam();
|
|
843
|
+
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
844
|
+
// create new DynCallSite
|
|
845
|
+
let sdkParamCallSite = new CallGraph_1.DynCallSite(funcID, sdkParamInvokeStmt, undefined, undefined);
|
|
846
|
+
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
847
|
+
}
|
|
848
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
849
|
+
srcNodes.push(srcPagNode.getID());
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
return srcNodes;
|
|
854
|
+
}
|
|
642
855
|
getOrNewPagNode(cid, v, s) {
|
|
643
856
|
if (v instanceof Ref_1.ArkThisRef) {
|
|
644
857
|
return this.getOrNewThisRefNode(cid, v);
|
|
@@ -647,15 +860,17 @@ class PagBuilder {
|
|
|
647
860
|
// remove below block once this issue fixed
|
|
648
861
|
// globalThis process can not be removed while all `globalThis` ref is the same Value
|
|
649
862
|
if (v instanceof Local_1.Local) {
|
|
650
|
-
if (v.getName()
|
|
863
|
+
if (v.getName() === "this") {
|
|
651
864
|
return this.getOrNewThisLoalNode(cid, v, s);
|
|
652
865
|
}
|
|
653
|
-
else if (v.getName()
|
|
866
|
+
else if (v.getName() === TSConst_1.GLOBAL_THIS && v.getDeclaringStmt() == null) {
|
|
654
867
|
// globalThis node has no cid
|
|
655
|
-
return this.getOrNewGlobalThisNode(
|
|
868
|
+
return this.getOrNewGlobalThisNode(-1);
|
|
656
869
|
}
|
|
657
870
|
}
|
|
658
|
-
v
|
|
871
|
+
if (v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef) {
|
|
872
|
+
v = this.getRealInstanceRef(v);
|
|
873
|
+
}
|
|
659
874
|
return this.pag.getOrNewNode(cid, v, s);
|
|
660
875
|
}
|
|
661
876
|
/**
|
|
@@ -706,7 +921,7 @@ class PagBuilder {
|
|
|
706
921
|
}
|
|
707
922
|
getPropertyNode(storage, propertyName, stmt) {
|
|
708
923
|
let storageMap = this.storagePropertyMap.get(storage);
|
|
709
|
-
let propertyLocal
|
|
924
|
+
let propertyLocal;
|
|
710
925
|
if (!storageMap) {
|
|
711
926
|
storageMap = new Map();
|
|
712
927
|
this.storagePropertyMap.set(storage, storageMap);
|
|
@@ -764,7 +979,7 @@ class PagBuilder {
|
|
|
764
979
|
let real;
|
|
765
980
|
if (v instanceof Ref_1.ArkInstanceFieldRef) {
|
|
766
981
|
base = v.getBase();
|
|
767
|
-
if (base instanceof Local_1.Local && base.getName()
|
|
982
|
+
if (base instanceof Local_1.Local && base.getName() === TSConst_1.GLOBAL_THIS && base.getDeclaringStmt() == null) {
|
|
768
983
|
// replace the base in fieldRef
|
|
769
984
|
base = this.getGlobalThisValue();
|
|
770
985
|
v.setBase(base);
|
|
@@ -797,13 +1012,13 @@ class PagBuilder {
|
|
|
797
1012
|
this.singletonFuncMap.set(funcID, false);
|
|
798
1013
|
return false;
|
|
799
1014
|
}
|
|
800
|
-
if (!arkMethod.
|
|
1015
|
+
if (!arkMethod.isStatic()) {
|
|
801
1016
|
this.singletonFuncMap.set(funcID, false);
|
|
802
1017
|
return false;
|
|
803
1018
|
}
|
|
804
1019
|
let funcPag = this.funcPags.get(funcID);
|
|
805
1020
|
let heapObjects = [...funcPag.getInternalEdges()]
|
|
806
|
-
.filter(edge => edge.kind
|
|
1021
|
+
.filter(edge => edge.kind === Pag_1.PagEdgeKind.Address)
|
|
807
1022
|
.map(edge => edge.dst);
|
|
808
1023
|
let returnValues = arkMethod.getReturnValues();
|
|
809
1024
|
let result = this.isValueConnected([...funcPag.getInternalEdges()], heapObjects, returnValues);
|
|
@@ -868,8 +1083,7 @@ class PagBuilder {
|
|
|
868
1083
|
return false;
|
|
869
1084
|
}
|
|
870
1085
|
getGlobalThisValue() {
|
|
871
|
-
|
|
872
|
-
return (_a = this.globalThisValue) !== null && _a !== void 0 ? _a : new Local_1.Local(Pag_1.GLOBAL_THIS);
|
|
1086
|
+
return this.globalThisValue;
|
|
873
1087
|
}
|
|
874
1088
|
getEdgeKindForAssignStmt(stmt) {
|
|
875
1089
|
if (this.stmtIsCreateAddressObj(stmt)) {
|
|
@@ -902,13 +1116,15 @@ class PagBuilder {
|
|
|
902
1116
|
switch (storageName) {
|
|
903
1117
|
case 'AppStorage':
|
|
904
1118
|
return Pag_1.StorageType.APP_STORAGE;
|
|
905
|
-
case 'SubscribedAbstractProperty':
|
|
1119
|
+
case 'SubscribedAbstractProperty': {
|
|
906
1120
|
let calleeBaseLocal = cs.callStmt.getInvokeExpr().getBase();
|
|
907
1121
|
let calleeBaseLocalNode = this.pag.getOrNewNode(cid, calleeBaseLocal);
|
|
908
1122
|
if (calleeBaseLocalNode.isStorageLinked()) {
|
|
909
1123
|
let storage = calleeBaseLocalNode.getStorage();
|
|
910
1124
|
return storage.StorageType;
|
|
911
1125
|
}
|
|
1126
|
+
return Pag_1.StorageType.Undefined;
|
|
1127
|
+
}
|
|
912
1128
|
default:
|
|
913
1129
|
return Pag_1.StorageType.Undefined;
|
|
914
1130
|
}
|
|
@@ -920,10 +1136,10 @@ class PagBuilder {
|
|
|
920
1136
|
let lhOp = stmt.getLeftOp();
|
|
921
1137
|
let rhOp = stmt.getRightOp();
|
|
922
1138
|
if ((rhOp instanceof Expr_1.ArkNewExpr || rhOp instanceof Expr_1.ArkNewArrayExpr) ||
|
|
923
|
-
(lhOp instanceof Local_1.Local && rhOp instanceof Local_1.Local &&
|
|
924
|
-
rhOp.
|
|
925
|
-
rhOp.
|
|
926
|
-
|
|
1139
|
+
(lhOp instanceof Local_1.Local && ((rhOp instanceof Local_1.Local && rhOp.getType() instanceof Type_1.FunctionType &&
|
|
1140
|
+
rhOp.getDeclaringStmt() === null) ||
|
|
1141
|
+
(rhOp instanceof Ref_1.AbstractFieldRef && rhOp.getType() instanceof Type_1.FunctionType))) ||
|
|
1142
|
+
(rhOp instanceof Local_1.Local && rhOp.getName() === TSConst_1.GLOBAL_THIS && rhOp.getDeclaringStmt() == null)) {
|
|
927
1143
|
return true;
|
|
928
1144
|
}
|
|
929
1145
|
// TODO: add other Address Obj creation
|
|
@@ -973,7 +1189,7 @@ class PagBuilder {
|
|
|
973
1189
|
}
|
|
974
1190
|
getRealThisLocal(input, funcId) {
|
|
975
1191
|
var _a;
|
|
976
|
-
if (input.getName()
|
|
1192
|
+
if (input.getName() !== 'this')
|
|
977
1193
|
return input;
|
|
978
1194
|
let real = input;
|
|
979
1195
|
let f = this.cg.getArkMethodByFuncID(funcId);
|
|
@@ -1003,5 +1219,142 @@ class PagBuilder {
|
|
|
1003
1219
|
getHandledFuncs() {
|
|
1004
1220
|
return Array.from(this.funcPags.keys());
|
|
1005
1221
|
}
|
|
1222
|
+
/**
|
|
1223
|
+
* build export edge in internal func pag
|
|
1224
|
+
* @param value: Value that need to check if it is from import/export
|
|
1225
|
+
* @param originValue: if Value if InstanceFieldRef, the base will be passed to `value` recursively,
|
|
1226
|
+
* fieldRef will be passed to `originValue`
|
|
1227
|
+
*/
|
|
1228
|
+
handleValueFromExternalScope(value, funcID, originValue) {
|
|
1229
|
+
if (value instanceof Local_1.Local) {
|
|
1230
|
+
if (value.getDeclaringStmt()) {
|
|
1231
|
+
// not from external scope
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (!value.getType()) {
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
let srcLocal = this.getSourceValueFromExternalScope(value, funcID);
|
|
1238
|
+
if (srcLocal) {
|
|
1239
|
+
// if `value` is from field base, use origin value(fieldRef) instead
|
|
1240
|
+
this.addInterFuncEdge(srcLocal, originValue !== null && originValue !== void 0 ? originValue : value, funcID);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
else if (value instanceof Ref_1.ArkInstanceFieldRef) {
|
|
1244
|
+
let base = value.getBase();
|
|
1245
|
+
if (base) {
|
|
1246
|
+
this.handleValueFromExternalScope(base, funcID, value);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
addInterFuncEdge(src, dst, funcID) {
|
|
1251
|
+
var _a, _b, _c;
|
|
1252
|
+
this.interFuncPags = (_a = this.interFuncPags) !== null && _a !== void 0 ? _a : new Map();
|
|
1253
|
+
let interFuncPag = (_b = this.interFuncPags.get(funcID)) !== null && _b !== void 0 ? _b : new Pag_1.InterFuncPag();
|
|
1254
|
+
// Export a local
|
|
1255
|
+
// Add a InterProcedural edge
|
|
1256
|
+
if (dst instanceof Local_1.Local) {
|
|
1257
|
+
let e = { src: src, dst: dst, kind: Pag_1.PagEdgeKind.InterProceduralCopy };
|
|
1258
|
+
interFuncPag.addToInterProceduralEdgeSet(e);
|
|
1259
|
+
this.addExportVariableMap(src, dst);
|
|
1260
|
+
}
|
|
1261
|
+
else if (dst instanceof Ref_1.ArkInstanceFieldRef) {
|
|
1262
|
+
// record the export base use
|
|
1263
|
+
this.addExportVariableMap(src, dst.getBase());
|
|
1264
|
+
}
|
|
1265
|
+
this.interFuncPags.set(funcID, interFuncPag);
|
|
1266
|
+
// Put the function which the src belongs to to worklist
|
|
1267
|
+
let srcFunc = (_c = src.getDeclaringStmt()) === null || _c === void 0 ? void 0 : _c.getCfg().getDeclaringMethod();
|
|
1268
|
+
if (srcFunc) {
|
|
1269
|
+
let srcFuncID = this.cg.getCallGraphNodeByMethod(srcFunc.getSignature()).getID();
|
|
1270
|
+
let cid = this.ctx.getNewContextID(srcFuncID);
|
|
1271
|
+
let csFuncID = new CSFuncID(cid, srcFuncID);
|
|
1272
|
+
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
1273
|
+
}
|
|
1274
|
+
// Extend other types of src here
|
|
1275
|
+
}
|
|
1276
|
+
getSourceValueFromExternalScope(value, funcID) {
|
|
1277
|
+
let sourceValue;
|
|
1278
|
+
// TODO: first from default method
|
|
1279
|
+
sourceValue = this.getDefaultMethodSourceValue(value, funcID);
|
|
1280
|
+
if (!sourceValue) {
|
|
1281
|
+
sourceValue = this.getExportSourceValue(value, funcID);
|
|
1282
|
+
}
|
|
1283
|
+
return sourceValue;
|
|
1284
|
+
}
|
|
1285
|
+
getDefaultMethodSourceValue(value, funcID) {
|
|
1286
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1287
|
+
// namespace check
|
|
1288
|
+
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
1289
|
+
if (!arkMethod) {
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
let declaringNameSpace = arkMethod.getDeclaringArkClass().getDeclaringArkNamespace();
|
|
1293
|
+
while (declaringNameSpace) {
|
|
1294
|
+
let nameSpaceLocals = (_c = (_b = (_a = declaringNameSpace.getDefaultClass()
|
|
1295
|
+
.getDefaultArkMethod()) === null || _a === void 0 ? void 0 : _a.getBody()) === null || _b === void 0 ? void 0 : _b.getLocals()) !== null && _c !== void 0 ? _c : new Map();
|
|
1296
|
+
if (nameSpaceLocals.has(value.getName())) {
|
|
1297
|
+
return nameSpaceLocals.get(value.getName());
|
|
1298
|
+
}
|
|
1299
|
+
declaringNameSpace = (_d = declaringNameSpace.getDeclaringArkNamespace()) !== null && _d !== void 0 ? _d : undefined;
|
|
1300
|
+
}
|
|
1301
|
+
// file check
|
|
1302
|
+
let declaringFile = arkMethod.getDeclaringArkFile();
|
|
1303
|
+
let fileLocals = (_g = (_f = (_e = declaringFile.getDefaultClass()
|
|
1304
|
+
.getDefaultArkMethod()) === null || _e === void 0 ? void 0 : _e.getBody()) === null || _f === void 0 ? void 0 : _f.getLocals()) !== null && _g !== void 0 ? _g : new Map();
|
|
1305
|
+
if (!fileLocals.has(value.getName())) {
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
return fileLocals.get(value.getName());
|
|
1309
|
+
}
|
|
1310
|
+
getExportSourceValue(value, funcID) {
|
|
1311
|
+
let curMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
1312
|
+
if (!curMethod) {
|
|
1313
|
+
return;
|
|
1314
|
+
}
|
|
1315
|
+
let curFile = curMethod.getDeclaringArkFile();
|
|
1316
|
+
let impInfo = curFile.getImportInfoBy(value.getName());
|
|
1317
|
+
if (!impInfo) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
let exportSource = impInfo.getLazyExportInfo();
|
|
1321
|
+
if (!exportSource) {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
let exportSouceValue = exportSource.getArkExport();
|
|
1325
|
+
if (exportSouceValue instanceof Local_1.Local) {
|
|
1326
|
+
return exportSouceValue;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
addExportVariableMap(src, dst) {
|
|
1330
|
+
var _a;
|
|
1331
|
+
let exportMap = (_a = this.externalScopeVariableMap.get(src)) !== null && _a !== void 0 ? _a : [];
|
|
1332
|
+
if (!exportMap.includes(dst)) {
|
|
1333
|
+
exportMap.push(dst);
|
|
1334
|
+
this.externalScopeVariableMap.set(src, exportMap);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
getExportVariableMap(src) {
|
|
1338
|
+
var _a;
|
|
1339
|
+
return (_a = this.externalScopeVariableMap.get(src)) !== null && _a !== void 0 ? _a : [];
|
|
1340
|
+
}
|
|
1341
|
+
/// Add inter-procedural Pag Nodes and Edges
|
|
1342
|
+
addEdgesFromInterFuncPag(interFuncPag, cid) {
|
|
1343
|
+
let edges = interFuncPag.getInterProceduralEdges();
|
|
1344
|
+
if (edges.size === 0) {
|
|
1345
|
+
return false;
|
|
1346
|
+
}
|
|
1347
|
+
for (let e of edges) {
|
|
1348
|
+
// Existing local exported nodes -> ExportNode
|
|
1349
|
+
let exportLocal = e.src;
|
|
1350
|
+
let dstPagNode = this.getOrNewPagNode(cid, e.dst);
|
|
1351
|
+
// get export local node in all cid
|
|
1352
|
+
let existingNodes = this.pag.getNodesByValue(exportLocal);
|
|
1353
|
+
existingNodes === null || existingNodes === void 0 ? void 0 : existingNodes.forEach(n => {
|
|
1354
|
+
this.pag.addPagEdge(this.pag.getNode(n), dstPagNode, e.kind);
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1006
1359
|
}
|
|
1007
1360
|
exports.PagBuilder = PagBuilder;
|