// Copyright 2015 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.

#include "base/profiler/win32_stack_frame_unwinder.h"

#include <windows.h>

#include <utility>

#include "base/macros.h"
#include "base/memory/ptr_util.h"

namespace base {

// Win32UnwindFunctions -------------------------------------------------------

const HMODULE ModuleHandleTraits::kNonNullModuleForTesting =
    reinterpret_cast<HMODULE>(static_cast<uintptr_t>(-1));

// static
bool ModuleHandleTraits::CloseHandle(HMODULE handle) {
  if (handle == kNonNullModuleForTesting)
    return true;

  return ::FreeLibrary(handle) != 0;
}

// static
bool ModuleHandleTraits::IsHandleValid(HMODULE handle) {
  return handle != nullptr;
}

// static
HMODULE ModuleHandleTraits::NullHandle() {
  return nullptr;
}

namespace {

// Implements the UnwindFunctions interface for the corresponding Win32
// functions.
class Win32UnwindFunctions : public Win32StackFrameUnwinder::UnwindFunctions {
public:
  Win32UnwindFunctions();
  ~Win32UnwindFunctions() override;

  PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter,
                                        PDWORD64 image_base) override;

  void VirtualUnwind(DWORD64 image_base,
                     DWORD64 program_counter,
                     PRUNTIME_FUNCTION runtime_function,
                     CONTEXT* context) override;

  ScopedModuleHandle GetModuleForProgramCounter(
      DWORD64 program_counter) override;

private:
  DISALLOW_COPY_AND_ASSIGN(Win32UnwindFunctions);
};

Win32UnwindFunctions::Win32UnwindFunctions() {}
Win32UnwindFunctions::~Win32UnwindFunctions() {}

PRUNTIME_FUNCTION Win32UnwindFunctions::LookupFunctionEntry(
    DWORD64 program_counter,
    PDWORD64 image_base) {
#ifdef _WIN64
  return RtlLookupFunctionEntry(program_counter, image_base, nullptr);
#else
  NOTREACHED();
  return nullptr;
#endif
}

void Win32UnwindFunctions::VirtualUnwind(DWORD64 image_base,
                                         DWORD64 program_counter,
                                         PRUNTIME_FUNCTION runtime_function,
                                         CONTEXT* context) {
#ifdef _WIN64
  void* handler_data;
  ULONG64 establisher_frame;
  KNONVOLATILE_CONTEXT_POINTERS nvcontext = {};
  RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, program_counter,
                   runtime_function, context, &handler_data,
                   &establisher_frame, &nvcontext);
#else
  NOTREACHED();
#endif
}

ScopedModuleHandle Win32UnwindFunctions::GetModuleForProgramCounter(
    DWORD64 program_counter) {
  HMODULE module_handle = nullptr;
  // GetModuleHandleEx() increments the module reference count, which is then
  // managed and ultimately decremented by ScopedModuleHandle.
  if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                           reinterpret_cast<LPCTSTR>(program_counter),
                           &module_handle)) {
    const DWORD error = ::GetLastError();
    DCHECK_EQ(ERROR_MOD_NOT_FOUND, static_cast<int>(error));
  }
  return ScopedModuleHandle(module_handle);
}

}  // namespace

// Win32StackFrameUnwinder ----------------------------------------------------

Win32StackFrameUnwinder::UnwindFunctions::~UnwindFunctions() {}
Win32StackFrameUnwinder::UnwindFunctions::UnwindFunctions() {}

Win32StackFrameUnwinder::Win32StackFrameUnwinder()
    : Win32StackFrameUnwinder(WrapUnique(new Win32UnwindFunctions)) {}

Win32StackFrameUnwinder::~Win32StackFrameUnwinder() {}

bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context,
                                        ScopedModuleHandle* module) {
#ifdef _WIN64
  ScopedModuleHandle frame_module =
      unwind_functions_->GetModuleForProgramCounter(context->Rip);
  if (!frame_module.IsValid()) {
    // There's no loaded module containing the instruction pointer. This can be
    // due to executing code that is not in a module. In particular,
    // runtime-generated code associated with third-party injected DLLs
    // typically is not in a module. It can also be due to the the module having
    // been unloaded since we recorded the stack.  In the latter case the
    // function unwind information was part of the unloaded module, so it's not
    // possible to unwind further.
    //
    // If a module was found, it's still theoretically possible for the detected
    // module module to be different than the one that was loaded when the stack
    // was copied (i.e. if the module was unloaded and a different module loaded
    // in overlapping memory). This likely would cause a crash, but has not been
    // observed in practice.
    return false;
  }

  ULONG64 image_base;
  // Try to look up unwind metadata for the current function.
  PRUNTIME_FUNCTION runtime_function =
      unwind_functions_->LookupFunctionEntry(context->Rip, &image_base);

  if (runtime_function) {
    unwind_functions_->VirtualUnwind(image_base, context->Rip, runtime_function,
                                     context);
    at_top_frame_ = false;
  } else {
    if (at_top_frame_) {
      at_top_frame_ = false;

      // This is a leaf function (i.e. a function that neither calls a function,
      // nor allocates any stack space itself) so the return address is at RSP.
      context->Rip = *reinterpret_cast<DWORD64*>(context->Rsp);
      context->Rsp += 8;
    } else {
      // In theory we shouldn't get here, as it means we've encountered a
      // function without unwind information below the top of the stack, which
      // is forbidden by the Microsoft x64 calling convention.
      //
      // The one known case in Chrome code that executes this path occurs
      // because of BoringSSL unwind information inconsistent with the actual
      // function code. See https://crbug.com/542919.
      //
      // Note that dodgy third-party generated code that otherwise would enter
      // this path should be caught by the module check above, since the code
      // typically is located outside of a module.
      return false;
    }
  }

  module->Set(frame_module.Take());
  return true;
#else
  NOTREACHED();
  return false;
#endif
}

Win32StackFrameUnwinder::Win32StackFrameUnwinder(
    std::unique_ptr<UnwindFunctions> unwind_functions)
    : at_top_frame_(true), unwind_functions_(std::move(unwind_functions)) {}

}  // namespace base
