/*
 * 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_SRC_IMAGE_H_
#define ART_SRC_IMAGE_H_

#include <string.h>

#include "globals.h"
#include "object.h"

namespace art {

// header of image files written by ImageWriter, read and validated by Space.
class PACKED ImageHeader {
 public:
  ImageHeader() {}

  ImageHeader(uint32_t image_begin,
              uint32_t image_roots,
              uint32_t oat_checksum,
              uint32_t oat_begin,
              uint32_t oat_end)
      : image_begin_(image_begin),
        oat_checksum_(oat_checksum),
        oat_begin_(oat_begin),
        oat_end_(oat_end),
        image_roots_(image_roots) {
    CHECK_EQ(image_begin, RoundUp(image_begin, kPageSize));
    CHECK_EQ(oat_begin, RoundUp(oat_begin, kPageSize));
    CHECK_LT(image_begin, image_roots);
    CHECK_LT(image_roots, oat_begin);
    CHECK_LT(oat_begin, oat_end);
    memcpy(magic_, kImageMagic, sizeof(kImageMagic));
    memcpy(version_, kImageVersion, sizeof(kImageVersion));
  }

  bool IsValid() const {
    if (memcmp(magic_, kImageMagic, sizeof(kImageMagic) != 0)) {
      return false;
    }
    if (memcmp(version_, kImageVersion, sizeof(kImageVersion) != 0)) {
      return false;
    }
    return true;
  }

  const char* GetMagic() const {
    CHECK(IsValid());
    return reinterpret_cast<const char*>(magic_);
  }

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

  uint32_t GetOatChecksum() const {
    return oat_checksum_;
  }

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

  byte* GetOatBegin() const {
    return reinterpret_cast<byte*>(oat_begin_);
  }

  byte* GetOatEnd() const {
    return reinterpret_cast<byte*>(oat_end_);
  }

  enum ImageRoot {
    kJniStubArray,
    kAbstractMethodErrorStubArray,
    kStaticResolutionStubArray,
    kUnknownMethodResolutionStubArray,
    kResolutionMethod,
    kCalleeSaveMethod,
    kRefsOnlySaveMethod,
    kRefsAndArgsSaveMethod,
    kOatLocation,
    kDexCaches,
    kClassRoots,
    kImageRootsMax,
  };

  Object* GetImageRoot(ImageRoot image_root) const
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    return GetImageRoots()->Get(image_root);
  }

 private:
  ObjectArray<Object>* GetImageRoots() const {
    return reinterpret_cast<ObjectArray<Object>*>(image_roots_);
  }

  static const byte kImageMagic[4];
  static const byte kImageVersion[4];

  byte magic_[4];
  byte version_[4];

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

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

  // required oat address expected by image Method::GetCode() pointers.
  uint32_t oat_begin_;

  // end of oat address range for this image file, used for positioning a following image
  uint32_t oat_end_;

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

  friend class ImageWriter;
  friend class ImageDumper;  // For GetImageRoots()
};

}  // namespace art

#endif  // ART_SRC_IMAGE_H_
