/*
 * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_MEMORY_GUARDEDMEMORY_HPP
#define SHARE_MEMORY_GUARDEDMEMORY_HPP

#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"

/**
 * Guarded memory for detecting buffer overrun.
 *
 * Allows allocations to be wrapped with padded bytes of a known byte pattern,
 * that is a "guard". Guard patterns may be verified to detect buffer overruns.
 *
 * Primarily used by "debug malloc" and "checked JNI".
 *
 * Memory layout:
 *
 * |Offset             | Content              | Description    |
 * |------------------------------------------------------------
 * |base_addr          | 0xABABABABABABABAB   | Head guard     |
 * |+GUARD_SIZE        | <size_t:user_size>   | User data size |
 * |+sizeof(size_t)    | <tag>                | Tag word       |
 * |+sizeof(void*)     | <tag2>               | Tag word       |
 * |+sizeof(void*)     | <pad bytes>          | Padding        |
 * |+sizeof(void*)     | 0xF1 <user_data> (   | User data      |
 * |+user_size         | 0xABABABABABABABAB   | Tail guard     |
 * -------------------------------------------------------------
 *
 * Where:
 *  - guard padding uses "badResourceValue" (0xAB)
 *  - tag word and tag2 word are general purpose
 *  - padding is inserted as-needed by the compiler to ensure
 *    the user data is aligned on a 16-byte boundary
 *  - user data
 *    -- initially padded with "uninitBlockPad" (0xF1),
 *    -- to "freeBlockPad" (0xBA), when freed
 *
 * Usage:
 *
 * * Allocations: one may wrap allocations with guard memory:
 * <code>
 *   Thing* alloc_thing() {
 *     void* mem = user_alloc_fn(GuardedMemory::get_total_size(sizeof(thing)));
 *     GuardedMemory guarded(mem, sizeof(thing));
 *     return (Thing*) guarded.get_user_ptr();
 *   }
 * </code>
 * * Verify: memory guards are still in tact
 * <code>
 *   bool verify_thing(Thing* thing) {
 *     GuardedMemory guarded((void*)thing);
 *     return guarded.verify_guards();
 *   }
 * </code>
 * * Free: one may mark bytes as freed (further debugging support)
 * <code>
 *   void free_thing(Thing* thing) {
 *    GuardedMemory guarded((void*)thing);
 *    assert(guarded.verify_guards(), "Corrupt thing");
 *    user_free_fn(guards.release_for_freeing();
 *   }
 * </code>
 */
class GuardedMemory : StackObj { // Wrapper on stack

  friend class GuardedMemoryTest;
  // Private inner classes for memory layout...

protected:

  /**
   * Guard class for header and trailer known pattern to test for overwrites.
   */
  class Guard { // Class for raw memory (no vtbl allowed)
    friend class GuardedMemory;
   protected:
    enum {
      GUARD_SIZE = 16
    };

    u_char _guard[GUARD_SIZE];

   public:

    void build() {
      u_char* c = _guard; // Possibly unaligned if tail guard
      u_char* end = c + GUARD_SIZE;
      while (c < end) {
        *c = badResourceValue;
        c++;
      }
    }

    bool verify() const {
      // We may not be able to dereference directly.
      if (!os::is_readable_range((const void*) _guard, (const void*) (_guard + GUARD_SIZE))) {
        return false;
      }
      u_char* c = (u_char*) _guard;
      u_char* end = c + GUARD_SIZE;
      while (c < end) {
        if (*c != badResourceValue) {
          return false;
        }
        c++;
      }
      return true;
    }

  }; // GuardedMemory::Guard

  /**
   * Header guard and size
   *
   * NB: the size and placement of the GuardHeader must be such that the
   * user-ptr is maximally aligned i.e. 16-byte alignment for x86 ABI for
   * stack alignment and use of vector (xmm) instructions. We use alignas
   * to achieve this.
   */
  class alignas(16) GuardHeader : Guard {
    friend class GuardedMemory;
   protected:
    union {
      uintptr_t __unused_full_word1;
      size_t _user_size;
    };
    void* _tag;
    void* _tag2;
   public:
    void set_user_size(const size_t usz) { _user_size = usz; }
    size_t get_user_size() const { return _user_size; }

    void set_tag(const void* tag) { _tag = (void*) tag; }
    void* get_tag() const { return _tag; }

    void set_tag2(const void* tag2) { _tag2 = (void*) tag2; }
    void* get_tag2() const { return _tag2; }
  }; // GuardedMemory::GuardHeader

  // Guarded Memory...

 protected:
  u_char* _base_addr;

 public:

  /**
   * Create new guarded memory.
   *
   * Wraps, starting at the given "base_ptr" with guards. Use "get_user_ptr()"
   * to return a pointer suitable for user data.
   *
   * @param base_ptr  allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
   * @param user_size the size of the user data to be wrapped.
   * @param tag       optional general purpose tag.
   * @param tag2      optional second general purpose tag.
   */
  GuardedMemory(void* base_ptr, const size_t user_size,
                const void* tag = nullptr, const void* tag2 = nullptr) {
    wrap_with_guards(base_ptr, user_size, tag, tag2);
  }

  /**
   * Wrap existing guarded memory.
   *
   * To use this constructor, one must have created guarded memory with
   * "GuardedMemory(void*, size_t, void*)" (or indirectly via helper, e.g. "wrap_copy()").
   *
   * @param user_p  existing wrapped memory.
   */
  GuardedMemory(void* userp) {
    u_char* user_ptr = (u_char*) userp;
    assert((uintptr_t)user_ptr > (sizeof(GuardHeader) + 0x1000), "Invalid pointer");
    _base_addr = (user_ptr - sizeof(GuardHeader));
  }

  /**
   * Create new guarded memory.
   *
   * Wraps, starting at the given "base_ptr" with guards. Allows reuse of stack allocated helper.
   *
   * @param base_ptr  allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
   * @param user_size the size of the user data to be wrapped.
   * @param tag       optional general purpose tag.
   * @param tag2      optional second general purpose tag.
   *
   * @return user data pointer (inner pointer to supplied "base_ptr").
   */
  void* wrap_with_guards(void* base_ptr, size_t user_size,
                         const void* tag = nullptr, const void* tag2 = nullptr) {
    assert(base_ptr != nullptr, "Attempt to wrap null with memory guard");
    _base_addr = (u_char*)base_ptr;
    get_head_guard()->build();
    get_head_guard()->set_user_size(user_size);
    get_tail_guard()->build();
    set_tag(tag);
    set_tag2(tag2);
    set_user_bytes(uninitBlockPad);
    assert(verify_guards(), "Expected valid memory guards");
    return get_user_ptr();
  }

  /**
   * Verify head and tail guards.
   *
   * @return true if guards are intact, false would indicate a buffer overrun.
   */
  bool verify_guards() const {
    if (_base_addr != nullptr) {
      return (get_head_guard()->verify() && get_tail_guard()->verify());
    }
    return false;
  }

  /**
   * Set the general purpose tag.
   *
   * @param tag general purpose tag.
   */
  void set_tag(const void* tag) { get_head_guard()->set_tag(tag); }

  /**
   * Return the general purpose tag.
   *
   * @return the general purpose tag, defaults to null.
   */
  void* get_tag() const { return get_head_guard()->get_tag(); }

  /**
   * Set the second general purpose tag.
   *
   * @param tag general purpose tag.
   */
  void set_tag2(const void* tag) { get_head_guard()->set_tag2(tag); }

  /**
   * Return the second general purpose tag.
   *
   * @return the second general purpose tag, defaults to null.
   */
  void* get_tag2() const { return get_head_guard()->get_tag2(); }

  /**
   * Return the size of the user data.
   *
   * @return the size of the user data.
   */
  size_t get_user_size() const {
    assert(_base_addr != nullptr, "Not wrapping any memory");
    return get_head_guard()->get_user_size();
  }

  /**
   * Return the user data pointer.
   *
   * @return the user data pointer.
   */
  u_char* get_user_ptr() const {
    assert(_base_addr != nullptr, "Not wrapping any memory");
    return _base_addr + sizeof(GuardHeader);
  }

  /**
   * Release the wrapped pointer for resource freeing.
   *
   * Pads the user data with "freeBlockPad", and dis-associates the helper.
   *
   * @return the original base pointer used to wrap the data.
   */
  void* release_for_freeing() {
    set_user_bytes(freeBlockPad);
    return release();
  }

  /**
   * Dis-associate the help from the original base address.
   *
   * @return the original base pointer used to wrap the data.
   */
  void* release() {
    void* p = (void*) _base_addr;
    _base_addr = nullptr;
    return p;
  }

  virtual void print_on(outputStream* st) const;

 protected:
  GuardHeader*  get_head_guard() const { return (GuardHeader*) _base_addr; }
  Guard*        get_tail_guard() const { return (Guard*) (get_user_ptr() + get_user_size()); };
  void set_user_bytes(u_char ch) {
    memset(get_user_ptr(), ch, get_user_size());
  }

 public:
  /**
   * Return the total size required for wrapping the given user size.
   *
   * @return the total size required for wrapping the given user size.
   */
  static size_t get_total_size(size_t user_size) {
    size_t total_size = sizeof(GuardHeader) + user_size + sizeof(Guard);
    assert(total_size > user_size, "Unexpected wrap-around");
    return total_size;
  }

  // Helper functions...

  /**
   * Wrap a copy of size "len" of "ptr".
   *
   * @param ptr the memory to be copied
   * @param len the length of the copy
   * @param tag optional general purpose tag (see GuardedMemory::get_tag())
   * @param tag2 optional general purpose tag (see GuardedMemory::get_tag2())
   *
   * @return guarded wrapped memory pointer to the user area, or null if OOM.
   */
  static void* wrap_copy(const void* p, const size_t len,
                         const void* tag = nullptr, const void* tag2 = nullptr);

  /**
   * Free wrapped copy.
   *
   * Frees memory copied with "wrap_copy()".
   *
   * @param p memory returned by "wrap_copy()".
   *
   * @return true if guards were verified as intact. false indicates a buffer overrun.
   */
  static bool free_copy(void* p);

}; // GuardedMemory

#endif // SHARE_MEMORY_GUARDEDMEMORY_HPP
