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