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