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