1 /* 2 * Copyright (c) 2021-2025 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 COMPILER_AOT_AOT_FILE_H 17 #define COMPILER_AOT_AOT_FILE_H 18 19 #include "aot_headers.h" 20 #include "compiler/code_info/code_info.h" 21 #include "os/library_loader.h" 22 #include "utils/span.h" 23 #include "libpandafile/file.h" 24 25 #include <string> 26 #include <array> 27 #include <memory> 28 #include <algorithm> 29 30 namespace ark::compiler { 31 class RuntimeInterface; 32 33 class AotFile { 34 public: 35 static constexpr std::array MAGIC = {'.', 'a', 'n', '\0'}; 36 static constexpr std::array VERSION = {'0', '0', '6', '\0'}; 37 38 enum AotSlotType { 39 PLT_SLOT = 1, 40 VTABLE_INDEX = 2, 41 CLASS_SLOT = 3, 42 STRING_SLOT = 4, 43 INLINECACHE_SLOT = 5, 44 COMMON_SLOT = 6, 45 COUNT 46 }; 47 AotFile(ark::os::library_loader::LibraryHandle && handle,Span<const uint8_t> aotData,Span<const uint8_t> code)48 AotFile(ark::os::library_loader::LibraryHandle &&handle, Span<const uint8_t> aotData, Span<const uint8_t> code) 49 : handle_(std::move(handle)), aotData_(aotData), code_(code) 50 { 51 } 52 53 NO_MOVE_SEMANTIC(AotFile); 54 NO_COPY_SEMANTIC(AotFile); 55 ~AotFile() = default; 56 57 public: 58 static Expected<std::unique_ptr<AotFile>, std::string> Open(const std::string &fileName, uint32_t gcType, 59 bool forDump = false); 60 GetCode()61 const void *GetCode() const 62 { 63 return code_.data(); 64 } 65 GetCodeSize()66 size_t GetCodeSize() const 67 { 68 return code_.size(); 69 } 70 FileHeaders()71 auto FileHeaders() const 72 { 73 return aotData_.SubSpan<const PandaFileHeader>(GetAotHeader()->filesOffset, GetFilesCount()); 74 } 75 GetMethodHeader(size_t index)76 auto GetMethodHeader(size_t index) const 77 { 78 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 79 return reinterpret_cast<const MethodHeader *>(&aotData_[GetAotHeader()->methodsOffset]) + index; 80 } 81 GetMethodHeadersPtr()82 const MethodHeader *GetMethodHeadersPtr() const 83 { 84 return reinterpret_cast<const MethodHeader *>(&aotData_[GetAotHeader()->methodsOffset]); 85 } 86 GetClassHeaders(const PandaFileHeader & fileHeader)87 auto GetClassHeaders(const PandaFileHeader &fileHeader) const 88 { 89 return aotData_.SubSpan<const ClassHeader>( 90 GetAotHeader()->classesOffset + fileHeader.classesOffset * sizeof(ClassHeader), fileHeader.classesCount); 91 } 92 GetClassHashTable(const PandaFileHeader & fileHeader)93 auto GetClassHashTable(const PandaFileHeader &fileHeader) const 94 { 95 return aotData_.SubSpan<const ark::panda_file::EntityPairHeader>( 96 GetAotHeader()->classHashTablesOffset + fileHeader.classHashTableOffset, fileHeader.classHashTableSize); 97 } 98 GetMethodsBitmap()99 const uint8_t *GetMethodsBitmap() const 100 { 101 return &aotData_[GetAotHeader()->bitmapOffset]; 102 } 103 GetFilesCount()104 size_t GetFilesCount() const 105 { 106 return GetAotHeader()->filesCount; 107 } 108 FindPandaFile(const std::string & fileName)109 const PandaFileHeader *FindPandaFile(const std::string &fileName) const 110 { 111 auto fileHeaders = FileHeaders(); 112 auto res = std::find_if(fileHeaders.begin(), fileHeaders.end(), 113 [this, &fileName](auto &header) { return fileName == GetString(header.fileNameStr); }); 114 return res == fileHeaders.end() ? nullptr : res; 115 } 116 GetMethodCode(const MethodHeader * methodHeader)117 const uint8_t *GetMethodCode(const MethodHeader *methodHeader) const 118 { 119 return code_.data() + methodHeader->codeOffset; 120 } 121 GetString(size_t offset)122 const char *GetString(size_t offset) const 123 { 124 return reinterpret_cast<const char *>(aotData_.data() + GetAotHeader()->strtabOffset + offset); 125 } 126 GetAotHeader()127 const AotHeader *GetAotHeader() const 128 { 129 return reinterpret_cast<const AotHeader *>(aotData_.data()); 130 } 131 GetFileName()132 const char *GetFileName() const 133 { 134 return GetString(GetAotHeader()->fileNameStr); 135 } 136 GetCommandLine()137 const char *GetCommandLine() const 138 { 139 return GetString(GetAotHeader()->cmdlineStr); 140 } 141 GetClassContext()142 const char *GetClassContext() const 143 { 144 return GetString(GetAotHeader()->classCtxStr); 145 } 146 IsCompiledWithCha()147 bool IsCompiledWithCha() const 148 { 149 return GetAotHeader()->withCha != 0U; 150 } 151 IsBootPandaFile()152 bool IsBootPandaFile() const 153 { 154 return GetAotHeader()->bootAot != 0U; 155 } 156 157 void InitializeGot(RuntimeInterface *runtime); 158 159 void PatchTable(RuntimeInterface *runtime); 160 161 private: 162 ark::os::library_loader::LibraryHandle handle_ {nullptr}; 163 Span<const uint8_t> aotData_; 164 Span<const uint8_t> code_; 165 }; 166 167 class AotClass final { 168 public: 169 AotClass() = default; AotClass(const AotFile * file,const ClassHeader * header)170 AotClass(const AotFile *file, const ClassHeader *header) : aotFile_(file), header_(header) {} 171 ~AotClass() = default; 172 DEFAULT_COPY_SEMANTIC(AotClass); 173 DEFAULT_MOVE_SEMANTIC(AotClass); 174 175 const void *FindMethodCodeEntry(size_t index) const; 176 Span<const uint8_t> FindMethodCodeSpan(size_t index) const; 177 const MethodHeader *FindMethodHeader(size_t index) const; 178 179 BitVectorSpan GetBitmap() const; 180 GetMethodHeaders()181 auto GetMethodHeaders() const 182 { 183 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 184 return Span(aotFile_->GetMethodHeadersPtr() + header_->methodsOffset, header_->methodsCount); 185 } 186 Invalid()187 static AotClass Invalid() 188 { 189 return AotClass(); 190 } 191 IsValid()192 bool IsValid() const 193 { 194 return header_ != nullptr; 195 } 196 197 private: 198 const AotFile *aotFile_ {nullptr}; 199 const ClassHeader *header_ {nullptr}; 200 }; 201 202 class AotPandaFile { 203 public: 204 AotPandaFile() = default; AotPandaFile(AotFile * file,const PandaFileHeader * header)205 AotPandaFile(AotFile *file, const PandaFileHeader *header) : aotFile_(file), header_(header) 206 { 207 LoadClassHashTable(); 208 } 209 210 DEFAULT_MOVE_SEMANTIC(AotPandaFile); 211 DEFAULT_COPY_SEMANTIC(AotPandaFile); 212 ~AotPandaFile() = default; 213 GetAotFile()214 const AotFile *GetAotFile() const 215 { 216 return aotFile_; 217 } GetHeader()218 const PandaFileHeader *GetHeader() 219 { 220 return header_; 221 } GetHeader()222 const PandaFileHeader *GetHeader() const 223 { 224 return header_; 225 } GetFileName()226 std::string GetFileName() const 227 { 228 return GetAotFile()->GetString(GetHeader()->fileNameStr); 229 } 230 AotClass GetClass(uint32_t classId) const; 231 GetClassHeaders()232 Span<const ClassHeader> GetClassHeaders() const 233 { 234 return aotFile_->GetClassHeaders(*header_); 235 } 236 GetMethodCodeInfo(const MethodHeader * methodHeader)237 CodeInfo GetMethodCodeInfo(const MethodHeader *methodHeader) const 238 { 239 return CodeInfo(GetAotFile()->GetMethodCode(methodHeader), methodHeader->codeSize); 240 } 241 LoadClassHashTable()242 void LoadClassHashTable() 243 { 244 ASSERT(header_ != nullptr); 245 classHashTable_ = GetAotFile()->GetClassHashTable(*header_); 246 } 247 GetClassHashTable()248 ark::Span<const ark::panda_file::EntityPairHeader> GetClassHashTable() const 249 { 250 return classHashTable_; 251 } 252 253 private: 254 AotFile *aotFile_ {nullptr}; 255 const PandaFileHeader *header_ {nullptr}; 256 ark::Span<const ark::panda_file::EntityPairHeader> classHashTable_; 257 }; 258 } // namespace ark::compiler 259 260 #endif // COMPILER_AOT_AOT_FILE_H 261