1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/debug/profiler.h"
#include "base/allocator/buildflags.h"
#include "base/check.h"
#include "base/process/process_handle.h"
#include "build/build_config.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/current_module.h"
#include "base/win/pe_image.h"
#endif // BUILDFLAG(IS_WIN)
namespace base::debug {
void StartProfiling(const std::string& name) {}
void StopProfiling() {}
void FlushProfiling() {}
bool BeingProfiled() {
return false;
}
void RestartProfilingAfterFork() {}
bool IsProfilingSupported() {
return false;
}
#if !BUILDFLAG(IS_WIN)
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() {
return nullptr;
}
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() {
return nullptr;
}
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() {
return nullptr;
}
#else // BUILDFLAG(IS_WIN)
namespace {
struct FunctionSearchContext {
const char* name;
FARPROC function;
};
// Callback function to PEImage::EnumImportChunks.
bool FindResolutionFunctionInImports(const base::win::PEImage& image,
const char* module_name,
PIMAGE_THUNK_DATA unused_name_table,
PIMAGE_THUNK_DATA import_address_table,
PVOID cookie) {
FunctionSearchContext* context =
reinterpret_cast<FunctionSearchContext*>(cookie);
DCHECK(context);
DCHECK(!context->function);
// Our import address table contains pointers to the functions we import
// at this point. Let's retrieve the first such function and use it to
// find the module this import was resolved to by the loader.
const wchar_t* function_in_module =
reinterpret_cast<const wchar_t*>(import_address_table->u1.Function);
// Retrieve the module by a function in the module.
const DWORD kFlags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE module = NULL;
if (!::GetModuleHandleEx(kFlags, function_in_module, &module)) {
// This can happen if someone IAT patches us to a thunk.
return true;
}
// See whether this module exports the function we're looking for.
FARPROC exported_func = ::GetProcAddress(module, context->name);
if (exported_func != NULL) {
// We found it, return the function and terminate the enumeration.
context->function = exported_func;
return false;
}
// Keep going.
return true;
}
template <typename FunctionType>
FunctionType FindFunctionInImports(const char* function_name) {
base::win::PEImage image(CURRENT_MODULE());
FunctionSearchContext ctx = {function_name, NULL};
image.EnumImportChunks(FindResolutionFunctionInImports, &ctx, nullptr);
return reinterpret_cast<FunctionType>(ctx.function);
}
} // namespace
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() {
return FindFunctionInImports<ReturnAddressLocationResolver>(
"ResolveReturnAddressLocation");
}
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() {
return FindFunctionInImports<AddDynamicSymbol>("AddDynamicSymbol");
}
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() {
return FindFunctionInImports<MoveDynamicSymbol>("MoveDynamicSymbol");
}
#endif // BUILDFLAG(IS_WIN)
} // namespace base::debug
|