// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Static class for hooking Win32 API routines.

// Some notes about how to hook Memory Allocation Routines in Windows.
//
// For our purposes we do not hook the libc routines.  There are two
// reasons for this.  First, the libc routines all go through HeapAlloc
// anyway.  So, it's redundant to log both HeapAlloc and malloc.
// Second, it can be tricky to hook in both static and dynamic linkages
// of libc.

#include <windows.h>

#include "memory_hook.h"
#include "memory_watcher.h"
#include "preamble_patcher.h"

// Calls GetProcAddress, but casts to the correct type.
#define GET_PROC_ADDRESS(hmodule, name) \
  ( (Type_##name)(::GetProcAddress(hmodule, #name)) )

// Macro to declare Patch functions.
#define DECLARE_PATCH(name) Patch<Type_##name> patch_##name

// Macro to install Patch functions.
#define INSTALL_PATCH(name)  do {                                       \
  patch_##name.set_original(GET_PROC_ADDRESS(hkernel32, ##name));       \
  patch_##name.Install(&Perftools_##name);                              \
} while (0)

// Macro to install Patch functions.
#define INSTALL_NTDLLPATCH(name)  do {                                  \
  patch_##name.set_original(GET_PROC_ADDRESS(hntdll, ##name));          \
  patch_##name.Install(&Perftools_##name);                              \
} while (0)

// Macro to uninstall Patch functions.
#define UNINSTALL_PATCH(name) patch_##name.Uninstall();



// Windows APIs to be hooked

// HeapAlloc routines
typedef HANDLE (WINAPI *Type_HeapCreate)(DWORD flOptions,
                                         SIZE_T dwInitialSize,
                                         SIZE_T dwMaximumSize);
typedef BOOL (WINAPI *Type_HeapDestroy)(HANDLE hHeap);
typedef LPVOID (WINAPI *Type_HeapAlloc)(HANDLE hHeap, DWORD dwFlags,
                                        DWORD_PTR dwBytes);
typedef LPVOID (WINAPI *Type_HeapReAlloc)(HANDLE hHeap, DWORD dwFlags,
                                          LPVOID lpMem, SIZE_T dwBytes);
typedef BOOL (WINAPI *Type_HeapFree)(HANDLE hHeap, DWORD dwFlags,
                                     LPVOID lpMem);

// GlobalAlloc routines
typedef HGLOBAL (WINAPI *Type_GlobalAlloc)(UINT uFlags, SIZE_T dwBytes);
typedef HGLOBAL (WINAPI *Type_GlobalReAlloc)(HGLOBAL hMem, SIZE_T dwBytes,
                                             UINT uFlags);
typedef HGLOBAL (WINAPI *Type_GlobalFree)(HGLOBAL hMem);

// LocalAlloc routines
typedef HLOCAL (WINAPI *Type_LocalAlloc)(UINT uFlags, SIZE_T uBytes);
typedef HLOCAL (WINAPI *Type_LocalReAlloc)(HLOCAL hMem, SIZE_T uBytes,
                                           UINT uFlags);
typedef HLOCAL (WINAPI *Type_LocalFree)(HLOCAL hMem);

// A Windows-API equivalent of mmap and munmap, for "anonymous regions"
typedef LPVOID (WINAPI *Type_VirtualAllocEx)(HANDLE process, LPVOID address,
                                             SIZE_T size, DWORD type,
                                             DWORD protect);
typedef BOOL (WINAPI *Type_VirtualFreeEx)(HANDLE process, LPVOID address,
                                          SIZE_T size, DWORD type);

// A Windows-API equivalent of mmap and munmap, for actual files
typedef LPVOID (WINAPI *Type_MapViewOfFile)(HANDLE hFileMappingObject,
                                            DWORD dwDesiredAccess,
                                            DWORD dwFileOffsetHigh,
                                            DWORD dwFileOffsetLow,
                                            SIZE_T dwNumberOfBytesToMap);
typedef LPVOID (WINAPI *Type_MapViewOfFileEx)(HANDLE hFileMappingObject,
                                              DWORD dwDesiredAccess,
                                              DWORD dwFileOffsetHigh,
                                              DWORD dwFileOffsetLow,
                                              SIZE_T dwNumberOfBytesToMap,
                                              LPVOID lpBaseAddress);
typedef BOOL (WINAPI *Type_UnmapViewOfFile)(LPVOID lpBaseAddress);

typedef DWORD (WINAPI *Type_NtUnmapViewOfSection)(HANDLE process,
                                                  LPVOID lpBaseAddress);


// Patch is a template for keeping the pointer to the original
// hooked routine, the function to call when hooked, and the
// stub routine which is patched.
template<class T>
class Patch {
 public:
  // Constructor.  Does not hook the function yet.
  Patch<T>()
    : original_function_(NULL),
      patch_function_(NULL),
      stub_function_(NULL) {
  }

  // Destructor.  Unhooks the function if it has been hooked.
  ~Patch<T>() {
    Uninstall();
  }

  // Patches original function with func.
  // Must have called set_original to set the original function.
  void Install(T func) {
    patch_function_ = func;
    CHECK(patch_function_ != NULL);
    CHECK(original_function_ != NULL);
    CHECK(stub_function_ == NULL);
    CHECK(sidestep::SIDESTEP_SUCCESS ==
          sidestep::PreamblePatcher::Patch(original_function_,
                                           patch_function_, &stub_function_));
  }

  // Un-patches the function.
  void Uninstall() {
    if (stub_function_)
      sidestep::PreamblePatcher::Unpatch(original_function_,
                                         patch_function_, stub_function_);
    stub_function_ = NULL;
  }

  // Set the function to be patched.
  void set_original(T original) { original_function_ = original; }

  // Get the original function being patched.
  T original() { return original_function_; }

  // Get the patched function.  (e.g. the replacement function)
  T patched() { return patch_function_; }

  // Access to the stub for calling the original function
  // while it is patched.
  T operator()() {
    DCHECK(stub_function_);
    return stub_function_;
  }

 private:
  // The function that we plan to patch.
  T original_function_;
  // The function to replace the original with.
  T patch_function_;
  // To unpatch, we also need to keep around a "stub" that points to the
  // pre-patched Windows function.
  T stub_function_;
};


// All Windows memory-allocation routines call through to one of these.
DECLARE_PATCH(HeapCreate);
DECLARE_PATCH(HeapDestroy);
DECLARE_PATCH(HeapAlloc);
DECLARE_PATCH(HeapReAlloc);
DECLARE_PATCH(HeapFree);
DECLARE_PATCH(VirtualAllocEx);
DECLARE_PATCH(VirtualFreeEx);
DECLARE_PATCH(MapViewOfFile);
DECLARE_PATCH(MapViewOfFileEx);
DECLARE_PATCH(UnmapViewOfFile);
DECLARE_PATCH(GlobalAlloc);
DECLARE_PATCH(GlobalReAlloc);
DECLARE_PATCH(GlobalFree);
DECLARE_PATCH(LocalAlloc);
DECLARE_PATCH(LocalReAlloc);
DECLARE_PATCH(LocalFree);
DECLARE_PATCH(NtUnmapViewOfSection);

// Our replacement functions.

static HANDLE WINAPI Perftools_HeapCreate(DWORD flOptions,
                                          SIZE_T dwInitialSize,
                                          SIZE_T dwMaximumSize) {
  if (dwInitialSize > 4096)
    dwInitialSize = 4096;
  return patch_HeapCreate()(flOptions, dwInitialSize, dwMaximumSize);
}

static BOOL WINAPI Perftools_HeapDestroy(HANDLE hHeap) {
  return patch_HeapDestroy()(hHeap);
}

static LPVOID WINAPI Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
                                         DWORD_PTR dwBytes) {
  LPVOID rv = patch_HeapAlloc()(hHeap, dwFlags, dwBytes);
  MemoryHook::hook()->OnTrack(hHeap, reinterpret_cast<int32>(rv), dwBytes);
  return rv;
}

static BOOL WINAPI Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,
                                      LPVOID lpMem) {
  size_t size = 0;
  if (lpMem != 0) {
    size = HeapSize(hHeap, 0, lpMem);  // Will crash if lpMem is 0.
    // Note: size could be 0; HeapAlloc does allocate 0 length buffers.
  }
  MemoryHook::hook()->OnUntrack(hHeap, reinterpret_cast<int32>(lpMem), size);
  return patch_HeapFree()(hHeap, dwFlags, lpMem);
}

static LPVOID WINAPI Perftools_HeapReAlloc(HANDLE hHeap, DWORD dwFlags,
                                           LPVOID lpMem, SIZE_T dwBytes) {
  // Don't call realloc, but instead do a free/malloc.  The problem is that
  // the builtin realloc may either expand a buffer, or it may simply
  // just call free/malloc.  If so, we will already have tracked the new
  // block via Perftools_HeapAlloc.

  LPVOID rv = Perftools_HeapAlloc(hHeap, dwFlags, dwBytes);
  DCHECK_EQ((HEAP_REALLOC_IN_PLACE_ONLY & dwFlags), 0u);

  // If there was an old buffer, now copy the data to the new buffer.
  if (lpMem != 0) {
    size_t size = HeapSize(hHeap, 0, lpMem);
    if (size > dwBytes)
      size = dwBytes;
    // Note: size could be 0; HeapAlloc does allocate 0 length buffers.
    memcpy(rv, lpMem, size);
    Perftools_HeapFree(hHeap, dwFlags, lpMem);
  }
  return rv;
}

static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address,
                                              SIZE_T size, DWORD type,
                                              DWORD protect) {
  bool already_committed = false;
  if (address != NULL) {
    MEMORY_BASIC_INFORMATION info;
    CHECK(VirtualQuery(address, &info, sizeof(info)));
    if (info.State & MEM_COMMIT) {
      already_committed = true;
      CHECK(size >= info.RegionSize);
    }
  }
  bool reserving = (address == NULL) || (type & MEM_RESERVE);
  bool committing = !already_committed && (type & MEM_COMMIT);


  LPVOID result = patch_VirtualAllocEx()(process, address, size, type,
                                         protect);
  MEMORY_BASIC_INFORMATION info;
  CHECK(VirtualQuery(result, &info, sizeof(info)));
  size = info.RegionSize;

  if (committing)
    MemoryHook::hook()->OnTrack(0, reinterpret_cast<int32>(result), size);

  return result;
}

static BOOL WINAPI Perftools_VirtualFreeEx(HANDLE process, LPVOID address,
                                           SIZE_T size, DWORD type) {
  int chunk_size = size;
  MEMORY_BASIC_INFORMATION info;
  CHECK(VirtualQuery(address, &info, sizeof(info)));
  if (chunk_size == 0)
    chunk_size = info.RegionSize;
  bool decommit = (info.State & MEM_COMMIT) != 0;

  if (decommit)
      MemoryHook::hook()->OnUntrack(0, reinterpret_cast<int32>(address),
                                     chunk_size);

  return patch_VirtualFreeEx()(process, address, size, type);
}

static base::Lock known_maps_lock;
static std::map<void*, int> known_maps;

static LPVOID WINAPI Perftools_MapViewOfFileEx(HANDLE hFileMappingObject,
                                               DWORD dwDesiredAccess,
                                               DWORD dwFileOffsetHigh,
                                               DWORD dwFileOffsetLow,
                                               SIZE_T dwNumberOfBytesToMap,
                                               LPVOID lpBaseAddress) {
  // For this function pair, you always deallocate the full block of
  // data that you allocate, so NewHook/DeleteHook is the right API.
  LPVOID result = patch_MapViewOfFileEx()(hFileMappingObject, dwDesiredAccess,
                                           dwFileOffsetHigh, dwFileOffsetLow,
                                           dwNumberOfBytesToMap, lpBaseAddress);
  {
    base::AutoLock lock(known_maps_lock);
    MEMORY_BASIC_INFORMATION info;
    if (known_maps.find(result) == known_maps.end()) {
      CHECK(VirtualQuery(result, &info, sizeof(info)));
      // TODO(mbelshe):  THIS map uses the standard heap!!!!
      known_maps[result] = 1;
      MemoryHook::hook()->OnTrack(0, reinterpret_cast<int32>(result),
                                  info.RegionSize);
    } else {
      known_maps[result] = known_maps[result] + 1;
    }
  }
  return result;
}

static LPVOID WINAPI Perftools_MapViewOfFile(HANDLE hFileMappingObject,
                                               DWORD dwDesiredAccess,
                                               DWORD dwFileOffsetHigh,
                                               DWORD dwFileOffsetLow,
                                               SIZE_T dwNumberOfBytesToMap) {
  return Perftools_MapViewOfFileEx(hFileMappingObject, dwDesiredAccess,
                                   dwFileOffsetHigh, dwFileOffsetLow,
                                   dwNumberOfBytesToMap, 0);
}

static BOOL WINAPI Perftools_UnmapViewOfFile(LPVOID lpBaseAddress) {
  // This will call into NtUnmapViewOfSection().
  return patch_UnmapViewOfFile()(lpBaseAddress);
}

static DWORD WINAPI Perftools_NtUnmapViewOfSection(HANDLE process,
                                                   LPVOID lpBaseAddress) {
  // Some windows APIs call directly into this routine rather
  // than calling UnmapViewOfFile.  If we didn't trap this function,
  // then we appear to have bogus leaks.
  {
    base::AutoLock lock(known_maps_lock);
    MEMORY_BASIC_INFORMATION info;
    CHECK(VirtualQuery(lpBaseAddress, &info, sizeof(info)));
    if (known_maps.find(lpBaseAddress) != known_maps.end()) {
      if (known_maps[lpBaseAddress] == 1) {
        MemoryHook::hook()->OnUntrack(0, reinterpret_cast<int32>(lpBaseAddress),
                                       info.RegionSize);
        known_maps.erase(lpBaseAddress);
      } else {
        known_maps[lpBaseAddress] = known_maps[lpBaseAddress] - 1;
      }
    }
  }
  return patch_NtUnmapViewOfSection()(process, lpBaseAddress);
}

static HGLOBAL WINAPI Perftools_GlobalAlloc(UINT uFlags, SIZE_T dwBytes) {
  // GlobalAlloc is built atop HeapAlloc anyway.  So we don't track these.
  // GlobalAlloc will internally call into HeapAlloc and we track there.

  // Force all memory to be fixed.
  uFlags &= ~GMEM_MOVEABLE;
  HGLOBAL rv = patch_GlobalAlloc()(uFlags, dwBytes);
  return rv;
}

static HGLOBAL WINAPI Perftools_GlobalFree(HGLOBAL hMem) {
  return patch_GlobalFree()(hMem);
}

static HGLOBAL WINAPI Perftools_GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes,
                                              UINT uFlags) {
  // TODO(jar): [The following looks like a copy/paste typo from LocalRealloc.]
  // GlobalDiscard is a macro which calls LocalReAlloc with size 0.
  if (dwBytes == 0) {
    return patch_GlobalReAlloc()(hMem, dwBytes, uFlags);
  }

  HGLOBAL rv = Perftools_GlobalAlloc(uFlags, dwBytes);
  if (hMem != 0) {
    size_t size = GlobalSize(hMem);
    if (size > dwBytes)
      size = dwBytes;
    // Note: size could be 0; HeapAlloc does allocate 0 length buffers.
    memcpy(rv, hMem, size);
    Perftools_GlobalFree(hMem);
  }

  return rv;
}

static HLOCAL WINAPI Perftools_LocalAlloc(UINT uFlags, SIZE_T dwBytes) {
  // LocalAlloc is built atop HeapAlloc anyway.  So we don't track these.
  // LocalAlloc will internally call into HeapAlloc and we track there.

  // Force all memory to be fixed.
  uFlags &= ~LMEM_MOVEABLE;
  HLOCAL rv = patch_LocalAlloc()(uFlags, dwBytes);
  return rv;
}

static HLOCAL WINAPI Perftools_LocalFree(HLOCAL hMem) {
  return patch_LocalFree()(hMem);
}

static HLOCAL WINAPI Perftools_LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes,
                                            UINT uFlags) {
  // LocalDiscard is a macro which calls LocalReAlloc with size 0.
  if (dwBytes == 0) {
    return patch_LocalReAlloc()(hMem, dwBytes, uFlags);
  }

  HGLOBAL rv = Perftools_LocalAlloc(uFlags, dwBytes);
  if (hMem != 0) {
    size_t size = LocalSize(hMem);
    if (size > dwBytes)
      size = dwBytes;
    // Note: size could be 0; HeapAlloc does allocate 0 length buffers.
    memcpy(rv, hMem, size);
    Perftools_LocalFree(hMem);
  }

  return rv;
}

bool MemoryHook::hooked_ = false;
MemoryHook* MemoryHook::global_hook_ = NULL;

MemoryHook::MemoryHook()
  : watcher_(NULL),
    heap_(NULL) {
  CreateHeap();
}

MemoryHook::~MemoryHook() {
  // It's a bit dangerous to ever close this heap; MemoryWatchers may have
  // used this heap for their tracking data.  Closing the heap while any
  // MemoryWatchers still exist is pretty dangerous.
  CloseHeap();
}

bool MemoryHook::Initialize() {
  if (global_hook_ == NULL)
    global_hook_ = new MemoryHook();
  return true;
}

bool MemoryHook::Hook() {
  DCHECK(!hooked_);
  if (!hooked_) {
    DCHECK(global_hook_);

    // Luckily, Patch() doesn't call malloc or windows alloc routines
    // itself -- though it does call new (we can use PatchWithStub to
    // get around that, and will need to if we need to patch new).

    HMODULE hkernel32 = ::GetModuleHandle(L"kernel32");
    CHECK(hkernel32 != NULL);

    HMODULE hntdll = ::GetModuleHandle(L"ntdll");
    CHECK(hntdll != NULL);

    // Now that we've found all the functions, patch them
    INSTALL_PATCH(HeapCreate);
    INSTALL_PATCH(HeapDestroy);
    INSTALL_PATCH(HeapAlloc);
    INSTALL_PATCH(HeapReAlloc);
    INSTALL_PATCH(HeapFree);
    INSTALL_PATCH(VirtualAllocEx);
    INSTALL_PATCH(VirtualFreeEx);
    INSTALL_PATCH(MapViewOfFileEx);
    INSTALL_PATCH(MapViewOfFile);
    INSTALL_PATCH(UnmapViewOfFile);
    INSTALL_NTDLLPATCH(NtUnmapViewOfSection);
    INSTALL_PATCH(GlobalAlloc);
    INSTALL_PATCH(GlobalReAlloc);
    INSTALL_PATCH(GlobalFree);
    INSTALL_PATCH(LocalAlloc);
    INSTALL_PATCH(LocalReAlloc);
    INSTALL_PATCH(LocalFree);

    // We are finally completely hooked.
    hooked_ = true;
  }
  return true;
}

bool MemoryHook::Unhook() {
  if (hooked_) {
    // We need to go back to the system malloc/etc at global destruct time,
    // so objects that were constructed before tcmalloc, using the system
    // malloc, can destroy themselves using the system free.  This depends
    // on DLLs unloading in the reverse order in which they load!
    //
    // We also go back to the default HeapAlloc/etc, just for consistency.
    // Who knows, it may help avoid weird bugs in some situations.
    UNINSTALL_PATCH(HeapCreate);
    UNINSTALL_PATCH(HeapDestroy);
    UNINSTALL_PATCH(HeapAlloc);
    UNINSTALL_PATCH(HeapReAlloc);
    UNINSTALL_PATCH(HeapFree);
    UNINSTALL_PATCH(VirtualAllocEx);
    UNINSTALL_PATCH(VirtualFreeEx);
    UNINSTALL_PATCH(MapViewOfFile);
    UNINSTALL_PATCH(MapViewOfFileEx);
    UNINSTALL_PATCH(UnmapViewOfFile);
    UNINSTALL_PATCH(NtUnmapViewOfSection);
    UNINSTALL_PATCH(GlobalAlloc);
    UNINSTALL_PATCH(GlobalReAlloc);
    UNINSTALL_PATCH(GlobalFree);
    UNINSTALL_PATCH(LocalAlloc);
    UNINSTALL_PATCH(LocalReAlloc);
    UNINSTALL_PATCH(LocalFree);

    hooked_ = false;
  }
  return true;
}

bool MemoryHook::RegisterWatcher(MemoryObserver* watcher) {
  DCHECK(global_hook_->watcher_ == NULL);

  if (!hooked_)
    Hook();

  DCHECK(global_hook_);
  global_hook_->watcher_ = watcher;
  return true;
}

bool MemoryHook::UnregisterWatcher(MemoryObserver* watcher) {
  DCHECK(hooked_);
  DCHECK(global_hook_->watcher_ == watcher);
  // TODO(jar): changing watcher_ here is very racy.  Other threads may (without
  // a lock) testing, and then calling through this value.  We probably can't
  // remove this until we are single threaded.
  global_hook_->watcher_ = NULL;

  // For now, since there are no more watchers, unhook memory.
  return Unhook();
}

bool MemoryHook::CreateHeap() {
  // Create a heap for our own memory.
  DCHECK(heap_ == NULL);
  heap_ = HeapCreate(0, 0, 0);
  DCHECK(heap_ != NULL);
  return heap_ != NULL;
}

bool MemoryHook::CloseHeap() {
  DCHECK(heap_ != NULL);
  HeapDestroy(heap_);
  heap_ = NULL;
  return true;
}

void MemoryHook::OnTrack(HANDLE heap, int32 id, int32 size) {
  // Don't notify about allocations to our internal heap.
  if (heap == heap_)
    return;

  if (watcher_)
    watcher_->OnTrack(heap, id, size);
}

void MemoryHook::OnUntrack(HANDLE heap, int32 id, int32 size) {
  // Don't notify about allocations to our internal heap.
  if (heap == heap_)
    return;

  if (watcher_)
    watcher_->OnUntrack(heap, id, size);
}
