/*
 * Copyright (C) 2018 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 <atomic>
#include <memory>

#include <jni.h>
#include <signal.h>
#include <stdint.h>
#include <sys/mman.h>

#include "base/globals.h"
#include "base/mem_map.h"
#include "fault_handler.h"

namespace art {

class TestFaultHandler final : public FaultHandler {
 public:
  explicit TestFaultHandler(FaultManager* manager)
      : FaultHandler(manager),
        map_error_(),
        target_map_(MemMap::MapAnonymous("test-305-mmap",
                                         /* addr */ nullptr,
                                         /* byte_count */ MemMap::GetPageSize(),
                                         /* prot */ PROT_NONE,
                                         /* low_4gb */ false,
                                         /* reuse */ false,
                                         /* reservation */ nullptr,
                                         /* error_msg */ &map_error_,
                                         /* use_ashmem */ false)),
        was_hit_(false) {
    CHECK(target_map_.IsValid()) << "Unable to create segfault target address " << map_error_;
    manager_->AddHandler(this, /*in_generated_code*/false);
  }

  virtual ~TestFaultHandler() {
    manager_->RemoveHandler(this);
  }

  bool Action(int sig, siginfo_t* siginfo, [[maybe_unused]] void* context) override {
    CHECK_EQ(sig, SIGSEGV);
    CHECK_EQ(reinterpret_cast<uint32_t*>(siginfo->si_addr),
             GetTargetPointer()) << "Segfault on unexpected address!";
    CHECK(!was_hit_) << "Recursive signal!";
    was_hit_ = true;

    LOG(INFO) << "SEGV Caught. mprotecting map.";
    CHECK(target_map_.Protect(PROT_READ | PROT_WRITE)) << "Failed to mprotect R/W";
    LOG(INFO) << "Setting value to be read.";
    *GetTargetPointer() = kDataValue;
    LOG(INFO) << "Changing prot to be read-only.";
    CHECK(target_map_.Protect(PROT_READ)) << "Failed to mprotect R-only";
    return true;
  }

  void CauseSegfault() {
    CHECK_EQ(target_map_.GetProtect(), PROT_NONE);

    // This will segfault. The handler should deal with it though and we will get a value out of it.
    uint32_t data = *GetTargetPointer();

    // Prevent re-ordering around the *GetTargetPointer by the compiler
    std::atomic_signal_fence(std::memory_order_seq_cst);

    CHECK(was_hit_);
    CHECK_EQ(data, kDataValue) << "Unexpected read value from mmap";
    CHECK_EQ(target_map_.GetProtect(), PROT_READ);
    LOG(INFO) << "Success!";
  }

 private:
  uint32_t* GetTargetPointer() {
    return reinterpret_cast<uint32_t*>(target_map_.Begin() + 8);
  }

  static constexpr uint32_t kDataValue = 0xDEADBEEF;

  std::string map_error_;
  MemMap target_map_;
  bool was_hit_;
};

extern "C" JNIEXPORT void JNICALL Java_Main_runFaultHandlerTest(JNIEnv*, jclass) {
  std::unique_ptr<TestFaultHandler> handler(new TestFaultHandler(&fault_manager));
  handler->CauseSegfault();
}

}  // namespace art
