• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LIBARK_DEFECT_SCAN_AUX_INCLUDE_ABC_FILE_H
17 #define LIBARK_DEFECT_SCAN_AUX_INCLUDE_ABC_FILE_H
18 
19 #include <list>
20 #include <memory>
21 #include <optional>
22 #include <string>
23 #include <tuple>
24 #include <unordered_map>
25 #include <vector>
26 #include "compiler/optimizer/ir/graph.h"
27 #include "libpandabase/mem/arena_allocator.h"
28 #include "libpandafile/method_data_accessor.h"
29 #include "libpandafile/debug_info_extractor.h"
30 #include "graph.h"
31 
32 namespace panda::defect_scan_aux {
33 class Class;
34 class Function;
35 class CalleeInfo;
36 class ModuleRecord;
37 
38 enum class ResolveType {
39     CLASS_OBJECT,
40     CLASS_INSTANCE,
41     FUNCTION_OBJECT,
42     OBJECT_VARIABLE,
43     UNRESOLVED_MODULE,
44     UNRESOLVED_GLOBAL_VAR,
45     UNRESOLVED_OTHER,
46 };
47 using FuncInstPair = std::pair<Function *, Inst>;
48 using ResolveResult = std::tuple<const void *, std::string, ResolveType>;
49 
50 class AbcFile final {
51 public:
52     static std::unique_ptr<const AbcFile> Open(std::string_view abc_filename);
53     ~AbcFile();
54 
55     bool IsModule(std::string_view record_name = "") const;
56     bool IsMergeAbc() const;
57     const std::string &GetAbcFileName() const;
58     const std::vector<std::shared_ptr<Class>> &GetClassList() const;
59     size_t GetDefinedFunctionCount() const;
60     size_t GetDefinedClassCount() const;
61     const Function *GetDefinedFunctionByIndex(size_t index) const;
62     const Function *GetFunctionByName(std::string_view func_name) const;
63     const Function *GetExportFunctionByExportName(std::string_view export_func_name,
64                                                   std::string_view record_name = "") const;
65     const Class *GetDefinedClassByIndex(size_t index) const;
66     const Class *GetClassByName(std::string_view class_name) const;
67     const Class *GetExportClassByExportName(std::string_view export_class_name,
68                                             std::string_view record_name = "") const;
69     ssize_t GetLineNumberByInst(const Function *func, const Inst &inst) const;
70     const std::set<std::string> GetFileRecordList() const;
71     size_t GetFileRecordCount() const;
72 
73     // used for export stat
74     std::string GetLocalNameByExportName(std::string_view export_name, std::string_view record_name = "") const;
75     // used exclusively for indirect export stat
76     std::string GetImportNameByExportName(std::string_view export_name, std::string_view record_name = "") const;
77     std::string GetModuleNameByExportName(std::string_view export_name, std::string_view record_name = "") const;
78     // used for import stat
79     std::string GetModuleNameByLocalName(std::string_view local_name, std::string_view record_name = "") const;
80     std::string GetImportNameByLocalName(std::string_view local_name, std::string_view record_name = "") const;
81     // return a string without #xx# prefix
82     std::string_view GetNameWithoutHashtag(std::string_view full_name, std::string_view record_name = "") const;
83     std::string GetStringByInst(const Inst &inst) const;
84     std::optional<FuncInstPair> GetStLexInstByLdLexInst(FuncInstPair func_inst_pair) const;
85     std::optional<FuncInstPair> GetStGlobalInstByLdGlobalInst(FuncInstPair func_inst_pair) const;
86 
87 private:
88     static constexpr char MODULE_CLASS[] = "L_ESModuleRecord;";
89     static constexpr char MODULE_IDX_FIELD_NAME[] = "moduleRecordIdx";
90     static constexpr char ENTRY_FUNCTION_NAME[] = "func_main_0";
91     static constexpr char PROTOTYPE[] = "prototype";
92     static constexpr char CALL[] = "call";
93     static constexpr char APPLY[] = "apply";
94     static constexpr char DELIM = '.';
95     static constexpr char EMPTY_STR[] = "";
96 
97     AbcFile(std::string_view filename, std::unique_ptr<const panda_file::File> &&panda_file);
98     NO_COPY_SEMANTIC(AbcFile);
99     NO_MOVE_SEMANTIC(AbcFile);
100 
101     void ExtractDebugInfo();
102     void ExtractModuleInfo();
103     void ExtractMergeAbcModuleInfo();
104     void ExtractModuleRecord(panda_file::File::EntityId module_id, std::unique_ptr<ModuleRecord> &module_record);
105     void InitializeAllDefinedFunction();
106     void ExtractDefinedClassAndFunctionInfo();
107     void ExtractMergedDefinedClassAndFunctionInfo();
108     void ExtractSingleDefinedClassAndFunctionInfo();
109     void ExtractClassAndFunctionInfo(Function *func);
110     void ExtractClassInheritInfo(Function *func) const;
111     void ExtractFunctionCalleeInfo(Function *func);
112     void BuildFunctionDefineChain(Function *parent_func, Function *child_func) const;
113     void BuildClassAndMemberFuncRelation(Class *clazz, Function *member_func) const;
114     void ExtractClassAndFunctionExportList();
115     void ExtractMergedClassAndFunctionExportList();
116     void ExtractSingleClassAndFunctionExportList();
117     void AddExportListForMerge(const Function *func_main, const Inst &inst);
118     void AddExportListForSingle(const Function *func_main, const Inst &inst);
119     void ExtractMergedClassAndFunctionInfo(Function *func);
120     compiler::Graph *GenerateFunctionGraph(const panda_file::MethodDataAccessor &mda, std::string_view func_name);
121     ResolveResult ResolveInstCommon(Function *func, Inst inst) const;
122     ResolveResult HandleLdObjByNameInstResolveResult(const Inst &ldobjbyname_inst, const ResolveResult &resolve_res,
123                                                      const std::string record_name = "") const;
124     ResolveResult HandleNewObjInstResolveResultCommon(const ResolveResult &resolve_res) const;
125     Function *ResolveDefineFuncInstCommon(const Function *func, const Inst &def_func_inst) const;
126     std::unique_ptr<Class> ResolveDefineClassWithBufferInst(Function *func, const Inst &define_class_inst) const;
127     void ResolveDefineMethodWithBufferInst(Function *func, const Inst &define_class_inst) const;
128     Class *GetClassFromMemberFunctionName(const std::string &member_func_name) const;
129     std::unique_ptr<CalleeInfo> ResolveCallInstCommon(Function *func, const Inst &call_inst,
130                                                       uint32_t func_obj_idx = 0) const;
131     std::unique_ptr<CalleeInfo> ResolveSuperCallInst(Function *func, const Inst &call_inst) const;
132     void ResolveDefineMethodInst(Function *member_func, const Inst &define_method_inst);
133     void HandleMemberFunctionFromClassBuf(const std::string &func_name, Function *def_func, Class *def_class) const;
134     void AddDefinedClass(std::shared_ptr<Class> &&def_class);
135     void AddDefinedFunction(std::shared_ptr<Function> &&def_func);
136     void AddMergedDefinedFunction(std::shared_ptr<Function> &&def_func);
137     void AddMergedDefinedClass(std::shared_ptr<Class> &&def_class, std::string record_name);
138     void AddCalleeInfo(std::unique_ptr<CalleeInfo> &&callee_info);
139     void AddModuleRecord(std::string record_name, std::unique_ptr<ModuleRecord> &&module_record);
140     Function *GetFunctionByNameImpl(std::string_view func_name) const;
141     Class *GetClassByNameImpl(std::string_view class_name) const;
142     const ModuleRecord *GetModuleRecordByName(std::string record_name) const;
143     std::string GetStringByMethodId(panda_file::File::EntityId method_id) const;
144     std::string GetStringByStringId(panda_file::File::EntityId string_id) const;
145 
146     std::string filename_;
147     bool is_merge_abc_ {false};
148     std::unique_ptr<const panda_file::File> panda_file_ {nullptr};
149     std::unique_ptr<const panda_file::DebugInfoExtractor> debug_info_ {nullptr};
150     std::vector<const Class *> export_class_list_;
151     std::vector<const Function *> export_func_list_;
152     std::unordered_map<std::string, std::vector<const Class *>> merge_export_class_map_;
153     std::unordered_map<std::string, std::vector<const Function *>> merge_export_func_map_;
154     std::vector<std::shared_ptr<Function>> def_func_list_;
155     std::vector<std::shared_ptr<Function>> merged_def_func_list_;
156     std::unordered_map<std::string, Function *> def_func_map_;
157     std::unordered_map<std::string, std::vector<std::shared_ptr<Function>>> merge_def_func_map_;
158     std::unordered_map<std::string, ModuleRecord *> module_record_map_;
159     std::vector<std::unique_ptr<const ModuleRecord>> module_record_list_;
160     std::vector<std::shared_ptr<Class>> def_class_list_;
161     std::vector<std::shared_ptr<Class>> merged_def_class_list_;
162     std::unordered_map<std::string, Class *> def_class_map_;
163     std::unordered_map<std::string, std::vector<std::shared_ptr<Class>>> merge_def_class_map_;
164     std::list<std::unique_ptr<CalleeInfo>> callee_info_list_;
165     std::set<std::string> record_name_set_;
166     std::unique_ptr<ArenaAllocator> allocator_ {nullptr};
167     std::unique_ptr<ArenaAllocator> local_allocator_ {nullptr};
168 };
169 }  // namespace panda::defect_scan_aux
170 
171 #endif  // LIBARK_DEFECT_SCAN_AUX_INCLUDE_ABC_FILE_H