summaryrefslogtreecommitdiff
path: root/runtime/image.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/image.h')
-rw-r--r--runtime/image.h84
1 files changed, 84 insertions, 0 deletions
diff --git a/runtime/image.h b/runtime/image.h
index 8f045e9339..324cd3c6d7 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -21,6 +21,8 @@
#include "base/enums.h"
#include "base/iteration_range.h"
+#include "base/os.h"
+#include "base/unix_file/fd_file.h"
#include "mirror/object.h"
#include "runtime_globals.h"
@@ -28,6 +30,8 @@ namespace art {
class ArtField;
class ArtMethod;
+class ImageFileGuard;
+
template <class MirrorType> class ObjPtr;
namespace linker {
@@ -230,6 +234,9 @@ class PACKED(8) ImageHeader {
// Aliases.
kAppImageClassLoader = kSpecialRoots, // The class loader used to build the app image.
kBootImageLiveObjects = kSpecialRoots, // Array of boot image objects that must be kept live.
+ kAppImageOatHeader = kSpecialRoots, // A byte array containing 1) a fake OatHeader to check
+ // if the image can be loaded against the current
+ // runtime, and 2) the dex checksums.
};
enum BootImageLiveObjects {
@@ -261,6 +268,7 @@ class PACKED(8) ImageHeader {
kSectionInternedStrings,
kSectionClassTable,
kSectionStringReferenceOffsets,
+ kSectionDexCacheArrays,
kSectionMetadata,
kSectionImageBitmap,
kSectionCount, // Number of elements in enum.
@@ -414,6 +422,16 @@ class PACKED(8) ImageHeader {
return blocks_count_;
}
+ // Helper for writing `data` and `bitmap_data` into `image_file`, following
+ // the information stored in this header and passed as arguments.
+ bool WriteData(const ImageFileGuard& image_file,
+ const uint8_t* data,
+ const uint8_t* bitmap_data,
+ ImageHeader::StorageMode image_storage_mode,
+ uint32_t max_image_block_size,
+ bool update_checksum,
+ std::string* error_msg);
+
private:
static const uint8_t kImageMagic[4];
static const uint8_t kImageVersion[4];
@@ -502,8 +520,66 @@ class PACKED(8) ImageHeader {
uint32_t blocks_count_ = 0u;
friend class linker::ImageWriter;
+ friend class RuntimeImageHelper;
};
+// Helper class that erases the image file if it isn't properly flushed and closed.
+class ImageFileGuard {
+ public:
+ ImageFileGuard() noexcept = default;
+ ImageFileGuard(ImageFileGuard&& other) noexcept = default;
+ ImageFileGuard& operator=(ImageFileGuard&& other) noexcept = default;
+
+ ~ImageFileGuard() {
+ if (image_file_ != nullptr) {
+ // Failure, erase the image file.
+ image_file_->Erase();
+ }
+ }
+
+ void reset(File* image_file) {
+ image_file_.reset(image_file);
+ }
+
+ bool operator==(std::nullptr_t) {
+ return image_file_ == nullptr;
+ }
+
+ bool operator!=(std::nullptr_t) {
+ return image_file_ != nullptr;
+ }
+
+ File* operator->() const {
+ return image_file_.get();
+ }
+
+ bool WriteHeaderAndClose(const std::string& image_filename,
+ const ImageHeader* image_header,
+ std::string* error_msg) {
+ // The header is uncompressed since it contains whether the image is compressed or not.
+ if (!image_file_->PwriteFully(image_header, sizeof(ImageHeader), 0)) {
+ *error_msg = "Failed to write image file header "
+ + image_filename + ": " + std::string(strerror(errno));
+ return false;
+ }
+
+ // FlushCloseOrErase() takes care of erasing, so the destructor does not need
+ // to do that whether the FlushCloseOrErase() succeeds or fails.
+ std::unique_ptr<File> image_file = std::move(image_file_);
+ if (image_file->FlushCloseOrErase() != 0) {
+ *error_msg = "Failed to flush and close image file "
+ + image_filename + ": " + std::string(strerror(errno));
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ std::unique_ptr<File> image_file_;
+};
+
+
/*
* This type holds the information necessary to fix up AppImage string
* references.
@@ -520,6 +596,14 @@ std::ostream& operator<<(std::ostream& os, ImageHeader::StorageMode mode);
std::ostream& operator<<(std::ostream& os, const ImageSection& section);
+// Wrapper over LZ4_decompress_safe() that checks if return value is negative. See b/242914915.
+bool LZ4_decompress_safe_checked(const char* source,
+ char* dest,
+ int compressed_size,
+ int max_decompressed_size,
+ /*out*/ size_t* decompressed_size_checked,
+ /*out*/ std::string* error_msg);
+
} // namespace art
#endif // ART_RUNTIME_IMAGE_H_