xref: /aosp_15_r20/art/runtime/oat/image.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 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_OAT_IMAGE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_OAT_IMAGE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <string.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "base/file_utils.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/iteration_range.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/unix_file/fd_file.h"
28*795d594fSAndroid Build Coastguard Worker #include "mirror/object.h"
29*795d594fSAndroid Build Coastguard Worker #include "runtime_globals.h"
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker class ArtField;
34*795d594fSAndroid Build Coastguard Worker class ArtMethod;
35*795d594fSAndroid Build Coastguard Worker class ImageFileGuard;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker template <class MirrorType> class ObjPtr;
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker namespace linker {
40*795d594fSAndroid Build Coastguard Worker class ImageWriter;
41*795d594fSAndroid Build Coastguard Worker }  // namespace linker
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker class ObjectVisitor {
44*795d594fSAndroid Build Coastguard Worker  public:
~ObjectVisitor()45*795d594fSAndroid Build Coastguard Worker   virtual ~ObjectVisitor() {}
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   virtual void Visit(mirror::Object* object) = 0;
48*795d594fSAndroid Build Coastguard Worker };
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker class PACKED(4) ImageSection {
51*795d594fSAndroid Build Coastguard Worker  public:
ImageSection()52*795d594fSAndroid Build Coastguard Worker   ImageSection() : offset_(0), size_(0) { }
ImageSection(uint32_t offset,uint32_t size)53*795d594fSAndroid Build Coastguard Worker   ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
54*795d594fSAndroid Build Coastguard Worker   ImageSection(const ImageSection& section) = default;
55*795d594fSAndroid Build Coastguard Worker   ImageSection& operator=(const ImageSection& section) = default;
56*795d594fSAndroid Build Coastguard Worker 
Offset()57*795d594fSAndroid Build Coastguard Worker   uint32_t Offset() const {
58*795d594fSAndroid Build Coastguard Worker     return offset_;
59*795d594fSAndroid Build Coastguard Worker   }
60*795d594fSAndroid Build Coastguard Worker 
Size()61*795d594fSAndroid Build Coastguard Worker   uint32_t Size() const {
62*795d594fSAndroid Build Coastguard Worker     return size_;
63*795d594fSAndroid Build Coastguard Worker   }
64*795d594fSAndroid Build Coastguard Worker 
End()65*795d594fSAndroid Build Coastguard Worker   uint32_t End() const {
66*795d594fSAndroid Build Coastguard Worker     return Offset() + Size();
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker 
Contains(uint64_t offset)69*795d594fSAndroid Build Coastguard Worker   bool Contains(uint64_t offset) const {
70*795d594fSAndroid Build Coastguard Worker     return offset - offset_ < size_;
71*795d594fSAndroid Build Coastguard Worker   }
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker  private:
74*795d594fSAndroid Build Coastguard Worker   uint32_t offset_;
75*795d594fSAndroid Build Coastguard Worker   uint32_t size_;
76*795d594fSAndroid Build Coastguard Worker };
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker // Header of image files written by ImageWriter, read and validated by Space.
79*795d594fSAndroid Build Coastguard Worker // Packed to object alignment since the first object follows directly after the header.
80*795d594fSAndroid Build Coastguard Worker static_assert(kObjectAlignment == 8, "Alignment check");
81*795d594fSAndroid Build Coastguard Worker class PACKED(8) ImageHeader {
82*795d594fSAndroid Build Coastguard Worker  public:
83*795d594fSAndroid Build Coastguard Worker   enum StorageMode : uint32_t {
84*795d594fSAndroid Build Coastguard Worker     kStorageModeUncompressed,
85*795d594fSAndroid Build Coastguard Worker     kStorageModeLZ4,
86*795d594fSAndroid Build Coastguard Worker     kStorageModeLZ4HC,
87*795d594fSAndroid Build Coastguard Worker     kStorageModeCount,  // Number of elements in enum.
88*795d594fSAndroid Build Coastguard Worker   };
89*795d594fSAndroid Build Coastguard Worker   static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   // Solid block of the image. May be compressed or uncompressed.
92*795d594fSAndroid Build Coastguard Worker   class PACKED(4) Block final {
93*795d594fSAndroid Build Coastguard Worker    public:
Block(StorageMode storage_mode,uint32_t data_offset,uint32_t data_size,uint32_t image_offset,uint32_t image_size)94*795d594fSAndroid Build Coastguard Worker     Block(StorageMode storage_mode,
95*795d594fSAndroid Build Coastguard Worker           uint32_t data_offset,
96*795d594fSAndroid Build Coastguard Worker           uint32_t data_size,
97*795d594fSAndroid Build Coastguard Worker           uint32_t image_offset,
98*795d594fSAndroid Build Coastguard Worker           uint32_t image_size)
99*795d594fSAndroid Build Coastguard Worker         : storage_mode_(storage_mode),
100*795d594fSAndroid Build Coastguard Worker           data_offset_(data_offset),
101*795d594fSAndroid Build Coastguard Worker           data_size_(data_size),
102*795d594fSAndroid Build Coastguard Worker           image_offset_(image_offset),
103*795d594fSAndroid Build Coastguard Worker           image_size_(image_size) {}
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker     bool Decompress(uint8_t* out_ptr, const uint8_t* in_ptr, std::string* error_msg) const;
106*795d594fSAndroid Build Coastguard Worker 
GetStorageMode()107*795d594fSAndroid Build Coastguard Worker     StorageMode GetStorageMode() const {
108*795d594fSAndroid Build Coastguard Worker       return storage_mode_;
109*795d594fSAndroid Build Coastguard Worker     }
110*795d594fSAndroid Build Coastguard Worker 
GetDataSize()111*795d594fSAndroid Build Coastguard Worker     uint32_t GetDataSize() const {
112*795d594fSAndroid Build Coastguard Worker       return data_size_;
113*795d594fSAndroid Build Coastguard Worker     }
114*795d594fSAndroid Build Coastguard Worker 
GetImageSize()115*795d594fSAndroid Build Coastguard Worker     uint32_t GetImageSize() const {
116*795d594fSAndroid Build Coastguard Worker       return image_size_;
117*795d594fSAndroid Build Coastguard Worker     }
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker    private:
120*795d594fSAndroid Build Coastguard Worker     // Storage method for the image, the image may be compressed.
121*795d594fSAndroid Build Coastguard Worker     StorageMode storage_mode_ = kDefaultStorageMode;
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker     // Compressed offset and size.
124*795d594fSAndroid Build Coastguard Worker     uint32_t data_offset_ = 0u;
125*795d594fSAndroid Build Coastguard Worker     uint32_t data_size_ = 0u;
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker     // Image offset and size (decompressed or mapped location).
128*795d594fSAndroid Build Coastguard Worker     uint32_t image_offset_ = 0u;
129*795d594fSAndroid Build Coastguard Worker     uint32_t image_size_ = 0u;
130*795d594fSAndroid Build Coastguard Worker   };
131*795d594fSAndroid Build Coastguard Worker 
ImageHeader()132*795d594fSAndroid Build Coastguard Worker   ImageHeader() {}
133*795d594fSAndroid Build Coastguard Worker   EXPORT ImageHeader(uint32_t image_reservation_size,
134*795d594fSAndroid Build Coastguard Worker                      uint32_t component_count,
135*795d594fSAndroid Build Coastguard Worker                      uint32_t image_begin,
136*795d594fSAndroid Build Coastguard Worker                      uint32_t image_size,
137*795d594fSAndroid Build Coastguard Worker                      ImageSection* sections,
138*795d594fSAndroid Build Coastguard Worker                      uint32_t image_roots,
139*795d594fSAndroid Build Coastguard Worker                      uint32_t oat_checksum,
140*795d594fSAndroid Build Coastguard Worker                      uint32_t oat_file_begin,
141*795d594fSAndroid Build Coastguard Worker                      uint32_t oat_data_begin,
142*795d594fSAndroid Build Coastguard Worker                      uint32_t oat_data_end,
143*795d594fSAndroid Build Coastguard Worker                      uint32_t oat_file_end,
144*795d594fSAndroid Build Coastguard Worker                      uint32_t boot_image_begin,
145*795d594fSAndroid Build Coastguard Worker                      uint32_t boot_image_size,
146*795d594fSAndroid Build Coastguard Worker                      uint32_t boot_image_component_count,
147*795d594fSAndroid Build Coastguard Worker                      uint32_t boot_image_checksum,
148*795d594fSAndroid Build Coastguard Worker                      PointerSize pointer_size);
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   EXPORT bool IsValid() const;
151*795d594fSAndroid Build Coastguard Worker   EXPORT const char* GetMagic() const;
152*795d594fSAndroid Build Coastguard Worker 
GetImageReservationSize()153*795d594fSAndroid Build Coastguard Worker   uint32_t GetImageReservationSize() const {
154*795d594fSAndroid Build Coastguard Worker     return image_reservation_size_;
155*795d594fSAndroid Build Coastguard Worker   }
156*795d594fSAndroid Build Coastguard Worker 
GetComponentCount()157*795d594fSAndroid Build Coastguard Worker   uint32_t GetComponentCount() const {
158*795d594fSAndroid Build Coastguard Worker     return component_count_;
159*795d594fSAndroid Build Coastguard Worker   }
160*795d594fSAndroid Build Coastguard Worker 
GetImageBegin()161*795d594fSAndroid Build Coastguard Worker   uint8_t* GetImageBegin() const {
162*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(image_begin_);
163*795d594fSAndroid Build Coastguard Worker   }
164*795d594fSAndroid Build Coastguard Worker 
GetImageSize()165*795d594fSAndroid Build Coastguard Worker   size_t GetImageSize() const {
166*795d594fSAndroid Build Coastguard Worker     return image_size_;
167*795d594fSAndroid Build Coastguard Worker   }
168*795d594fSAndroid Build Coastguard Worker 
GetImageChecksum()169*795d594fSAndroid Build Coastguard Worker   uint32_t GetImageChecksum() const {
170*795d594fSAndroid Build Coastguard Worker     return image_checksum_;
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker 
SetImageChecksum(uint32_t image_checksum)173*795d594fSAndroid Build Coastguard Worker   void SetImageChecksum(uint32_t image_checksum) {
174*795d594fSAndroid Build Coastguard Worker     image_checksum_ = image_checksum;
175*795d594fSAndroid Build Coastguard Worker   }
176*795d594fSAndroid Build Coastguard Worker 
GetOatChecksum()177*795d594fSAndroid Build Coastguard Worker   uint32_t GetOatChecksum() const {
178*795d594fSAndroid Build Coastguard Worker     return oat_checksum_;
179*795d594fSAndroid Build Coastguard Worker   }
180*795d594fSAndroid Build Coastguard Worker 
SetOatChecksum(uint32_t oat_checksum)181*795d594fSAndroid Build Coastguard Worker   void SetOatChecksum(uint32_t oat_checksum) {
182*795d594fSAndroid Build Coastguard Worker     oat_checksum_ = oat_checksum;
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   // The location that the oat file was expected to be when the image was created. The actual
186*795d594fSAndroid Build Coastguard Worker   // oat file may be at a different location for application images.
GetOatFileBegin()187*795d594fSAndroid Build Coastguard Worker   uint8_t* GetOatFileBegin() const {
188*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(oat_file_begin_);
189*795d594fSAndroid Build Coastguard Worker   }
190*795d594fSAndroid Build Coastguard Worker 
GetOatDataBegin()191*795d594fSAndroid Build Coastguard Worker   uint8_t* GetOatDataBegin() const {
192*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(oat_data_begin_);
193*795d594fSAndroid Build Coastguard Worker   }
194*795d594fSAndroid Build Coastguard Worker 
GetOatDataEnd()195*795d594fSAndroid Build Coastguard Worker   uint8_t* GetOatDataEnd() const {
196*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(oat_data_end_);
197*795d594fSAndroid Build Coastguard Worker   }
198*795d594fSAndroid Build Coastguard Worker 
GetOatFileEnd()199*795d594fSAndroid Build Coastguard Worker   uint8_t* GetOatFileEnd() const {
200*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(oat_file_end_);
201*795d594fSAndroid Build Coastguard Worker   }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker   EXPORT PointerSize GetPointerSize() const;
204*795d594fSAndroid Build Coastguard Worker 
GetOatLocationFromImageLocation(const std::string & image)205*795d594fSAndroid Build Coastguard Worker   static std::string GetOatLocationFromImageLocation(const std::string& image) {
206*795d594fSAndroid Build Coastguard Worker     return ReplaceFileExtension(image, kOatExtension);
207*795d594fSAndroid Build Coastguard Worker   }
208*795d594fSAndroid Build Coastguard Worker 
GetVdexLocationFromImageLocation(const std::string & image)209*795d594fSAndroid Build Coastguard Worker   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
210*795d594fSAndroid Build Coastguard Worker     return ReplaceFileExtension(image, kVdexExtension);
211*795d594fSAndroid Build Coastguard Worker   }
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker   enum ImageMethod {
214*795d594fSAndroid Build Coastguard Worker     kResolutionMethod,
215*795d594fSAndroid Build Coastguard Worker     kImtConflictMethod,
216*795d594fSAndroid Build Coastguard Worker     kImtUnimplementedMethod,
217*795d594fSAndroid Build Coastguard Worker     kSaveAllCalleeSavesMethod,
218*795d594fSAndroid Build Coastguard Worker     kSaveRefsOnlyMethod,
219*795d594fSAndroid Build Coastguard Worker     kSaveRefsAndArgsMethod,
220*795d594fSAndroid Build Coastguard Worker     kSaveEverythingMethod,
221*795d594fSAndroid Build Coastguard Worker     kSaveEverythingMethodForClinit,
222*795d594fSAndroid Build Coastguard Worker     kSaveEverythingMethodForSuspendCheck,
223*795d594fSAndroid Build Coastguard Worker     kImageMethodsCount,  // Number of elements in enum.
224*795d594fSAndroid Build Coastguard Worker   };
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   enum ImageRoot {
227*795d594fSAndroid Build Coastguard Worker     kDexCaches,
228*795d594fSAndroid Build Coastguard Worker     kClassRoots,
229*795d594fSAndroid Build Coastguard Worker     kSpecialRoots,                    // Different for boot image and app image, see aliases below.
230*795d594fSAndroid Build Coastguard Worker     kImageRootsMax,
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker     // Aliases.
233*795d594fSAndroid Build Coastguard Worker     kAppImageClassLoader = kSpecialRoots,   // The class loader used to build the app image.
234*795d594fSAndroid Build Coastguard Worker     kBootImageLiveObjects = kSpecialRoots,  // Array of boot image objects that must be kept live.
235*795d594fSAndroid Build Coastguard Worker     kAppImageOatHeader = kSpecialRoots,     // A byte array containing 1) a fake OatHeader to check
236*795d594fSAndroid Build Coastguard Worker                                             // if the image can be loaded against the current
237*795d594fSAndroid Build Coastguard Worker                                             // runtime, and 2) the dex checksums.
238*795d594fSAndroid Build Coastguard Worker   };
239*795d594fSAndroid Build Coastguard Worker 
240*795d594fSAndroid Build Coastguard Worker   enum BootImageLiveObjects {
241*795d594fSAndroid Build Coastguard Worker     kOomeWhenThrowingException,       // Pre-allocated OOME when throwing exception.
242*795d594fSAndroid Build Coastguard Worker     kOomeWhenThrowingOome,            // Pre-allocated OOME when throwing OOME.
243*795d594fSAndroid Build Coastguard Worker     kOomeWhenHandlingStackOverflow,   // Pre-allocated OOME when handling StackOverflowError.
244*795d594fSAndroid Build Coastguard Worker     kNoClassDefFoundError,            // Pre-allocated NoClassDefFoundError.
245*795d594fSAndroid Build Coastguard Worker     kClearedJniWeakSentinel,          // Pre-allocated sentinel for cleared weak JNI references.
246*795d594fSAndroid Build Coastguard Worker     kIntrinsicObjectsStart
247*795d594fSAndroid Build Coastguard Worker   };
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker   /*
250*795d594fSAndroid Build Coastguard Worker    * This describes the number and ordering of sections inside of Boot
251*795d594fSAndroid Build Coastguard Worker    * and App Images.  It is very important that changes to this struct
252*795d594fSAndroid Build Coastguard Worker    * are reflected in the compiler and loader.
253*795d594fSAndroid Build Coastguard Worker    *
254*795d594fSAndroid Build Coastguard Worker    * See:
255*795d594fSAndroid Build Coastguard Worker    *   - ImageWriter::ImageInfo::CreateImageSections()
256*795d594fSAndroid Build Coastguard Worker    *   - ImageWriter::Write()
257*795d594fSAndroid Build Coastguard Worker    *   - ImageWriter::AllocMemory()
258*795d594fSAndroid Build Coastguard Worker    */
259*795d594fSAndroid Build Coastguard Worker   enum ImageSections {
260*795d594fSAndroid Build Coastguard Worker     kSectionObjects,
261*795d594fSAndroid Build Coastguard Worker     kSectionArtFields,
262*795d594fSAndroid Build Coastguard Worker     kSectionArtMethods,
263*795d594fSAndroid Build Coastguard Worker     kSectionImTables,
264*795d594fSAndroid Build Coastguard Worker     kSectionIMTConflictTables,
265*795d594fSAndroid Build Coastguard Worker     kSectionRuntimeMethods,
266*795d594fSAndroid Build Coastguard Worker     kSectionJniStubMethods,
267*795d594fSAndroid Build Coastguard Worker     kSectionInternedStrings,
268*795d594fSAndroid Build Coastguard Worker     kSectionClassTable,
269*795d594fSAndroid Build Coastguard Worker     kSectionStringReferenceOffsets,
270*795d594fSAndroid Build Coastguard Worker     kSectionDexCacheArrays,
271*795d594fSAndroid Build Coastguard Worker     kSectionMetadata,
272*795d594fSAndroid Build Coastguard Worker     kSectionImageBitmap,
273*795d594fSAndroid Build Coastguard Worker     kSectionCount,  // Number of elements in enum.
274*795d594fSAndroid Build Coastguard Worker   };
275*795d594fSAndroid Build Coastguard Worker 
NumberOfImageRoots(bool app_image)276*795d594fSAndroid Build Coastguard Worker   static size_t NumberOfImageRoots([[maybe_unused]] bool app_image) {
277*795d594fSAndroid Build Coastguard Worker     // At the moment, boot image and app image have the same number of roots,
278*795d594fSAndroid Build Coastguard Worker     // though the meaning of the kSpecialRoots is different.
279*795d594fSAndroid Build Coastguard Worker     return kImageRootsMax;
280*795d594fSAndroid Build Coastguard Worker   }
281*795d594fSAndroid Build Coastguard Worker 
282*795d594fSAndroid Build Coastguard Worker   EXPORT ArtMethod* GetImageMethod(ImageMethod index) const;
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   EXPORT static const char* GetImageSectionName(ImageSections index);
285*795d594fSAndroid Build Coastguard Worker 
GetImageSection(ImageSections index)286*795d594fSAndroid Build Coastguard Worker   ImageSection& GetImageSection(ImageSections index) {
287*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
288*795d594fSAndroid Build Coastguard Worker     return sections_[index];
289*795d594fSAndroid Build Coastguard Worker   }
290*795d594fSAndroid Build Coastguard Worker 
GetImageSection(ImageSections index)291*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetImageSection(ImageSections index) const {
292*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
293*795d594fSAndroid Build Coastguard Worker     return sections_[index];
294*795d594fSAndroid Build Coastguard Worker   }
295*795d594fSAndroid Build Coastguard Worker 
GetObjectsSection()296*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetObjectsSection() const {
297*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionObjects);
298*795d594fSAndroid Build Coastguard Worker   }
299*795d594fSAndroid Build Coastguard Worker 
GetFieldsSection()300*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetFieldsSection() const {
301*795d594fSAndroid Build Coastguard Worker     return GetImageSection(ImageHeader::kSectionArtFields);
302*795d594fSAndroid Build Coastguard Worker   }
303*795d594fSAndroid Build Coastguard Worker 
GetMethodsSection()304*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetMethodsSection() const {
305*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionArtMethods);
306*795d594fSAndroid Build Coastguard Worker   }
307*795d594fSAndroid Build Coastguard Worker 
GetRuntimeMethodsSection()308*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetRuntimeMethodsSection() const {
309*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionRuntimeMethods);
310*795d594fSAndroid Build Coastguard Worker   }
311*795d594fSAndroid Build Coastguard Worker 
GetImTablesSection()312*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetImTablesSection() const {
313*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionImTables);
314*795d594fSAndroid Build Coastguard Worker   }
315*795d594fSAndroid Build Coastguard Worker 
GetIMTConflictTablesSection()316*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetIMTConflictTablesSection() const {
317*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionIMTConflictTables);
318*795d594fSAndroid Build Coastguard Worker   }
319*795d594fSAndroid Build Coastguard Worker 
GetInternedStringsSection()320*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetInternedStringsSection() const {
321*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionInternedStrings);
322*795d594fSAndroid Build Coastguard Worker   }
323*795d594fSAndroid Build Coastguard Worker 
GetClassTableSection()324*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetClassTableSection() const {
325*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionClassTable);
326*795d594fSAndroid Build Coastguard Worker   }
327*795d594fSAndroid Build Coastguard Worker 
GetImageStringReferenceOffsetsSection()328*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetImageStringReferenceOffsetsSection() const {
329*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionStringReferenceOffsets);
330*795d594fSAndroid Build Coastguard Worker   }
331*795d594fSAndroid Build Coastguard Worker 
GetMetadataSection()332*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetMetadataSection() const {
333*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionMetadata);
334*795d594fSAndroid Build Coastguard Worker   }
335*795d594fSAndroid Build Coastguard Worker 
GetJniStubMethodsSection()336*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetJniStubMethodsSection() const {
337*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionJniStubMethods);
338*795d594fSAndroid Build Coastguard Worker   }
339*795d594fSAndroid Build Coastguard Worker 
GetImageBitmapSection()340*795d594fSAndroid Build Coastguard Worker   const ImageSection& GetImageBitmapSection() const {
341*795d594fSAndroid Build Coastguard Worker     return GetImageSection(kSectionImageBitmap);
342*795d594fSAndroid Build Coastguard Worker   }
343*795d594fSAndroid Build Coastguard Worker 
344*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
345*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Object> GetImageRoot(ImageRoot image_root) const
346*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
349*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::ObjectArray<mirror::Object>> GetImageRoots() const
350*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker   void RelocateImageReferences(int64_t delta);
353*795d594fSAndroid Build Coastguard Worker   void RelocateBootImageReferences(int64_t delta);
354*795d594fSAndroid Build Coastguard Worker 
GetBootImageBegin()355*795d594fSAndroid Build Coastguard Worker   uint32_t GetBootImageBegin() const {
356*795d594fSAndroid Build Coastguard Worker     return boot_image_begin_;
357*795d594fSAndroid Build Coastguard Worker   }
358*795d594fSAndroid Build Coastguard Worker 
GetBootImageSize()359*795d594fSAndroid Build Coastguard Worker   uint32_t GetBootImageSize() const {
360*795d594fSAndroid Build Coastguard Worker     return boot_image_size_;
361*795d594fSAndroid Build Coastguard Worker   }
362*795d594fSAndroid Build Coastguard Worker 
GetBootImageComponentCount()363*795d594fSAndroid Build Coastguard Worker   uint32_t GetBootImageComponentCount() const {
364*795d594fSAndroid Build Coastguard Worker     return boot_image_component_count_;
365*795d594fSAndroid Build Coastguard Worker   }
366*795d594fSAndroid Build Coastguard Worker 
GetBootImageChecksum()367*795d594fSAndroid Build Coastguard Worker   uint32_t GetBootImageChecksum() const {
368*795d594fSAndroid Build Coastguard Worker     return boot_image_checksum_;
369*795d594fSAndroid Build Coastguard Worker   }
370*795d594fSAndroid Build Coastguard Worker 
GetDataSize()371*795d594fSAndroid Build Coastguard Worker   uint64_t GetDataSize() const {
372*795d594fSAndroid Build Coastguard Worker     return data_size_;
373*795d594fSAndroid Build Coastguard Worker   }
374*795d594fSAndroid Build Coastguard Worker 
375*795d594fSAndroid Build Coastguard Worker   EXPORT bool IsAppImage() const;
376*795d594fSAndroid Build Coastguard Worker 
377*795d594fSAndroid Build Coastguard Worker   EXPORT uint32_t GetImageSpaceCount() const;
378*795d594fSAndroid Build Coastguard Worker 
379*795d594fSAndroid Build Coastguard Worker   // Visit mirror::Objects in the section starting at base.
380*795d594fSAndroid Build Coastguard Worker   // TODO: Delete base parameter if it is always equal to GetImageBegin.
381*795d594fSAndroid Build Coastguard Worker   EXPORT void VisitObjects(ObjectVisitor* visitor, uint8_t* base, PointerSize pointer_size) const
382*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker   // Visit ArtMethods in the section starting at base. Includes runtime methods.
385*795d594fSAndroid Build Coastguard Worker   // TODO: Delete base parameter if it is always equal to GetImageBegin.
386*795d594fSAndroid Build Coastguard Worker   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
387*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
388*795d594fSAndroid Build Coastguard Worker   void VisitPackedArtMethods(const Visitor& visitor,
389*795d594fSAndroid Build Coastguard Worker                              uint8_t* base,
390*795d594fSAndroid Build Coastguard Worker                              PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker   // Visit ArtMethods in the section starting at base.
393*795d594fSAndroid Build Coastguard Worker   // TODO: Delete base parameter if it is always equal to GetImageBegin.
394*795d594fSAndroid Build Coastguard Worker   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
395*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
396*795d594fSAndroid Build Coastguard Worker   void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
399*795d594fSAndroid Build Coastguard Worker   void VisitPackedImTables(const Visitor& visitor,
400*795d594fSAndroid Build Coastguard Worker                            uint8_t* base,
401*795d594fSAndroid Build Coastguard Worker                            PointerSize pointer_size) const;
402*795d594fSAndroid Build Coastguard Worker 
403*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
404*795d594fSAndroid Build Coastguard Worker   void VisitPackedImtConflictTables(const Visitor& visitor,
405*795d594fSAndroid Build Coastguard Worker                                     uint8_t* base,
406*795d594fSAndroid Build Coastguard Worker                                     PointerSize pointer_size) const;
407*795d594fSAndroid Build Coastguard Worker 
408*795d594fSAndroid Build Coastguard Worker   template <bool kUpdate = false, typename Visitor>
409*795d594fSAndroid Build Coastguard Worker   void VisitJniStubMethods(const Visitor& visitor,
410*795d594fSAndroid Build Coastguard Worker                            uint8_t* base,
411*795d594fSAndroid Build Coastguard Worker                            PointerSize pointer_size) const REQUIRES_SHARED(Locks::mutator_lock_);
412*795d594fSAndroid Build Coastguard Worker 
GetBlocks()413*795d594fSAndroid Build Coastguard Worker   IterationRange<const Block*> GetBlocks() const {
414*795d594fSAndroid Build Coastguard Worker     return GetBlocks(GetImageBegin());
415*795d594fSAndroid Build Coastguard Worker   }
416*795d594fSAndroid Build Coastguard Worker 
GetBlocks(const uint8_t * image_begin)417*795d594fSAndroid Build Coastguard Worker   IterationRange<const Block*> GetBlocks(const uint8_t* image_begin) const {
418*795d594fSAndroid Build Coastguard Worker     const Block* begin = reinterpret_cast<const Block*>(image_begin + blocks_offset_);
419*795d594fSAndroid Build Coastguard Worker     return {begin, begin + blocks_count_};
420*795d594fSAndroid Build Coastguard Worker   }
421*795d594fSAndroid Build Coastguard Worker 
422*795d594fSAndroid Build Coastguard Worker   // Return true if the image has any compressed blocks.
HasCompressedBlock()423*795d594fSAndroid Build Coastguard Worker   bool HasCompressedBlock() const {
424*795d594fSAndroid Build Coastguard Worker     return blocks_count_ != 0u;
425*795d594fSAndroid Build Coastguard Worker   }
426*795d594fSAndroid Build Coastguard Worker 
GetBlockCount()427*795d594fSAndroid Build Coastguard Worker   uint32_t GetBlockCount() const {
428*795d594fSAndroid Build Coastguard Worker     return blocks_count_;
429*795d594fSAndroid Build Coastguard Worker   }
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker   // Helper for writing `data` and `bitmap_data` into `image_file`, following
432*795d594fSAndroid Build Coastguard Worker   // the information stored in this header and passed as arguments.
433*795d594fSAndroid Build Coastguard Worker   EXPORT bool WriteData(const ImageFileGuard& image_file,
434*795d594fSAndroid Build Coastguard Worker                         const uint8_t* data,
435*795d594fSAndroid Build Coastguard Worker                         const uint8_t* bitmap_data,
436*795d594fSAndroid Build Coastguard Worker                         ImageHeader::StorageMode image_storage_mode,
437*795d594fSAndroid Build Coastguard Worker                         uint32_t max_image_block_size,
438*795d594fSAndroid Build Coastguard Worker                         bool update_checksum,
439*795d594fSAndroid Build Coastguard Worker                         std::string* error_msg);
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker  private:
442*795d594fSAndroid Build Coastguard Worker   static const uint8_t kImageMagic[4];
443*795d594fSAndroid Build Coastguard Worker   static const uint8_t kImageVersion[4];
444*795d594fSAndroid Build Coastguard Worker 
445*795d594fSAndroid Build Coastguard Worker   uint8_t magic_[4];
446*795d594fSAndroid Build Coastguard Worker   uint8_t version_[4];
447*795d594fSAndroid Build Coastguard Worker 
448*795d594fSAndroid Build Coastguard Worker   // The total memory reservation size for the image.
449*795d594fSAndroid Build Coastguard Worker   // For boot image or boot image extension, the primary image includes the reservation
450*795d594fSAndroid Build Coastguard Worker   // for all image files and oat files, secondary images have the reservation set to 0.
451*795d594fSAndroid Build Coastguard Worker   // App images have reservation equal to `image_size_` rounded up to page size because
452*795d594fSAndroid Build Coastguard Worker   // their oat files are mmapped independently.
453*795d594fSAndroid Build Coastguard Worker   uint32_t image_reservation_size_ = 0u;
454*795d594fSAndroid Build Coastguard Worker 
455*795d594fSAndroid Build Coastguard Worker   // The number of components (jar files contributing to the image).
456*795d594fSAndroid Build Coastguard Worker   // For boot image or boot image extension, the primary image stores the total number
457*795d594fSAndroid Build Coastguard Worker   // of components, secondary images have this set to 0. App images have 1 component.
458*795d594fSAndroid Build Coastguard Worker   // The component count usually matches the total number of images (one image per component), but
459*795d594fSAndroid Build Coastguard Worker   // if multiple components are compiled with --single-image there will only be 1 image associated
460*795d594fSAndroid Build Coastguard Worker   // with those components.
461*795d594fSAndroid Build Coastguard Worker   uint32_t component_count_ = 0u;
462*795d594fSAndroid Build Coastguard Worker 
463*795d594fSAndroid Build Coastguard Worker   // Required base address for mapping the image.
464*795d594fSAndroid Build Coastguard Worker   uint32_t image_begin_ = 0u;
465*795d594fSAndroid Build Coastguard Worker 
466*795d594fSAndroid Build Coastguard Worker   // Image size, not page aligned.
467*795d594fSAndroid Build Coastguard Worker   uint32_t image_size_ = 0u;
468*795d594fSAndroid Build Coastguard Worker 
469*795d594fSAndroid Build Coastguard Worker   // Image file checksum (calculated with the checksum field set to 0).
470*795d594fSAndroid Build Coastguard Worker   uint32_t image_checksum_ = 0u;
471*795d594fSAndroid Build Coastguard Worker 
472*795d594fSAndroid Build Coastguard Worker   // Checksum of the oat file we link to for load time consistency check.
473*795d594fSAndroid Build Coastguard Worker   uint32_t oat_checksum_ = 0u;
474*795d594fSAndroid Build Coastguard Worker 
475*795d594fSAndroid Build Coastguard Worker   // Start address for oat file. Will be before oat_data_begin_ for .so files.
476*795d594fSAndroid Build Coastguard Worker   uint32_t oat_file_begin_ = 0u;
477*795d594fSAndroid Build Coastguard Worker 
478*795d594fSAndroid Build Coastguard Worker   // Required oat address expected by image Method::GetCode() pointers.
479*795d594fSAndroid Build Coastguard Worker   uint32_t oat_data_begin_ = 0u;
480*795d594fSAndroid Build Coastguard Worker 
481*795d594fSAndroid Build Coastguard Worker   // End of oat data address range for this image file.
482*795d594fSAndroid Build Coastguard Worker   uint32_t oat_data_end_ = 0u;
483*795d594fSAndroid Build Coastguard Worker 
484*795d594fSAndroid Build Coastguard Worker   // End of oat file address range. will be after oat_data_end_ for
485*795d594fSAndroid Build Coastguard Worker   // .so files. Used for positioning a following alloc spaces.
486*795d594fSAndroid Build Coastguard Worker   uint32_t oat_file_end_ = 0u;
487*795d594fSAndroid Build Coastguard Worker 
488*795d594fSAndroid Build Coastguard Worker   // Boot image begin and end (only applies to boot image extension and app image headers).
489*795d594fSAndroid Build Coastguard Worker   uint32_t boot_image_begin_ = 0u;
490*795d594fSAndroid Build Coastguard Worker   uint32_t boot_image_size_ = 0u;  // Includes heap (*.art) and code (.oat).
491*795d594fSAndroid Build Coastguard Worker 
492*795d594fSAndroid Build Coastguard Worker   // Number of boot image components that this image depends on and their composite checksum
493*795d594fSAndroid Build Coastguard Worker   // (only applies to boot image extension and app image headers).
494*795d594fSAndroid Build Coastguard Worker   uint32_t boot_image_component_count_ = 0u;
495*795d594fSAndroid Build Coastguard Worker   uint32_t boot_image_checksum_ = 0u;
496*795d594fSAndroid Build Coastguard Worker 
497*795d594fSAndroid Build Coastguard Worker   // Absolute address of an Object[] of objects needed to reinitialize from an image.
498*795d594fSAndroid Build Coastguard Worker   uint32_t image_roots_ = 0u;
499*795d594fSAndroid Build Coastguard Worker 
500*795d594fSAndroid Build Coastguard Worker   // Pointer size, this affects the size of the ArtMethods.
501*795d594fSAndroid Build Coastguard Worker   PointerSize pointer_size_;
502*795d594fSAndroid Build Coastguard Worker 
503*795d594fSAndroid Build Coastguard Worker   // Image section sizes/offsets correspond to the uncompressed form.
504*795d594fSAndroid Build Coastguard Worker   ImageSection sections_[kSectionCount];
505*795d594fSAndroid Build Coastguard Worker 
506*795d594fSAndroid Build Coastguard Worker   // Image methods, may be inside of the boot image for app images.
507*795d594fSAndroid Build Coastguard Worker   uint64_t image_methods_[kImageMethodsCount];
508*795d594fSAndroid Build Coastguard Worker 
509*795d594fSAndroid Build Coastguard Worker   // Data size for the image data excluding the bitmap and the header. For compressed images, this
510*795d594fSAndroid Build Coastguard Worker   // is the compressed size in the file.
511*795d594fSAndroid Build Coastguard Worker   uint32_t data_size_ = 0u;
512*795d594fSAndroid Build Coastguard Worker 
513*795d594fSAndroid Build Coastguard Worker   // Image blocks, only used for compressed images.
514*795d594fSAndroid Build Coastguard Worker   uint32_t blocks_offset_ = 0u;
515*795d594fSAndroid Build Coastguard Worker   uint32_t blocks_count_ = 0u;
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker   friend class linker::ImageWriter;
518*795d594fSAndroid Build Coastguard Worker   friend class RuntimeImageHelper;
519*795d594fSAndroid Build Coastguard Worker };
520*795d594fSAndroid Build Coastguard Worker 
521*795d594fSAndroid Build Coastguard Worker // Helper class that erases the image file if it isn't properly flushed and closed.
522*795d594fSAndroid Build Coastguard Worker class ImageFileGuard {
523*795d594fSAndroid Build Coastguard Worker  public:
524*795d594fSAndroid Build Coastguard Worker   ImageFileGuard() noexcept = default;
525*795d594fSAndroid Build Coastguard Worker   ImageFileGuard(ImageFileGuard&& other) noexcept = default;
526*795d594fSAndroid Build Coastguard Worker   ImageFileGuard& operator=(ImageFileGuard&& other) noexcept = default;
527*795d594fSAndroid Build Coastguard Worker 
~ImageFileGuard()528*795d594fSAndroid Build Coastguard Worker   ~ImageFileGuard() {
529*795d594fSAndroid Build Coastguard Worker     if (image_file_ != nullptr) {
530*795d594fSAndroid Build Coastguard Worker       // Failure, erase the image file.
531*795d594fSAndroid Build Coastguard Worker       image_file_->Erase();
532*795d594fSAndroid Build Coastguard Worker     }
533*795d594fSAndroid Build Coastguard Worker   }
534*795d594fSAndroid Build Coastguard Worker 
reset(File * image_file)535*795d594fSAndroid Build Coastguard Worker   void reset(File* image_file) {
536*795d594fSAndroid Build Coastguard Worker     image_file_.reset(image_file);
537*795d594fSAndroid Build Coastguard Worker   }
538*795d594fSAndroid Build Coastguard Worker 
539*795d594fSAndroid Build Coastguard Worker   bool operator==(std::nullptr_t) {
540*795d594fSAndroid Build Coastguard Worker     return image_file_ == nullptr;
541*795d594fSAndroid Build Coastguard Worker   }
542*795d594fSAndroid Build Coastguard Worker 
543*795d594fSAndroid Build Coastguard Worker   bool operator!=(std::nullptr_t) {
544*795d594fSAndroid Build Coastguard Worker     return image_file_ != nullptr;
545*795d594fSAndroid Build Coastguard Worker   }
546*795d594fSAndroid Build Coastguard Worker 
547*795d594fSAndroid Build Coastguard Worker   File* operator->() const {
548*795d594fSAndroid Build Coastguard Worker     return image_file_.get();
549*795d594fSAndroid Build Coastguard Worker   }
550*795d594fSAndroid Build Coastguard Worker 
WriteHeaderAndClose(const std::string & image_filename,const ImageHeader * image_header,std::string * error_msg)551*795d594fSAndroid Build Coastguard Worker   bool WriteHeaderAndClose(const std::string& image_filename,
552*795d594fSAndroid Build Coastguard Worker                            const ImageHeader* image_header,
553*795d594fSAndroid Build Coastguard Worker                            std::string* error_msg) {
554*795d594fSAndroid Build Coastguard Worker     // The header is uncompressed since it contains whether the image is compressed or not.
555*795d594fSAndroid Build Coastguard Worker     if (!image_file_->PwriteFully(image_header, sizeof(ImageHeader), 0)) {
556*795d594fSAndroid Build Coastguard Worker       *error_msg = "Failed to write image file header "
557*795d594fSAndroid Build Coastguard Worker           + image_filename + ": " + std::string(strerror(errno));
558*795d594fSAndroid Build Coastguard Worker       return false;
559*795d594fSAndroid Build Coastguard Worker     }
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker     // FlushCloseOrErase() takes care of erasing, so the destructor does not need
562*795d594fSAndroid Build Coastguard Worker     // to do that whether the FlushCloseOrErase() succeeds or fails.
563*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<File> image_file = std::move(image_file_);
564*795d594fSAndroid Build Coastguard Worker     if (image_file->FlushCloseOrErase() != 0) {
565*795d594fSAndroid Build Coastguard Worker       *error_msg = "Failed to flush and close image file "
566*795d594fSAndroid Build Coastguard Worker           + image_filename + ": " + std::string(strerror(errno));
567*795d594fSAndroid Build Coastguard Worker       return false;
568*795d594fSAndroid Build Coastguard Worker     }
569*795d594fSAndroid Build Coastguard Worker 
570*795d594fSAndroid Build Coastguard Worker     return true;
571*795d594fSAndroid Build Coastguard Worker   }
572*795d594fSAndroid Build Coastguard Worker 
573*795d594fSAndroid Build Coastguard Worker  private:
574*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<File> image_file_;
575*795d594fSAndroid Build Coastguard Worker };
576*795d594fSAndroid Build Coastguard Worker 
577*795d594fSAndroid Build Coastguard Worker 
578*795d594fSAndroid Build Coastguard Worker /*
579*795d594fSAndroid Build Coastguard Worker  * This type holds the information necessary to fix up AppImage string
580*795d594fSAndroid Build Coastguard Worker  * references.
581*795d594fSAndroid Build Coastguard Worker  *
582*795d594fSAndroid Build Coastguard Worker  * The first element indicates the location of a managed object with a field that needs fixing up.
583*795d594fSAndroid Build Coastguard Worker  * The second element of the pair is an object-relative offset to the field in question.
584*795d594fSAndroid Build Coastguard Worker  */
585*795d594fSAndroid Build Coastguard Worker using AppImageReferenceOffsetInfo = std::pair<uint32_t, uint32_t>;
586*795d594fSAndroid Build Coastguard Worker 
587*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, ImageHeader::ImageMethod method);
588*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, ImageHeader::ImageRoot root);
589*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, ImageHeader::ImageSections section);
590*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, ImageHeader::StorageMode mode);
591*795d594fSAndroid Build Coastguard Worker 
592*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, const ImageSection& section);
593*795d594fSAndroid Build Coastguard Worker 
594*795d594fSAndroid Build Coastguard Worker // Wrapper over LZ4_decompress_safe() that checks if return value is negative. See b/242914915.
595*795d594fSAndroid Build Coastguard Worker bool LZ4_decompress_safe_checked(const char* source,
596*795d594fSAndroid Build Coastguard Worker                                  char* dest,
597*795d594fSAndroid Build Coastguard Worker                                  int compressed_size,
598*795d594fSAndroid Build Coastguard Worker                                  int max_decompressed_size,
599*795d594fSAndroid Build Coastguard Worker                                  /*out*/ size_t* decompressed_size_checked,
600*795d594fSAndroid Build Coastguard Worker                                  /*out*/ std::string* error_msg);
601*795d594fSAndroid Build Coastguard Worker 
602*795d594fSAndroid Build Coastguard Worker }  // namespace art
603*795d594fSAndroid Build Coastguard Worker 
604*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_OAT_IMAGE_H_
605