/*
 * Copyright (C) 2015 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.
 */

#pragma once

#include <errno.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
#include <sys/user.h>

#include <async_safe/log.h>

#include "platform/bionic/macros.h"
#include "platform/bionic/page.h"

template <typename T>
union WriteProtectedContents {
  T value;
  char padding[max_android_page_size()];

  WriteProtectedContents() = default;
  BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
} __attribute__((aligned(max_android_page_size())));

// Write protected wrapper class that aligns its contents to a page boundary,
// and sets the memory protection to be non-writable, except when being modified
// explicitly.
template <typename T>
class WriteProtected {
 public:
  static_assert(sizeof(T) < max_android_page_size(),
                "WriteProtected only supports contents up to max_android_page_size()");

  WriteProtected() = default;
  BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);

  void initialize() {
    // Not strictly necessary, but this will hopefully segfault if we initialize
    // multiple times by accident.
    memset(contents_addr(), 0, sizeof(contents));
    set_protection(PROT_READ);
  }

  const T* operator->() {
    return &contents_addr()->value;
  }

  const T& operator*() {
    return contents_addr()->value;
  }

  template <typename Mutator>
  void mutate(Mutator mutator) {
    set_protection(PROT_READ | PROT_WRITE);
    mutator(&contents_addr()->value);
    set_protection(PROT_READ);
  }

 private:
  WriteProtectedContents<T> contents;

  WriteProtectedContents<T>* contents_addr() {
    auto addr = &contents;
    // Hide the fact that we're returning the address of contents from the compiler.
    // Otherwise it may generate code assuming alignment of 64KB even though the
    // variable is only guaranteed to have 4KB alignment.
    __asm__ __volatile__("" : "+r"(addr));
    return addr;
  }

  void set_protection(int prot) {
    auto addr = contents_addr();
#if __has_feature(hwaddress_sanitizer)
    // The mprotect system call does not currently untag pointers, so do it
    // ourselves.
    addr = untag_address(addr);
#endif
    if (mprotect(reinterpret_cast<void*>(addr), max_android_page_size(), prot) == -1) {
      async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
    }
  }
};
