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 LIBPANDAFILE_FILE_READER_H 17b1994897Sopenharmony_ci#define LIBPANDAFILE_FILE_READER_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <type_traits> 20b1994897Sopenharmony_ci#include "annotation_data_accessor.h" 21b1994897Sopenharmony_ci#include "bytecode_instruction.h" 22b1994897Sopenharmony_ci#include "class_data_accessor.h" 23b1994897Sopenharmony_ci#include "code_data_accessor.h" 24b1994897Sopenharmony_ci#include "debug_data_accessor.h" 25b1994897Sopenharmony_ci#include "field_data_accessor.h" 26b1994897Sopenharmony_ci#include "file_item_container.h" 27b1994897Sopenharmony_ci#include "libpandafile/helpers.h" 28b1994897Sopenharmony_ci#include "literal_data_accessor.h" 29b1994897Sopenharmony_ci#include "method_data_accessor.h" 30b1994897Sopenharmony_ci#include "method_handle_data_accessor.h" 31b1994897Sopenharmony_ci#include "os/file.h" 32b1994897Sopenharmony_ci#include "param_annotations_data_accessor.h" 33b1994897Sopenharmony_ci#include "proto_data_accessor.h" 34b1994897Sopenharmony_ci#include "utils/pandargs.h" 35b1994897Sopenharmony_ci#include "utils/span.h" 36b1994897Sopenharmony_ci#include "utils/type_helpers.h" 37b1994897Sopenharmony_ci#include "utils/leb128.h" 38b1994897Sopenharmony_ci#if !PANDA_TARGET_WINDOWS 39b1994897Sopenharmony_ci#include "securec.h" 40b1994897Sopenharmony_ci#endif 41b1994897Sopenharmony_ci 42b1994897Sopenharmony_ci#include <cstdint> 43b1994897Sopenharmony_ci#include <cerrno> 44b1994897Sopenharmony_ci 45b1994897Sopenharmony_ci#include <limits> 46b1994897Sopenharmony_ci#include <vector> 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_cinamespace panda::panda_file { 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ciclass FileReader { 51b1994897Sopenharmony_cipublic: 52b1994897Sopenharmony_ci // default methods 53b1994897Sopenharmony_ci explicit FileReader(std::unique_ptr<const File> &&file) : file_(std::move(file)) {} 54b1994897Sopenharmony_ci virtual ~FileReader() = default; 55b1994897Sopenharmony_ci 56b1994897Sopenharmony_ci bool ReadContainer(); 57b1994897Sopenharmony_ci 58b1994897Sopenharmony_ci ItemContainer *GetContainerPtr() 59b1994897Sopenharmony_ci { 60b1994897Sopenharmony_ci return &container_; 61b1994897Sopenharmony_ci } 62b1994897Sopenharmony_ci 63b1994897Sopenharmony_ci void ComputeLayoutAndUpdateIndices(); 64b1994897Sopenharmony_ci 65b1994897Sopenharmony_ci NO_COPY_SEMANTIC(FileReader); 66b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(FileReader); 67b1994897Sopenharmony_ci 68b1994897Sopenharmony_ciprivate: 69b1994897Sopenharmony_ci bool ReadLiteralArrayItems(); 70b1994897Sopenharmony_ci bool ReadIndexHeaders(); 71b1994897Sopenharmony_ci bool ReadClasses(); 72b1994897Sopenharmony_ci 73b1994897Sopenharmony_ci bool CreateLiteralArrayItem(const LiteralDataAccessor::LiteralValue &lit_value, const LiteralTag &tag, 74b1994897Sopenharmony_ci File::EntityId array_id); 75b1994897Sopenharmony_ci AnnotationItem *CreateAnnotationItem(File::EntityId ann_id); 76b1994897Sopenharmony_ci MethodItem *CreateMethodItem(ClassItem *cls, File::EntityId method_id); 77b1994897Sopenharmony_ci ForeignMethodItem *CreateForeignMethodItem(BaseClassItem *fcls, File::EntityId method_id); 78b1994897Sopenharmony_ci FieldItem *CreateFieldItem(ClassItem *cls, File::EntityId field_id); 79b1994897Sopenharmony_ci ForeignFieldItem *CreateForeignFieldItem(BaseClassItem *fcls, File::EntityId field_id); 80b1994897Sopenharmony_ci ClassItem *CreateClassItem(File::EntityId class_id); 81b1994897Sopenharmony_ci ForeignClassItem *CreateForeignClassItem(File::EntityId class_id); 82b1994897Sopenharmony_ci MethodHandleItem *CreateMethodHandleItem(File::EntityId mh_id); 83b1994897Sopenharmony_ci TypeItem *CreateParamTypeItem(ProtoDataAccessor *proto_acc, size_t param_num, size_t reference_num); 84b1994897Sopenharmony_ci TypeItem *GetReturnTypeItem(Type type, size_t &reference_num); 85b1994897Sopenharmony_ci std::vector<MethodParamItem> CreateMethodParamItems(ProtoDataAccessor *proto_acc, MethodDataAccessor *method_acc, 86b1994897Sopenharmony_ci size_t reference_num); 87b1994897Sopenharmony_ci DebugInfoItem *CreateDebugInfoItem(File::EntityId debug_info_id); 88b1994897Sopenharmony_ci void EnumerateBlocks(MethodDataAccessor method_acc, MethodItem *method_item); 89b1994897Sopenharmony_ci void UpdateDebugInfoDependecies(File::EntityId debug_info_id); 90b1994897Sopenharmony_ci void UpdateDebugInfo(DebugInfoItem *debug_info_item, File::EntityId debug_info_id); 91b1994897Sopenharmony_ci void CreateSuperClassItem(ClassDataAccessor& class_acc, ClassItem* class_item, const std::string& class_name); 92b1994897Sopenharmony_ci void AddIndexDependencyInstFlag(CodeItem *code_item, MethodItem *method_item, 93b1994897Sopenharmony_ci const std::unordered_map<File::EntityId, File::EntityId> &reverse_done); 94b1994897Sopenharmony_ci void UpdateIdInstFlag(CodeItem *code_item, MethodItem *method_item, 95b1994897Sopenharmony_ci const std::unordered_map<File::EntityId, File::EntityId> &reverse_done); 96b1994897Sopenharmony_ci 97b1994897Sopenharmony_ci template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true> 98b1994897Sopenharmony_ci void SetIntegerFieldValue(FieldDataAccessor *field_acc, FieldItem *field_item) 99b1994897Sopenharmony_ci { 100b1994897Sopenharmony_ci auto value = field_acc->GetValue<T>(); 101b1994897Sopenharmony_ci if (!value) { 102b1994897Sopenharmony_ci return; 103b1994897Sopenharmony_ci } 104b1994897Sopenharmony_ci 105b1994897Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements) 106b1994897Sopenharmony_ci if constexpr (is_same_v<T, int64_t> || is_same_v<T, uint64_t>) { 107b1994897Sopenharmony_ci auto *value_item = container_.GetOrCreateLongValueItem(value.value()); 108b1994897Sopenharmony_ci field_item->SetValue(value_item); 109b1994897Sopenharmony_ci // NOLINTNEXTLINE(readability-misleading-indentation) 110b1994897Sopenharmony_ci } else { 111b1994897Sopenharmony_ci auto *value_item = container_.GetOrCreateIntegerValueItem(value.value()); 112b1994897Sopenharmony_ci field_item->SetValue(value_item); 113b1994897Sopenharmony_ci } 114b1994897Sopenharmony_ci } 115b1994897Sopenharmony_ci 116b1994897Sopenharmony_ci template <typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true> 117b1994897Sopenharmony_ci void SetFloatFieldValue(FieldDataAccessor *field_acc, FieldItem *field_item) 118b1994897Sopenharmony_ci { 119b1994897Sopenharmony_ci auto value = field_acc->GetValue<T>(); 120b1994897Sopenharmony_ci if (!value) { 121b1994897Sopenharmony_ci return; 122b1994897Sopenharmony_ci } 123b1994897Sopenharmony_ci 124b1994897Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements) 125b1994897Sopenharmony_ci if constexpr (is_same_v<T, double>) { 126b1994897Sopenharmony_ci auto *value_item = container_.GetOrCreateDoubleValueItem(value.value()); 127b1994897Sopenharmony_ci field_item->SetValue(value_item); 128b1994897Sopenharmony_ci // NOLINTNEXTLINE(readability-misleading-indentation) 129b1994897Sopenharmony_ci } else { 130b1994897Sopenharmony_ci auto *value_item = container_.GetOrCreateFloatValueItem(value.value()); 131b1994897Sopenharmony_ci field_item->SetValue(value_item); 132b1994897Sopenharmony_ci } 133b1994897Sopenharmony_ci } 134b1994897Sopenharmony_ci 135b1994897Sopenharmony_ci void SetStringFieldValue(FieldDataAccessor *field_acc, FieldItem *field_item) 136b1994897Sopenharmony_ci { 137b1994897Sopenharmony_ci auto value = field_acc->GetValue<uint32_t>(); 138b1994897Sopenharmony_ci if (value) { 139b1994897Sopenharmony_ci panda_file::File::EntityId string_id(value.value()); 140b1994897Sopenharmony_ci auto data = file_->GetStringData(string_id); 141b1994897Sopenharmony_ci std::string string_data(reinterpret_cast<const char *>(data.data)); 142b1994897Sopenharmony_ci auto *string_item = container_.GetOrCreateStringItem(string_data); 143b1994897Sopenharmony_ci auto *value_item = container_.GetOrCreateIdValueItem(string_item); 144b1994897Sopenharmony_ci field_item->SetValue(value_item); 145b1994897Sopenharmony_ci } 146b1994897Sopenharmony_ci } 147b1994897Sopenharmony_ci 148b1994897Sopenharmony_ci // Creates foreign or non-foreign method item 149b1994897Sopenharmony_ci inline BaseItem *CreateGenericMethodItem(BaseClassItem *class_item, File::EntityId method_id) 150b1994897Sopenharmony_ci { 151b1994897Sopenharmony_ci if (file_->IsExternal(method_id)) { 152b1994897Sopenharmony_ci return CreateForeignMethodItem(class_item, method_id); 153b1994897Sopenharmony_ci } 154b1994897Sopenharmony_ci return CreateMethodItem(static_cast<ClassItem *>(class_item), method_id); 155b1994897Sopenharmony_ci } 156b1994897Sopenharmony_ci 157b1994897Sopenharmony_ci // Creates foreign or non-foreign field item 158b1994897Sopenharmony_ci inline BaseItem *CreateGenericFieldItem(BaseClassItem *class_item, File::EntityId field_id) 159b1994897Sopenharmony_ci { 160b1994897Sopenharmony_ci if (file_->IsExternal(field_id)) { 161b1994897Sopenharmony_ci return CreateForeignFieldItem(class_item, field_id); 162b1994897Sopenharmony_ci } 163b1994897Sopenharmony_ci return CreateFieldItem(static_cast<ClassItem *>(class_item), field_id); 164b1994897Sopenharmony_ci } 165b1994897Sopenharmony_ci 166b1994897Sopenharmony_ci // Creates foreign or non-foreign class item 167b1994897Sopenharmony_ci inline BaseClassItem *CreateGenericClassItem(File::EntityId class_id) 168b1994897Sopenharmony_ci { 169b1994897Sopenharmony_ci if (file_->IsExternal(class_id)) { 170b1994897Sopenharmony_ci return CreateForeignClassItem(class_id); 171b1994897Sopenharmony_ci } 172b1994897Sopenharmony_ci return CreateClassItem(class_id); 173b1994897Sopenharmony_ci } 174b1994897Sopenharmony_ci 175b1994897Sopenharmony_ci void UpdateCodeAndDebugInfoDependencies(const std::map<BaseItem *, File::EntityId> &reverse_done); 176b1994897Sopenharmony_ci 177b1994897Sopenharmony_ci std::unique_ptr<const File> file_; 178b1994897Sopenharmony_ci ItemContainer container_; 179b1994897Sopenharmony_ci std::map<File::EntityId, BaseItem *> items_done_; 180b1994897Sopenharmony_ci}; 181b1994897Sopenharmony_ci 182b1994897Sopenharmony_ci} // namespace panda::panda_file 183b1994897Sopenharmony_ci 184b1994897Sopenharmony_ci#endif // LIBPANDAFILE_FILE_READER_H 185