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 LIBPANDAFILE_CODE_DATA_ACCESSOR_H 17 #define 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_; 67 uint32_t length_; 68 uint32_t num_catches_; 69 Span<const uint8_t> catch_blocks_sp_ {nullptr, nullptr}; 70 71 size_t size_; 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_; 105 uint32_t handler_pc_; 106 uint32_t code_size_; 107 108 size_t size_; 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 118 static uint32_t GetNumVregs(const File &pf, File::EntityId code_id); 119 120 static const uint8_t *GetInstructions(const File &pf, File::EntityId code_id, uint32_t *vregs); 121 122 static const uint8_t *GetInstructions(const File &pf, File::EntityId code_id); 123 GetNumVregs()124 uint32_t GetNumVregs() const 125 { 126 return num_vregs_; 127 } 128 GetNumArgs()129 uint32_t GetNumArgs() const 130 { 131 return num_args_; 132 } 133 GetCodeSize()134 uint32_t GetCodeSize() const 135 { 136 return code_size_; 137 } 138 GetTriesSize()139 uint32_t GetTriesSize() const 140 { 141 return tries_size_; 142 } 143 GetInstructions()144 const uint8_t *GetInstructions() const 145 { 146 return instructions_ptr_; 147 } 148 149 template <class Callback> 150 void EnumerateTryBlocks(const Callback &cb); 151 GetSize()152 size_t GetSize() 153 { 154 if (size_ == 0) { 155 SkipTryBlocks(); 156 } 157 158 return size_; 159 } 160 GetPandaFile()161 const File &GetPandaFile() const 162 { 163 return panda_file_; 164 } 165 GetCodeId()166 File::EntityId GetCodeId() 167 { 168 return code_id_; 169 } 170 171 private: 172 void SkipTryBlocks(); 173 174 const File &panda_file_; 175 File::EntityId code_id_; 176 177 uint32_t num_vregs_; 178 uint32_t num_args_; 179 uint32_t code_size_; 180 uint32_t tries_size_; 181 const uint8_t *instructions_ptr_; 182 Span<const uint8_t> try_blocks_sp_ {nullptr, nullptr}; 183 184 size_t size_; 185 }; 186 187 } // namespace panda::panda_file 188 189 #endif // LIBPANDAFILE_CODE_DATA_ACCESSOR_H 190