1b1994897Sopenharmony_ci/* 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef DISASSEMBLER_DISASSEMBLER_H 17b1994897Sopenharmony_ci#define DISASSEMBLER_DISASSEMBLER_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include "macros.h" 20b1994897Sopenharmony_ci#include "utils/type_helpers.h" 21b1994897Sopenharmony_ci#include "utils/span.h" 22b1994897Sopenharmony_ci 23b1994897Sopenharmony_ci#include "class_data_accessor-inl.h" 24b1994897Sopenharmony_ci#include "code_data_accessor-inl.h" 25b1994897Sopenharmony_ci#include "debug_data_accessor-inl.h" 26b1994897Sopenharmony_ci#include "debug_info_extractor.h" 27b1994897Sopenharmony_ci#include "field_data_accessor-inl.h" 28b1994897Sopenharmony_ci#include "method_data_accessor-inl.h" 29b1994897Sopenharmony_ci#include "literal_data_accessor-inl.h" 30b1994897Sopenharmony_ci#include "libpandafile/module_data_accessor-inl.h" 31b1994897Sopenharmony_ci#include "param_annotations_data_accessor.h" 32b1994897Sopenharmony_ci#include "annotation_data_accessor.h" 33b1994897Sopenharmony_ci#include "proto_data_accessor-inl.h" 34b1994897Sopenharmony_ci#include "file-inl.h" 35b1994897Sopenharmony_ci#include "file.h" 36b1994897Sopenharmony_ci#include "os/file.h" 37b1994897Sopenharmony_ci 38b1994897Sopenharmony_ci#include "assembly-program.h" 39b1994897Sopenharmony_ci#include "assembly-ins.h" 40b1994897Sopenharmony_ci 41b1994897Sopenharmony_ci#include "bytecode_instruction-inl.h" 42b1994897Sopenharmony_ci#include "libpandabase/macros.h" 43b1994897Sopenharmony_ci 44b1994897Sopenharmony_ci#include <map> 45b1994897Sopenharmony_ci#include <memory> 46b1994897Sopenharmony_ci#include <string> 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_ci#include "accumulators.h" 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_cinamespace panda::disasm { 51b1994897Sopenharmony_ciclass Disassembler { 52b1994897Sopenharmony_cipublic: 53b1994897Sopenharmony_ci NO_COPY_SEMANTIC(Disassembler); 54b1994897Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(Disassembler); 55b1994897Sopenharmony_ci 56b1994897Sopenharmony_ci Disassembler() = default; 57b1994897Sopenharmony_ci ~Disassembler() = default; 58b1994897Sopenharmony_ci 59b1994897Sopenharmony_ci void Disassemble(const std::string &filename_in, const bool quiet = false, const bool skip_strings = false); 60b1994897Sopenharmony_ci void CollectInfo(); 61b1994897Sopenharmony_ci void Serialize(std::ostream &os, bool add_separators = false, bool print_information = false) const; 62b1994897Sopenharmony_ci 63b1994897Sopenharmony_ci static inline bool IsPandasmFriendly(const char c); 64b1994897Sopenharmony_ci static inline bool IsSystemType(const std::string &type_name); 65b1994897Sopenharmony_ci 66b1994897Sopenharmony_ci void GetRecord(pandasm::Record *record, const panda_file::File::EntityId &record_id); 67b1994897Sopenharmony_ci void AddMethodToTables(const panda_file::File::EntityId &method_id); 68b1994897Sopenharmony_ci void GetMethod(pandasm::Function *method, const panda_file::File::EntityId &method_id); 69b1994897Sopenharmony_ci void GetLiteralArray(pandasm::LiteralArray *lit_array, size_t index) const; 70b1994897Sopenharmony_ci std::optional<std::vector<std::string>> GetAnnotationByMethodName(const std::string &method_name) const; 71b1994897Sopenharmony_ci std::optional<std::string> GetSerializedRecord(const std::string &record_name) const; 72b1994897Sopenharmony_ci std::optional<std::string> GetSerializedMethodAnnotation(const std::string &method_name, 73b1994897Sopenharmony_ci const std::string &anno_name) const; 74b1994897Sopenharmony_ci std::vector<std::string> GetStrings() const; 75b1994897Sopenharmony_ci std::vector<std::string> GetModuleLiterals() const; 76b1994897Sopenharmony_ci template <typename T> 77b1994897Sopenharmony_ci void FillLiteralArrayData(pandasm::LiteralArray *lit_array, const panda_file::LiteralTag &tag, 78b1994897Sopenharmony_ci const panda_file::LiteralDataAccessor::LiteralValue &value) const; 79b1994897Sopenharmony_ci pandasm::Ins BytecodeInstructionToPandasmInstruction(BytecodeInstruction bc_ins, 80b1994897Sopenharmony_ci panda_file::File::EntityId method_id) const; 81b1994897Sopenharmony_ci 82b1994897Sopenharmony_ci const ProgInfo &GetProgInfo() const 83b1994897Sopenharmony_ci { 84b1994897Sopenharmony_ci return prog_info_; 85b1994897Sopenharmony_ci } 86b1994897Sopenharmony_ci 87b1994897Sopenharmony_ci std::vector<size_t> GetColumnNumber(); 88b1994897Sopenharmony_ci std::vector<size_t> GetLineNumber(); 89b1994897Sopenharmony_ci 90b1994897Sopenharmony_ciprivate: 91b1994897Sopenharmony_ci void GetLiteralArrays(); 92b1994897Sopenharmony_ci void FillLiteralArrayTable(panda_file::File::EntityId &id, size_t index); 93b1994897Sopenharmony_ci void FillLiteralData(pandasm::LiteralArray *lit_array, const panda_file::LiteralDataAccessor::LiteralValue &value, 94b1994897Sopenharmony_ci const panda_file::LiteralTag &tag) const; 95b1994897Sopenharmony_ci void GetRecords(); 96b1994897Sopenharmony_ci void GetFields(pandasm::Record *record, const panda_file::File::EntityId &record_id); 97b1994897Sopenharmony_ci 98b1994897Sopenharmony_ci void GetMethods(const panda_file::File::EntityId &record_id); 99b1994897Sopenharmony_ci void GetAnnotationElements(pandasm::Function &method, const panda_file::AnnotationDataAccessor &ada, 100b1994897Sopenharmony_ci const std::string &annotation_name); 101b1994897Sopenharmony_ci void GetMethodAnnotations(pandasm::Function &method, const panda_file::File::EntityId &method_id); 102b1994897Sopenharmony_ci void CreateAnnotationElement(panda_file::AnnotationDataAccessor &ada, pandasm::Function &method, 103b1994897Sopenharmony_ci const std::string &ann_name, const std::string &ann_elem_name, 104b1994897Sopenharmony_ci const std::string &ann_elem_index); 105b1994897Sopenharmony_ci template <typename T, typename U> 106b1994897Sopenharmony_ci void AddAnnotationElement(pandasm::Function &method, const std::string &annotation_name, const std::string &key, 107b1994897Sopenharmony_ci const U &value); 108b1994897Sopenharmony_ci void GetParams(pandasm::Function *method, const panda_file::File::EntityId &code_id) const; 109b1994897Sopenharmony_ci IdList GetInstructions(pandasm::Function *method, panda_file::File::EntityId method_id, 110b1994897Sopenharmony_ci panda_file::File::EntityId code_id) const; 111b1994897Sopenharmony_ci LabelTable GetExceptions(pandasm::Function *method, panda_file::File::EntityId method_id, 112b1994897Sopenharmony_ci panda_file::File::EntityId code_id) const; 113b1994897Sopenharmony_ci bool LocateTryBlock(const BytecodeInstruction &bc_ins, const BytecodeInstruction &bc_ins_last, 114b1994897Sopenharmony_ci const panda_file::CodeDataAccessor::TryBlock &try_block, 115b1994897Sopenharmony_ci pandasm::Function::CatchBlock *catch_block_pa, LabelTable *label_table, size_t try_idx) const; 116b1994897Sopenharmony_ci bool LocateCatchBlock(const BytecodeInstruction &bc_ins, const BytecodeInstruction &bc_ins_last, 117b1994897Sopenharmony_ci const panda_file::CodeDataAccessor::CatchBlock &catch_block, 118b1994897Sopenharmony_ci pandasm::Function::CatchBlock *catch_block_pa, LabelTable *label_table, size_t try_idx, 119b1994897Sopenharmony_ci size_t catch_idx) const; 120b1994897Sopenharmony_ci 121b1994897Sopenharmony_ci void GetMetaData(pandasm::Record *record, const panda_file::File::EntityId &record_id) const; 122b1994897Sopenharmony_ci void GetMetaData(pandasm::Function *method, const panda_file::File::EntityId &method_id) const; 123b1994897Sopenharmony_ci void GetMetaData(pandasm::Field *field, const panda_file::File::EntityId &field_id, bool is_scope_names_record); 124b1994897Sopenharmony_ci void GetMetadataFieldValue(panda_file::FieldDataAccessor &field_accessor, pandasm::Field *field, 125b1994897Sopenharmony_ci bool isScopeNamesRecord); 126b1994897Sopenharmony_ci 127b1994897Sopenharmony_ci void GetLanguageSpecificMetadata(); 128b1994897Sopenharmony_ci 129b1994897Sopenharmony_ci std::string AnnotationTagToString(const char tag) const; 130b1994897Sopenharmony_ci 131b1994897Sopenharmony_ci std::string ScalarValueToString(const panda_file::ScalarValue &value, const std::string &type); 132b1994897Sopenharmony_ci std::string ArrayValueToString(const panda_file::ArrayValue &value, const std::string &type, const size_t idx); 133b1994897Sopenharmony_ci 134b1994897Sopenharmony_ci std::string GetFullMethodName(const panda_file::File::EntityId &method_id) const; 135b1994897Sopenharmony_ci std::string GetMethodSignature(const panda_file::File::EntityId &method_id) const; 136b1994897Sopenharmony_ci std::string GetFullRecordName(const panda_file::File::EntityId &class_id) const; 137b1994897Sopenharmony_ci 138b1994897Sopenharmony_ci void GetRecordInfo(const panda_file::File::EntityId &record_id, RecordInfo *record_info) const; 139b1994897Sopenharmony_ci void GetMethodInfo(const panda_file::File::EntityId &method_id, MethodInfo *method_info) const; 140b1994897Sopenharmony_ci void GetInsInfo(const panda_file::File::EntityId &code_id, MethodInfo *method_info) const; 141b1994897Sopenharmony_ci 142b1994897Sopenharmony_ci template <typename T> 143b1994897Sopenharmony_ci void SerializeValues(const pandasm::LiteralArray &lit_array, T &os) const; 144b1994897Sopenharmony_ci std::string SerializeLiteralArray(const pandasm::LiteralArray &lit_array) const; 145b1994897Sopenharmony_ci void Serialize(const std::string &key, const pandasm::LiteralArray &lit_array, std::ostream &os) const; 146b1994897Sopenharmony_ci void Serialize(const std::string &module_offset, const std::vector<std::string> &module_array, 147b1994897Sopenharmony_ci std::ostream &os) const; 148b1994897Sopenharmony_ci template <typename T> 149b1994897Sopenharmony_ci void SerializeLiterals(const pandasm::LiteralArray &lit_array, T &os) const; 150b1994897Sopenharmony_ci std::string LiteralTagToString(const panda_file::LiteralTag &tag) const; 151b1994897Sopenharmony_ci void Serialize(const pandasm::Record &record, std::ostream &os, bool print_information = false) const; 152b1994897Sopenharmony_ci void SerializeFields(const pandasm::Record &record, std::ostream &os, bool print_information) const; 153b1994897Sopenharmony_ci void Serialize(const pandasm::Function &method, std::ostream &os, bool print_information = false) const; 154b1994897Sopenharmony_ci void SerializeInstructions(const pandasm::Function &method, std::ostream &os, 155b1994897Sopenharmony_ci const std::map<std::string, MethodInfo>::const_iterator &method_info_it, 156b1994897Sopenharmony_ci bool print_method_info = false) const; 157b1994897Sopenharmony_ci void SerializeMethodAnnotations(const pandasm::Function &method, std::ostream &os) const; 158b1994897Sopenharmony_ci void SerializeMethodAnnotation(const pandasm::AnnotationData &anno, std::ostream &os) const; 159b1994897Sopenharmony_ci void SerializeAnnotationElement(const std::vector<pandasm::AnnotationElement> &elements, std::stringstream &ss, 160b1994897Sopenharmony_ci uint32_t idx) const; 161b1994897Sopenharmony_ci void SerializeStrings(const panda_file::File::EntityId &offset, const std::string &name_value, 162b1994897Sopenharmony_ci std::ostream &os) const; 163b1994897Sopenharmony_ci void Serialize(const pandasm::Function::CatchBlock &catch_block, std::ostream &os) const; 164b1994897Sopenharmony_ci void Serialize(const pandasm::ItemMetadata &meta, const AnnotationList &ann_list, std::ostream &os) const; 165b1994897Sopenharmony_ci void SerializeLineNumberTable(const panda_file::LineNumberTable &line_number_table, std::ostream &os) const; 166b1994897Sopenharmony_ci void SerializeColumnNumberTable(const panda_file::ColumnNumberTable &column_number_table, std::ostream &os) const; 167b1994897Sopenharmony_ci void SerializeLocalVariableTable(const panda_file::LocalVariableTable &local_variable_table, 168b1994897Sopenharmony_ci const pandasm::Function &method, std::ostream &os) const; 169b1994897Sopenharmony_ci bool IsModuleLiteralOffset(const panda_file::File::EntityId &id) const; 170b1994897Sopenharmony_ci inline void SerializeLanguage(std::ostream &os) const 171b1994897Sopenharmony_ci { 172b1994897Sopenharmony_ci os << ".language " << panda::panda_file::LanguageToString(file_language_) << "\n\n"; 173b1994897Sopenharmony_ci } 174b1994897Sopenharmony_ci 175b1994897Sopenharmony_ci pandasm::Type PFTypeToPandasmType(const panda_file::Type &type, panda_file::ProtoDataAccessor &pda, 176b1994897Sopenharmony_ci size_t &ref_idx) const; 177b1994897Sopenharmony_ci 178b1994897Sopenharmony_ci pandasm::Type FieldTypeToPandasmType(const uint32_t &type) const; 179b1994897Sopenharmony_ci 180b1994897Sopenharmony_ci static inline std::string StringDataToString(panda_file::File::StringData sd) 181b1994897Sopenharmony_ci { 182b1994897Sopenharmony_ci return std::string(utf::Mutf8AsCString(sd.data)); 183b1994897Sopenharmony_ci } 184b1994897Sopenharmony_ci 185b1994897Sopenharmony_ci pandasm::Opcode BytecodeOpcodeToPandasmOpcode(BytecodeInstruction::Opcode o) const; 186b1994897Sopenharmony_ci pandasm::Opcode BytecodeOpcodeToPandasmOpcode(uint8_t o) const; 187b1994897Sopenharmony_ci 188b1994897Sopenharmony_ci std::string IDToString(BytecodeInstruction bc_ins, panda_file::File::EntityId method_id, size_t idx) const; 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci panda::panda_file::SourceLang GetRecordLanguage(panda_file::File::EntityId class_id) const; 191b1994897Sopenharmony_ci void GetLiteralArrayByOffset(pandasm::LiteralArray *lit_array, panda_file::File::EntityId offset) const; 192b1994897Sopenharmony_ci 193b1994897Sopenharmony_ci std::vector<std::string> GetModuleLiteralArray(panda_file::File::EntityId &module_id) const; 194b1994897Sopenharmony_ci std::string SerializeModuleLiteralArray(const std::vector<std::string> &module_array) const; 195b1994897Sopenharmony_ci std::string ModuleTagToString(panda_file::ModuleTag &tag) const; 196b1994897Sopenharmony_ci 197b1994897Sopenharmony_ci std::string getLiteralArrayTypeFromValue(const pandasm::LiteralArray &literal_array) const; 198b1994897Sopenharmony_ci void DumpLiteralArray(const pandasm::LiteralArray &literal_array, std::stringstream &ss) const; 199b1994897Sopenharmony_ci void SerializeFieldValue(const pandasm::Field &f, std::stringstream &ss) const; 200b1994897Sopenharmony_ci 201b1994897Sopenharmony_ci std::unique_ptr<const panda_file::File> file_; 202b1994897Sopenharmony_ci pandasm::Program prog_; 203b1994897Sopenharmony_ci 204b1994897Sopenharmony_ci inline std::string GetStringByOffset(uint32_t offset) const 205b1994897Sopenharmony_ci { 206b1994897Sopenharmony_ci const auto sd = file_->GetStringData(panda_file::File::EntityId(offset)); 207b1994897Sopenharmony_ci return std::string(utf::Mutf8AsCString(sd.data)); 208b1994897Sopenharmony_ci } 209b1994897Sopenharmony_ci 210b1994897Sopenharmony_ci inline bool IsValidOffset(uint32_t offset) const 211b1994897Sopenharmony_ci { 212b1994897Sopenharmony_ci return panda_file::File::EntityId(offset).IsValid() && offset < file_->GetHeader()->file_size; 213b1994897Sopenharmony_ci } 214b1994897Sopenharmony_ci 215b1994897Sopenharmony_ci inline std::string GetFileNameByPath(const std::string &file_path) const 216b1994897Sopenharmony_ci { 217b1994897Sopenharmony_ci size_t pos = file_path.find_last_of(panda::os::file::File::GetPathDelim()); 218b1994897Sopenharmony_ci if (pos == std::string::npos) { 219b1994897Sopenharmony_ci return file_path; 220b1994897Sopenharmony_ci } 221b1994897Sopenharmony_ci 222b1994897Sopenharmony_ci return file_path.substr(pos + 1); 223b1994897Sopenharmony_ci } 224b1994897Sopenharmony_ci 225b1994897Sopenharmony_ci panda::panda_file::SourceLang file_language_ = panda::panda_file::SourceLang::PANDA_ASSEMBLY; 226b1994897Sopenharmony_ci 227b1994897Sopenharmony_ci std::map<std::string, panda_file::File::EntityId> record_name_to_id_; 228b1994897Sopenharmony_ci std::map<std::string, panda_file::File::EntityId> method_name_to_id_; 229b1994897Sopenharmony_ci std::map<std::string, std::vector<std::string>> modulearray_table_; 230b1994897Sopenharmony_ci mutable std::map<panda_file::File::EntityId, std::string> string_offset_to_name_; 231b1994897Sopenharmony_ci 232b1994897Sopenharmony_ci ProgAnnotations prog_ann_; 233b1994897Sopenharmony_ci 234b1994897Sopenharmony_ci ProgInfo prog_info_; 235b1994897Sopenharmony_ci 236b1994897Sopenharmony_ci std::unique_ptr<panda_file::DebugInfoExtractor> debug_info_extractor_; 237b1994897Sopenharmony_ci 238b1994897Sopenharmony_ci bool quiet_; 239b1994897Sopenharmony_ci bool skip_strings_; 240b1994897Sopenharmony_ci std::unordered_set<uint32_t> module_literals_; 241b1994897Sopenharmony_ci std::unordered_set<uint32_t> module_request_phase_literals_; 242b1994897Sopenharmony_ci#include "disasm_plugins.inc" 243b1994897Sopenharmony_ci}; 244b1994897Sopenharmony_ci} // namespace panda::disasm 245b1994897Sopenharmony_ci 246b1994897Sopenharmony_ci#endif // DISASSEMBLER_DISASSEMBLER_H 247