arkanalyzer 1.0.7 → 1.0.9
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/lib/Config.d.ts +9 -1
- package/lib/Config.d.ts.map +1 -1
- package/lib/Config.js +24 -11
- package/lib/Scene.d.ts +49 -42
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +124 -93
- package/lib/callgraph/algorithm/AbstractAnalysis.js +1 -1
- package/lib/callgraph/common/Statistics.js +1 -1
- 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 +15 -5
- package/lib/callgraph/model/builder/CallGraphBuilder.js +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +35 -8
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +89 -8
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +32 -5
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +378 -83
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +3 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +71 -18
- package/lib/core/base/Constant.d.ts +25 -5
- package/lib/core/base/Constant.d.ts.map +1 -1
- package/lib/core/base/Constant.js +46 -8
- package/lib/core/base/Expr.d.ts +45 -40
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +236 -150
- package/lib/core/base/Local.d.ts +2 -2
- package/lib/core/base/Local.d.ts.map +1 -1
- package/lib/core/base/Local.js +2 -2
- package/lib/core/base/Ref.d.ts +38 -37
- package/lib/core/base/Ref.d.ts.map +1 -1
- package/lib/core/base/Ref.js +102 -70
- package/lib/core/base/Stmt.d.ts +4 -0
- package/lib/core/base/Stmt.d.ts.map +1 -1
- package/lib/core/base/Stmt.js +12 -1
- package/lib/core/base/Type.d.ts +4 -0
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +41 -17
- 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 +1 -1
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +24 -8
- package/lib/core/common/CfgBuilder.d.ts.map +1 -1
- package/lib/core/common/CfgBuilder.js +5 -0
- 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 +2 -1
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +28 -15
- 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/IRUtils.d.ts +6 -0
- package/lib/core/common/IRUtils.d.ts.map +1 -1
- package/lib/core/common/IRUtils.js +29 -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 +32 -32
- 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 +218 -87
- 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 +8 -25
- package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowSolver.js +2 -4
- package/lib/core/dataflow/TiantAnalysis.js +2 -1
- package/lib/core/dataflow/Util.d.ts +1 -1
- package/lib/core/dataflow/Util.d.ts.map +1 -1
- package/lib/core/dataflow/Util.js +8 -7
- package/lib/core/graph/BasicBlock.d.ts +41 -0
- package/lib/core/graph/BasicBlock.d.ts.map +1 -1
- package/lib/core/graph/BasicBlock.js +132 -1
- 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 +129 -6
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ViewTreeBuilder.js +3 -2
- package/lib/core/model/ArkBaseModel.d.ts +8 -0
- package/lib/core/model/ArkBaseModel.d.ts.map +1 -1
- package/lib/core/model/ArkBaseModel.js +55 -3
- package/lib/core/model/ArkClass.d.ts +36 -30
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +78 -39
- package/lib/core/model/ArkExport.d.ts +3 -0
- package/lib/core/model/ArkExport.d.ts.map +1 -1
- package/lib/core/model/ArkExport.js +10 -0
- package/lib/core/model/ArkField.d.ts +2 -0
- package/lib/core/model/ArkField.d.ts.map +1 -1
- package/lib/core/model/ArkField.js +3 -0
- package/lib/core/model/ArkFile.d.ts +4 -0
- package/lib/core/model/ArkFile.d.ts.map +1 -1
- package/lib/core/model/ArkFile.js +20 -0
- package/lib/core/model/ArkImport.d.ts +2 -0
- package/lib/core/model/ArkImport.d.ts.map +1 -1
- package/lib/core/model/ArkImport.js +3 -0
- 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 +156 -53
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +309 -54
- package/lib/core/model/ArkNamespace.d.ts +4 -0
- package/lib/core/model/ArkNamespace.d.ts.map +1 -1
- package/lib/core/model/ArkNamespace.js +13 -0
- package/lib/core/model/ArkSignature.d.ts +11 -5
- package/lib/core/model/ArkSignature.d.ts.map +1 -1
- package/lib/core/model/ArkSignature.js +38 -18
- package/lib/core/model/builder/ArkClassBuilder.d.ts +0 -1
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +9 -34
- package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkExportBuilder.js +6 -1
- package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkFieldBuilder.js +3 -0
- package/lib/core/model/builder/ArkFileBuilder.js +1 -1
- 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 +12 -5
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +2 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +87 -47
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkNamespaceBuilder.js +2 -0
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +25 -2
- package/lib/save/source/SourceClass.d.ts.map +1 -1
- package/lib/save/source/SourceClass.js +4 -0
- package/lib/save/source/SourceField.d.ts.map +1 -1
- package/lib/save/source/SourceField.js +4 -0
- package/lib/save/source/SourceMethod.d.ts.map +1 -1
- package/lib/save/source/SourceMethod.js +7 -0
- package/lib/save/source/SourceModule.d.ts.map +1 -1
- package/lib/save/source/SourceModule.js +14 -9
- 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.map +1 -1
- package/lib/save/source/SourceStmt.js +15 -3
- 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 +72 -41
- package/lib/save/source/SourceUtils.d.ts.map +1 -1
- package/lib/save/source/SourceUtils.js +3 -2
- package/lib/transformer/StaticSingleAssignmentFormer.js +1 -1
- package/lib/utils/CfgStructualAnalysis.d.ts +1 -0
- package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -1
- package/lib/utils/CfgStructualAnalysis.js +41 -7
- 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/getAllFiles.d.ts +1 -1
- package/lib/utils/getAllFiles.d.ts.map +1 -1
- package/lib/utils/getAllFiles.js +4 -5
- package/package.json +3 -2
|
@@ -50,6 +50,8 @@ const Statistics_1 = require("../common/Statistics");
|
|
|
50
50
|
const Context_1 = require("./Context");
|
|
51
51
|
const Pag_1 = require("./Pag");
|
|
52
52
|
const PtsDS_1 = require("./PtsDS");
|
|
53
|
+
const TSConst_1 = require("../../core/common/TSConst");
|
|
54
|
+
const Const_1 = require("../../core/common/Const");
|
|
53
55
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
|
|
54
56
|
class CSFuncID {
|
|
55
57
|
constructor(cid, fid) {
|
|
@@ -69,10 +71,15 @@ class PagBuilder {
|
|
|
69
71
|
this.cid2ThisRefMap = new Map();
|
|
70
72
|
this.cid2ThisLocalMap = new Map();
|
|
71
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(""));
|
|
72
77
|
this.funcHandledThisRound = new Set();
|
|
73
78
|
this.updatedNodesThisRound = new Map();
|
|
74
79
|
this.singletonFuncMap = new Map();
|
|
80
|
+
this.globalThisValue = new Local_1.Local(TSConst_1.GLOBAL_THIS);
|
|
75
81
|
this.storagePropertyMap = new Map();
|
|
82
|
+
this.externalScopeVariableMap = new Map();
|
|
76
83
|
this.pag = p;
|
|
77
84
|
this.cg = cg;
|
|
78
85
|
this.funcPags = new Map;
|
|
@@ -105,6 +112,8 @@ class PagBuilder {
|
|
|
105
112
|
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
106
113
|
});
|
|
107
114
|
this.handleReachable();
|
|
115
|
+
this.globalThisPagNode = this.getOrNewGlobalThisNode(-1);
|
|
116
|
+
this.pag.addPagEdge(this.globalThisPagNode, this.globalThisPagNode, Pag_1.PagEdgeKind.Copy);
|
|
108
117
|
}
|
|
109
118
|
handleReachable() {
|
|
110
119
|
if (this.worklist.length === 0) {
|
|
@@ -130,18 +139,20 @@ class PagBuilder {
|
|
|
130
139
|
if (this.funcPags.has(funcID)) {
|
|
131
140
|
return false;
|
|
132
141
|
}
|
|
133
|
-
let fpag = new Pag_1.FuncPag();
|
|
134
142
|
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
135
143
|
if (arkMethod == null) {
|
|
136
144
|
return false;
|
|
137
145
|
}
|
|
138
146
|
let cfg = arkMethod.getCfg();
|
|
139
147
|
if (!cfg) {
|
|
148
|
+
this.buildSDKFuncPag(funcID);
|
|
140
149
|
return false;
|
|
141
150
|
}
|
|
142
151
|
logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`);
|
|
152
|
+
let fpag = new Pag_1.FuncPag();
|
|
143
153
|
for (let stmt of cfg.getStmts()) {
|
|
144
154
|
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
155
|
+
this.handleValueFromExternalScope(stmt.getRightOp(), funcID);
|
|
145
156
|
// Add non-call edges
|
|
146
157
|
let kind = this.getEdgeKindForAssignStmt(stmt);
|
|
147
158
|
if (kind !== Pag_1.PagEdgeKind.Unknown) {
|
|
@@ -154,7 +165,13 @@ class PagBuilder {
|
|
|
154
165
|
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
155
166
|
if (cs) {
|
|
156
167
|
// direct call is already existing in CG
|
|
168
|
+
// TODO: API Invoke stmt has anonymous method param, how to add these param into callee
|
|
157
169
|
fpag.addNormalCallSite(cs);
|
|
170
|
+
if (ivkExpr.getMethodSignature().getDeclaringClassSignature()
|
|
171
|
+
.getDeclaringFileSignature().getFileName() === Const_1.UNKNOWN_FILE_NAME) {
|
|
172
|
+
fpag.addUnknownCallSite(cs);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
158
175
|
}
|
|
159
176
|
else {
|
|
160
177
|
throw new Error('Can not find static callsite');
|
|
@@ -172,7 +189,14 @@ class PagBuilder {
|
|
|
172
189
|
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
173
190
|
if (cs) {
|
|
174
191
|
// direct call or constructor call is already existing in CG
|
|
175
|
-
|
|
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
|
+
}
|
|
176
200
|
continue;
|
|
177
201
|
}
|
|
178
202
|
let dycs = this.cg.getDynCallsiteByStmt(stmt);
|
|
@@ -191,7 +215,30 @@ class PagBuilder {
|
|
|
191
215
|
this.pagStat.numTotalFunction++;
|
|
192
216
|
return true;
|
|
193
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
|
+
}
|
|
194
240
|
buildPagFromFuncPag(funcID, cid) {
|
|
241
|
+
var _a;
|
|
195
242
|
let funcPag = this.funcPags.get(funcID);
|
|
196
243
|
if (funcPag === undefined) {
|
|
197
244
|
return;
|
|
@@ -200,8 +247,13 @@ class PagBuilder {
|
|
|
200
247
|
return;
|
|
201
248
|
}
|
|
202
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
|
+
}
|
|
203
254
|
this.addCallsEdgesFromFuncPag(funcPag, cid);
|
|
204
|
-
this.addDynamicCallSite(funcPag);
|
|
255
|
+
this.addDynamicCallSite(funcPag, funcID);
|
|
256
|
+
this.addUnknownCallSite(funcPag, funcID);
|
|
205
257
|
this.handledFunc.add(`${cid}-${funcID}`);
|
|
206
258
|
}
|
|
207
259
|
/// Add Pag Nodes and Edges in function
|
|
@@ -224,9 +276,9 @@ class PagBuilder {
|
|
|
224
276
|
/// add Copy edges interprocedural
|
|
225
277
|
addCallsEdgesFromFuncPag(funcPag, cid) {
|
|
226
278
|
for (let cs of funcPag.getNormalCallSites()) {
|
|
279
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
227
280
|
let calleeCid = this.ctx.getOrNewContext(cid, cs.calleeFuncID, true);
|
|
228
281
|
let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
|
|
229
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
230
282
|
// process the Storage API(Static)
|
|
231
283
|
if (!this.processStorage(cs, calleeCGNode, cid)) {
|
|
232
284
|
// If not Storage API, process normal edge
|
|
@@ -335,6 +387,9 @@ class PagBuilder {
|
|
|
335
387
|
}
|
|
336
388
|
}
|
|
337
389
|
processStorageGet(cs, cid) {
|
|
390
|
+
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
338
393
|
let leftOp = cs.callStmt.getLeftOp();
|
|
339
394
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
340
395
|
let propertyName;
|
|
@@ -368,7 +423,7 @@ class PagBuilder {
|
|
|
368
423
|
}
|
|
369
424
|
return undefined;
|
|
370
425
|
}
|
|
371
|
-
addDynamicCallSite(funcPag) {
|
|
426
|
+
addDynamicCallSite(funcPag, funcID) {
|
|
372
427
|
// add dyn callsite in funcpag to base node
|
|
373
428
|
for (let cs of funcPag.getDynamicCallSites()) {
|
|
374
429
|
let invokeExpr = cs.callStmt.getInvokeExpr();
|
|
@@ -381,6 +436,13 @@ class PagBuilder {
|
|
|
381
436
|
}
|
|
382
437
|
// TODO: check base under different cid
|
|
383
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
|
+
}
|
|
384
446
|
if (!baseNodeIDs) {
|
|
385
447
|
logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
|
|
386
448
|
continue;
|
|
@@ -394,79 +456,111 @@ class PagBuilder {
|
|
|
394
456
|
}
|
|
395
457
|
}
|
|
396
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
|
+
}
|
|
397
486
|
addDynamicCallEdge(cs, baseClassPTNode, cid) {
|
|
398
487
|
let srcNodes = [];
|
|
399
488
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
400
489
|
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
401
490
|
let value = ptNode.getValue();
|
|
402
|
-
let
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
491
|
+
let callees = this.getDynamicCallee(ptNode, value, ivkExpr, cs);
|
|
492
|
+
for (let callee of callees) {
|
|
493
|
+
if (!callee) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
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
|
+
}
|
|
424
515
|
}
|
|
425
516
|
}
|
|
426
517
|
return srcNodes;
|
|
427
518
|
}
|
|
428
519
|
getDynamicCallee(ptNode, value, ivkExpr, cs) {
|
|
429
|
-
let callee =
|
|
430
|
-
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
520
|
+
let callee = [];
|
|
431
521
|
if (ptNode instanceof Pag_1.PagFuncNode) {
|
|
432
522
|
// function ptr invoke
|
|
433
|
-
|
|
523
|
+
let tempCallee = this.scene.getMethod(ptNode.getMethod());
|
|
434
524
|
if (!callee) {
|
|
435
|
-
return
|
|
525
|
+
return callee;
|
|
436
526
|
}
|
|
527
|
+
callee.push(tempCallee);
|
|
437
528
|
}
|
|
438
529
|
else {
|
|
530
|
+
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
439
531
|
// instance method invoke
|
|
440
532
|
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
441
|
-
return
|
|
533
|
+
return callee;
|
|
442
534
|
}
|
|
535
|
+
let tempCallee;
|
|
443
536
|
// try to get callee by MethodSignature
|
|
444
537
|
if (value instanceof Expr_1.ArkNewExpr) {
|
|
445
538
|
// get class signature
|
|
446
539
|
let clsSig = value.getType().getClassSignature();
|
|
447
540
|
let cls;
|
|
448
541
|
cls = this.scene.getClass(clsSig);
|
|
449
|
-
while (!
|
|
450
|
-
|
|
542
|
+
while (!tempCallee && cls) {
|
|
543
|
+
tempCallee = cls.getMethodWithName(calleeName);
|
|
451
544
|
cls = cls.getSuperClass();
|
|
452
545
|
}
|
|
453
|
-
if (!
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
// try to get callee by anonymous method in param
|
|
458
|
-
if (!callee) {
|
|
459
|
-
// try to change callee to param anonymous method
|
|
460
|
-
// TODO: anonymous method param and return value pointer pass
|
|
461
|
-
let args = cs.args;
|
|
462
|
-
if ((args === null || args === void 0 ? void 0 : args.length) === 1 && args[0].getType() instanceof Type_1.FunctionType) {
|
|
463
|
-
callee = this.scene.getMethod(args[0].getType().getMethodSignature());
|
|
546
|
+
if (!tempCallee) {
|
|
547
|
+
tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
464
548
|
}
|
|
465
549
|
}
|
|
466
|
-
if (!
|
|
550
|
+
if (!tempCallee && cs.args) {
|
|
467
551
|
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
468
552
|
// return empty node when {o_2} come in
|
|
469
|
-
|
|
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);
|
|
470
564
|
}
|
|
471
565
|
}
|
|
472
566
|
return callee;
|
|
@@ -566,7 +660,7 @@ class PagBuilder {
|
|
|
566
660
|
addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, callerFunID) {
|
|
567
661
|
var _a;
|
|
568
662
|
if (!callee || !callee.getCfg()) {
|
|
569
|
-
|
|
663
|
+
logger.error(`callee is null`);
|
|
570
664
|
return -1;
|
|
571
665
|
}
|
|
572
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);
|
|
@@ -581,6 +675,14 @@ class PagBuilder {
|
|
|
581
675
|
let srcBaseLocal = ivkExpr.getBase();
|
|
582
676
|
srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID);
|
|
583
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
|
+
}
|
|
584
686
|
if (!srcNodeId) {
|
|
585
687
|
throw new Error('Can not get base node');
|
|
586
688
|
}
|
|
@@ -605,31 +707,8 @@ class PagBuilder {
|
|
|
605
707
|
// TODO: check if nodes need to delete
|
|
606
708
|
return srcNodes;
|
|
607
709
|
}
|
|
608
|
-
if (calleeNode.
|
|
609
|
-
|
|
610
|
-
// TODO: add new array type
|
|
611
|
-
if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
612
|
-
return srcNodes;
|
|
613
|
-
}
|
|
614
|
-
// check fake heap object exists or not
|
|
615
|
-
let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
|
|
616
|
-
if (!cidMap) {
|
|
617
|
-
cidMap = new Map();
|
|
618
|
-
}
|
|
619
|
-
let newExpr = cidMap.get(calleeCid);
|
|
620
|
-
if (!newExpr) {
|
|
621
|
-
if (returnType instanceof Type_1.ClassType) {
|
|
622
|
-
newExpr = new Expr_1.ArkNewExpr(returnType);
|
|
623
|
-
}
|
|
624
|
-
// } else if (returnType instanceof ArrayType) {
|
|
625
|
-
// TODO: check how to transform array type 2 newArrayExpr
|
|
626
|
-
// }
|
|
627
|
-
}
|
|
628
|
-
cidMap.set(calleeCid, newExpr);
|
|
629
|
-
this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
|
|
630
|
-
let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
|
|
631
|
-
let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
|
|
632
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
|
|
710
|
+
if (calleeNode.isSdkMethod()) {
|
|
711
|
+
srcNodes.push(...this.addSDKMethodPagCallEdge(cs, callerCid, calleeCid));
|
|
633
712
|
return srcNodes;
|
|
634
713
|
}
|
|
635
714
|
if (!calleeMethod.getCfg()) {
|
|
@@ -640,7 +719,6 @@ class PagBuilder {
|
|
|
640
719
|
// callee cid will updated if callee is singleton
|
|
641
720
|
calleeCid = calleeCS.cid;
|
|
642
721
|
// TODO: getParameterInstances's performance is not good. Need to refactor
|
|
643
|
-
//let params = calleeMethod.getParameterInstances();
|
|
644
722
|
let params = calleeMethod.getCfg().getStmts()
|
|
645
723
|
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
646
724
|
.map(stmt => stmt.getRightOp());
|
|
@@ -651,7 +729,6 @@ class PagBuilder {
|
|
|
651
729
|
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
652
730
|
let param = params.at(i);
|
|
653
731
|
// TODO: param type should be ArkParameterRef?
|
|
654
|
-
//if (arg && param && param instanceof ArkParameterRef) {
|
|
655
732
|
if (arg && param) {
|
|
656
733
|
if (arg instanceof Constant_1.Constant) {
|
|
657
734
|
continue;
|
|
@@ -685,7 +762,7 @@ class PagBuilder {
|
|
|
685
762
|
continue;
|
|
686
763
|
}
|
|
687
764
|
else if (retValue instanceof Expr_1.AbstractExpr) {
|
|
688
|
-
|
|
765
|
+
logger.debug(retValue);
|
|
689
766
|
continue;
|
|
690
767
|
}
|
|
691
768
|
else {
|
|
@@ -695,6 +772,86 @@ class PagBuilder {
|
|
|
695
772
|
}
|
|
696
773
|
return srcNodes;
|
|
697
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
|
+
}
|
|
698
855
|
getOrNewPagNode(cid, v, s) {
|
|
699
856
|
if (v instanceof Ref_1.ArkThisRef) {
|
|
700
857
|
return this.getOrNewThisRefNode(cid, v);
|
|
@@ -706,12 +863,14 @@ class PagBuilder {
|
|
|
706
863
|
if (v.getName() === "this") {
|
|
707
864
|
return this.getOrNewThisLoalNode(cid, v, s);
|
|
708
865
|
}
|
|
709
|
-
else if (v.getName() ===
|
|
866
|
+
else if (v.getName() === TSConst_1.GLOBAL_THIS && v.getDeclaringStmt() == null) {
|
|
710
867
|
// globalThis node has no cid
|
|
711
|
-
return this.getOrNewGlobalThisNode(
|
|
868
|
+
return this.getOrNewGlobalThisNode(-1);
|
|
712
869
|
}
|
|
713
870
|
}
|
|
714
|
-
v
|
|
871
|
+
if (v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef) {
|
|
872
|
+
v = this.getRealInstanceRef(v);
|
|
873
|
+
}
|
|
715
874
|
return this.pag.getOrNewNode(cid, v, s);
|
|
716
875
|
}
|
|
717
876
|
/**
|
|
@@ -820,7 +979,7 @@ class PagBuilder {
|
|
|
820
979
|
let real;
|
|
821
980
|
if (v instanceof Ref_1.ArkInstanceFieldRef) {
|
|
822
981
|
base = v.getBase();
|
|
823
|
-
if (base instanceof Local_1.Local && base.getName() ===
|
|
982
|
+
if (base instanceof Local_1.Local && base.getName() === TSConst_1.GLOBAL_THIS && base.getDeclaringStmt() == null) {
|
|
824
983
|
// replace the base in fieldRef
|
|
825
984
|
base = this.getGlobalThisValue();
|
|
826
985
|
v.setBase(base);
|
|
@@ -924,8 +1083,7 @@ class PagBuilder {
|
|
|
924
1083
|
return false;
|
|
925
1084
|
}
|
|
926
1085
|
getGlobalThisValue() {
|
|
927
|
-
|
|
928
|
-
return (_a = this.globalThisValue) !== null && _a !== void 0 ? _a : new Local_1.Local(Pag_1.GLOBAL_THIS);
|
|
1086
|
+
return this.globalThisValue;
|
|
929
1087
|
}
|
|
930
1088
|
getEdgeKindForAssignStmt(stmt) {
|
|
931
1089
|
if (this.stmtIsCreateAddressObj(stmt)) {
|
|
@@ -981,7 +1139,7 @@ class PagBuilder {
|
|
|
981
1139
|
(lhOp instanceof Local_1.Local && ((rhOp instanceof Local_1.Local && rhOp.getType() instanceof Type_1.FunctionType &&
|
|
982
1140
|
rhOp.getDeclaringStmt() === null) ||
|
|
983
1141
|
(rhOp instanceof Ref_1.AbstractFieldRef && rhOp.getType() instanceof Type_1.FunctionType))) ||
|
|
984
|
-
(rhOp instanceof Local_1.Local && rhOp.getName() ===
|
|
1142
|
+
(rhOp instanceof Local_1.Local && rhOp.getName() === TSConst_1.GLOBAL_THIS && rhOp.getDeclaringStmt() == null)) {
|
|
985
1143
|
return true;
|
|
986
1144
|
}
|
|
987
1145
|
// TODO: add other Address Obj creation
|
|
@@ -1061,5 +1219,142 @@ class PagBuilder {
|
|
|
1061
1219
|
getHandledFuncs() {
|
|
1062
1220
|
return Array.from(this.funcPags.keys());
|
|
1063
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
|
+
}
|
|
1064
1359
|
}
|
|
1065
1360
|
exports.PagBuilder = PagBuilder;
|