1 /* 2 * Copyright (c) 2021-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 DISASSEMBLER_DISASSEMBLER_H 17 #define DISASSEMBLER_DISASSEMBLER_H 18 19 #include "macros.h" 20 #include "utils/type_helpers.h" 21 #include "utils/span.h" 22 23 #include "class_data_accessor-inl.h" 24 #include "code_data_accessor-inl.h" 25 #include "debug_data_accessor-inl.h" 26 #include "debug_info_extractor.h" 27 #include "field_data_accessor-inl.h" 28 #include "method_data_accessor-inl.h" 29 #include "literal_data_accessor-inl.h" 30 #include "param_annotations_data_accessor.h" 31 #include "annotation_data_accessor.h" 32 #include "proto_data_accessor-inl.h" 33 #include "file-inl.h" 34 #include "file.h" 35 #include "os/file.h" 36 37 #include "assembly-program.h" 38 #include "assembly-ins.h" 39 40 #include "bytecode_instruction-inl.h" 41 #include "libpandabase/macros.h" 42 43 #include <map> 44 #include <memory> 45 #include <string> 46 47 #include "accumulators.h" 48 49 namespace panda::disasm { 50 class Disassembler { 51 public: 52 NO_COPY_SEMANTIC(Disassembler); 53 DEFAULT_MOVE_SEMANTIC(Disassembler); 54 55 Disassembler() = default; 56 ~Disassembler() = default; 57 58 void Disassemble(const std::string &filename_in, const bool quiet = false, const bool skip_strings = false); 59 void CollectInfo(); 60 void Serialize(std::ostream &os, bool add_separators = false, bool print_information = false) const; 61 62 static inline bool IsPandasmFriendly(const char c); 63 static inline bool IsSystemType(const std::string &type_name); 64 65 void GetRecord(pandasm::Record *record, const panda_file::File::EntityId &record_id); 66 void AddMethodToTables(const panda_file::File::EntityId &method_id); 67 void GetMethod(pandasm::Function *method, const panda_file::File::EntityId &method_id); 68 void GetLiteralArray(pandasm::LiteralArray *lit_array, size_t index) const; 69 template <typename T> 70 void FillLiteralArrayData(pandasm::LiteralArray *lit_array, const panda_file::LiteralTag &tag, 71 const panda_file::LiteralDataAccessor::LiteralValue &value) const; 72 GetProgInfo()73 const ProgInfo &GetProgInfo() const 74 { 75 return prog_info_; 76 } 77 78 private: 79 void GetLiteralArrays(); 80 void FillLiteralData(pandasm::LiteralArray *lit_array, const panda_file::LiteralDataAccessor::LiteralValue &value, 81 const panda_file::LiteralTag &tag) const; 82 void GetRecords(); 83 void GetFields(pandasm::Record *record, const panda_file::File::EntityId &record_id); 84 85 void GetMethods(const panda_file::File::EntityId &record_id); 86 void GetParams(pandasm::Function *method, const panda_file::File::EntityId &proto_id) const; 87 IdList GetInstructions(pandasm::Function *method, panda_file::File::EntityId method_id, 88 panda_file::File::EntityId code_id) const; 89 LabelTable GetExceptions(pandasm::Function *method, panda_file::File::EntityId method_id, 90 panda_file::File::EntityId code_id) const; 91 bool LocateTryBlock(const BytecodeInstruction &bc_ins, const BytecodeInstruction &bc_ins_last, 92 const panda_file::CodeDataAccessor::TryBlock &try_block, 93 pandasm::Function::CatchBlock *catch_block_pa, LabelTable *label_table, size_t try_idx) const; 94 bool LocateCatchBlock(const BytecodeInstruction &bc_ins, const BytecodeInstruction &bc_ins_last, 95 const panda_file::CodeDataAccessor::CatchBlock &catch_block, 96 pandasm::Function::CatchBlock *catch_block_pa, LabelTable *label_table, size_t try_idx, 97 size_t catch_idx) const; 98 99 void GetMetaData(pandasm::Record *record, const panda_file::File::EntityId &record_id) const; 100 void GetMetaData(pandasm::Function *method, const panda_file::File::EntityId &method_id) const; 101 void GetMetaData(pandasm::Field *field, const panda_file::File::EntityId &field_id); 102 103 void GetLanguageSpecificMetadata(); 104 105 std::string AnnotationTagToString(const char tag) const; 106 107 std::string ScalarValueToString(const panda_file::ScalarValue &value, const std::string &type); 108 std::string ArrayValueToString(const panda_file::ArrayValue &value, const std::string &type, const size_t idx); 109 110 std::string GetFullMethodName(const panda_file::File::EntityId &method_id) const; 111 std::string GetMethodSignature(const panda_file::File::EntityId &method_id) const; 112 std::string GetFullRecordName(const panda_file::File::EntityId &class_id) const; 113 114 void GetRecordInfo(const panda_file::File::EntityId &record_id, RecordInfo *record_info) const; 115 void GetMethodInfo(const panda_file::File::EntityId &method_id, MethodInfo *method_info) const; 116 void GetInsInfo(const panda_file::File::EntityId &code_id, MethodInfo *method_info) const; 117 118 template <typename T> 119 void SerializeValues(const pandasm::LiteralArray &lit_array, T &os) const; 120 std::string SerializeLiteralArray(const pandasm::LiteralArray &lit_array) const; 121 void Serialize(const std::string &key, const pandasm::LiteralArray &lit_array, std::ostream &os) const; 122 template <typename T> 123 void SerializeLiterals(const pandasm::LiteralArray &lit_array, T &os) const; 124 std::string LiteralTagToString(const panda_file::LiteralTag &tag) const; 125 void Serialize(const pandasm::Record &record, std::ostream &os, bool print_information = false) const; 126 void SerializeFields(const pandasm::Record &record, std::ostream &os, bool print_information) const; 127 void Serialize(const pandasm::Function &method, std::ostream &os, bool print_information = false) const; 128 void Serialize(const pandasm::Function::CatchBlock &catch_block, std::ostream &os) const; 129 void Serialize(const pandasm::ItemMetadata &meta, const AnnotationList &ann_list, std::ostream &os) const; 130 void SerializeLineNumberTable(const panda_file::LineNumberTable &line_number_table, std::ostream &os) const; 131 void SerializeLocalVariableTable(const panda_file::LocalVariableTable &local_variable_table, 132 const pandasm::Function &method, std::ostream &os) const; 133 bool IsModuleLiteralOffset(const panda_file::File::EntityId &id) const; SerializeLanguage(std::ostream & os)134 inline void SerializeLanguage(std::ostream &os) const 135 { 136 os << ".language " << panda::panda_file::LanguageToString(file_language_) << "\n\n"; 137 } 138 139 pandasm::Type PFTypeToPandasmType(const panda_file::Type &type, panda_file::ProtoDataAccessor &pda, 140 size_t &ref_idx) const; 141 142 pandasm::Type FieldTypeToPandasmType(const uint32_t &type) const; 143 StringDataToString(panda_file::File::StringData sd)144 static inline std::string StringDataToString(panda_file::File::StringData sd) 145 { 146 return std::string(utf::Mutf8AsCString(sd.data)); 147 } 148 149 pandasm::Opcode BytecodeOpcodeToPandasmOpcode(BytecodeInstruction::Opcode o) const; 150 pandasm::Opcode BytecodeOpcodeToPandasmOpcode(uint8_t o) const; 151 152 pandasm::Ins BytecodeInstructionToPandasmInstruction(BytecodeInstruction bc_ins, 153 panda_file::File::EntityId method_id) const; 154 155 std::string IDToString(BytecodeInstruction bc_ins, panda_file::File::EntityId method_id, size_t idx) const; 156 157 panda::panda_file::SourceLang GetRecordLanguage(panda_file::File::EntityId class_id) const; 158 159 void GetLiteralArrayByOffset(pandasm::LiteralArray *lit_array, panda_file::File::EntityId offset) const; 160 161 std::unique_ptr<const panda_file::File> file_; 162 pandasm::Program prog_; 163 164 panda::panda_file::SourceLang file_language_ = panda::panda_file::SourceLang::PANDA_ASSEMBLY; 165 166 std::map<std::string, panda_file::File::EntityId> record_name_to_id_; 167 std::map<std::string, panda_file::File::EntityId> method_name_to_id_; 168 169 ProgAnnotations prog_ann_; 170 171 ProgInfo prog_info_; 172 173 std::unique_ptr<panda_file::DebugInfoExtractor> debug_info_extractor_; 174 175 bool quiet_; 176 bool skip_strings_; 177 std::unordered_set<uint32_t> module_literals_; 178 #include "disasm_plugins.inc" 179 }; 180 } // namespace panda::disasm 181 182 #endif // DISASSEMBLER_DISASSEMBLER_H 183