#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
namespace base {
namespace debug {
void StartProfiling(const std::string& name) { … }
void StopProfiling() { … }
void FlushProfiling() { … }
bool BeingProfiled() { … }
void RestartProfilingAfterFork() { … }
bool IsProfilingSupported() { … }
#if !BUILDFLAG(IS_WIN)
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() { … }
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() { … }
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() { … }
#else
namespace {
struct FunctionSearchContext {
const char* name;
FARPROC function;
};
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);
const wchar_t* function_in_module =
reinterpret_cast<const wchar_t*>(import_address_table->u1.Function);
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)) {
return true;
}
FARPROC exported_func = ::GetProcAddress(module, context->name);
if (exported_func != NULL) {
context->function = exported_func;
return false;
}
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);
}
}
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() {
return FindFunctionInImports<ReturnAddressLocationResolver>(
"ResolveReturnAddressLocation");
}
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() {
return FindFunctionInImports<AddDynamicSymbol>(
"AddDynamicSymbol");
}
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() {
return FindFunctionInImports<MoveDynamicSymbol>(
"MoveDynamicSymbol");
}
#endif
}
}