• 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<const 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() const;
56     const std::string &GetAbcFileName() const;
57     size_t GetDefinedFunctionCount() const;
58     size_t GetDefinedClassCount() const;
59     const Function *GetDefinedFunctionByIndex(size_t index) const;
60     const Function *GetFunctionByName(std::string_view func_name) const;
61     const Function *GetExportFunctionByExportName(std::string_view export_func_name) const;
62     const Class *GetDefinedClassByIndex(size_t index) const;
63     const Class *GetClassByName(std::string_view class_name) const;
64     const Class *GetExportClassByExportName(std::string_view export_class_name) const;
65     ssize_t GetLineNumberByInst(const Function *func, const Inst &inst) const;
66 
67     // used for export stat
68     std::string GetInternalNameByExportName(std::string_view export_name) const;
69     // used exclusively for indirect export stat
70     std::string GetImportNameByExportName(std::string_view export_name) const;
71     std::string GetModuleNameByExportName(std::string_view export_name) const;
72     // used for import stat
73     std::string GetModuleNameByInternalName(std::string_view internal_name) const;
74     std::string GetImportNameByInternalName(std::string_view internal_name) const;
75     // return a string without #xx# prefix
76     std::string_view GetNameWithoutHashtag(std::string_view name) const;
77     std::string GetStringByInst(const Inst &inst) const;
78     std::optional<FuncInstPair> GetStLexInstByLdLexInst(FuncInstPair func_inst_pair) const;
79     std::optional<FuncInstPair> GetStGlobalInstByLdGlobalInst(FuncInstPair func_inst_pair) const;
80 
81 private:
82     static constexpr char MODULE_CLASS[] = "L_ESModuleRecord;";
83     static constexpr char ENTRY_FUNCTION_NAME[] = "func_main_0";
84     static constexpr char PROTOTYPE[] = "prototype";
85     static constexpr char CALL[] = "call";
86     static constexpr char APPLY[] = "apply";
87     static constexpr char DELIM = '.';
88     static constexpr char EMPTY_STR[] = "";
89 
90     AbcFile(std::string_view filename, std::unique_ptr<const panda_file::File> &&panda_file);
91     NO_COPY_SEMANTIC(AbcFile);
92     NO_MOVE_SEMANTIC(AbcFile);
93 
94     void ExtractDebugInfo();
95     void ExtractModuleInfo();
96     void ExtractModuleRecord(panda_file::File::EntityId module_id, std::unique_ptr<ModuleRecord> &module_record);
97     void InitializeAllDefinedFunction();
98     void ExtractDefinedClassAndFunctionInfo();
99     void ExtractClassAndFunctionInfo(Function *func);
100     void ExtractClassInheritInfo(const Function *func) const;
101     void ExtractFunctionCalleeInfo(Function *func);
102     void BuildFunctionDefineChain(Function *parent_func, Function *child_func) const;
103     void BuildClassAndMemberFuncRelation(Class *clazz, Function *member_func) const;
104     void ExtractClassAndFunctionExportList();
105     compiler::Graph *GenerateFunctionGraph(const panda_file::MethodDataAccessor &mda, std::string_view func_name);
106     ResolveResult ResolveInstCommon(const Function *func, Inst inst) const;
107     ResolveResult HandleLdObjByNameInstResolveResult(const Inst &ldobjbyname_inst,
108                                                      const ResolveResult &resolve_res) const;
109     ResolveResult HandleNewObjInstResolveResultCommon(const ResolveResult &resolve_res) const;
110     Function *ResolveDefineFuncInstCommon(const Function *func, const Inst &def_func_inst) const;
111     std::unique_ptr<Class> ResolveDefineClassWithBufferInst(Function *func, const Inst &define_class_inst) const;
112     std::unique_ptr<CalleeInfo> ResolveCallInstCommon(Function *func, const Inst &call_inst,
113                                                       uint32_t func_obj_idx = 0) const;
114     std::unique_ptr<CalleeInfo> ResolveSuperCallInst(Function *func, const Inst &call_inst) const;
115     void HandleMemberFunctionFromClassBuf(const std::string &func_name, Function *def_func, Class *def_class) const;
116     void AddDefinedClass(std::unique_ptr<Class> &&def_class);
117     void AddDefinedFunction(std::unique_ptr<Function> &&def_func);
118     void AddCalleeInfo(std::unique_ptr<CalleeInfo> &&callee_info);
119     Function *GetFunctionByNameImpl(std::string_view func_name) const;
120     Class *GetClassByNameImpl(std::string_view class_name) const;
121     std::string GetStringByMethodId(panda_file::File::EntityId method_id) const;
122     std::string GetStringByStringId(panda_file::File::EntityId string_id) const;
123 
124     std::string filename_;
125     std::unique_ptr<const panda_file::File> panda_file_ {nullptr};
126     std::unique_ptr<const panda_file::DebugInfoExtractor> debug_info_ {nullptr};
127     std::unique_ptr<const ModuleRecord> module_record_ {nullptr};
128     std::vector<const Class *> export_class_list_;
129     std::vector<const Function *> export_func_list_;
130     std::vector<std::unique_ptr<Function>> def_func_list_;
131     std::unordered_map<std::string, Function *> def_func_map_;
132     std::vector<std::unique_ptr<Class>> def_class_list_;
133     std::unordered_map<std::string, Class *> def_class_map_;
134     std::list<std::unique_ptr<CalleeInfo>> callee_info_list_;
135     std::unique_ptr<ArenaAllocator> allocator_ {nullptr};
136     std::unique_ptr<ArenaAllocator> local_allocator_ {nullptr};
137 };
138 }  // namespace panda::defect_scan_aux
139 
140 #endif  // LIBARK_DEFECT_SCAN_AUX_INCLUDE_ABC_FILE_H