/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_IMAGE_H_
#define ART_RUNTIME_IMAGE_H_

#include <string.h>

#include "base/bit_utils.h"
#include "base/enums.h"
#include "globals.h"
#include "mirror/object.h"

namespace art {

class ArtField;
class ArtMethod;

namespace linker {
class ImageWriter;
}  // namespace linker

class ObjectVisitor {
 public:
  virtual ~ObjectVisitor() {}

  virtual void Visit(mirror::Object* object) = 0;
};

class ArtMethodVisitor {
 public:
  virtual ~ArtMethodVisitor() {}

  virtual void Visit(ArtMethod* method) = 0;
};

class ArtFieldVisitor {
 public:
  virtual ~ArtFieldVisitor() {}

  virtual void Visit(ArtField* method) = 0;
};

class PACKED(4) ImageSection {
 public:
  ImageSection() : offset_(0), size_(0) { }
  ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
  ImageSection(const ImageSection& section) = default;
  ImageSection& operator=(const ImageSection& section) = default;

  uint32_t Offset() const {
    return offset_;
  }

  uint32_t Size() const {
    return size_;
  }

  uint32_t End() const {
    return Offset() + Size();
  }

  bool Contains(uint64_t offset) const {
    return offset - offset_ < size_;
  }

 private:
  uint32_t offset_;
  uint32_t size_;
};

// header of image files written by ImageWriter, read and validated by Space.
class PACKED(4) ImageHeader {
 public:
  enum StorageMode : uint32_t {
    kStorageModeUncompressed,
    kStorageModeLZ4,
    kStorageModeLZ4HC,
    kStorageModeCount,  // Number of elements in enum.
  };
  static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;

  ImageHeader()
      : image_begin_(0U),
        image_size_(0U),
        oat_checksum_(0U),
        oat_file_begin_(0U),
        oat_data_begin_(0U),
        oat_data_end_(0U),
        oat_file_end_(0U),
        boot_image_begin_(0U),
        boot_image_size_(0U),
        boot_oat_begin_(0U),
        boot_oat_size_(0U),
        patch_delta_(0),
        image_roots_(0U),
        pointer_size_(0U),
        compile_pic_(0),
        is_pic_(0),
        storage_mode_(kDefaultStorageMode),
        data_size_(0) {}

  ImageHeader(uint32_t image_begin,
              uint32_t image_size,
              ImageSection* sections,
              uint32_t image_roots,
              uint32_t oat_checksum,
              uint32_t oat_file_begin,
              uint32_t oat_data_begin,
              uint32_t oat_data_end,
              uint32_t oat_file_end,
              uint32_t boot_image_begin,
              uint32_t boot_image_size,
              uint32_t boot_oat_begin,
              uint32_t boot_oat_size,
              uint32_t pointer_size,
              bool compile_pic,
              bool is_pic,
              StorageMode storage_mode,
              size_t data_size);

  bool IsValid() const;
  const char* GetMagic() const;

  uint8_t* GetImageBegin() const {
    return reinterpret_cast<uint8_t*>(image_begin_);
  }

  size_t GetImageSize() const {
    return static_cast<uint32_t>(image_size_);
  }

  uint32_t GetOatChecksum() const {
    return oat_checksum_;
  }

  void SetOatChecksum(uint32_t oat_checksum) {
    oat_checksum_ = oat_checksum;
  }

  // The location that the oat file was expected to be when the image was created. The actual
  // oat file may be at a different location for application images.
  uint8_t* GetOatFileBegin() const {
    return reinterpret_cast<uint8_t*>(oat_file_begin_);
  }

  uint8_t* GetOatDataBegin() const {
    return reinterpret_cast<uint8_t*>(oat_data_begin_);
  }

  uint8_t* GetOatDataEnd() const {
    return reinterpret_cast<uint8_t*>(oat_data_end_);
  }

  uint8_t* GetOatFileEnd() const {
    return reinterpret_cast<uint8_t*>(oat_file_end_);
  }

  PointerSize GetPointerSize() const;

  uint32_t GetPointerSizeUnchecked() const {
    return pointer_size_;
  }

  off_t GetPatchDelta() const {
    return patch_delta_;
  }

  static std::string GetOatLocationFromImageLocation(const std::string& image) {
    return GetLocationFromImageLocation(image, "oat");
  }

  static std::string GetVdexLocationFromImageLocation(const std::string& image) {
    return GetLocationFromImageLocation(image, "vdex");
  }

  enum ImageMethod {
    kResolutionMethod,
    kImtConflictMethod,
    kImtUnimplementedMethod,
    kSaveAllCalleeSavesMethod,
    kSaveRefsOnlyMethod,
    kSaveRefsAndArgsMethod,
    kSaveEverythingMethod,
    kSaveEverythingMethodForClinit,
    kSaveEverythingMethodForSuspendCheck,
    kImageMethodsCount,  // Number of elements in enum.
  };

  enum ImageRoot {
    kDexCaches,
    kClassRoots,
    kClassLoader,  // App image only.
    kImageRootsMax,
  };

  enum ImageSections {
    kSectionObjects,
    kSectionArtFields,
    kSectionArtMethods,
    kSectionRuntimeMethods,
    kSectionImTables,
    kSectionIMTConflictTables,
    kSectionDexCacheArrays,
    kSectionInternedStrings,
    kSectionClassTable,
    kSectionImageBitmap,
    kSectionCount,  // Number of elements in enum.
  };

  static size_t NumberOfImageRoots(bool app_image) {
    return app_image ? kImageRootsMax : kImageRootsMax - 1u;
  }

  ArtMethod* GetImageMethod(ImageMethod index) const;
  void SetImageMethod(ImageMethod index, ArtMethod* method);

  const ImageSection& GetImageSection(ImageSections index) const {
    DCHECK_LT(static_cast<size_t>(index), kSectionCount);
    return sections_[index];
  }

  const ImageSection& GetObjectsSection() const {
    return GetImageSection(kSectionObjects);
  }

  const ImageSection& GetFieldsSection() const {
    return GetImageSection(ImageHeader::kSectionArtFields);
  }

  const ImageSection& GetMethodsSection() const {
    return GetImageSection(kSectionArtMethods);
  }

  const ImageSection& GetRuntimeMethodsSection() const {
    return GetImageSection(kSectionRuntimeMethods);
  }

  const ImageSection& GetImTablesSection() const {
    return GetImageSection(kSectionImTables);
  }

  const ImageSection& GetIMTConflictTablesSection() const {
    return GetImageSection(kSectionIMTConflictTables);
  }

  const ImageSection& GetDexCacheArraysSection() const {
    return GetImageSection(kSectionDexCacheArrays);
  }

  const ImageSection& GetInternedStringsSection() const {
    return GetImageSection(kSectionInternedStrings);
  }

  const ImageSection& GetClassTableSection() const {
    return GetImageSection(kSectionClassTable);
  }

  const ImageSection& GetImageBitmapSection() const {
    return GetImageSection(kSectionImageBitmap);
  }

  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
  mirror::Object* GetImageRoot(ImageRoot image_root) const
      REQUIRES_SHARED(Locks::mutator_lock_);

  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
  mirror::ObjectArray<mirror::Object>* GetImageRoots() const
      REQUIRES_SHARED(Locks::mutator_lock_);

  void RelocateImage(off_t delta);
  void RelocateImageMethods(off_t delta);
  void RelocateImageObjects(off_t delta);

  bool CompilePic() const {
    return compile_pic_ != 0;
  }

  bool IsPic() const {
    return is_pic_ != 0;
  }

  uint32_t GetBootImageBegin() const {
    return boot_image_begin_;
  }

  uint32_t GetBootImageSize() const {
    return boot_image_size_;
  }

  uint32_t GetBootOatBegin() const {
    return boot_oat_begin_;
  }

  uint32_t GetBootOatSize() const {
    return boot_oat_size_;
  }

  StorageMode GetStorageMode() const {
    return storage_mode_;
  }

  uint64_t GetDataSize() const {
    return data_size_;
  }

  bool IsAppImage() const {
    // App images currently require a boot image, if the size is non zero then it is an app image
    // header.
    return boot_image_size_ != 0u;
  }

  uint32_t GetBootImageConstantTablesOffset() const {
    // Interned strings table and class table for boot image are mmapped read only.
    DCHECK(!IsAppImage());
    const ImageSection& interned_strings = GetInternedStringsSection();
    DCHECK_ALIGNED(interned_strings.Offset(), kPageSize);
    return interned_strings.Offset();
  }

  uint32_t GetBootImageConstantTablesSize() const {
    uint32_t start_offset = GetBootImageConstantTablesOffset();
    const ImageSection& class_table = GetClassTableSection();
    DCHECK_LE(start_offset, class_table.Offset());
    size_t tables_size = class_table.Offset() + class_table.Size() - start_offset;
    return RoundUp(tables_size, kPageSize);
  }

  // Visit mirror::Objects in the section starting at base.
  // TODO: Delete base parameter if it is always equal to GetImageBegin.
  void VisitObjects(ObjectVisitor* visitor,
                    uint8_t* base,
                    PointerSize pointer_size) const
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Visit ArtMethods in the section starting at base. Includes runtime methods.
  // TODO: Delete base parameter if it is always equal to GetImageBegin.
  void VisitPackedArtMethods(ArtMethodVisitor* visitor,
                             uint8_t* base,
                             PointerSize pointer_size) const;

  // Visit ArtMethods in the section starting at base.
  // TODO: Delete base parameter if it is always equal to GetImageBegin.
  void VisitPackedArtFields(ArtFieldVisitor* visitor, uint8_t* base) const;

  template <typename Visitor>
  void VisitPackedImTables(const Visitor& visitor,
                           uint8_t* base,
                           PointerSize pointer_size) const;

  template <typename Visitor>
  void VisitPackedImtConflictTables(const Visitor& visitor,
                                    uint8_t* base,
                                    PointerSize pointer_size) const;

 private:
  static const uint8_t kImageMagic[4];
  static const uint8_t kImageVersion[4];

  static std::string GetLocationFromImageLocation(const std::string& image,
                                                  const std::string& extension) {
    std::string filename = image;
    if (filename.length() <= 3) {
      filename += "." + extension;
    } else {
      filename.replace(filename.length() - 3, 3, extension);
    }
    return filename;
  }

  uint8_t magic_[4];
  uint8_t version_[4];

  // Required base address for mapping the image.
  uint32_t image_begin_;

  // Image size, not page aligned.
  uint32_t image_size_;

  // Checksum of the oat file we link to for load time sanity check.
  uint32_t oat_checksum_;

  // Start address for oat file. Will be before oat_data_begin_ for .so files.
  uint32_t oat_file_begin_;

  // Required oat address expected by image Method::GetCode() pointers.
  uint32_t oat_data_begin_;

  // End of oat data address range for this image file.
  uint32_t oat_data_end_;

  // End of oat file address range. will be after oat_data_end_ for
  // .so files. Used for positioning a following alloc spaces.
  uint32_t oat_file_end_;

  // Boot image begin and end (app image headers only).
  uint32_t boot_image_begin_;
  uint32_t boot_image_size_;

  // Boot oat begin and end (app image headers only).
  uint32_t boot_oat_begin_;
  uint32_t boot_oat_size_;

  // TODO: We should probably insert a boot image checksum for app images.

  // The total delta that this image has been patched.
  int32_t patch_delta_;

  // Absolute address of an Object[] of objects needed to reinitialize from an image.
  uint32_t image_roots_;

  // Pointer size, this affects the size of the ArtMethods.
  uint32_t pointer_size_;

  // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
  const uint32_t compile_pic_;

  // Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
  // the .art file. Currently, app oat files do not depend on their app image. There are no pointers
  // from the app oat code to the app image.
  const uint32_t is_pic_;

  // Image section sizes/offsets correspond to the uncompressed form.
  ImageSection sections_[kSectionCount];

  // Image methods, may be inside of the boot image for app images.
  uint64_t image_methods_[kImageMethodsCount];

  // Storage method for the image, the image may be compressed.
  StorageMode storage_mode_;

  // Data size for the image data excluding the bitmap and the header. For compressed images, this
  // is the compressed size in the file.
  uint32_t data_size_;

  friend class linker::ImageWriter;
};

std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& policy);
std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& policy);
std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section);
std::ostream& operator<<(std::ostream& os, const ImageSection& section);
std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode);

}  // namespace art

#endif  // ART_RUNTIME_IMAGE_H_
