| Index: chrome_frame/function_stub.cc
|
| diff --git a/chrome_frame/function_stub.cc b/chrome_frame/function_stub.cc
|
| deleted file mode 100644
|
| index 2b04148d5a0f9194f18e92846fb7796847a0f98d..0000000000000000000000000000000000000000
|
| --- a/chrome_frame/function_stub.cc
|
| +++ /dev/null
|
| @@ -1,143 +0,0 @@
|
| -// Copyright (c) 2009 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 "chrome_frame/function_stub.h"
|
| -
|
| -#include <new>
|
| -
|
| -#include "base/synchronization/lock.h"
|
| -#include "base/logging.h"
|
| -
|
| -#ifndef _M_IX86
|
| -#error Only x86 supported right now.
|
| -#endif
|
| -
|
| -namespace {
|
| -typedef enum AsmConstants {
|
| - POP_EAX = 0x58,
|
| - PUSH_IND = 0x35ff,
|
| - PUSH_EAX = 0x50,
|
| - JUMP_IND = 0x25ff,
|
| -};
|
| -
|
| -// A quick and dirty wrapper class that allows us to defer allocating
|
| -// the executable heap until first use, and to release it teardown.
|
| -class ExecutableHeap {
|
| - public:
|
| - ExecutableHeap() : heap_(NULL) {
|
| - }
|
| -
|
| - ~ExecutableHeap() {
|
| - if (heap_ != NULL) {
|
| - BOOL ret = ::HeapDestroy(heap_);
|
| - heap_ = NULL;
|
| - }
|
| - }
|
| -
|
| - void* Allocate(size_t size) {
|
| - if (!heap_)
|
| - CreateHeap();
|
| -
|
| - DCHECK(heap_);
|
| -
|
| - return ::HeapAlloc(heap_, 0, size);
|
| - }
|
| -
|
| - void Free(void* ptr) {
|
| - DCHECK(heap_ != NULL);
|
| - ::HeapFree(heap_, 0, ptr);
|
| - }
|
| -
|
| - void CreateHeap() {
|
| - base::AutoLock lock(init_lock_);
|
| -
|
| - if (heap_ == NULL)
|
| - heap_ = ::HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
|
| - }
|
| -
|
| - private:
|
| - base::Lock init_lock_;
|
| - HANDLE heap_;
|
| -};
|
| -
|
| -// Our executable heap instance, all stubs are allocated from here.
|
| -ExecutableHeap heap_;
|
| -
|
| -} // namespace
|
| -
|
| -extern "C" IMAGE_DOS_HEADER __ImageBase;
|
| -
|
| -bool FunctionStub::is_valid() const {
|
| - return signature_ == reinterpret_cast<HMODULE>(&__ImageBase) &&
|
| - !is_bypassed();
|
| -}
|
| -
|
| -FunctionStub::FunctionStub(uintptr_t extra_argument, void* dest)
|
| - : signature_(reinterpret_cast<HMODULE>(&__ImageBase)),
|
| - argument_(extra_argument),
|
| - destination_function_(reinterpret_cast<uintptr_t>(dest)) {
|
| - bypass_address_ = reinterpret_cast<uintptr_t>(&stub_.pop_return_addr_);
|
| - Init(&stub_);
|
| -}
|
| -
|
| -FunctionStub::~FunctionStub() {
|
| -}
|
| -
|
| -void FunctionStub::Init(FunctionStubAsm* stub) {
|
| - DCHECK(stub != NULL);
|
| -
|
| - stub->jump_to_bypass_ = JUMP_IND;
|
| - stub->bypass_target_addr_ = reinterpret_cast<uintptr_t>(&bypass_address_);
|
| - stub->pop_return_addr_ = POP_EAX;
|
| - stub->push_ = PUSH_IND;
|
| - stub->arg_addr_ = reinterpret_cast<uintptr_t>(&argument_);
|
| - stub->push_return_addr_ = PUSH_EAX;
|
| - stub->jump_to_target = JUMP_IND;
|
| - stub->target_addr_ = reinterpret_cast<uintptr_t>(&destination_function_);
|
| -
|
| - // Flush the instruction cache for the newly written code.
|
| - BOOL ret = ::FlushInstructionCache(::GetCurrentProcess(),
|
| - stub,
|
| - sizeof(*stub));
|
| -}
|
| -
|
| -void FunctionStub::BypassStub(void* new_target) {
|
| - set_bypass_address(reinterpret_cast<uintptr_t>(new_target));
|
| -}
|
| -
|
| -FunctionStub* FunctionStub::Create(uintptr_t extra_argument, void* dest) {
|
| - DCHECK(dest);
|
| - FunctionStub* stub =
|
| - reinterpret_cast<FunctionStub*>(heap_.Allocate(sizeof(FunctionStub)));
|
| -
|
| - if (stub != NULL)
|
| - new (stub) FunctionStub(extra_argument, dest);
|
| -
|
| - return stub;
|
| -}
|
| -
|
| -FunctionStub* FunctionStub::FromCode(void* address) {
|
| - // Address points to arbitrary code here, which may e.g.
|
| - // lie at the end of an executable segment, which in turn
|
| - // may terminate earlier than the last address we probe.
|
| - // We therefore execute under an SEH, so as not to crash
|
| - // on failed probes.
|
| - __try {
|
| - // Retrieve the candidata function stub.
|
| - FunctionStub* candidate = CONTAINING_RECORD(address, FunctionStub, stub_);
|
| - if (candidate->stub_.jump_to_bypass_ == JUMP_IND &&
|
| - candidate->signature_ == reinterpret_cast<HMODULE>(&__ImageBase)) {
|
| - return candidate;
|
| - }
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -bool FunctionStub::Destroy(FunctionStub* stub) {
|
| - heap_.Free(stub);
|
| -
|
| - return true;
|
| -}
|
|
|