1 /** 2 * Copyright (c) 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_INDEX_ACCESSOR_H 17 #define LIBPANDAFILE_INDEX_ACCESSOR_H 18 19 #include "file.h" 20 #include "file_items.h" 21 22 namespace panda::panda_file { 23 24 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 25 class IndexAccessor { 26 public: IndexAccessor(const File & pf,File::EntityId method_id)27 IndexAccessor(const File &pf, File::EntityId method_id) 28 { 29 constexpr size_t SKIP_NUM = 3; // 3 : skip class_idx and proto_idx and name 30 auto sp = pf.GetSpanFromId(method_id).SubSpan(IDX_SIZE * (SKIP_NUM - 1) + ID_SIZE); 31 access_flags_ = helpers::ReadULeb128(&sp); 32 header_index_ = access_flags_ >> (FUNTION_KIND_WIDTH + FLAG_WIDTH); 33 num_headers_ = pf.GetHeader()->num_indexes; 34 const auto *header = &(pf.GetIndexHeaders()[header_index_]); 35 indexes_ = pf.GetMethodIndex(header); 36 } 37 38 ~IndexAccessor() = default; 39 40 // quick way to resolve offset by 16-bit id in method's instructions GetOffsetById(uint16_t idx)41 uint32_t GetOffsetById(uint16_t idx) const 42 { 43 return indexes_[idx].GetOffset(); 44 } 45 GetFunctionKind()46 FunctionKind GetFunctionKind() const 47 { 48 return static_cast<FunctionKind>((access_flags_ & FUNCTION_KIND_MASK) >> FLAG_WIDTH); 49 } 50 GetHeaderIndex()51 uint16_t GetHeaderIndex() const 52 { 53 return header_index_; 54 } 55 GetNumHeaders()56 uint32_t GetNumHeaders() const 57 { 58 return num_headers_; 59 } 60 61 private: 62 Span<const File::EntityId> indexes_; 63 uint32_t access_flags_; 64 uint16_t header_index_; 65 uint32_t num_headers_; 66 }; 67 68 } // namespace panda::panda_file 69 70 #endif // LIBPANDAFILE_INDEX_ACCESSOR_H 71