1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2024 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_H 17b1994897Sopenharmony_ci#define LIBPANDAFILE_FILE_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <array> 20b1994897Sopenharmony_ci#include <cstdint> 21b1994897Sopenharmony_ci#include <fcntl.h> 22b1994897Sopenharmony_ci#include <iostream> 23b1994897Sopenharmony_ci#include <memory> 24b1994897Sopenharmony_ci#include <string> 25b1994897Sopenharmony_ci#include <string_view> 26b1994897Sopenharmony_ci 27b1994897Sopenharmony_ci#include "helpers.h" 28b1994897Sopenharmony_ci#include "os/mem.h" 29b1994897Sopenharmony_ci#include "os/filesystem.h" 30b1994897Sopenharmony_ci#include "utils/span.h" 31b1994897Sopenharmony_ci#include "utils/utf.h" 32b1994897Sopenharmony_ci#include "utils/logger.h" 33b1994897Sopenharmony_ci 34b1994897Sopenharmony_cinamespace panda { 35b1994897Sopenharmony_cistruct EntryFileStat; 36b1994897Sopenharmony_ci} // namespace panda 37b1994897Sopenharmony_ci 38b1994897Sopenharmony_cinamespace panda::panda_file { 39b1994897Sopenharmony_ci 40b1994897Sopenharmony_ciclass PandaCache; 41b1994897Sopenharmony_ci 42b1994897Sopenharmony_ci#define XPM_PROC_LENGTH 50 43b1994897Sopenharmony_ci#define PROC_SELF_XPM_REGION_PATH "/proc/self/xpm_region" 44b1994897Sopenharmony_ci/* 45b1994897Sopenharmony_ci * EntityPairHeader Describes pair for hash value of class's descriptor and its entity id offset, 46b1994897Sopenharmony_ci * used to quickly find class by its descriptor. 47b1994897Sopenharmony_ci */ 48b1994897Sopenharmony_cistruct EntityPairHeader { 49b1994897Sopenharmony_ci uint32_t descriptor_hash; 50b1994897Sopenharmony_ci uint32_t entity_id_offset; 51b1994897Sopenharmony_ci uint32_t next_pos; 52b1994897Sopenharmony_ci}; 53b1994897Sopenharmony_ci 54b1994897Sopenharmony_ciclass File { 55b1994897Sopenharmony_cipublic: 56b1994897Sopenharmony_ci using Index = uint16_t; 57b1994897Sopenharmony_ci using Index32 = uint32_t; 58b1994897Sopenharmony_ci 59b1994897Sopenharmony_ci static constexpr size_t MAGIC_SIZE = 8; 60b1994897Sopenharmony_ci static constexpr size_t VERSION_SIZE = 4; 61b1994897Sopenharmony_ci static const std::array<uint8_t, MAGIC_SIZE> MAGIC; 62b1994897Sopenharmony_ci 63b1994897Sopenharmony_ci struct Header { 64b1994897Sopenharmony_ci std::array<uint8_t, MAGIC_SIZE> magic; 65b1994897Sopenharmony_ci uint32_t checksum; 66b1994897Sopenharmony_ci std::array<uint8_t, VERSION_SIZE> version; 67b1994897Sopenharmony_ci uint32_t file_size; 68b1994897Sopenharmony_ci uint32_t foreign_off; 69b1994897Sopenharmony_ci uint32_t foreign_size; 70b1994897Sopenharmony_ci uint32_t num_classes; 71b1994897Sopenharmony_ci uint32_t class_idx_off; 72b1994897Sopenharmony_ci uint32_t num_lnps; 73b1994897Sopenharmony_ci uint32_t lnp_idx_off; 74b1994897Sopenharmony_ci uint32_t num_literalarrays; 75b1994897Sopenharmony_ci uint32_t literalarray_idx_off; 76b1994897Sopenharmony_ci uint32_t num_indexes; 77b1994897Sopenharmony_ci uint32_t index_section_off; 78b1994897Sopenharmony_ci }; 79b1994897Sopenharmony_ci 80b1994897Sopenharmony_ci struct IndexHeader { 81b1994897Sopenharmony_ci uint32_t start; 82b1994897Sopenharmony_ci uint32_t end; 83b1994897Sopenharmony_ci uint32_t class_idx_size; 84b1994897Sopenharmony_ci uint32_t class_idx_off; 85b1994897Sopenharmony_ci uint32_t method_idx_size; 86b1994897Sopenharmony_ci uint32_t method_idx_off; 87b1994897Sopenharmony_ci uint32_t field_idx_size; 88b1994897Sopenharmony_ci uint32_t field_idx_off; 89b1994897Sopenharmony_ci uint32_t proto_idx_size; 90b1994897Sopenharmony_ci uint32_t proto_idx_off; 91b1994897Sopenharmony_ci }; 92b1994897Sopenharmony_ci 93b1994897Sopenharmony_ci struct StringData { 94b1994897Sopenharmony_ci StringData(uint32_t len, const uint8_t *d) : utf16_length(len), is_ascii(false), data(d) {} 95b1994897Sopenharmony_ci StringData() = default; 96b1994897Sopenharmony_ci uint32_t utf16_length; // NOLINT(misc-non-private-member-variables-in-classes) 97b1994897Sopenharmony_ci bool is_ascii; // NOLINT(misc-non-private-member-variables-in-classes) 98b1994897Sopenharmony_ci const uint8_t *data; // NOLINT(misc-non-private-member-variables-in-classes) 99b1994897Sopenharmony_ci }; 100b1994897Sopenharmony_ci 101b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 102b1994897Sopenharmony_ci class EntityId { 103b1994897Sopenharmony_ci public: 104b1994897Sopenharmony_ci explicit constexpr EntityId(uint32_t offset) : offset_(offset) {} 105b1994897Sopenharmony_ci 106b1994897Sopenharmony_ci EntityId() = default; 107b1994897Sopenharmony_ci 108b1994897Sopenharmony_ci ~EntityId() = default; 109b1994897Sopenharmony_ci 110b1994897Sopenharmony_ci bool IsValid() const 111b1994897Sopenharmony_ci { 112b1994897Sopenharmony_ci return offset_ > sizeof(Header); 113b1994897Sopenharmony_ci } 114b1994897Sopenharmony_ci 115b1994897Sopenharmony_ci uint32_t GetOffset() const 116b1994897Sopenharmony_ci { 117b1994897Sopenharmony_ci return offset_; 118b1994897Sopenharmony_ci } 119b1994897Sopenharmony_ci 120b1994897Sopenharmony_ci static constexpr size_t GetSize() 121b1994897Sopenharmony_ci { 122b1994897Sopenharmony_ci return sizeof(uint32_t); 123b1994897Sopenharmony_ci } 124b1994897Sopenharmony_ci 125b1994897Sopenharmony_ci friend bool operator<(const EntityId &l, const EntityId &r) 126b1994897Sopenharmony_ci { 127b1994897Sopenharmony_ci return l.offset_ < r.offset_; 128b1994897Sopenharmony_ci } 129b1994897Sopenharmony_ci 130b1994897Sopenharmony_ci friend bool operator==(const EntityId &l, const EntityId &r) 131b1994897Sopenharmony_ci { 132b1994897Sopenharmony_ci return l.offset_ == r.offset_; 133b1994897Sopenharmony_ci } 134b1994897Sopenharmony_ci 135b1994897Sopenharmony_ci friend std::ostream &operator<<(std::ostream &stream, const EntityId &id) 136b1994897Sopenharmony_ci { 137b1994897Sopenharmony_ci return stream << id.offset_; 138b1994897Sopenharmony_ci } 139b1994897Sopenharmony_ci 140b1994897Sopenharmony_ci private: 141b1994897Sopenharmony_ci uint32_t offset_ {0}; 142b1994897Sopenharmony_ci }; 143b1994897Sopenharmony_ci 144b1994897Sopenharmony_ci enum OpenMode { READ_ONLY, READ_WRITE, WRITE_ONLY }; 145b1994897Sopenharmony_ci 146b1994897Sopenharmony_ci StringData GetStringData(EntityId id) const; 147b1994897Sopenharmony_ci EntityId GetLiteralArraysId() const; 148b1994897Sopenharmony_ci 149b1994897Sopenharmony_ci EntityId GetClassId(const uint8_t *mutf8_name) const; 150b1994897Sopenharmony_ci 151b1994897Sopenharmony_ci EntityId GetClassIdFromClassHashTable(const uint8_t *mutf8_name) const; 152b1994897Sopenharmony_ci 153b1994897Sopenharmony_ci const Header *GetHeader() const 154b1994897Sopenharmony_ci { 155b1994897Sopenharmony_ci return reinterpret_cast<const Header *>(GetBase()); 156b1994897Sopenharmony_ci } 157b1994897Sopenharmony_ci 158b1994897Sopenharmony_ci const uint8_t *GetBase() const 159b1994897Sopenharmony_ci { 160b1994897Sopenharmony_ci return reinterpret_cast<const uint8_t *>(base_.Get()); 161b1994897Sopenharmony_ci } 162b1994897Sopenharmony_ci 163b1994897Sopenharmony_ci const os::mem::ConstBytePtr &GetPtr() const 164b1994897Sopenharmony_ci { 165b1994897Sopenharmony_ci return base_; 166b1994897Sopenharmony_ci } 167b1994897Sopenharmony_ci 168b1994897Sopenharmony_ci bool IsExternal(EntityId id) const 169b1994897Sopenharmony_ci { 170b1994897Sopenharmony_ci const Header *header = GetHeader(); 171b1994897Sopenharmony_ci uint32_t foreign_begin = header->foreign_off; 172b1994897Sopenharmony_ci uint32_t foreign_end = foreign_begin + header->foreign_size; 173b1994897Sopenharmony_ci return id.GetOffset() >= foreign_begin && id.GetOffset() < foreign_end; 174b1994897Sopenharmony_ci } 175b1994897Sopenharmony_ci 176b1994897Sopenharmony_ci EntityId GetIdFromPointer(const uint8_t *ptr) const 177b1994897Sopenharmony_ci { 178b1994897Sopenharmony_ci return EntityId(ptr - GetBase()); 179b1994897Sopenharmony_ci } 180b1994897Sopenharmony_ci 181b1994897Sopenharmony_ci Span<const uint8_t> GetSpanFromId(EntityId id) const 182b1994897Sopenharmony_ci { 183b1994897Sopenharmony_ci const Header *header = GetHeader(); 184b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 185b1994897Sopenharmony_ci ThrowIfWithCheck(!id.IsValid() || id.GetOffset() >= file.size(), File::INVALID_FILE_OFFSET, 186b1994897Sopenharmony_ci File::GET_SPAN_FROM_ID); 187b1994897Sopenharmony_ci return file.Last(file.size() - id.GetOffset()); 188b1994897Sopenharmony_ci } 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci Span<const uint32_t> GetClasses() const 191b1994897Sopenharmony_ci { 192b1994897Sopenharmony_ci const Header *header = GetHeader(); 193b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 194b1994897Sopenharmony_ci Span class_idx_data = file.SubSpan(header->class_idx_off, header->num_classes * sizeof(uint32_t)); 195b1994897Sopenharmony_ci return Span(reinterpret_cast<const uint32_t *>(class_idx_data.data()), header->num_classes); 196b1994897Sopenharmony_ci } 197b1994897Sopenharmony_ci 198b1994897Sopenharmony_ci Span<const uint32_t> GetLiteralArrays() const 199b1994897Sopenharmony_ci { 200b1994897Sopenharmony_ci const Header *header = GetHeader(); 201b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 202b1994897Sopenharmony_ci Span litarr_idx_data = file.SubSpan(header->literalarray_idx_off, header->num_literalarrays * sizeof(uint32_t)); 203b1994897Sopenharmony_ci return Span(reinterpret_cast<const uint32_t *>(litarr_idx_data.data()), header->num_literalarrays); 204b1994897Sopenharmony_ci } 205b1994897Sopenharmony_ci 206b1994897Sopenharmony_ci Span<const IndexHeader> GetIndexHeaders() const 207b1994897Sopenharmony_ci { 208b1994897Sopenharmony_ci const Header *header = GetHeader(); 209b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 210b1994897Sopenharmony_ci auto sp = file.SubSpan(header->index_section_off, header->num_indexes * sizeof(IndexHeader)); 211b1994897Sopenharmony_ci return Span(reinterpret_cast<const IndexHeader *>(sp.data()), header->num_indexes); 212b1994897Sopenharmony_ci } 213b1994897Sopenharmony_ci 214b1994897Sopenharmony_ci const IndexHeader *GetIndexHeader(EntityId id) const 215b1994897Sopenharmony_ci { 216b1994897Sopenharmony_ci if (UNLIKELY(!id.IsValid() || id.GetOffset() >= GetHeader()->file_size)) { 217b1994897Sopenharmony_ci return nullptr; 218b1994897Sopenharmony_ci } 219b1994897Sopenharmony_ci auto headers = GetIndexHeaders(); 220b1994897Sopenharmony_ci auto offset = id.GetOffset(); 221b1994897Sopenharmony_ci for (const auto &header : headers) { 222b1994897Sopenharmony_ci if (header.start <= offset && offset < header.end) { 223b1994897Sopenharmony_ci return &header; 224b1994897Sopenharmony_ci } 225b1994897Sopenharmony_ci } 226b1994897Sopenharmony_ci return nullptr; 227b1994897Sopenharmony_ci } 228b1994897Sopenharmony_ci 229b1994897Sopenharmony_ci Span<const EntityId> GetClassIndex(const IndexHeader *index_header) const 230b1994897Sopenharmony_ci { 231b1994897Sopenharmony_ci ThrowIfWithCheck(index_header == nullptr, File::NULL_INDEX_HEADER, File::GET_CLASS_INDEX); 232b1994897Sopenharmony_ci auto *header = GetHeader(); 233b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 234b1994897Sopenharmony_ci ASSERT(index_header != nullptr); 235b1994897Sopenharmony_ci auto class_idx_size = index_header->class_idx_size * EntityId::GetSize(); 236b1994897Sopenharmony_ci ThrowIfWithCheck(index_header->class_idx_off > header->file_size || class_idx_size > header->file_size || 237b1994897Sopenharmony_ci index_header->class_idx_off > header->file_size - class_idx_size, File::INVALID_INDEX_HEADER, 238b1994897Sopenharmony_ci File::GET_CLASS_INDEX); 239b1994897Sopenharmony_ci auto sp = file.SubSpan(index_header->class_idx_off, index_header->class_idx_size * EntityId::GetSize()); 240b1994897Sopenharmony_ci return Span(reinterpret_cast<const EntityId *>(sp.data()), index_header->class_idx_size); 241b1994897Sopenharmony_ci } 242b1994897Sopenharmony_ci 243b1994897Sopenharmony_ci Span<const EntityId> GetClassIndex(EntityId id) const 244b1994897Sopenharmony_ci { 245b1994897Sopenharmony_ci auto *index_header = GetIndexHeader(id); 246b1994897Sopenharmony_ci return GetClassIndex(index_header); 247b1994897Sopenharmony_ci } 248b1994897Sopenharmony_ci 249b1994897Sopenharmony_ci Span<const EntityId> GetMethodIndex(const IndexHeader *index_header) const 250b1994897Sopenharmony_ci { 251b1994897Sopenharmony_ci ThrowIfWithCheck(index_header == nullptr, File::NULL_INDEX_HEADER, File::GET_METHOD_INDEX); 252b1994897Sopenharmony_ci auto *header = GetHeader(); 253b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 254b1994897Sopenharmony_ci ASSERT(index_header != nullptr); 255b1994897Sopenharmony_ci auto method_idx_size = index_header->method_idx_size * EntityId::GetSize(); 256b1994897Sopenharmony_ci ThrowIfWithCheck(index_header->method_idx_off > header->file_size || method_idx_size > header->file_size || 257b1994897Sopenharmony_ci index_header->method_idx_off > header->file_size - method_idx_size, File::INVALID_INDEX_HEADER, 258b1994897Sopenharmony_ci File::GET_METHOD_INDEX); 259b1994897Sopenharmony_ci auto sp = file.SubSpan(index_header->method_idx_off, index_header->method_idx_size * EntityId::GetSize()); 260b1994897Sopenharmony_ci return Span(reinterpret_cast<const EntityId *>(sp.data()), index_header->method_idx_size); 261b1994897Sopenharmony_ci } 262b1994897Sopenharmony_ci 263b1994897Sopenharmony_ci Span<const EntityId> GetMethodIndex(EntityId id) const 264b1994897Sopenharmony_ci { 265b1994897Sopenharmony_ci auto *index_header = GetIndexHeader(id); 266b1994897Sopenharmony_ci return GetMethodIndex(index_header); 267b1994897Sopenharmony_ci } 268b1994897Sopenharmony_ci 269b1994897Sopenharmony_ci Span<const EntityId> GetFieldIndex(const IndexHeader *index_header) const 270b1994897Sopenharmony_ci { 271b1994897Sopenharmony_ci ThrowIfWithCheck(index_header == nullptr, File::NULL_INDEX_HEADER, File::GET_FIELD_INDEX); 272b1994897Sopenharmony_ci auto *header = GetHeader(); 273b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 274b1994897Sopenharmony_ci ASSERT(index_header != nullptr); 275b1994897Sopenharmony_ci auto field_idx_size = index_header->field_idx_size * EntityId::GetSize(); 276b1994897Sopenharmony_ci ThrowIfWithCheck(index_header->field_idx_off > header->file_size || field_idx_size > header->file_size || 277b1994897Sopenharmony_ci index_header->field_idx_off > header->file_size - field_idx_size, File::INVALID_INDEX_HEADER, 278b1994897Sopenharmony_ci File::GET_FIELD_INDEX); 279b1994897Sopenharmony_ci auto sp = file.SubSpan(index_header->field_idx_off, index_header->field_idx_size * EntityId::GetSize()); 280b1994897Sopenharmony_ci return Span(reinterpret_cast<const EntityId *>(sp.data()), index_header->field_idx_size); 281b1994897Sopenharmony_ci } 282b1994897Sopenharmony_ci 283b1994897Sopenharmony_ci Span<const EntityId> GetFieldIndex(EntityId id) const 284b1994897Sopenharmony_ci { 285b1994897Sopenharmony_ci auto *index_header = GetIndexHeader(id); 286b1994897Sopenharmony_ci return GetFieldIndex(index_header); 287b1994897Sopenharmony_ci } 288b1994897Sopenharmony_ci 289b1994897Sopenharmony_ci Span<const EntityId> GetProtoIndex(const IndexHeader *index_header) const 290b1994897Sopenharmony_ci { 291b1994897Sopenharmony_ci ThrowIfWithCheck(index_header == nullptr, File::NULL_INDEX_HEADER, File::GET_PROTO_INDEX); 292b1994897Sopenharmony_ci auto *header = GetHeader(); 293b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 294b1994897Sopenharmony_ci ASSERT(index_header != nullptr); 295b1994897Sopenharmony_ci auto proto_idx_size = index_header->proto_idx_size * EntityId::GetSize(); 296b1994897Sopenharmony_ci ThrowIfWithCheck(index_header->proto_idx_off > header->file_size || proto_idx_size > header->file_size || 297b1994897Sopenharmony_ci index_header->proto_idx_off > header->file_size - proto_idx_size, File::INVALID_INDEX_HEADER, 298b1994897Sopenharmony_ci File::GET_PROTO_INDEX); 299b1994897Sopenharmony_ci auto sp = file.SubSpan(index_header->proto_idx_off, index_header->proto_idx_size * EntityId::GetSize()); 300b1994897Sopenharmony_ci return Span(reinterpret_cast<const EntityId *>(sp.data()), index_header->proto_idx_size); 301b1994897Sopenharmony_ci } 302b1994897Sopenharmony_ci 303b1994897Sopenharmony_ci Span<const EntityId> GetProtoIndex(EntityId id) const 304b1994897Sopenharmony_ci { 305b1994897Sopenharmony_ci auto *index_header = GetIndexHeader(id); 306b1994897Sopenharmony_ci return GetProtoIndex(index_header); 307b1994897Sopenharmony_ci } 308b1994897Sopenharmony_ci 309b1994897Sopenharmony_ci Span<const EntityId> GetLineNumberProgramIndex() const 310b1994897Sopenharmony_ci { 311b1994897Sopenharmony_ci const Header *header = GetHeader(); 312b1994897Sopenharmony_ci Span file(GetBase(), header->file_size); 313b1994897Sopenharmony_ci Span lnp_idx_data = file.SubSpan(header->lnp_idx_off, header->num_lnps * EntityId::GetSize()); 314b1994897Sopenharmony_ci return Span(reinterpret_cast<const EntityId *>(lnp_idx_data.data()), header->num_lnps); 315b1994897Sopenharmony_ci } 316b1994897Sopenharmony_ci 317b1994897Sopenharmony_ci EntityId ResolveClassIndex(EntityId id, Index idx) const 318b1994897Sopenharmony_ci { 319b1994897Sopenharmony_ci auto index = GetClassIndex(id); 320b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 321b1994897Sopenharmony_ci return EntityId(); 322b1994897Sopenharmony_ci } 323b1994897Sopenharmony_ci return index[idx]; 324b1994897Sopenharmony_ci } 325b1994897Sopenharmony_ci 326b1994897Sopenharmony_ci EntityId ResolveMethodIndex(EntityId id, Index idx) const 327b1994897Sopenharmony_ci { 328b1994897Sopenharmony_ci auto index = GetMethodIndex(id); 329b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 330b1994897Sopenharmony_ci return EntityId(); 331b1994897Sopenharmony_ci } 332b1994897Sopenharmony_ci return index[idx]; 333b1994897Sopenharmony_ci } 334b1994897Sopenharmony_ci 335b1994897Sopenharmony_ci EntityId ResolveOffsetByIndex(EntityId id, Index idx) const 336b1994897Sopenharmony_ci { 337b1994897Sopenharmony_ci auto index = GetMethodIndex(id); 338b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 339b1994897Sopenharmony_ci return EntityId(); 340b1994897Sopenharmony_ci } 341b1994897Sopenharmony_ci return index[idx]; 342b1994897Sopenharmony_ci } 343b1994897Sopenharmony_ci 344b1994897Sopenharmony_ci EntityId ResolveFieldIndex(EntityId id, Index idx) const 345b1994897Sopenharmony_ci { 346b1994897Sopenharmony_ci auto index = GetFieldIndex(id); 347b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 348b1994897Sopenharmony_ci return EntityId(); 349b1994897Sopenharmony_ci } 350b1994897Sopenharmony_ci return index[idx]; 351b1994897Sopenharmony_ci } 352b1994897Sopenharmony_ci 353b1994897Sopenharmony_ci EntityId ResolveProtoIndex(EntityId id, Index idx) const 354b1994897Sopenharmony_ci { 355b1994897Sopenharmony_ci auto index = GetProtoIndex(id); 356b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 357b1994897Sopenharmony_ci return EntityId(); 358b1994897Sopenharmony_ci } 359b1994897Sopenharmony_ci return index[idx]; 360b1994897Sopenharmony_ci } 361b1994897Sopenharmony_ci 362b1994897Sopenharmony_ci EntityId ResolveLineNumberProgramIndex(Index32 idx) const 363b1994897Sopenharmony_ci { 364b1994897Sopenharmony_ci auto index = GetLineNumberProgramIndex(); 365b1994897Sopenharmony_ci if (UNLIKELY(idx >= index.Size())) { 366b1994897Sopenharmony_ci return EntityId(); 367b1994897Sopenharmony_ci } 368b1994897Sopenharmony_ci return index[idx]; 369b1994897Sopenharmony_ci } 370b1994897Sopenharmony_ci 371b1994897Sopenharmony_ci const std::string &GetFilename() const 372b1994897Sopenharmony_ci { 373b1994897Sopenharmony_ci return FILENAME; 374b1994897Sopenharmony_ci } 375b1994897Sopenharmony_ci 376b1994897Sopenharmony_ci PandaCache *GetPandaCache() const 377b1994897Sopenharmony_ci { 378b1994897Sopenharmony_ci#ifdef ENABLE_FULL_FILE_FIELDS 379b1994897Sopenharmony_ci return panda_cache_.get(); 380b1994897Sopenharmony_ci#else 381b1994897Sopenharmony_ci LOG(WARNING, PANDAFILE) << "Not Support GetPandaCache from ohos side."; 382b1994897Sopenharmony_ci return nullptr; 383b1994897Sopenharmony_ci#endif 384b1994897Sopenharmony_ci } 385b1994897Sopenharmony_ci 386b1994897Sopenharmony_ci uint32_t GetFilenameHash() const 387b1994897Sopenharmony_ci { 388b1994897Sopenharmony_ci return FILENAME_HASH; 389b1994897Sopenharmony_ci } 390b1994897Sopenharmony_ci 391b1994897Sopenharmony_ci // note: intentionally returns uint64_t instead of the field type due to usage 392b1994897Sopenharmony_ci uint64_t GetUniqId() const 393b1994897Sopenharmony_ci { 394b1994897Sopenharmony_ci return UNIQ_ID; 395b1994897Sopenharmony_ci } 396b1994897Sopenharmony_ci 397b1994897Sopenharmony_ci const std::string &GetFullFileName() const 398b1994897Sopenharmony_ci { 399b1994897Sopenharmony_ci#ifdef ENABLE_FULL_FILE_FIELDS 400b1994897Sopenharmony_ci return FULL_FILENAME; 401b1994897Sopenharmony_ci#else 402b1994897Sopenharmony_ci LOG(FATAL, PANDAFILE) << "Not Support GetFullFileName from ohos side."; 403b1994897Sopenharmony_ci return FILENAME; 404b1994897Sopenharmony_ci#endif 405b1994897Sopenharmony_ci } 406b1994897Sopenharmony_ci 407b1994897Sopenharmony_ci static constexpr uint32_t GetFileBaseOffset() 408b1994897Sopenharmony_ci { 409b1994897Sopenharmony_ci return MEMBER_OFFSET(File, base_); 410b1994897Sopenharmony_ci } 411b1994897Sopenharmony_ci 412b1994897Sopenharmony_ci Span<const panda::panda_file::EntityPairHeader> GetClassHashTable() const 413b1994897Sopenharmony_ci { 414b1994897Sopenharmony_ci return class_hash_table_; 415b1994897Sopenharmony_ci } 416b1994897Sopenharmony_ci 417b1994897Sopenharmony_ci static uint32_t CalcFilenameHash(const std::string &filename); 418b1994897Sopenharmony_ci 419b1994897Sopenharmony_ci static std::unique_ptr<const File> Open(std::string_view filename, OpenMode open_mode = READ_ONLY); 420b1994897Sopenharmony_ci 421b1994897Sopenharmony_ci static std::unique_ptr<const File> OpenFromMemory(os::mem::ConstBytePtr &&ptr); 422b1994897Sopenharmony_ci 423b1994897Sopenharmony_ci static std::unique_ptr<const File> OpenFromMemory(os::mem::ConstBytePtr &&ptr, std::string_view filename); 424b1994897Sopenharmony_ci 425b1994897Sopenharmony_ci static std::unique_ptr<const File> OpenUncompressedArchive(int fd, const std::string_view &filename, size_t size, 426b1994897Sopenharmony_ci uint32_t offset, OpenMode open_mode = READ_ONLY); 427b1994897Sopenharmony_ci 428b1994897Sopenharmony_ci void SetClassHashTable(panda::Span<const panda::panda_file::EntityPairHeader> class_hash_table) const 429b1994897Sopenharmony_ci { 430b1994897Sopenharmony_ci class_hash_table_ = class_hash_table; 431b1994897Sopenharmony_ci } 432b1994897Sopenharmony_ci 433b1994897Sopenharmony_ci bool ValidateChecksum(uint32_t *cal_checksum_out = nullptr) const; 434b1994897Sopenharmony_ci 435b1994897Sopenharmony_ci void ThrowIfWithCheck(bool cond, const std::string_view& msg, const std::string_view& tag = "") const; 436b1994897Sopenharmony_ci 437b1994897Sopenharmony_ci static constexpr const char *INVALID_FILE_OFFSET = "Invalid file offset"; 438b1994897Sopenharmony_ci static constexpr const char *NULL_INDEX_HEADER = "index_header is null"; 439b1994897Sopenharmony_ci static constexpr const char *INVALID_INDEX_HEADER = "index_header is invalid"; 440b1994897Sopenharmony_ci 441b1994897Sopenharmony_ci static constexpr const char *GET_CLASS_INDEX = "GetClassIndex"; 442b1994897Sopenharmony_ci static constexpr const char *GET_METHOD_INDEX = "GetMethodIndex"; 443b1994897Sopenharmony_ci static constexpr const char *GET_FIELD_INDEX = "GetFieldIndex"; 444b1994897Sopenharmony_ci static constexpr const char *GET_PROTO_INDEX = "GetProtoIndex"; 445b1994897Sopenharmony_ci 446b1994897Sopenharmony_ci static constexpr const char *ANNOTATION_DATA_ACCESSOR = "AnnotationDataAccessor"; 447b1994897Sopenharmony_ci static constexpr const char *CLASS_DATA_ACCESSOR = "ClassDataAccessor"; 448b1994897Sopenharmony_ci static constexpr const char *CODE_DATA_ACCESSOR = "CodeDataAccessor"; 449b1994897Sopenharmony_ci static constexpr const char *FIELD_DATA_ACCESSOR = "FieldDataAccessor"; 450b1994897Sopenharmony_ci static constexpr const char *GET_SPAN_FROM_ID = "GetSpanFromId"; 451b1994897Sopenharmony_ci 452b1994897Sopenharmony_ci ~File(); 453b1994897Sopenharmony_ci 454b1994897Sopenharmony_ci NO_COPY_SEMANTIC(File); 455b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(File); 456b1994897Sopenharmony_ci 457b1994897Sopenharmony_ciprivate: 458b1994897Sopenharmony_ci File(std::string filename, os::mem::ConstBytePtr &&base); 459b1994897Sopenharmony_ci 460b1994897Sopenharmony_ci os::mem::ConstBytePtr base_; 461b1994897Sopenharmony_ci const std::string FILENAME; 462b1994897Sopenharmony_ci const uint32_t FILENAME_HASH; 463b1994897Sopenharmony_ci#ifdef ENABLE_FULL_FILE_FIELDS 464b1994897Sopenharmony_ci const std::string FULL_FILENAME; 465b1994897Sopenharmony_ci std::unique_ptr<PandaCache> panda_cache_; 466b1994897Sopenharmony_ci#endif 467b1994897Sopenharmony_ci const uint32_t UNIQ_ID; 468b1994897Sopenharmony_ci mutable panda::Span<const panda::panda_file::EntityPairHeader> class_hash_table_; 469b1994897Sopenharmony_ci}; 470b1994897Sopenharmony_ci 471b1994897Sopenharmony_cistatic_assert(File::GetFileBaseOffset() == 0); 472b1994897Sopenharmony_ci 473b1994897Sopenharmony_ciinline bool operator==(const File::StringData &string_data1, const File::StringData &string_data2) 474b1994897Sopenharmony_ci{ 475b1994897Sopenharmony_ci if (string_data1.utf16_length != string_data2.utf16_length) { 476b1994897Sopenharmony_ci return false; 477b1994897Sopenharmony_ci } 478b1994897Sopenharmony_ci 479b1994897Sopenharmony_ci return utf::IsEqual(string_data1.data, string_data2.data); 480b1994897Sopenharmony_ci} 481b1994897Sopenharmony_ci 482b1994897Sopenharmony_ciinline bool operator!=(const File::StringData &string_data1, const File::StringData &string_data2) 483b1994897Sopenharmony_ci{ 484b1994897Sopenharmony_ci return !(string_data1 == string_data2); 485b1994897Sopenharmony_ci} 486b1994897Sopenharmony_ci 487b1994897Sopenharmony_ciinline bool operator<(const File::StringData &string_data1, const File::StringData &string_data2) 488b1994897Sopenharmony_ci{ 489b1994897Sopenharmony_ci if (string_data1.utf16_length == string_data2.utf16_length) { 490b1994897Sopenharmony_ci return utf::CompareMUtf8ToMUtf8(string_data1.data, string_data2.data) < 0; 491b1994897Sopenharmony_ci } 492b1994897Sopenharmony_ci 493b1994897Sopenharmony_ci return string_data1.utf16_length < string_data2.utf16_length; 494b1994897Sopenharmony_ci} 495b1994897Sopenharmony_ci 496b1994897Sopenharmony_cibool CheckSecureMem(uintptr_t mem, size_t size); 497b1994897Sopenharmony_ci 498b1994897Sopenharmony_ci/* 499b1994897Sopenharmony_ci * OpenPandaFileOrZip from location which specicify the name. 500b1994897Sopenharmony_ci */ 501b1994897Sopenharmony_cistd::unique_ptr<const File> OpenPandaFileOrZip(std::string_view location, 502b1994897Sopenharmony_ci panda_file::File::OpenMode open_mode = panda_file::File::READ_ONLY); 503b1994897Sopenharmony_ci 504b1994897Sopenharmony_ci/* 505b1994897Sopenharmony_ci * OpenPandaFileFromMemory from file buffer. 506b1994897Sopenharmony_ci */ 507b1994897Sopenharmony_cistd::unique_ptr<const File> OpenPandaFileFromMemory(const void *buffer, size_t size, std::string tag = ""); 508b1994897Sopenharmony_ci 509b1994897Sopenharmony_ci/* 510b1994897Sopenharmony_ci * OpenPandaFileFromMemory from secure buffer. 511b1994897Sopenharmony_ci */ 512b1994897Sopenharmony_cistd::unique_ptr<const File> OpenPandaFileFromSecureMemory(uint8_t *buffer, size_t size); 513b1994897Sopenharmony_ci 514b1994897Sopenharmony_ci/* 515b1994897Sopenharmony_ci * OpenPandaFile from location which specicify the name. 516b1994897Sopenharmony_ci */ 517b1994897Sopenharmony_cistd::unique_ptr<const File> OpenPandaFile(std::string_view location, std::string_view archive_filename = "", 518b1994897Sopenharmony_ci panda_file::File::OpenMode open_mode = panda_file::File::READ_ONLY); 519b1994897Sopenharmony_ci 520b1994897Sopenharmony_ci/* 521b1994897Sopenharmony_ci * Check ptr point valid panda file: magic 522b1994897Sopenharmony_ci */ 523b1994897Sopenharmony_cibool CheckHeader(const os::mem::ConstBytePtr &ptr, const std::string_view &filename = ""); 524b1994897Sopenharmony_civoid CheckFileVersion(const std::array<uint8_t, File::VERSION_SIZE> &file_version, const std::string_view &filename); 525b1994897Sopenharmony_ci 526b1994897Sopenharmony_ci// Last version which contains redundance literal array in header 527b1994897Sopenharmony_ciconstexpr std::array<uint8_t, File::VERSION_SIZE> LAST_CONTAINS_LITERAL_IN_HEADER_VERSION {12, 0, 6, 0}; 528b1994897Sopenharmony_cibool ContainsLiteralArrayInHeader(const std::array<uint8_t, File::VERSION_SIZE> &version); 529b1994897Sopenharmony_ci 530b1994897Sopenharmony_ci// NOLINTNEXTLINE(readability-identifier-naming) 531b1994897Sopenharmony_ciextern const char *ARCHIVE_FILENAME; 532b1994897Sopenharmony_ci} // namespace panda::panda_file 533b1994897Sopenharmony_ci 534b1994897Sopenharmony_cinamespace std { 535b1994897Sopenharmony_citemplate <> 536b1994897Sopenharmony_cistruct hash<panda::panda_file::File::EntityId> { 537b1994897Sopenharmony_ci std::size_t operator()(panda::panda_file::File::EntityId id) const 538b1994897Sopenharmony_ci { 539b1994897Sopenharmony_ci return std::hash<uint32_t> {}(id.GetOffset()); 540b1994897Sopenharmony_ci } 541b1994897Sopenharmony_ci}; 542b1994897Sopenharmony_ci 543b1994897Sopenharmony_ci} // namespace std 544b1994897Sopenharmony_ci 545b1994897Sopenharmony_ci#endif // LIBPANDAFILE_FILE_H 546