• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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