arkanalyzer 1.0.5
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/LICENSE +201 -0
- package/README.en.md +88 -0
- package/README.md +98 -0
- package/docs/HowToCreatePR.md +55 -0
- package/docs/HowToHandleIssues.md +155 -0
- package/docs/quickstart.pdf +0 -0
- package/lib/Config.d.ts +26 -0
- package/lib/Config.d.ts.map +1 -0
- package/lib/Config.js +128 -0
- package/lib/Scene.d.ts +125 -0
- package/lib/Scene.d.ts.map +1 -0
- package/lib/Scene.js +762 -0
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +28 -0
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -0
- package/lib/callgraph/algorithm/AbstractAnalysis.js +137 -0
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts +11 -0
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -0
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +71 -0
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts +16 -0
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -0
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +147 -0
- package/lib/callgraph/common/Statistics.d.ts +58 -0
- package/lib/callgraph/common/Statistics.d.ts.map +1 -0
- package/lib/callgraph/common/Statistics.js +203 -0
- package/lib/callgraph/model/BaseGraph.d.ts +62 -0
- package/lib/callgraph/model/BaseGraph.d.ts.map +1 -0
- package/lib/callgraph/model/BaseGraph.js +158 -0
- package/lib/callgraph/model/CallGraph.d.ts +94 -0
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -0
- package/lib/callgraph/model/CallGraph.js +339 -0
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +16 -0
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts.map +1 -0
- package/lib/callgraph/model/builder/CallGraphBuilder.js +106 -0
- package/lib/callgraph/pointerAnalysis/Context.d.ts +38 -0
- package/lib/callgraph/pointerAnalysis/Context.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/Context.js +156 -0
- package/lib/callgraph/pointerAnalysis/DummyCallCreator.d.ts +23 -0
- package/lib/callgraph/pointerAnalysis/DummyCallCreator.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/DummyCallCreator.js +104 -0
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +209 -0
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/Pag.js +774 -0
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +88 -0
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +821 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +64 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +502 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts +9 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.js +57 -0
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts +58 -0
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/PtsDS.js +234 -0
- package/lib/core/base/Constant.d.ts +17 -0
- package/lib/core/base/Constant.d.ts.map +1 -0
- package/lib/core/base/Constant.js +53 -0
- package/lib/core/base/Decorator.d.ts +15 -0
- package/lib/core/base/Decorator.d.ts.map +1 -0
- package/lib/core/base/Decorator.js +43 -0
- package/lib/core/base/DefUseChain.d.ts +9 -0
- package/lib/core/base/DefUseChain.d.ts.map +1 -0
- package/lib/core/base/DefUseChain.js +25 -0
- package/lib/core/base/Expr.d.ts +219 -0
- package/lib/core/base/Expr.d.ts.map +1 -0
- package/lib/core/base/Expr.js +896 -0
- package/lib/core/base/Local.d.ts +40 -0
- package/lib/core/base/Local.d.ts.map +1 -0
- package/lib/core/base/Local.js +101 -0
- package/lib/core/base/Position.d.ts +39 -0
- package/lib/core/base/Position.d.ts.map +1 -0
- package/lib/core/base/Position.js +86 -0
- package/lib/core/base/Ref.d.ts +75 -0
- package/lib/core/base/Ref.d.ts.map +1 -0
- package/lib/core/base/Ref.js +286 -0
- package/lib/core/base/Stmt.d.ts +109 -0
- package/lib/core/base/Stmt.d.ts.map +1 -0
- package/lib/core/base/Stmt.js +374 -0
- package/lib/core/base/Type.d.ts +220 -0
- package/lib/core/base/Type.d.ts.map +1 -0
- package/lib/core/base/Type.js +477 -0
- package/lib/core/base/Value.d.ts +11 -0
- package/lib/core/base/Value.d.ts.map +1 -0
- package/lib/core/base/Value.js +16 -0
- package/lib/core/common/ArkIRTransformer.d.ts +101 -0
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -0
- package/lib/core/common/ArkIRTransformer.js +1674 -0
- package/lib/core/common/BodyBuilder.d.ts +10 -0
- package/lib/core/common/BodyBuilder.d.ts.map +1 -0
- package/lib/core/common/BodyBuilder.js +34 -0
- package/lib/core/common/Builtin.d.ts +35 -0
- package/lib/core/common/Builtin.d.ts.map +1 -0
- package/lib/core/common/Builtin.js +78 -0
- package/lib/core/common/CfgBuilder.d.ts +136 -0
- package/lib/core/common/CfgBuilder.d.ts.map +1 -0
- package/lib/core/common/CfgBuilder.js +1241 -0
- package/lib/core/common/Const.d.ts +15 -0
- package/lib/core/common/Const.d.ts.map +1 -0
- package/lib/core/common/Const.js +34 -0
- package/lib/core/common/DummyMainCreater.d.ts +48 -0
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -0
- package/lib/core/common/DummyMainCreater.js +433 -0
- package/lib/core/common/EtsConst.d.ts +65 -0
- package/lib/core/common/EtsConst.d.ts.map +1 -0
- package/lib/core/common/EtsConst.js +918 -0
- package/lib/core/common/ExprUseReplacer.d.ts +18 -0
- package/lib/core/common/ExprUseReplacer.d.ts.map +1 -0
- package/lib/core/common/ExprUseReplacer.js +88 -0
- package/lib/core/common/IRUtils.d.ts +7 -0
- package/lib/core/common/IRUtils.d.ts.map +1 -0
- package/lib/core/common/IRUtils.js +39 -0
- package/lib/core/common/ModelUtils.d.ts +61 -0
- package/lib/core/common/ModelUtils.d.ts.map +1 -0
- package/lib/core/common/ModelUtils.js +628 -0
- package/lib/core/common/RefUseReplacer.d.ts +14 -0
- package/lib/core/common/RefUseReplacer.d.ts.map +1 -0
- package/lib/core/common/RefUseReplacer.js +50 -0
- package/lib/core/common/StmtUseReplacer.d.ts +16 -0
- package/lib/core/common/StmtUseReplacer.d.ts.map +1 -0
- package/lib/core/common/StmtUseReplacer.js +88 -0
- package/lib/core/common/TSConst.d.ts +11 -0
- package/lib/core/common/TSConst.d.ts.map +1 -0
- package/lib/core/common/TSConst.js +28 -0
- package/lib/core/common/TypeInference.d.ts +44 -0
- package/lib/core/common/TypeInference.d.ts.map +1 -0
- package/lib/core/common/TypeInference.js +519 -0
- package/lib/core/common/ValueUtil.d.ts +17 -0
- package/lib/core/common/ValueUtil.d.ts.map +1 -0
- package/lib/core/common/ValueUtil.js +71 -0
- package/lib/core/common/VisibleValue.d.ts +37 -0
- package/lib/core/common/VisibleValue.d.ts.map +1 -0
- package/lib/core/common/VisibleValue.js +212 -0
- package/lib/core/dataflow/DataflowProblem.d.ts +21 -0
- package/lib/core/dataflow/DataflowProblem.d.ts.map +1 -0
- package/lib/core/dataflow/DataflowProblem.js +33 -0
- package/lib/core/dataflow/DataflowResult.d.ts +8 -0
- package/lib/core/dataflow/DataflowResult.d.ts.map +1 -0
- package/lib/core/dataflow/DataflowResult.js +26 -0
- package/lib/core/dataflow/DataflowSolver.d.ts +40 -0
- package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -0
- package/lib/core/dataflow/DataflowSolver.js +318 -0
- package/lib/core/dataflow/Edge.d.ts +16 -0
- package/lib/core/dataflow/Edge.d.ts.map +1 -0
- package/lib/core/dataflow/Edge.js +40 -0
- package/lib/core/dataflow/Fact.d.ts +7 -0
- package/lib/core/dataflow/Fact.d.ts.map +1 -0
- package/lib/core/dataflow/Fact.js +24 -0
- package/lib/core/dataflow/TiantAnalysis.d.ts +37 -0
- package/lib/core/dataflow/TiantAnalysis.d.ts.map +1 -0
- package/lib/core/dataflow/TiantAnalysis.js +326 -0
- package/lib/core/dataflow/UndefinedVariable.d.ts +32 -0
- package/lib/core/dataflow/UndefinedVariable.d.ts.map +1 -0
- package/lib/core/dataflow/UndefinedVariable.js +235 -0
- package/lib/core/dataflow/Util.d.ts +8 -0
- package/lib/core/dataflow/Util.d.ts.map +1 -0
- package/lib/core/dataflow/Util.js +137 -0
- package/lib/core/graph/BasicBlock.d.ts +26 -0
- package/lib/core/graph/BasicBlock.d.ts.map +1 -0
- package/lib/core/graph/BasicBlock.js +92 -0
- package/lib/core/graph/Cfg.d.ts +29 -0
- package/lib/core/graph/Cfg.d.ts.map +1 -0
- package/lib/core/graph/Cfg.js +154 -0
- package/lib/core/graph/DominanceFinder.d.ts +16 -0
- package/lib/core/graph/DominanceFinder.d.ts.map +1 -0
- package/lib/core/graph/DominanceFinder.js +121 -0
- package/lib/core/graph/DominanceTree.d.ts +13 -0
- package/lib/core/graph/DominanceTree.d.ts.map +1 -0
- package/lib/core/graph/DominanceTree.js +70 -0
- package/lib/core/graph/ViewTree.d.ts +115 -0
- package/lib/core/graph/ViewTree.d.ts.map +1 -0
- package/lib/core/graph/ViewTree.js +16 -0
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts +204 -0
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -0
- package/lib/core/graph/builder/ViewTreeBuilder.js +1046 -0
- package/lib/core/model/ArkBody.d.ts +22 -0
- package/lib/core/model/ArkBody.d.ts.map +1 -0
- package/lib/core/model/ArkBody.js +63 -0
- package/lib/core/model/ArkClass.d.ts +110 -0
- package/lib/core/model/ArkClass.d.ts.map +1 -0
- package/lib/core/model/ArkClass.js +315 -0
- package/lib/core/model/ArkExport.d.ts +70 -0
- package/lib/core/model/ArkExport.d.ts.map +1 -0
- package/lib/core/model/ArkExport.js +143 -0
- package/lib/core/model/ArkField.d.ts +60 -0
- package/lib/core/model/ArkField.d.ts.map +1 -0
- package/lib/core/model/ArkField.js +157 -0
- package/lib/core/model/ArkFile.d.ts +62 -0
- package/lib/core/model/ArkFile.d.ts.map +1 -0
- package/lib/core/model/ArkFile.js +160 -0
- package/lib/core/model/ArkImport.d.ts +43 -0
- package/lib/core/model/ArkImport.d.ts.map +1 -0
- package/lib/core/model/ArkImport.js +109 -0
- package/lib/core/model/ArkMethod.d.ts +76 -0
- package/lib/core/model/ArkMethod.d.ts.map +1 -0
- package/lib/core/model/ArkMethod.js +235 -0
- package/lib/core/model/ArkNamespace.d.ts +65 -0
- package/lib/core/model/ArkNamespace.d.ts.map +1 -0
- package/lib/core/model/ArkNamespace.js +182 -0
- package/lib/core/model/ArkSignature.d.ts +98 -0
- package/lib/core/model/ArkSignature.d.ts.map +1 -0
- package/lib/core/model/ArkSignature.js +281 -0
- package/lib/core/model/builder/ArkClassBuilder.d.ts +13 -0
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkClassBuilder.js +422 -0
- package/lib/core/model/builder/ArkExportBuilder.d.ts +25 -0
- package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkExportBuilder.js +207 -0
- package/lib/core/model/builder/ArkFieldBuilder.d.ts +9 -0
- package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkFieldBuilder.js +189 -0
- package/lib/core/model/builder/ArkFileBuilder.d.ts +10 -0
- package/lib/core/model/builder/ArkFileBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkFileBuilder.js +164 -0
- package/lib/core/model/builder/ArkImportBuilder.d.ts +4 -0
- package/lib/core/model/builder/ArkImportBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkImportBuilder.js +125 -0
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +60 -0
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkMethodBuilder.js +419 -0
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts +5 -0
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkNamespaceBuilder.js +171 -0
- package/lib/core/model/builder/ArkSignatureBuilder.d.ts +9 -0
- package/lib/core/model/builder/ArkSignatureBuilder.d.ts.map +1 -0
- package/lib/core/model/builder/ArkSignatureBuilder.js +40 -0
- package/lib/core/model/builder/builderUtils.d.ts +18 -0
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -0
- package/lib/core/model/builder/builderUtils.js +449 -0
- package/lib/index.d.ts +77 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +190 -0
- package/lib/save/ArkStream.d.ts +24 -0
- package/lib/save/ArkStream.d.ts.map +1 -0
- package/lib/save/ArkStream.js +83 -0
- package/lib/save/DotPrinter.d.ts +48 -0
- package/lib/save/DotPrinter.d.ts.map +1 -0
- package/lib/save/DotPrinter.js +229 -0
- package/lib/save/GraphPrinter.d.ts +17 -0
- package/lib/save/GraphPrinter.d.ts.map +1 -0
- package/lib/save/GraphPrinter.js +135 -0
- package/lib/save/JsonPrinter.d.ts +28 -0
- package/lib/save/JsonPrinter.d.ts.map +1 -0
- package/lib/save/JsonPrinter.js +511 -0
- package/lib/save/Printer.d.ts +17 -0
- package/lib/save/Printer.d.ts.map +1 -0
- package/lib/save/Printer.js +27 -0
- package/lib/save/PrinterBuilder.d.ts +38 -0
- package/lib/save/PrinterBuilder.d.ts.map +1 -0
- package/lib/save/PrinterBuilder.js +102 -0
- package/lib/save/serializeArkIR.d.ts +3 -0
- package/lib/save/serializeArkIR.d.ts.map +1 -0
- package/lib/save/serializeArkIR.js +166 -0
- package/lib/save/source/SourceBase.d.ts +32 -0
- package/lib/save/source/SourceBase.d.ts.map +1 -0
- package/lib/save/source/SourceBase.js +93 -0
- package/lib/save/source/SourceBody.d.ts +60 -0
- package/lib/save/source/SourceBody.d.ts.map +1 -0
- package/lib/save/source/SourceBody.js +292 -0
- package/lib/save/source/SourceClass.d.ts +27 -0
- package/lib/save/source/SourceClass.d.ts.map +1 -0
- package/lib/save/source/SourceClass.js +202 -0
- package/lib/save/source/SourceField.d.ts +15 -0
- package/lib/save/source/SourceField.d.ts.map +1 -0
- package/lib/save/source/SourceField.js +68 -0
- package/lib/save/source/SourceFilePrinter.d.ts +14 -0
- package/lib/save/source/SourceFilePrinter.d.ts.map +1 -0
- package/lib/save/source/SourceFilePrinter.js +73 -0
- package/lib/save/source/SourceMethod.d.ts +24 -0
- package/lib/save/source/SourceMethod.d.ts.map +1 -0
- package/lib/save/source/SourceMethod.js +170 -0
- package/lib/save/source/SourceModule.d.ts +18 -0
- package/lib/save/source/SourceModule.d.ts.map +1 -0
- package/lib/save/source/SourceModule.js +120 -0
- package/lib/save/source/SourceNamespace.d.ts +13 -0
- package/lib/save/source/SourceNamespace.d.ts.map +1 -0
- package/lib/save/source/SourceNamespace.js +80 -0
- package/lib/save/source/SourceStmt.d.ts +172 -0
- package/lib/save/source/SourceStmt.d.ts.map +1 -0
- package/lib/save/source/SourceStmt.js +757 -0
- package/lib/save/source/SourceTransformer.d.ts +37 -0
- package/lib/save/source/SourceTransformer.d.ts.map +1 -0
- package/lib/save/source/SourceTransformer.js +338 -0
- package/lib/save/source/SourceUtils.d.ts +25 -0
- package/lib/save/source/SourceUtils.d.ts.map +1 -0
- package/lib/save/source/SourceUtils.js +201 -0
- package/lib/transformer/FunctionTransformer.d.ts +3 -0
- package/lib/transformer/FunctionTransformer.d.ts.map +1 -0
- package/lib/transformer/FunctionTransformer.js +17 -0
- package/lib/transformer/SceneTransformer.d.ts +3 -0
- package/lib/transformer/SceneTransformer.d.ts.map +1 -0
- package/lib/transformer/SceneTransformer.js +17 -0
- package/lib/transformer/StaticSingleAssignmentFormer.d.ts +13 -0
- package/lib/transformer/StaticSingleAssignmentFormer.d.ts.map +1 -0
- package/lib/transformer/StaticSingleAssignmentFormer.js +259 -0
- package/lib/transformer/Transformer.d.ts +7 -0
- package/lib/transformer/Transformer.d.ts.map +1 -0
- package/lib/transformer/Transformer.js +22 -0
- package/lib/utils/CfgStructualAnalysis.d.ts +93 -0
- package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -0
- package/lib/utils/CfgStructualAnalysis.js +955 -0
- package/lib/utils/FileUtils.d.ts +18 -0
- package/lib/utils/FileUtils.d.ts.map +1 -0
- package/lib/utils/FileUtils.js +131 -0
- package/lib/utils/callGraphUtils.d.ts +31 -0
- package/lib/utils/callGraphUtils.d.ts.map +1 -0
- package/lib/utils/callGraphUtils.js +208 -0
- package/lib/utils/entryMethodUtils.d.ts +16 -0
- package/lib/utils/entryMethodUtils.d.ts.map +1 -0
- package/lib/utils/entryMethodUtils.js +139 -0
- package/lib/utils/getAllFiles.d.ts +10 -0
- package/lib/utils/getAllFiles.d.ts.map +1 -0
- package/lib/utils/getAllFiles.js +91 -0
- package/lib/utils/json5parser.d.ts +7 -0
- package/lib/utils/json5parser.d.ts.map +1 -0
- package/lib/utils/json5parser.js +146 -0
- package/lib/utils/logger.d.ts +19 -0
- package/lib/utils/logger.d.ts.map +1 -0
- package/lib/utils/logger.js +90 -0
- package/lib/utils/pathTransfer.d.ts +2 -0
- package/lib/utils/pathTransfer.d.ts.map +1 -0
- package/lib/utils/pathTransfer.js +25 -0
- package/package.json +29 -0
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.PagBuilder = exports.CSFuncID = void 0;
|
|
41
|
+
const CallGraph_1 = require("../model/CallGraph");
|
|
42
|
+
const Stmt_1 = require("../../core/base/Stmt");
|
|
43
|
+
const Expr_1 = require("../../core/base/Expr");
|
|
44
|
+
const Ref_1 = require("../../core/base/Ref");
|
|
45
|
+
const logger_1 = __importStar(require("../../utils/logger"));
|
|
46
|
+
const Local_1 = require("../../core/base/Local");
|
|
47
|
+
const Type_1 = require("../../core/base/Type");
|
|
48
|
+
const Constant_1 = require("../../core/base/Constant");
|
|
49
|
+
const Statistics_1 = require("../common/Statistics");
|
|
50
|
+
const Context_1 = require("./Context");
|
|
51
|
+
const Pag_1 = require("./Pag");
|
|
52
|
+
const PtsDS_1 = require("./PtsDS");
|
|
53
|
+
const TSConst_1 = require("../../core/common/TSConst");
|
|
54
|
+
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
|
|
55
|
+
class CSFuncID {
|
|
56
|
+
constructor(cid, fid) {
|
|
57
|
+
this.cid = cid;
|
|
58
|
+
this.funcID = fid;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.CSFuncID = CSFuncID;
|
|
62
|
+
class PagBuilder {
|
|
63
|
+
constructor(p, cg, s, kLimit) {
|
|
64
|
+
this.handledFunc = new Set();
|
|
65
|
+
this.worklist = [];
|
|
66
|
+
// TODO: change string to hash value
|
|
67
|
+
this.staticField2UniqInstanceMap = new Map();
|
|
68
|
+
this.instanceField2UniqInstanceMap = new Map();
|
|
69
|
+
this.cid2ThisRefPtMap = new Map();
|
|
70
|
+
this.cid2ThisRefMap = new Map();
|
|
71
|
+
this.cid2ThisLocalMap = new Map();
|
|
72
|
+
this.sdkMethodReturnValueMap = new Map();
|
|
73
|
+
this.funcHandledThisRound = new Set();
|
|
74
|
+
this.updatedNodesThisRound = new Map();
|
|
75
|
+
this.singletonFuncMap = new Map();
|
|
76
|
+
this.pag = p;
|
|
77
|
+
this.cg = cg;
|
|
78
|
+
this.funcPags = new Map;
|
|
79
|
+
this.ctx = new Context_1.KLimitedContextSensitive(kLimit);
|
|
80
|
+
this.scene = s;
|
|
81
|
+
this.pagStat = new Statistics_1.PAGStat();
|
|
82
|
+
}
|
|
83
|
+
buildFuncPagAndAddToWorklist(cs) {
|
|
84
|
+
if (this.worklist.includes(cs)) {
|
|
85
|
+
return cs;
|
|
86
|
+
}
|
|
87
|
+
this.buildFuncPag(cs.funcID);
|
|
88
|
+
if (this.isSingletonFunction(cs.funcID)) {
|
|
89
|
+
cs.cid = Context_1.DUMMY_CID;
|
|
90
|
+
}
|
|
91
|
+
this.worklist.push(cs);
|
|
92
|
+
return cs;
|
|
93
|
+
}
|
|
94
|
+
addToFuncHandledListThisRound(id) {
|
|
95
|
+
if (this.funcHandledThisRound.has(id)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.funcHandledThisRound.add(id);
|
|
99
|
+
}
|
|
100
|
+
buildForEntries(funcIDs) {
|
|
101
|
+
this.worklist = [];
|
|
102
|
+
funcIDs.forEach(funcID => {
|
|
103
|
+
let cid = this.ctx.getNewContextID(funcID);
|
|
104
|
+
let csFuncID = new CSFuncID(cid, funcID);
|
|
105
|
+
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
106
|
+
});
|
|
107
|
+
this.handleReachable();
|
|
108
|
+
}
|
|
109
|
+
handleReachable() {
|
|
110
|
+
if (this.worklist.length == 0) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
this.funcHandledThisRound.clear();
|
|
114
|
+
while (this.worklist.length > 0) {
|
|
115
|
+
let csFunc = this.worklist.shift();
|
|
116
|
+
this.buildPagFromFuncPag(csFunc.funcID, csFunc.cid);
|
|
117
|
+
this.addToFuncHandledListThisRound(csFunc.funcID);
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
build() {
|
|
122
|
+
for (let funcID of this.cg.getEntries()) {
|
|
123
|
+
let cid = this.ctx.getNewContextID(funcID);
|
|
124
|
+
let csFuncID = new CSFuncID(cid, funcID);
|
|
125
|
+
this.buildFuncPagAndAddToWorklist(csFuncID);
|
|
126
|
+
this.handleReachable();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
buildFuncPag(funcID) {
|
|
130
|
+
if (this.funcPags.has(funcID)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
let fpag = new Pag_1.FuncPag();
|
|
134
|
+
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
135
|
+
if (arkMethod == null) {
|
|
136
|
+
//throw new Error("function ID");
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
let cfg = arkMethod.getCfg();
|
|
140
|
+
if (!cfg) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`);
|
|
144
|
+
for (let stmt of cfg.getStmts()) {
|
|
145
|
+
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
146
|
+
// Add non-call edges
|
|
147
|
+
let kind = this.getEdgeKindForAssignStmt(stmt);
|
|
148
|
+
if (kind != Pag_1.PagEdgeKind.Unknown) {
|
|
149
|
+
fpag.addInternalEdge(stmt, kind);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// handle call
|
|
153
|
+
let inkExpr = stmt.getInvokeExpr();
|
|
154
|
+
if (inkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
155
|
+
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
156
|
+
if (cs) {
|
|
157
|
+
// direct call is already existing in CG
|
|
158
|
+
fpag.addNormalCallSite(cs);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
throw new Error('Can not find static callsite');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (inkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
165
|
+
let ptcs = this.cg.getDynCallsiteByStmt(stmt);
|
|
166
|
+
if (ptcs) {
|
|
167
|
+
this.addToDynamicCallSite(fpag, ptcs);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (stmt instanceof Stmt_1.ArkInvokeStmt) {
|
|
172
|
+
// TODO: discuss if we need a invokeStmt
|
|
173
|
+
let cs = this.cg.getCallSiteByStmt(stmt);
|
|
174
|
+
if (cs) {
|
|
175
|
+
// direct call or constructor call is already existing in CG
|
|
176
|
+
fpag.addNormalCallSite(cs);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
let dycs = this.cg.getDynCallsiteByStmt(stmt);
|
|
180
|
+
if (dycs) {
|
|
181
|
+
this.addToDynamicCallSite(fpag, dycs);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw new Error('Can not find callsite by stmt');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// TODO: need handle other type of stmt?
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
this.funcPags.set(funcID, fpag);
|
|
192
|
+
this.pagStat.numTotalFunction++;
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
buildPagFromFuncPag(funcID, cid) {
|
|
196
|
+
let funcPag = this.funcPags.get(funcID);
|
|
197
|
+
if (funcPag == undefined) {
|
|
198
|
+
//throw new Error("No Func PAG is found for #" + funcID);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (this.handledFunc.has(`${cid}-${funcID}`)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
this.addEdgesFromFuncPag(funcPag, cid);
|
|
205
|
+
this.addCallsEdgesFromFuncPag(funcPag, cid);
|
|
206
|
+
this.addDynamicCallSite(funcPag);
|
|
207
|
+
this.handledFunc.add(`${cid}-${funcID}`);
|
|
208
|
+
}
|
|
209
|
+
/// Add Pag Nodes and Edges in function
|
|
210
|
+
addEdgesFromFuncPag(funcPag, cid) {
|
|
211
|
+
let inEdges = funcPag.getInternalEdges();
|
|
212
|
+
if (inEdges == undefined) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
for (let e of inEdges) {
|
|
216
|
+
let srcPagNode = this.getOrNewPagNode(cid, e.src, e.stmt);
|
|
217
|
+
let dstPagNode = this.getOrNewPagNode(cid, e.dst, e.stmt);
|
|
218
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, e.kind, e.stmt);
|
|
219
|
+
// Take place of the real stmt for return
|
|
220
|
+
if (dstPagNode.getStmt() instanceof Stmt_1.ArkReturnStmt) {
|
|
221
|
+
dstPagNode.setStmt(e.stmt);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
/// add Copy edges interprocedural
|
|
227
|
+
addCallsEdgesFromFuncPag(funcPag, cid) {
|
|
228
|
+
for (let cs of funcPag.getNormalCallSites()) {
|
|
229
|
+
let calleeCid = this.ctx.getOrNewContext(cid, cs.calleeFuncID, true);
|
|
230
|
+
this.addStaticPagCallEdge(cs, cid, calleeCid);
|
|
231
|
+
// Add edge to thisRef for special calls
|
|
232
|
+
let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
|
|
233
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
234
|
+
if (calleeCGNode.getKind() == CallGraph_1.CallGraphNodeKind.constructor ||
|
|
235
|
+
calleeCGNode.getKind() == CallGraph_1.CallGraphNodeKind.intrinsic) {
|
|
236
|
+
let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID));
|
|
237
|
+
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
238
|
+
let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase());
|
|
239
|
+
let baseNodeID = baseNode.getID();
|
|
240
|
+
this.addThisRefCallEdge(baseNodeID, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
logger.error(`constructor or intrinsic func is static ${ivkExpr.toString()}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
addDynamicCallSite(funcPag) {
|
|
250
|
+
// add dyn callsite in funcpag to base node
|
|
251
|
+
for (let cs of funcPag.getDynamicCallSites()) {
|
|
252
|
+
let base = cs.callStmt.getInvokeExpr().getBase();
|
|
253
|
+
// TODO: check base under different cid
|
|
254
|
+
let baseNodeIDs = this.pag.getNodesByValue(base);
|
|
255
|
+
if (!baseNodeIDs) {
|
|
256
|
+
logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
for (let nodeID of baseNodeIDs.values()) {
|
|
260
|
+
let node = this.pag.getNode(nodeID);
|
|
261
|
+
if (!(node instanceof Pag_1.PagLocalNode)) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
node.addRelatedDynCallSite(cs);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
addDynamicCallEdge(cs, baseClassPTNode, cid) {
|
|
269
|
+
let srcNodes = [];
|
|
270
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
271
|
+
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
272
|
+
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
273
|
+
let value = ptNode.getValue();
|
|
274
|
+
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
275
|
+
return srcNodes;
|
|
276
|
+
}
|
|
277
|
+
let callee = null;
|
|
278
|
+
if (value instanceof Expr_1.ArkNewExpr) {
|
|
279
|
+
// get class signature
|
|
280
|
+
let clsSig = value.getType().getClassSignature();
|
|
281
|
+
let cls;
|
|
282
|
+
cls = this.scene.getClass(clsSig);
|
|
283
|
+
while (!callee && cls) {
|
|
284
|
+
callee = cls.getMethodWithName(calleeName);
|
|
285
|
+
cls = cls.getSuperClass();
|
|
286
|
+
}
|
|
287
|
+
if (!callee) {
|
|
288
|
+
callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// anonymous method
|
|
292
|
+
if (!callee) {
|
|
293
|
+
// try to change callee to param anonymous method
|
|
294
|
+
// TODO: anonymous method param and return value pointer pass
|
|
295
|
+
let args = cs.args;
|
|
296
|
+
if ((args === null || args === void 0 ? void 0 : args.length) == 1 && args[0].getType() instanceof Type_1.FunctionType) {
|
|
297
|
+
callee = this.scene.getMethod(args[0].getType().getMethodSignature());
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!callee) {
|
|
301
|
+
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
302
|
+
// return empty node when {o_2} come in
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature());
|
|
306
|
+
let callerNode = this.cg.getNode(cs.callerFuncID);
|
|
307
|
+
if (!callerNode) {
|
|
308
|
+
throw new Error("Can not get caller method node");
|
|
309
|
+
}
|
|
310
|
+
// update call graph
|
|
311
|
+
// TODO: movo to cgbuilder
|
|
312
|
+
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
313
|
+
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
314
|
+
let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
|
|
315
|
+
let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
|
|
316
|
+
let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
|
|
317
|
+
srcNodes.push(...staticSrcNodes);
|
|
318
|
+
// Pass base's pts to callee's this pointer
|
|
319
|
+
if (!dstCGNode.getIsSdkMethod()) {
|
|
320
|
+
let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
|
|
321
|
+
srcNodes.push(srcBaseNode);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return srcNodes;
|
|
325
|
+
}
|
|
326
|
+
addUpdatedNode(nodeID, diffPT) {
|
|
327
|
+
var _a;
|
|
328
|
+
let updatedNode = (_a = this.updatedNodesThisRound.get(nodeID)) !== null && _a !== void 0 ? _a : new PtsDS_1.PtsSet();
|
|
329
|
+
updatedNode.union(diffPT);
|
|
330
|
+
this.updatedNodesThisRound.set(nodeID, updatedNode);
|
|
331
|
+
}
|
|
332
|
+
getUpdatedNodes() {
|
|
333
|
+
return this.updatedNodesThisRound;
|
|
334
|
+
}
|
|
335
|
+
resetUpdatedNodes() {
|
|
336
|
+
this.updatedNodesThisRound.clear();
|
|
337
|
+
}
|
|
338
|
+
handleUnkownDynamicCall(cs, cid) {
|
|
339
|
+
var _a;
|
|
340
|
+
let srcNodes = [];
|
|
341
|
+
let callerNode = this.cg.getNode(cs.callerFuncID);
|
|
342
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
343
|
+
logger.warn("Handling unknown dyn call site : \n " + callerNode.getMethod().toString()
|
|
344
|
+
+ '\n --> ' + ivkExpr.toString() + '\n CID: ' + cid);
|
|
345
|
+
let callees = [];
|
|
346
|
+
let callee = null;
|
|
347
|
+
callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
348
|
+
if (!callee) {
|
|
349
|
+
(_a = cs.args) === null || _a === void 0 ? void 0 : _a.forEach(arg => {
|
|
350
|
+
if (arg.getType() instanceof Type_1.FunctionType) {
|
|
351
|
+
callee = this.scene.getMethod(arg.getType().getMethodSignature());
|
|
352
|
+
if (callee) {
|
|
353
|
+
callees.push(callee);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
callees.push(callee);
|
|
360
|
+
}
|
|
361
|
+
if (callees.length == 0) {
|
|
362
|
+
return srcNodes;
|
|
363
|
+
}
|
|
364
|
+
callees.forEach(callee => {
|
|
365
|
+
let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature());
|
|
366
|
+
if (!callerNode) {
|
|
367
|
+
throw new Error("Can not get caller method node");
|
|
368
|
+
}
|
|
369
|
+
logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`);
|
|
370
|
+
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
371
|
+
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
372
|
+
let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
|
|
373
|
+
let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
|
|
374
|
+
let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
|
|
375
|
+
srcNodes.push(...staticSrcNodes);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
return srcNodes;
|
|
379
|
+
}
|
|
380
|
+
handleUnprocessedCallSites(processedCallSites) {
|
|
381
|
+
for (let funcID of this.funcHandledThisRound) {
|
|
382
|
+
let funcPag = this.funcPags.get(funcID);
|
|
383
|
+
if (!funcPag) {
|
|
384
|
+
logger.error(`can not find funcPag of handled func ${funcID}`);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
let callSites = funcPag.getDynamicCallSites();
|
|
388
|
+
const diffCallSites = new Set(Array.from(callSites).filter(item => !processedCallSites.has(item)));
|
|
389
|
+
diffCallSites.forEach((cs) => {
|
|
390
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
391
|
+
// Get local of base class
|
|
392
|
+
let base = ivkExpr.getBase();
|
|
393
|
+
// TODO: remove this after multiple this local fixed
|
|
394
|
+
base = this.getRealThisLocal(base, cs.callerFuncID);
|
|
395
|
+
// Get PAG nodes for this base's local
|
|
396
|
+
let ctx2NdMap = this.pag.getNodesByValue(base);
|
|
397
|
+
if (ctx2NdMap) {
|
|
398
|
+
for (let [cid] of ctx2NdMap.entries()) {
|
|
399
|
+
this.handleUnkownDynamicCall(cs, cid);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, callerFunID) {
|
|
406
|
+
//let thisPtr = callee.getThisInstance();
|
|
407
|
+
var _a;
|
|
408
|
+
if (!callee || !callee.getCfg()) {
|
|
409
|
+
console.log("callee is null");
|
|
410
|
+
return -1;
|
|
411
|
+
}
|
|
412
|
+
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);
|
|
413
|
+
let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt.at(0)).getRightOp();
|
|
414
|
+
if (!thisPtr) {
|
|
415
|
+
throw new Error('Can not get this ptr');
|
|
416
|
+
}
|
|
417
|
+
// IMPORTANT: set cid 2 base Pt info firstly
|
|
418
|
+
this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode);
|
|
419
|
+
let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr);
|
|
420
|
+
thisRefNode.addPTNode(baseClassPTNode);
|
|
421
|
+
let srcBaseLocal = ivkExpr.getBase();
|
|
422
|
+
srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID);
|
|
423
|
+
let srcNodeId = this.pag.hasCtxNode(cid, srcBaseLocal);
|
|
424
|
+
if (!srcNodeId) {
|
|
425
|
+
throw new Error('Can not get base node');
|
|
426
|
+
}
|
|
427
|
+
this.pag.addPagEdge(this.pag.getNode(srcNodeId), thisRefNode, Pag_1.PagEdgeKind.This);
|
|
428
|
+
return srcNodeId;
|
|
429
|
+
}
|
|
430
|
+
/*
|
|
431
|
+
* Add copy edges from arguments to parameters
|
|
432
|
+
* ret edges from return values to callsite
|
|
433
|
+
* Return src node
|
|
434
|
+
*/
|
|
435
|
+
addStaticPagCallEdge(cs, callerCid, calleeCid) {
|
|
436
|
+
var _a, _b;
|
|
437
|
+
if (!calleeCid) {
|
|
438
|
+
calleeCid = this.ctx.getOrNewContext(callerCid, cs.calleeFuncID, true);
|
|
439
|
+
}
|
|
440
|
+
let srcNodes = [];
|
|
441
|
+
// Add reachable
|
|
442
|
+
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
443
|
+
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
444
|
+
if (!calleeMethod) {
|
|
445
|
+
// TODO: check if nodes need to delete
|
|
446
|
+
// this.cg.removeCallGraphNode(cs.calleeFuncID)
|
|
447
|
+
return srcNodes;
|
|
448
|
+
}
|
|
449
|
+
if (calleeNode.getIsSdkMethod()) {
|
|
450
|
+
let returnType = calleeMethod.getReturnType();
|
|
451
|
+
// TODO: add new array type
|
|
452
|
+
if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
453
|
+
return srcNodes;
|
|
454
|
+
}
|
|
455
|
+
// check fake heap object exists or not
|
|
456
|
+
let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
|
|
457
|
+
if (!cidMap) {
|
|
458
|
+
cidMap = new Map();
|
|
459
|
+
}
|
|
460
|
+
let newExpr = cidMap.get(calleeCid);
|
|
461
|
+
if (!newExpr) {
|
|
462
|
+
if (returnType instanceof Type_1.ClassType) {
|
|
463
|
+
newExpr = new Expr_1.ArkNewExpr(returnType);
|
|
464
|
+
}
|
|
465
|
+
// } else if (returnType instanceof ArrayType) {
|
|
466
|
+
// TODO: check how to transform array type 2 newArrayExpr
|
|
467
|
+
// newExpr = new ArkNewArrayExpr(returnType.getBaseType(), )
|
|
468
|
+
// }
|
|
469
|
+
}
|
|
470
|
+
cidMap.set(calleeCid, newExpr);
|
|
471
|
+
this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
|
|
472
|
+
let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
|
|
473
|
+
let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
|
|
474
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
|
|
475
|
+
return srcNodes;
|
|
476
|
+
}
|
|
477
|
+
if (!calleeMethod.getCfg()) {
|
|
478
|
+
// method have no cfg body
|
|
479
|
+
return srcNodes;
|
|
480
|
+
}
|
|
481
|
+
let calleeCS = this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, cs.calleeFuncID));
|
|
482
|
+
// callee cid will updated if callee is singleton
|
|
483
|
+
calleeCid = calleeCS.cid;
|
|
484
|
+
// TODO: getParameterInstances's performance is not good. Need to refactor
|
|
485
|
+
//let params = calleeMethod.getParameterInstances();
|
|
486
|
+
let params = calleeMethod.getCfg().getStmts()
|
|
487
|
+
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
488
|
+
.map(stmt => stmt.getRightOp());
|
|
489
|
+
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
490
|
+
if (argNum) {
|
|
491
|
+
// add args to parameters edges
|
|
492
|
+
for (let i = 0; i < argNum; i++) {
|
|
493
|
+
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
494
|
+
let param = params.at(i);
|
|
495
|
+
// TODO: param type should be ArkParameterRef?
|
|
496
|
+
//if (arg && param && param instanceof ArkParameterRef) {
|
|
497
|
+
if (arg && param) {
|
|
498
|
+
if (arg instanceof Constant_1.Constant) {
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
if (arg instanceof Expr_1.AbstractExpr) {
|
|
502
|
+
// TODO: handle this
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
// Get or create new PAG node for argument and parameter
|
|
506
|
+
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
507
|
+
let dstPagNode = this.getOrNewPagNode(calleeCid, param, cs.callStmt);
|
|
508
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
509
|
+
srcNodes.push(srcPagNode.getID());
|
|
510
|
+
}
|
|
511
|
+
// TODO: handle other types of parmeters
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// add ret to caller edges
|
|
515
|
+
let retStmts = calleeMethod.getReturnStmt();
|
|
516
|
+
// TODO: call statement must be a assignment state
|
|
517
|
+
if (cs.callStmt instanceof Stmt_1.ArkAssignStmt) {
|
|
518
|
+
let retDst = cs.callStmt.getLeftOp();
|
|
519
|
+
for (let retStmt of retStmts) {
|
|
520
|
+
let retValue = retStmt.getOp();
|
|
521
|
+
if (retValue instanceof Local_1.Local) {
|
|
522
|
+
let srcPagNode = this.getOrNewPagNode(calleeCid, retValue, retStmt);
|
|
523
|
+
let dstPagNode = this.getOrNewPagNode(callerCid, retDst, cs.callStmt);
|
|
524
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, retStmt);
|
|
525
|
+
}
|
|
526
|
+
else if (retValue instanceof Constant_1.Constant) {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
else if (retValue instanceof Expr_1.AbstractExpr) {
|
|
530
|
+
console.log(retValue);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
throw new Error('return dst not a local or constant, but: ' + retValue.getType().toString());
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return srcNodes;
|
|
539
|
+
}
|
|
540
|
+
getOrNewPagNode(cid, v, s) {
|
|
541
|
+
if (v instanceof Ref_1.ArkThisRef) {
|
|
542
|
+
return this.getOrNewThisRefNode(cid, v);
|
|
543
|
+
}
|
|
544
|
+
// this local is also not uniq!!!
|
|
545
|
+
// remove below block once this issue fixed
|
|
546
|
+
// globalThis process can not be removed while all `globalThis` ref is the same Value
|
|
547
|
+
if (v instanceof Local_1.Local) {
|
|
548
|
+
if (v.getName() == "this") {
|
|
549
|
+
return this.getOrNewThisLoalNode(cid, v, s);
|
|
550
|
+
}
|
|
551
|
+
else if (v.getName() == Pag_1.GLOBAL_THIS && v.getDeclaringStmt() == null) {
|
|
552
|
+
// globalThis node has no cid
|
|
553
|
+
return this.getOrNewGlobalThisNode(0);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
v = this.getRealInstanceRef(v);
|
|
557
|
+
return this.pag.getOrNewNode(cid, v, s);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* return ThisRef PAG node according to cid, a cid has a unique ThisRef node
|
|
561
|
+
* @param cid: current contextID
|
|
562
|
+
*/
|
|
563
|
+
getOrNewThisRefNode(cid, v) {
|
|
564
|
+
let thisRefNodeID = this.cid2ThisRefMap.get(cid);
|
|
565
|
+
if (!thisRefNodeID) {
|
|
566
|
+
thisRefNodeID = -1;
|
|
567
|
+
}
|
|
568
|
+
let thisRefNode = this.pag.getOrNewThisRefNode(thisRefNodeID, v);
|
|
569
|
+
this.cid2ThisRefMap.set(cid, thisRefNode.getID());
|
|
570
|
+
return thisRefNode;
|
|
571
|
+
}
|
|
572
|
+
// TODO: remove it once this local not uniq issue is fixed
|
|
573
|
+
getOrNewThisLoalNode(cid, v, s) {
|
|
574
|
+
let thisLocalNodeID = this.cid2ThisLocalMap.get(cid);
|
|
575
|
+
if (thisLocalNodeID) {
|
|
576
|
+
return this.pag.getNode(thisLocalNodeID);
|
|
577
|
+
}
|
|
578
|
+
let thisNode = this.pag.getOrNewNode(cid, v, s);
|
|
579
|
+
this.cid2ThisLocalMap.set(cid, thisNode.getID());
|
|
580
|
+
return thisNode;
|
|
581
|
+
}
|
|
582
|
+
getOrNewGlobalThisNode(cid) {
|
|
583
|
+
return this.pag.getOrNewNode(cid, this.getGlobalThisValue());
|
|
584
|
+
}
|
|
585
|
+
getUniqThisLocalNode(cid) {
|
|
586
|
+
return this.cid2ThisLocalMap.get(cid);
|
|
587
|
+
}
|
|
588
|
+
/*
|
|
589
|
+
* In ArkIR, ArkField has multiple instances for each stmt which use it
|
|
590
|
+
* But the unique one is needed for pointer analysis
|
|
591
|
+
* This is a temp solution to use a ArkField->(first instance)
|
|
592
|
+
* as the unique instance
|
|
593
|
+
*
|
|
594
|
+
* node merge condition:
|
|
595
|
+
* instance field: value and ArkField
|
|
596
|
+
* static field: ArkField
|
|
597
|
+
*/
|
|
598
|
+
getRealInstanceRef(v) {
|
|
599
|
+
if (!(v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef)) {
|
|
600
|
+
return v;
|
|
601
|
+
}
|
|
602
|
+
let sig = v.getFieldSignature();
|
|
603
|
+
let sigStr = sig.toString();
|
|
604
|
+
let base;
|
|
605
|
+
let real;
|
|
606
|
+
if (v instanceof Ref_1.ArkInstanceFieldRef) {
|
|
607
|
+
base = v.getBase();
|
|
608
|
+
if (base instanceof Local_1.Local && base.getName() == Pag_1.GLOBAL_THIS && base.getDeclaringStmt() == null) {
|
|
609
|
+
// replace the base in fieldRef
|
|
610
|
+
base = this.getGlobalThisValue();
|
|
611
|
+
v.setBase(base);
|
|
612
|
+
}
|
|
613
|
+
real = this.instanceField2UniqInstanceMap.get([sigStr, base]);
|
|
614
|
+
if (!real) {
|
|
615
|
+
this.instanceField2UniqInstanceMap.set([sigStr, base], v);
|
|
616
|
+
real = v;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
real = this.staticField2UniqInstanceMap.get(sigStr);
|
|
621
|
+
if (!real) {
|
|
622
|
+
this.staticField2UniqInstanceMap.set(sigStr, v);
|
|
623
|
+
real = v;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return real;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* check if a method is singleton function
|
|
630
|
+
* rule: static method, assign heap obj to global var or static field, return the receiver
|
|
631
|
+
*/
|
|
632
|
+
isSingletonFunction(funcID) {
|
|
633
|
+
if (this.singletonFuncMap.has(funcID)) {
|
|
634
|
+
return this.singletonFuncMap.get(funcID);
|
|
635
|
+
}
|
|
636
|
+
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
637
|
+
if (!arkMethod) {
|
|
638
|
+
this.singletonFuncMap.set(funcID, false);
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
if (!arkMethod.getModifiers().has(TSConst_1.STATIC_KEYWORD)) {
|
|
642
|
+
this.singletonFuncMap.set(funcID, false);
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
let funcPag = this.funcPags.get(funcID);
|
|
646
|
+
let heapObjects = [...funcPag.getInternalEdges()]
|
|
647
|
+
.filter(edge => edge.kind == Pag_1.PagEdgeKind.Address)
|
|
648
|
+
.map(edge => edge.dst);
|
|
649
|
+
let returnValues = arkMethod.getReturnValues();
|
|
650
|
+
let result = this.isValueConnected([...funcPag.getInternalEdges()], heapObjects, returnValues);
|
|
651
|
+
this.singletonFuncMap.set(funcID, result);
|
|
652
|
+
if (result) {
|
|
653
|
+
logger.info(`function ${funcID} is marked as singleton function`);
|
|
654
|
+
}
|
|
655
|
+
return result;
|
|
656
|
+
}
|
|
657
|
+
isValueConnected(edges, leftNodes, targetNodes) {
|
|
658
|
+
// build funcPag graph
|
|
659
|
+
const graph = new Map();
|
|
660
|
+
let hasStaticFieldOrGlobalVar = false;
|
|
661
|
+
for (const edge of edges) {
|
|
662
|
+
let dst = this.getRealInstanceRef(edge.dst);
|
|
663
|
+
let src = this.getRealInstanceRef(edge.src);
|
|
664
|
+
if (!graph.has(dst)) {
|
|
665
|
+
graph.set(dst, []);
|
|
666
|
+
}
|
|
667
|
+
if (!graph.has(src)) {
|
|
668
|
+
graph.set(src, []);
|
|
669
|
+
}
|
|
670
|
+
if (dst instanceof Ref_1.ArkStaticFieldRef || src instanceof Ref_1.ArkStaticFieldRef) {
|
|
671
|
+
hasStaticFieldOrGlobalVar = true;
|
|
672
|
+
}
|
|
673
|
+
graph.get(src).push(dst);
|
|
674
|
+
}
|
|
675
|
+
if (!hasStaticFieldOrGlobalVar) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
for (const targetNode of targetNodes) {
|
|
679
|
+
for (const leftNode of leftNodes) {
|
|
680
|
+
const visited = new Set();
|
|
681
|
+
let meetStaticField = false;
|
|
682
|
+
if (this.funcPagDfs(graph, visited, leftNode, targetNode, meetStaticField)) {
|
|
683
|
+
return true; // a value pair that satisfy condition
|
|
684
|
+
}
|
|
685
|
+
if (!meetStaticField) {
|
|
686
|
+
break; // heap obj will not deal any more
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
funcPagDfs(graph, visited, currentNode, targetNode, staticFieldFound) {
|
|
693
|
+
if (currentNode === targetNode) {
|
|
694
|
+
return staticFieldFound;
|
|
695
|
+
}
|
|
696
|
+
visited.add(currentNode);
|
|
697
|
+
for (const neighbor of graph.get(currentNode) || []) {
|
|
698
|
+
// TODO: add global variable
|
|
699
|
+
const isSpecialNode = neighbor instanceof Ref_1.ArkStaticFieldRef;
|
|
700
|
+
if (!visited.has(neighbor)) {
|
|
701
|
+
if (isSpecialNode) {
|
|
702
|
+
staticFieldFound = true;
|
|
703
|
+
}
|
|
704
|
+
if (this.funcPagDfs(graph, visited, neighbor, targetNode, staticFieldFound)) {
|
|
705
|
+
return true;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
getGlobalThisValue() {
|
|
712
|
+
var _a;
|
|
713
|
+
return (_a = this.globalThisValue) !== null && _a !== void 0 ? _a : new Local_1.Local(Pag_1.GLOBAL_THIS);
|
|
714
|
+
}
|
|
715
|
+
getEdgeKindForAssignStmt(stmt) {
|
|
716
|
+
if (this.stmtIsCreateAddressObj(stmt)) {
|
|
717
|
+
return Pag_1.PagEdgeKind.Address;
|
|
718
|
+
}
|
|
719
|
+
if (this.stmtIsCopyKind(stmt)) {
|
|
720
|
+
return Pag_1.PagEdgeKind.Copy;
|
|
721
|
+
}
|
|
722
|
+
if (this.stmtIsReadKind(stmt)) {
|
|
723
|
+
return Pag_1.PagEdgeKind.Load;
|
|
724
|
+
}
|
|
725
|
+
if (this.stmtIsWriteKind(stmt)) {
|
|
726
|
+
return Pag_1.PagEdgeKind.Write;
|
|
727
|
+
}
|
|
728
|
+
return Pag_1.PagEdgeKind.Unknown;
|
|
729
|
+
}
|
|
730
|
+
/**\
|
|
731
|
+
* ArkNewExpr, ArkNewArrayExpr, function ptr, globalThis
|
|
732
|
+
*/
|
|
733
|
+
stmtIsCreateAddressObj(stmt) {
|
|
734
|
+
let lhOp = stmt.getLeftOp();
|
|
735
|
+
let rhOp = stmt.getRightOp();
|
|
736
|
+
if ((rhOp instanceof Expr_1.ArkNewExpr || rhOp instanceof Expr_1.ArkNewArrayExpr) ||
|
|
737
|
+
(lhOp instanceof Local_1.Local && rhOp instanceof Local_1.Local &&
|
|
738
|
+
rhOp.getType() instanceof Type_1.FunctionType &&
|
|
739
|
+
rhOp.getDeclaringStmt() === null ||
|
|
740
|
+
(rhOp instanceof Local_1.Local && rhOp.getName() == Pag_1.GLOBAL_THIS && rhOp.getDeclaringStmt() == null))) {
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
// TODO: add other Address Obj creation
|
|
744
|
+
// like static object
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
747
|
+
stmtIsCopyKind(stmt) {
|
|
748
|
+
let lhOp = stmt.getLeftOp();
|
|
749
|
+
let rhOp = stmt.getRightOp();
|
|
750
|
+
let condition = (lhOp instanceof Local_1.Local && (rhOp instanceof Local_1.Local || rhOp instanceof Ref_1.ArkParameterRef ||
|
|
751
|
+
rhOp instanceof Ref_1.ArkThisRef || rhOp instanceof Ref_1.ArkStaticFieldRef)) ||
|
|
752
|
+
(lhOp instanceof Ref_1.ArkStaticFieldRef && rhOp instanceof Local_1.Local);
|
|
753
|
+
if (condition) {
|
|
754
|
+
return true;
|
|
755
|
+
}
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
stmtIsWriteKind(stmt) {
|
|
759
|
+
let lhOp = stmt.getLeftOp();
|
|
760
|
+
let rhOp = stmt.getRightOp();
|
|
761
|
+
if (rhOp instanceof Local_1.Local &&
|
|
762
|
+
(lhOp instanceof Ref_1.ArkInstanceFieldRef || lhOp instanceof Ref_1.ArkArrayRef)) {
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
stmtIsReadKind(stmt) {
|
|
768
|
+
let lhOp = stmt.getLeftOp();
|
|
769
|
+
let rhOp = stmt.getRightOp();
|
|
770
|
+
if (lhOp instanceof Local_1.Local &&
|
|
771
|
+
(rhOp instanceof Ref_1.ArkInstanceFieldRef || rhOp instanceof Ref_1.ArkArrayRef)) {
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
addToDynamicCallSite(funcPag, cs) {
|
|
777
|
+
var _a;
|
|
778
|
+
funcPag.addDynamicCallSite(cs);
|
|
779
|
+
this.pagStat.numDynamicCall++;
|
|
780
|
+
logger.trace("[add dynamic callsite] " + cs.callStmt.toString() + ": " + ((_a = cs.callStmt.getCfg()) === null || _a === void 0 ? void 0 : _a.getDeclaringMethod().getSignature().toString()));
|
|
781
|
+
}
|
|
782
|
+
setPtForNode(node, pts) {
|
|
783
|
+
if (!pts) {
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
this.pag.getNode(node).setPointTo(pts.getProtoPtsSet());
|
|
787
|
+
}
|
|
788
|
+
getRealThisLocal(input, funcId) {
|
|
789
|
+
var _a;
|
|
790
|
+
if (input.getName() != 'this')
|
|
791
|
+
return input;
|
|
792
|
+
let real = input;
|
|
793
|
+
let f = this.cg.getArkMethodByFuncID(funcId);
|
|
794
|
+
(_a = f === null || f === void 0 ? void 0 : f.getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().forEach(s => {
|
|
795
|
+
if (s instanceof Stmt_1.ArkAssignStmt && s.getLeftOp() instanceof Local_1.Local) {
|
|
796
|
+
if (s.getLeftOp().getName() === 'this') {
|
|
797
|
+
real = s.getLeftOp();
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
return real;
|
|
803
|
+
}
|
|
804
|
+
doStat() {
|
|
805
|
+
this.pagStat.numTotalNode = this.pag.getNodeNum();
|
|
806
|
+
}
|
|
807
|
+
printStat() {
|
|
808
|
+
this.pagStat.printStat();
|
|
809
|
+
}
|
|
810
|
+
getUnhandledFuncs() {
|
|
811
|
+
let handledFuncs = this.getHandledFuncs();
|
|
812
|
+
let unhandleFuncs = Array.from(this.cg.getNodesIter())
|
|
813
|
+
.filter(f => !handledFuncs.includes(f.getID()))
|
|
814
|
+
.map(f => f.getID());
|
|
815
|
+
return unhandleFuncs;
|
|
816
|
+
}
|
|
817
|
+
getHandledFuncs() {
|
|
818
|
+
return Array.from(this.funcPags.keys());
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
exports.PagBuilder = PagBuilder;
|