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