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