/*
 * 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/mem_map.h"
#include "fault_handler.h"
#include "globals.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 */ kPageSize,
                                         /* prot */ PROT_NONE,
                                         /* low_4gb */ false,
                                         /* reuse */ false,
                                         /* error_msg */ &map_error_,
                                         /* use_ashmem */ false)),
        was_hit_(false) {
    CHECK(target_map_ != nullptr) << "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, void* context ATTRIBUTE_UNUSED) 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_;
  std::unique_ptr<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
