/*
 * Copyright (C) 2017 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 "common_runtime_test.h"

#include "base/memory_tool.h"
#include "class_linker-inl.h"
#include "class_root-inl.h"
#include "handle_scope-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-alloc-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/string.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "verification-inl.h"

namespace art {
namespace gc {

class VerificationTest : public CommonRuntimeTest {
 protected:
  VerificationTest() {
    use_boot_image_ = true;  // Make the Runtime creation cheaper.
  }

  template <class T>
  ObjPtr<mirror::ObjectArray<T>> AllocObjectArray(Thread* self, size_t length)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return mirror::ObjectArray<T>::Alloc(
        self,
        GetClassRoot<mirror::ObjectArray<mirror::Object>>(),
        length);
  }
};

TEST_F(VerificationTest, IsValidHeapObjectAddress) {
  ScopedObjectAccess soa(Thread::Current());
  const Verification* const v = Runtime::Current()->GetHeap()->GetVerification();
  EXPECT_FALSE(v->IsValidHeapObjectAddress(reinterpret_cast<const void*>(1)));
  EXPECT_FALSE(v->IsValidHeapObjectAddress(reinterpret_cast<const void*>(4)));
  EXPECT_FALSE(v->IsValidHeapObjectAddress(nullptr));
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::String> string(
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test")));
  EXPECT_TRUE(v->IsValidHeapObjectAddress(string.Get()));
  // Address in the heap that isn't aligned.
  const void* unaligned_address =
      reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(string.Get()) + 1);
  EXPECT_TRUE(v->IsAddressInHeapSpace(unaligned_address));
  EXPECT_FALSE(v->IsValidHeapObjectAddress(unaligned_address));
  EXPECT_TRUE(v->IsValidHeapObjectAddress(string->GetClass()));
  const uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass());
  // Not actually a valid object but the verification can't know that. Guaranteed to be inside a
  // heap space.
  EXPECT_TRUE(v->IsValidHeapObjectAddress(
      reinterpret_cast<const void*>(uint_klass + kObjectAlignment)));
  EXPECT_FALSE(v->IsValidHeapObjectAddress(
      reinterpret_cast<const void*>(&uint_klass)));
}

TEST_F(VerificationTest, IsValidClassOrNotInHeap) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::String> string(
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test")));
  const Verification* const v = Runtime::Current()->GetHeap()->GetVerification();
  EXPECT_FALSE(v->IsValidClass(reinterpret_cast<mirror::Class*>(1)));
  EXPECT_FALSE(v->IsValidClass(reinterpret_cast<mirror::Class*>(4)));
  EXPECT_FALSE(v->IsValidClass(nullptr));
  EXPECT_TRUE(v->IsValidClass(string->GetClass()));
  EXPECT_FALSE(v->IsValidClass(reinterpret_cast<mirror::Class*>(string.Get())));
}

TEST_F(VerificationTest, IsValidClassInHeap) {
  // Now that the String class is allocated in the non-moving space when the
  // runtime is running without a boot image (which is the case in this gtest),
  // and we run with AddressSanizer, it is possible that the (presumably
  // invalid) memory location `uint_klass - kObjectAlignment` tested below is
  // poisoned when running with AddressSanizer. Disable this test in that case.
  TEST_DISABLED_FOR_MEMORY_TOOL();
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::String> string(
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test")));
  const Verification* const v = Runtime::Current()->GetHeap()->GetVerification();
  uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass());
  EXPECT_FALSE(v->IsValidClass(reinterpret_cast<mirror::Class*>(uint_klass - kObjectAlignment)));
  EXPECT_FALSE(v->IsValidClass(reinterpret_cast<mirror::Class*>(&uint_klass)));
}

TEST_F(VerificationTest, DumpInvalidObjectInfo) {
  ScopedLogSeverity sls(LogSeverity::INFO);
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  VariableSizedHandleScope hs(soa.Self());
  const Verification* const v = runtime->GetHeap()->GetVerification();
  LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(1), "obj");
  LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(4), "obj");
  LOG(INFO) << v->DumpObjectInfo(nullptr, "obj");
}

TEST_F(VerificationTest, DumpValidObjectInfo) {
  // Now that the String class is allocated in the non-moving space when the
  // runtime is running without a boot image (which is the case in this gtest),
  // and we run with AddressSanizer, it is possible that the calls to
  // Verification::DumpObjectInfo below involving the String class object
  // (`string->GetClass()`, `uint_klass`, etc.) access poisoned memory when they
  // call Verification::DumpRAMAroundAddress. Disable this test in that case.
  TEST_DISABLED_FOR_MEMORY_TOOL();
  ScopedLogSeverity sls(LogSeverity::INFO);
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::String> string(
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "obj")));
  Handle<mirror::ObjectArray<mirror::Object>> arr(
      hs.NewHandle(AllocObjectArray<mirror::Object>(soa.Self(), 256)));
  const Verification* const v = runtime->GetHeap()->GetVerification();
  LOG(INFO) << v->DumpObjectInfo(string.Get(), "test");
  LOG(INFO) << v->DumpObjectInfo(string->GetClass(), "obj");
  const uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass());
  LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(uint_klass - kObjectAlignment),
                                 "obj");
  LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(&uint_klass), "obj");
  LOG(INFO) << v->DumpObjectInfo(arr.Get(), "arr");
}

TEST_F(VerificationTest, LogHeapCorruption) {
  // Now that the String class is allocated in the non-moving space when the
  // runtime is running without a boot image (which is the case in this gtest),
  // and we run with AddressSanizer, it is possible that the call to
  // Verification::LogHeapCorruption below involving the String class object
  // (`string->GetClass()`) accesses poisoned memory when it calls
  // Verification::DumpRAMAroundAddress. Disable this test in that case.
  TEST_DISABLED_FOR_MEMORY_TOOL();
  ScopedLogSeverity sls(LogSeverity::INFO);
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::String> string(
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "obj")));
  using ObjArray = mirror::ObjectArray<mirror::Object>;
  Handle<ObjArray> arr(
      hs.NewHandle(AllocObjectArray<mirror::Object>(soa.Self(), 256)));
  const Verification* const v = runtime->GetHeap()->GetVerification();
  arr->Set(0, string.Get());
  // Test normal cases.
  v->LogHeapCorruption(arr.Get(), ObjArray::DataOffset(kHeapReferenceSize), string.Get(), false);
  v->LogHeapCorruption(string.Get(), mirror::Object::ClassOffset(), string->GetClass(), false);
  // Test null holder cases.
  v->LogHeapCorruption(nullptr, MemberOffset(0), string.Get(), false);
  v->LogHeapCorruption(nullptr, MemberOffset(0), arr.Get(), false);
}

TEST_F(VerificationTest, FindPathFromRootSet) {
  ScopedLogSeverity sls(LogSeverity::INFO);
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::ObjectArray<mirror::Object>> arr(
      hs.NewHandle(AllocObjectArray<mirror::Object>(soa.Self(), 256)));
  ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(soa.Self(), "obj");
  arr->Set(0, str);
  const Verification* const v = runtime->GetHeap()->GetVerification();
  std::string path = v->FirstPathFromRootSet(str);
  EXPECT_GT(path.length(), 0u);
  std::ostringstream oss;
  oss << arr.Get();
  EXPECT_NE(path.find(oss.str()), std::string::npos);
  LOG(INFO) << path;
}

}  // namespace gc
}  // namespace art
