1 /* 2 * Copyright (c) 2021 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 PANDA_LIBPANDAFILE_CODE_DATA_ACCESSOR_H_ 17 #define PANDA_LIBPANDAFILE_CODE_DATA_ACCESSOR_H_ 18 19 #include "file-inl.h" 20 21 namespace panda::panda_file { 22 23 class CodeDataAccessor { 24 public: 25 class TryBlock { 26 public: 27 explicit TryBlock(Span<const uint8_t> data); 28 29 ~TryBlock() = default; 30 31 NO_COPY_SEMANTIC(TryBlock); 32 NO_MOVE_SEMANTIC(TryBlock); 33 GetStartPc()34 uint32_t GetStartPc() const 35 { 36 return start_pc_; 37 } 38 GetLength()39 uint32_t GetLength() const 40 { 41 return length_; 42 } 43 GetNumCatches()44 uint32_t GetNumCatches() const 45 { 46 return num_catches_; 47 } 48 49 template <class Callback> 50 void EnumerateCatchBlocks(const Callback &cb); 51 GetSize()52 size_t GetSize() 53 { 54 if (size_ == 0) { 55 SkipCatchBlocks(); 56 } 57 58 return size_; 59 } 60 61 private: 62 void SkipCatchBlocks(); 63 64 Span<const uint8_t> data_; 65 66 uint32_t start_pc_ {0}; 67 uint32_t length_ {0}; 68 uint32_t num_catches_ {0}; 69 Span<const uint8_t> catch_blocks_sp_ {nullptr, nullptr}; 70 71 size_t size_ {0}; 72 }; 73 74 class CatchBlock { 75 public: 76 explicit CatchBlock(Span<const uint8_t> data); 77 78 ~CatchBlock() = default; 79 80 NO_COPY_SEMANTIC(CatchBlock); 81 NO_MOVE_SEMANTIC(CatchBlock); 82 GetTypeIdx()83 uint32_t GetTypeIdx() const 84 { 85 return type_idx_; 86 } 87 GetHandlerPc()88 uint32_t GetHandlerPc() const 89 { 90 return handler_pc_; 91 } 92 GetCodeSize()93 uint32_t GetCodeSize() const 94 { 95 return code_size_; 96 } 97 GetSize()98 size_t GetSize() const 99 { 100 return size_; 101 } 102 103 private: 104 uint32_t type_idx_ {0}; 105 uint32_t handler_pc_ {0}; 106 uint32_t code_size_ {0}; 107 108 size_t size_ {0}; 109 }; 110 111 CodeDataAccessor(const File &panda_file, File::EntityId code_id); 112 113 ~CodeDataAccessor() = default; 114 115 NO_COPY_SEMANTIC(CodeDataAccessor); 116 NO_MOVE_SEMANTIC(CodeDataAccessor); 117 GetNumVregs()118 uint32_t GetNumVregs() const 119 { 120 return num_vregs_; 121 } 122 GetNumArgs()123 uint32_t GetNumArgs() const 124 { 125 return num_args_; 126 } 127 GetCodeSize()128 uint32_t GetCodeSize() const 129 { 130 return code_size_; 131 } 132 GetTriesSize()133 uint32_t GetTriesSize() const 134 { 135 return tries_size_; 136 } 137 GetInstructions()138 const uint8_t *GetInstructions() const 139 { 140 return instructions_ptr_; 141 } 142 143 template <class Callback> 144 void EnumerateTryBlocks(const Callback &cb); 145 GetSize()146 size_t GetSize() 147 { 148 if (size_ == 0) { 149 SkipTryBlocks(); 150 } 151 152 return size_; 153 } 154 GetPandaFile()155 const File &GetPandaFile() const 156 { 157 return panda_file_; 158 } 159 GetCodeId()160 File::EntityId GetCodeId() const 161 { 162 return code_id_; 163 } 164 165 private: 166 void SkipTryBlocks(); 167 168 const File &panda_file_; 169 File::EntityId code_id_; 170 171 uint32_t num_vregs_ {0}; 172 uint32_t num_args_ {0}; 173 uint32_t code_size_ {0}; 174 uint32_t tries_size_ {0}; 175 const uint8_t *instructions_ptr_ {nullptr}; 176 Span<const uint8_t> try_blocks_sp_ {nullptr, nullptr}; 177 178 size_t size_; 179 }; 180 181 } // namespace panda::panda_file 182 183 #endif // PANDA_LIBPANDAFILE_CODE_DATA_ACCESSOR_H_ 184