/*
 * 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.
 */

#include <string.h>
#include <vector>

#include "image_test.h"

#include "image.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"

namespace art {
namespace linker {

TEST_F(ImageTest, TestImageLayout) {
  std::vector<size_t> image_sizes;
  std::vector<size_t> image_sizes_extra;
  // Compile multi-image with ImageLayoutA being the last image.
  {
    CompilationHelper helper;
    Compile(ImageHeader::kStorageModeUncompressed,
            /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
            helper,
            "ImageLayoutA",
            {"LMyClass;"});
    image_sizes = helper.GetImageObjectSectionSizes();
  }
  TearDown();
  runtime_.reset();
  SetUp();
  // Compile multi-image with ImageLayoutB being the last image.
  {
    CompilationHelper helper;
    Compile(ImageHeader::kStorageModeUncompressed,
            /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
            helper,
            "ImageLayoutB",
            {"LMyClass;"});
    image_sizes_extra = helper.GetImageObjectSectionSizes();
  }
  // Make sure that the new stuff in the clinit in ImageLayoutB is in the last image and not in the
  // first two images.
  ASSERT_EQ(image_sizes.size(), image_sizes.size());
  // Sizes of the object sections should be the same for all but the last image.
  for (size_t i = 0; i < image_sizes.size() - 1; ++i) {
    EXPECT_EQ(image_sizes[i], image_sizes_extra[i]);
  }
  // Last image should be larger since it has a hash map and a string.
  EXPECT_LT(image_sizes.back(), image_sizes_extra.back());
}

TEST_F(ImageTest, ImageHeaderIsValid) {
  uint32_t image_begin = ART_BASE_ADDRESS;
  uint32_t image_size_ = kElfSegmentAlignment;
  uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB);
  uint32_t oat_checksum = 0;
  uint32_t oat_file_begin = ART_BASE_ADDRESS + (kElfSegmentAlignment);
  uint32_t oat_data_begin = ART_BASE_ADDRESS + (2 * kElfSegmentAlignment);
  uint32_t oat_data_end = ART_BASE_ADDRESS + (2 * kElfSegmentAlignment + 1 * KB);
  uint32_t oat_file_end = ART_BASE_ADDRESS + (2 * kElfSegmentAlignment + 2 * KB);
  ImageSection sections[ImageHeader::kSectionCount];
  uint32_t image_reservation_size = RoundUp(oat_file_end - image_begin, kElfSegmentAlignment);
  ImageHeader image_header(image_reservation_size,
                           /*component_count=*/ 1u,
                           image_begin,
                           image_size_,
                           sections,
                           image_roots,
                           oat_checksum,
                           oat_file_begin,
                           oat_data_begin,
                           oat_data_end,
                           oat_file_end,
                           /*boot_image_begin=*/ 0u,
                           /*boot_image_size=*/ 0u,
                           /*boot_image_component_count=*/ 0u,
                           /*boot_image_checksum=*/ 0u,
                           sizeof(void*));

  ASSERT_TRUE(image_header.IsValid());

  // Please note that for the following condition to be true, the above values should be chosen in
  // a way that image_reservation_size != RoundUp(image_size_, kElfSegmentAlignment).
  ASSERT_TRUE(!image_header.IsAppImage());

  char* magic = const_cast<char*>(image_header.GetMagic());
  strcpy(magic, "");  // bad magic
  ASSERT_FALSE(image_header.IsValid());
  strcpy(magic, "art\n000");  // bad version
  ASSERT_FALSE(image_header.IsValid());
}

// Test that pointer to quick code is the same in
// a default method of an interface and in a copied method
// of a class which implements the interface. This should be true
// only if the copied method and the origin method are located in the
// same oat file.
TEST_F(ImageTest, TestDefaultMethods) {
  TEST_DISABLED_FOR_RISCV64();
  CompilationHelper helper;
  Compile(ImageHeader::kStorageModeUncompressed,
          /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
          helper,
          "DefaultMethods",
          {"LIface;", "LImpl;", "LIterableBase;"});

  PointerSize pointer_size = class_linker_->GetImagePointerSize();
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  // Test the pointer to quick code is the same in origin method
  // and in the copied method form the same oat file.
  ObjPtr<mirror::Class> iface_klass =
      class_linker_->LookupClass(self, "LIface;", /*class_loader=*/ nullptr);
  ASSERT_NE(nullptr, iface_klass);
  ArtMethod* origin = iface_klass->FindInterfaceMethod("defaultMethod", "()V", pointer_size);
  ASSERT_NE(nullptr, origin);
  ASSERT_OBJ_PTR_EQ(origin->GetDeclaringClass(), iface_klass);
  const void* code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
  // The origin method should have a pointer to quick code
  ASSERT_NE(nullptr, code);
  ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code));
  ObjPtr<mirror::Class> impl_klass =
      class_linker_->LookupClass(self, "LImpl;", /*class_loader=*/ nullptr);
  ASSERT_NE(nullptr, impl_klass);
  ArtMethod* copied = FindCopiedMethod(origin, impl_klass);
  ASSERT_NE(nullptr, copied);
  // the copied method should have pointer to the same quick code as the origin method
  ASSERT_EQ(code, copied->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size));

  // Test the origin method has pointer to quick code
  // but the copied method has pointer to interpreter
  // because these methods are in different oat files.
  ObjPtr<mirror::Class> iterable_klass =
      class_linker_->LookupClass(self, "Ljava/lang/Iterable;", /*class_loader=*/ nullptr);
  ASSERT_NE(nullptr, iterable_klass);
  origin = iterable_klass->FindClassMethod(
      "forEach", "(Ljava/util/function/Consumer;)V", pointer_size);
  ASSERT_NE(nullptr, origin);
  ASSERT_FALSE(origin->IsDirect());
  ASSERT_OBJ_PTR_EQ(origin->GetDeclaringClass(), iterable_klass);
  code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
  // the origin method should have a pointer to quick code
  ASSERT_NE(nullptr, code);
  ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code));
  ObjPtr<mirror::Class> iterablebase_klass =
      class_linker_->LookupClass(self, "LIterableBase;", /*class_loader=*/ nullptr);
  ASSERT_NE(nullptr, iterablebase_klass);
  copied = FindCopiedMethod(origin, iterablebase_klass);
  ASSERT_NE(nullptr, copied);
  code = copied->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
  // the copied method should have a pointer to interpreter
  ASSERT_TRUE(class_linker_->IsQuickToInterpreterBridge(code));
}

// Regression test for dex2oat crash for soft verification failure during
// class initialization check from the transactional interpreter while
// running the class initializer for another class.
TEST_F(ImageTest, TestSoftVerificationFailureDuringClassInitialization) {
  CompilationHelper helper;
  Compile(ImageHeader::kStorageModeUncompressed,
          /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
          helper,
          "VerifySoftFailDuringClinit",
          /*image_classes=*/ {"LClassToInitialize;"},
          /*image_classes_failing_aot_clinit=*/ {"LClassToInitialize;"});
}

TEST_F(ImageTest, TestImageClassWithArrayClassWithUnresolvedComponent) {
  CompilationHelper helper;
  Compile(ImageHeader::kStorageModeUncompressed,
          /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
          helper,
          "ArrayClassWithUnresolvedComponent",
          /*image_classes=*/ {"LClassWithStatic;",
                              "LClassWithStaticConst;",
                              "[LClassWithMissingInterface;",
                              "[[LClassWithMissingInterface;",
                              "[LClassWithMissingSuper",
                              "[[LClassWithMissingSuper"},
          /*image_classes_failing_aot_clinit=*/ {
                              "LClassWithStatic;",
                              "LClassWithStaticConst;"},
          /*image_classes_failing_resolution=*/ {
                              "[LClassWithMissingInterface;",
                              "[[LClassWithMissingInterface;",
                              "[LClassWithMissingSuper",
                              "[[LClassWithMissingSuper"});
}

TEST_F(ImageTest, TestSuperWithAccessChecks) {
  CompilationHelper helper;
  Compile(ImageHeader::kStorageModeUncompressed,
          /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
          helper,
          "SuperWithAccessChecks",
          /*image_classes=*/ {"LSubClass;", "LImplementsClass;"},
          /*image_classes_failing_aot_clinit=*/ {"LSubClass;", "LImplementsClass;"});
}

// Regression test for b/297453985, where we used to generate a bogus image
// checksum.
TEST_F(ImageTest, ImageChecksum) {
  uint32_t image_begin = ART_BASE_ADDRESS;
  uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB);
  ImageSection sections[ImageHeader::kSectionCount];
  // We require bitmap section to be at least kElfSegmentAlignment.
  sections[ImageHeader::kSectionImageBitmap] = ImageSection(0, kElfSegmentAlignment);
  ImageHeader image_header(/*image_reservation_size=*/ kElfSegmentAlignment,
                           /*component_count=*/ 1u,
                           image_begin,
                           /*image_size=*/ sizeof(ImageHeader),
                           sections,
                           image_roots,
                           /*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_image_component_count=*/ 0u,
                           /*boot_image_checksum=*/ 0u,
                           sizeof(void*));
    ASSERT_TRUE(image_header.IsValid());

    std::string error_msg;
    ImageFileGuard image_file;
    ScratchFile location;
    image_file.reset(OS::CreateEmptyFile(location.GetFilename().c_str()));
    const uint8_t* data = reinterpret_cast<const uint8_t*>(&image_header);
    std::unique_ptr<uint8_t> bitmap(new uint8_t[kElfSegmentAlignment]);
    memset(bitmap.get(), 0, kElfSegmentAlignment);
    ASSERT_EQ(image_header.GetImageChecksum(), 0u);
    ASSERT_TRUE(image_header.WriteData(
        image_file,
        data,
        bitmap.get(),
        ImageHeader::kStorageModeUncompressed,
        /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
        /*update_checksum=*/ true,
        &error_msg)) << error_msg;

    uint32_t first_checksum = image_header.GetImageChecksum();
    // Reset the image checksum, `WriteData` updated it.
    image_header.SetImageChecksum(0u);

    // Change the header to ensure the checksum will be different.
    image_header.SetOatChecksum(0xFFFF);

    ASSERT_TRUE(image_header.WriteData(
        image_file,
        data,
        bitmap.get(),
        ImageHeader::kStorageModeUncompressed,
        /*max_image_block_size=*/std::numeric_limits<uint32_t>::max(),
        /*update_checksum=*/ true,
        &error_msg)) << error_msg;

    ASSERT_NE(first_checksum, image_header.GetImageChecksum());
}

}  // namespace linker
}  // namespace art
