xref: /aosp_15_r20/external/cronet/base/profiler/win32_stack_frame_unwinder.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 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 #ifndef BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_
6 #define BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_
7 
8 #include <windows.h>
9 
10 #include <memory>
11 
12 #include "base/base_export.h"
13 #include "base/profiler/module_cache.h"
14 #include "build/build_config.h"
15 
16 namespace base {
17 
18 #if !defined(ARCH_CPU_64_BITS)
19 // Allows code to compile for x86. Actual support for x86 will require either
20 // refactoring these interfaces or separate architecture-specific interfaces.
21 struct RUNTIME_FUNCTION {
22   DWORD BeginAddress;
23   DWORD EndAddress;
24 };
25 using PRUNTIME_FUNCTION = RUNTIME_FUNCTION*;
26 #endif  // !defined(ARCH_CPU_64_BITS)
27 
ContextPC(CONTEXT * context)28 inline ULONG64 ContextPC(CONTEXT* context) {
29 #if defined(ARCH_CPU_X86_64)
30   return context->Rip;
31 #elif defined(ARCH_CPU_X86)
32   return context->Eip;
33 #elif defined(ARCH_CPU_ARM64)
34   return context->Pc;
35 #else
36 #error Unsupported Windows Arch
37 #endif
38 }
39 
40 // This class is not used while the target thread is suspended, so may allocate
41 // from the default heap.
42 class BASE_EXPORT Win32StackFrameUnwinder {
43  public:
44   // Interface for Win32 unwind-related functionality this class depends
45   // on. Provides a seam for testing.
46   class BASE_EXPORT UnwindFunctions {
47    public:
48     UnwindFunctions(const UnwindFunctions&) = delete;
49     UnwindFunctions& operator=(const UnwindFunctions&) = delete;
50 
51     virtual ~UnwindFunctions();
52 
53     virtual PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter,
54                                                   PDWORD64 image_base) = 0;
55     virtual void VirtualUnwind(DWORD64 image_base,
56                                DWORD64 program_counter,
57                                PRUNTIME_FUNCTION runtime_function,
58                                CONTEXT* context) = 0;
59 
60    protected:
61     UnwindFunctions();
62   };
63 
64   explicit Win32StackFrameUnwinder();
65 
66   Win32StackFrameUnwinder(const Win32StackFrameUnwinder&) = delete;
67   Win32StackFrameUnwinder& operator=(const Win32StackFrameUnwinder&) = delete;
68 
69   ~Win32StackFrameUnwinder();
70 
71   // Attempts to unwind the frame represented by |context|, where the
72   // instruction pointer is known to be in |module|. Updates |context| if
73   // successful.
74   bool TryUnwind(bool at_top_frame,
75                  CONTEXT* context,
76                  const ModuleCache::Module* module);
77 
78  private:
79   // This function is for internal and test purposes only.
80   Win32StackFrameUnwinder(std::unique_ptr<UnwindFunctions> unwind_functions);
81   friend class Win32StackFrameUnwinderTest;
82 
83   std::unique_ptr<UnwindFunctions> unwind_functions_;
84 };
85 
86 }  // namespace base
87 
88 #endif  // BASE_PROFILER_WIN32_STACK_FRAME_UNWINDER_H_
89