xref: /aosp_15_r20/art/runtime/vdex_file.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_VDEX_FILE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_VDEX_FILE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <stdint.h>
21*795d594fSAndroid Build Coastguard Worker #include <string>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/mem_map.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
27*795d594fSAndroid Build Coastguard Worker #include "class_status.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex/compact_offset_table.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h"
30*795d594fSAndroid Build Coastguard Worker #include "handle.h"
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker class ClassLoaderContext;
35*795d594fSAndroid Build Coastguard Worker class Thread;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker namespace mirror {
38*795d594fSAndroid Build Coastguard Worker class Class;
39*795d594fSAndroid Build Coastguard Worker }
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker namespace verifier {
42*795d594fSAndroid Build Coastguard Worker class VerifierDeps;
43*795d594fSAndroid Build Coastguard Worker }  // namespace verifier
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker // VDEX files contain extracted DEX files. The VdexFile class maps the file to
46*795d594fSAndroid Build Coastguard Worker // memory and provides tools for accessing its individual sections.
47*795d594fSAndroid Build Coastguard Worker //
48*795d594fSAndroid Build Coastguard Worker // In the description below, D is the number of dex files.
49*795d594fSAndroid Build Coastguard Worker //
50*795d594fSAndroid Build Coastguard Worker // File format:
51*795d594fSAndroid Build Coastguard Worker //   VdexFileHeader    fixed-length header
52*795d594fSAndroid Build Coastguard Worker //   VdexSectionHeader[kNumberOfSections]
53*795d594fSAndroid Build Coastguard Worker //
54*795d594fSAndroid Build Coastguard Worker //   Checksum section
55*795d594fSAndroid Build Coastguard Worker //     VdexChecksum[D]
56*795d594fSAndroid Build Coastguard Worker //
57*795d594fSAndroid Build Coastguard Worker //   Optionally:
58*795d594fSAndroid Build Coastguard Worker //      DexSection
59*795d594fSAndroid Build Coastguard Worker //          DEX[0]                array of the input DEX files
60*795d594fSAndroid Build Coastguard Worker //          DEX[1]
61*795d594fSAndroid Build Coastguard Worker //          ...
62*795d594fSAndroid Build Coastguard Worker //          DEX[D-1]
63*795d594fSAndroid Build Coastguard Worker //
64*795d594fSAndroid Build Coastguard Worker //   VerifierDeps
65*795d594fSAndroid Build Coastguard Worker //      4-byte alignment
66*795d594fSAndroid Build Coastguard Worker //      uint32[D]                  DexFileDeps offsets for each dex file
67*795d594fSAndroid Build Coastguard Worker //      DexFileDeps[D][]           verification dependencies
68*795d594fSAndroid Build Coastguard Worker //        4-byte alignment
69*795d594fSAndroid Build Coastguard Worker //        uint32[class_def_size]     TypeAssignability offsets (kNotVerifiedMarker for a class
70*795d594fSAndroid Build Coastguard Worker //                                        that isn't verified)
71*795d594fSAndroid Build Coastguard Worker //        uint32                     Offset of end of AssignabilityType sets
72*795d594fSAndroid Build Coastguard Worker //        uint8[]                    AssignabilityType sets
73*795d594fSAndroid Build Coastguard Worker //        4-byte alignment
74*795d594fSAndroid Build Coastguard Worker //        uint32                     Number of strings
75*795d594fSAndroid Build Coastguard Worker //        uint32[]                   String data offsets for each string
76*795d594fSAndroid Build Coastguard Worker //        uint8[]                    String data
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker enum VdexSection : uint32_t {
80*795d594fSAndroid Build Coastguard Worker   kChecksumSection = 0,
81*795d594fSAndroid Build Coastguard Worker   kDexFileSection = 1,
82*795d594fSAndroid Build Coastguard Worker   kVerifierDepsSection = 2,
83*795d594fSAndroid Build Coastguard Worker   kTypeLookupTableSection = 3,
84*795d594fSAndroid Build Coastguard Worker   kNumberOfSections = 4,
85*795d594fSAndroid Build Coastguard Worker };
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker class VdexFile {
88*795d594fSAndroid Build Coastguard Worker  public:
89*795d594fSAndroid Build Coastguard Worker   using VdexChecksum = uint32_t;
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   struct VdexSectionHeader {
92*795d594fSAndroid Build Coastguard Worker     VdexSection section_kind;
93*795d594fSAndroid Build Coastguard Worker     uint32_t section_offset;
94*795d594fSAndroid Build Coastguard Worker     uint32_t section_size;
95*795d594fSAndroid Build Coastguard Worker 
VdexSectionHeaderVdexSectionHeader96*795d594fSAndroid Build Coastguard Worker     VdexSectionHeader(VdexSection kind, uint32_t offset, uint32_t size)
97*795d594fSAndroid Build Coastguard Worker         : section_kind(kind), section_offset(offset), section_size(size) {}
98*795d594fSAndroid Build Coastguard Worker 
VdexSectionHeaderVdexSectionHeader99*795d594fSAndroid Build Coastguard Worker     VdexSectionHeader() {}
100*795d594fSAndroid Build Coastguard Worker   };
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   struct VdexFileHeader {
103*795d594fSAndroid Build Coastguard Worker    public:
104*795d594fSAndroid Build Coastguard Worker     EXPORT explicit VdexFileHeader(bool has_dex_section);
105*795d594fSAndroid Build Coastguard Worker 
GetMagicVdexFileHeader106*795d594fSAndroid Build Coastguard Worker     const char* GetMagic() const { return reinterpret_cast<const char*>(magic_); }
GetVdexVersionVdexFileHeader107*795d594fSAndroid Build Coastguard Worker     const char* GetVdexVersion() const {
108*795d594fSAndroid Build Coastguard Worker       return reinterpret_cast<const char*>(vdex_version_);
109*795d594fSAndroid Build Coastguard Worker     }
GetNumberOfSectionsVdexFileHeader110*795d594fSAndroid Build Coastguard Worker     uint32_t GetNumberOfSections() const {
111*795d594fSAndroid Build Coastguard Worker       return number_of_sections_;
112*795d594fSAndroid Build Coastguard Worker     }
113*795d594fSAndroid Build Coastguard Worker     EXPORT bool IsMagicValid() const;
114*795d594fSAndroid Build Coastguard Worker     EXPORT bool IsVdexVersionValid() const;
IsValidVdexFileHeader115*795d594fSAndroid Build Coastguard Worker     bool IsValid() const {
116*795d594fSAndroid Build Coastguard Worker       return IsMagicValid() && IsVdexVersionValid();
117*795d594fSAndroid Build Coastguard Worker     }
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker     static constexpr uint8_t kVdexInvalidMagic[] = { 'w', 'd', 'e', 'x' };
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker    private:
122*795d594fSAndroid Build Coastguard Worker     static constexpr uint8_t kVdexMagic[] = { 'v', 'd', 'e', 'x' };
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker     // The format version of the verifier deps header and the verifier deps.
125*795d594fSAndroid Build Coastguard Worker     // Last update: Introduce vdex sections.
126*795d594fSAndroid Build Coastguard Worker     static constexpr uint8_t kVdexVersion[] = { '0', '2', '7', '\0' };
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker     uint8_t magic_[4];
129*795d594fSAndroid Build Coastguard Worker     uint8_t vdex_version_[4];
130*795d594fSAndroid Build Coastguard Worker     uint32_t number_of_sections_;
131*795d594fSAndroid Build Coastguard Worker   };
132*795d594fSAndroid Build Coastguard Worker 
GetSectionHeaderAt(uint32_t index)133*795d594fSAndroid Build Coastguard Worker   const VdexSectionHeader& GetSectionHeaderAt(uint32_t index) const {
134*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(index, GetVdexFileHeader().GetNumberOfSections());
135*795d594fSAndroid Build Coastguard Worker     return *reinterpret_cast<const VdexSectionHeader*>(
136*795d594fSAndroid Build Coastguard Worker         Begin() + sizeof(VdexFileHeader) + index * sizeof(VdexSectionHeader));
137*795d594fSAndroid Build Coastguard Worker   }
138*795d594fSAndroid Build Coastguard Worker 
GetSectionHeader(VdexSection kind)139*795d594fSAndroid Build Coastguard Worker   const VdexSectionHeader& GetSectionHeader(VdexSection kind) const {
140*795d594fSAndroid Build Coastguard Worker     return GetSectionHeaderAt(static_cast<uint32_t>(kind));
141*795d594fSAndroid Build Coastguard Worker   }
142*795d594fSAndroid Build Coastguard Worker 
GetChecksumsOffset()143*795d594fSAndroid Build Coastguard Worker   static size_t GetChecksumsOffset() {
144*795d594fSAndroid Build Coastguard Worker     return sizeof(VdexFileHeader) +
145*795d594fSAndroid Build Coastguard Worker         static_cast<size_t>(VdexSection::kNumberOfSections) * sizeof(VdexSectionHeader);
146*795d594fSAndroid Build Coastguard Worker   }
147*795d594fSAndroid Build Coastguard Worker 
GetComputedFileSize()148*795d594fSAndroid Build Coastguard Worker   size_t GetComputedFileSize() const {
149*795d594fSAndroid Build Coastguard Worker     const VdexFileHeader& header = GetVdexFileHeader();
150*795d594fSAndroid Build Coastguard Worker     uint32_t size = sizeof(VdexFileHeader) +
151*795d594fSAndroid Build Coastguard Worker         header.GetNumberOfSections() * sizeof(VdexSectionHeader);
152*795d594fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < header.GetNumberOfSections(); ++i) {
153*795d594fSAndroid Build Coastguard Worker       size = std::max(size,
154*795d594fSAndroid Build Coastguard Worker                       GetSectionHeaderAt(i).section_offset + GetSectionHeaderAt(i).section_size);
155*795d594fSAndroid Build Coastguard Worker     }
156*795d594fSAndroid Build Coastguard Worker     return size;
157*795d594fSAndroid Build Coastguard Worker   }
158*795d594fSAndroid Build Coastguard Worker 
HasDexSection()159*795d594fSAndroid Build Coastguard Worker   bool HasDexSection() const {
160*795d594fSAndroid Build Coastguard Worker     return GetSectionHeader(VdexSection::kDexFileSection).section_size != 0u;
161*795d594fSAndroid Build Coastguard Worker   }
GetVerifierDepsSize()162*795d594fSAndroid Build Coastguard Worker   uint32_t GetVerifierDepsSize() const {
163*795d594fSAndroid Build Coastguard Worker     return GetSectionHeader(VdexSection::kVerifierDepsSection).section_size;
164*795d594fSAndroid Build Coastguard Worker   }
GetNumberOfDexFiles()165*795d594fSAndroid Build Coastguard Worker   uint32_t GetNumberOfDexFiles() const {
166*795d594fSAndroid Build Coastguard Worker     return GetSectionHeader(VdexSection::kChecksumSection).section_size / sizeof(VdexChecksum);
167*795d594fSAndroid Build Coastguard Worker   }
168*795d594fSAndroid Build Coastguard Worker 
HasTypeLookupTableSection()169*795d594fSAndroid Build Coastguard Worker   bool HasTypeLookupTableSection() const {
170*795d594fSAndroid Build Coastguard Worker     return GetVdexFileHeader().GetNumberOfSections() >= (kTypeLookupTableSection + 1);
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker 
GetDexChecksumsArray()173*795d594fSAndroid Build Coastguard Worker   const VdexChecksum* GetDexChecksumsArray() const {
174*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<const VdexChecksum*>(
175*795d594fSAndroid Build Coastguard Worker         Begin() + GetSectionHeader(VdexSection::kChecksumSection).section_offset);
176*795d594fSAndroid Build Coastguard Worker   }
177*795d594fSAndroid Build Coastguard Worker 
GetDexChecksumAt(size_t idx)178*795d594fSAndroid Build Coastguard Worker   VdexChecksum GetDexChecksumAt(size_t idx) const {
179*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(idx, GetNumberOfDexFiles());
180*795d594fSAndroid Build Coastguard Worker     return GetDexChecksumsArray()[idx];
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   // Note: The file is called "primary" to match the naming with profiles.
184*795d594fSAndroid Build Coastguard Worker   static const constexpr char* kVdexNameInDmFile = "primary.vdex";
185*795d594fSAndroid Build Coastguard Worker 
VdexFile(MemMap && mmap)186*795d594fSAndroid Build Coastguard Worker   explicit VdexFile(MemMap&& mmap) : mmap_(std::move(mmap)) {}
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker   // Returns nullptr if the vdex file cannot be opened or is not valid.
189*795d594fSAndroid Build Coastguard Worker   // The mmap_* parameters can be left empty (nullptr/0/false) to allocate at random address.
190*795d594fSAndroid Build Coastguard Worker   EXPORT static std::unique_ptr<VdexFile> OpenAtAddress(uint8_t* mmap_addr,
191*795d594fSAndroid Build Coastguard Worker                                                         size_t mmap_size,
192*795d594fSAndroid Build Coastguard Worker                                                         bool mmap_reuse,
193*795d594fSAndroid Build Coastguard Worker                                                         const std::string& vdex_filename,
194*795d594fSAndroid Build Coastguard Worker                                                         bool writable,
195*795d594fSAndroid Build Coastguard Worker                                                         bool low_4gb,
196*795d594fSAndroid Build Coastguard Worker                                                         std::string* error_msg);
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker   // Returns nullptr if the vdex file cannot be opened or is not valid.
199*795d594fSAndroid Build Coastguard Worker   // The mmap_* parameters can be left empty (nullptr/0/false) to allocate at random address.
200*795d594fSAndroid Build Coastguard Worker   EXPORT static std::unique_ptr<VdexFile> OpenAtAddress(uint8_t* mmap_addr,
201*795d594fSAndroid Build Coastguard Worker                                                         size_t mmap_size,
202*795d594fSAndroid Build Coastguard Worker                                                         bool mmap_reuse,
203*795d594fSAndroid Build Coastguard Worker                                                         int file_fd,
204*795d594fSAndroid Build Coastguard Worker                                                         size_t vdex_length,
205*795d594fSAndroid Build Coastguard Worker                                                         const std::string& vdex_filename,
206*795d594fSAndroid Build Coastguard Worker                                                         bool writable,
207*795d594fSAndroid Build Coastguard Worker                                                         bool low_4gb,
208*795d594fSAndroid Build Coastguard Worker                                                         std::string* error_msg);
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   // Returns nullptr if the vdex file cannot be opened or is not valid.
Open(const std::string & vdex_filename,bool writable,bool low_4gb,std::string * error_msg)211*795d594fSAndroid Build Coastguard Worker   static std::unique_ptr<VdexFile> Open(const std::string& vdex_filename,
212*795d594fSAndroid Build Coastguard Worker                                         bool writable,
213*795d594fSAndroid Build Coastguard Worker                                         bool low_4gb,
214*795d594fSAndroid Build Coastguard Worker                                         std::string* error_msg) {
215*795d594fSAndroid Build Coastguard Worker     return OpenAtAddress(nullptr,
216*795d594fSAndroid Build Coastguard Worker                          0,
217*795d594fSAndroid Build Coastguard Worker                          false,
218*795d594fSAndroid Build Coastguard Worker                          vdex_filename,
219*795d594fSAndroid Build Coastguard Worker                          writable,
220*795d594fSAndroid Build Coastguard Worker                          low_4gb,
221*795d594fSAndroid Build Coastguard Worker                          error_msg);
222*795d594fSAndroid Build Coastguard Worker   }
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   // Returns nullptr if the vdex file cannot be opened or is not valid.
Open(int file_fd,size_t vdex_length,const std::string & vdex_filename,bool writable,bool low_4gb,std::string * error_msg)225*795d594fSAndroid Build Coastguard Worker   static std::unique_ptr<VdexFile> Open(int file_fd,
226*795d594fSAndroid Build Coastguard Worker                                         size_t vdex_length,
227*795d594fSAndroid Build Coastguard Worker                                         const std::string& vdex_filename,
228*795d594fSAndroid Build Coastguard Worker                                         bool writable,
229*795d594fSAndroid Build Coastguard Worker                                         bool low_4gb,
230*795d594fSAndroid Build Coastguard Worker                                         std::string* error_msg) {
231*795d594fSAndroid Build Coastguard Worker     return OpenAtAddress(nullptr,
232*795d594fSAndroid Build Coastguard Worker                          0,
233*795d594fSAndroid Build Coastguard Worker                          false,
234*795d594fSAndroid Build Coastguard Worker                          file_fd,
235*795d594fSAndroid Build Coastguard Worker                          vdex_length,
236*795d594fSAndroid Build Coastguard Worker                          vdex_filename,
237*795d594fSAndroid Build Coastguard Worker                          writable,
238*795d594fSAndroid Build Coastguard Worker                          low_4gb,
239*795d594fSAndroid Build Coastguard Worker                          error_msg);
240*795d594fSAndroid Build Coastguard Worker   }
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   EXPORT static std::unique_ptr<VdexFile> OpenFromDm(const std::string& filename,
243*795d594fSAndroid Build Coastguard Worker                                                      const ZipArchive& archive);
244*795d594fSAndroid Build Coastguard Worker 
Begin()245*795d594fSAndroid Build Coastguard Worker   const uint8_t* Begin() const { return mmap_.Begin(); }
End()246*795d594fSAndroid Build Coastguard Worker   const uint8_t* End() const { return mmap_.End(); }
Size()247*795d594fSAndroid Build Coastguard Worker   size_t Size() const { return mmap_.Size(); }
Contains(const uint8_t * pointer,size_t size)248*795d594fSAndroid Build Coastguard Worker   bool Contains(const uint8_t* pointer, size_t size) const {
249*795d594fSAndroid Build Coastguard Worker     return Begin() <= pointer && size <= Size() && pointer <= End() - size;
250*795d594fSAndroid Build Coastguard Worker   }
251*795d594fSAndroid Build Coastguard Worker 
GetVdexFileHeader()252*795d594fSAndroid Build Coastguard Worker   const VdexFileHeader& GetVdexFileHeader() const {
253*795d594fSAndroid Build Coastguard Worker     return *reinterpret_cast<const VdexFileHeader*>(Begin());
254*795d594fSAndroid Build Coastguard Worker   }
255*795d594fSAndroid Build Coastguard Worker 
GetVerifierDepsData()256*795d594fSAndroid Build Coastguard Worker   ArrayRef<const uint8_t> GetVerifierDepsData() const {
257*795d594fSAndroid Build Coastguard Worker     return ArrayRef<const uint8_t>(
258*795d594fSAndroid Build Coastguard Worker         Begin() + GetSectionHeader(VdexSection::kVerifierDepsSection).section_offset,
259*795d594fSAndroid Build Coastguard Worker         GetSectionHeader(VdexSection::kVerifierDepsSection).section_size);
260*795d594fSAndroid Build Coastguard Worker   }
261*795d594fSAndroid Build Coastguard Worker 
IsValid()262*795d594fSAndroid Build Coastguard Worker   bool IsValid() const {
263*795d594fSAndroid Build Coastguard Worker     return mmap_.Size() >= sizeof(VdexFileHeader) && GetVdexFileHeader().IsValid();
264*795d594fSAndroid Build Coastguard Worker   }
265*795d594fSAndroid Build Coastguard Worker 
266*795d594fSAndroid Build Coastguard Worker   // This method is for iterating over the dex files in the vdex. If `cursor` is null,
267*795d594fSAndroid Build Coastguard Worker   // the first dex file is returned. If `cursor` is not null, it must point to a dex
268*795d594fSAndroid Build Coastguard Worker   // file and this method returns the next dex file if there is one, or null if there
269*795d594fSAndroid Build Coastguard Worker   // is none.
270*795d594fSAndroid Build Coastguard Worker   EXPORT const uint8_t* GetNextDexFileData(const uint8_t* cursor, uint32_t dex_file_index) const;
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   const uint8_t* GetNextTypeLookupTableData(const uint8_t* cursor, uint32_t dex_file_index) const;
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   // Get the location checksum of the dex file number `dex_file_index`.
GetLocationChecksum(uint32_t dex_file_index)275*795d594fSAndroid Build Coastguard Worker   uint32_t GetLocationChecksum(uint32_t dex_file_index) const {
276*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(dex_file_index, GetNumberOfDexFiles());
277*795d594fSAndroid Build Coastguard Worker     return GetDexChecksumAt(dex_file_index);
278*795d594fSAndroid Build Coastguard Worker   }
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   // Open all the dex files contained in this vdex file.
281*795d594fSAndroid Build Coastguard Worker   EXPORT bool OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>>* dex_files,
282*795d594fSAndroid Build Coastguard Worker                               std::string* error_msg) const;
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   // Writes a vdex into `path` and returns true on success.
285*795d594fSAndroid Build Coastguard Worker   // The vdex will not contain a dex section but will store checksums of `dex_files`,
286*795d594fSAndroid Build Coastguard Worker   // encoded `verifier_deps`, as well as the current boot class path cheksum and
287*795d594fSAndroid Build Coastguard Worker   // encoded `class_loader_context`.
288*795d594fSAndroid Build Coastguard Worker   static bool WriteToDisk(const std::string& path,
289*795d594fSAndroid Build Coastguard Worker                           const std::vector<const DexFile*>& dex_files,
290*795d594fSAndroid Build Coastguard Worker                           const verifier::VerifierDeps& verifier_deps,
291*795d594fSAndroid Build Coastguard Worker                           std::string* error_msg);
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker   // Returns true if the dex file checksums stored in the vdex header match
294*795d594fSAndroid Build Coastguard Worker   // the checksums in `dex_headers`. Both the number of dex files and their
295*795d594fSAndroid Build Coastguard Worker   // order must match too.
296*795d594fSAndroid Build Coastguard Worker   bool MatchesDexFileChecksums(const std::vector<const DexFile::Header*>& dex_headers) const;
297*795d594fSAndroid Build Coastguard Worker 
298*795d594fSAndroid Build Coastguard Worker   // Returns true if all dex files are standard dex rather than compact dex.
299*795d594fSAndroid Build Coastguard Worker   // Also returns true if there are no dex files at all.
300*795d594fSAndroid Build Coastguard Worker   bool HasOnlyStandardDexFiles() const;
301*795d594fSAndroid Build Coastguard Worker 
302*795d594fSAndroid Build Coastguard Worker   ClassStatus ComputeClassStatus(Thread* self, Handle<mirror::Class> cls) const
303*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker   // Return the name of the underlying `MemMap` of the vdex file, typically the
306*795d594fSAndroid Build Coastguard Worker   // location on disk of the vdex file.
GetName()307*795d594fSAndroid Build Coastguard Worker   const std::string& GetName() const {
308*795d594fSAndroid Build Coastguard Worker     return mmap_.GetName();
309*795d594fSAndroid Build Coastguard Worker   }
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker  private:
312*795d594fSAndroid Build Coastguard Worker   bool ContainsDexFile(const DexFile& dex_file) const;
313*795d594fSAndroid Build Coastguard Worker 
DexBegin()314*795d594fSAndroid Build Coastguard Worker   const uint8_t* DexBegin() const {
315*795d594fSAndroid Build Coastguard Worker     DCHECK(HasDexSection());
316*795d594fSAndroid Build Coastguard Worker     return Begin() + GetSectionHeader(VdexSection::kDexFileSection).section_offset;
317*795d594fSAndroid Build Coastguard Worker   }
318*795d594fSAndroid Build Coastguard Worker 
TypeLookupTableDataBegin()319*795d594fSAndroid Build Coastguard Worker   const uint8_t* TypeLookupTableDataBegin() const {
320*795d594fSAndroid Build Coastguard Worker     DCHECK(HasTypeLookupTableSection());
321*795d594fSAndroid Build Coastguard Worker     return Begin() + GetSectionHeader(VdexSection::kTypeLookupTableSection).section_offset;
322*795d594fSAndroid Build Coastguard Worker   }
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   MemMap mmap_;
325*795d594fSAndroid Build Coastguard Worker 
326*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(VdexFile);
327*795d594fSAndroid Build Coastguard Worker };
328*795d594fSAndroid Build Coastguard Worker 
329*795d594fSAndroid Build Coastguard Worker }  // namespace art
330*795d594fSAndroid Build Coastguard Worker 
331*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_VDEX_FILE_H_
332