1 : // Copyright 2012 Google Inc.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // The runtime portion of a basic-block entry counting agent. This is
16 : // responsible for initializing the RPC connection and per-thread entry-count
17 : // buffer on demand as necessary as well as saturation incrementing the
18 : // appropriate counter when requested.
19 : //
20 : // The instrumenter can be used to inject a run-time dependency on this
21 : // library as well as to add the appropriate entry-hook code.
22 :
23 : #ifndef SYZYGY_AGENT_BASIC_BLOCK_ENTRY_BASIC_BLOCK_ENTRY_H_
24 : #define SYZYGY_AGENT_BASIC_BLOCK_ENTRY_BASIC_BLOCK_ENTRY_H_
25 :
26 : #include <windows.h>
27 : #include <winnt.h>
28 : #include <vector>
29 :
30 : #include "base/lazy_instance.h"
31 : #include "base/win/pe_image.h"
32 : #include "syzygy/agent/common/thread_state.h"
33 : #include "syzygy/common/basic_block_frequency_data.h"
34 : #include "syzygy/trace/client/rpc_session.h"
35 :
36 : // Instrumentation stub to handle entry to a basic-block.
37 m : extern "C" void _cdecl _basic_block_enter();
38 :
39 : // Instrumentation stub to handle the invocation of a DllMain-like entry point.
40 m : extern "C" void _cdecl _indirect_penter_dllmain();
41 :
42 m : namespace agent {
43 m : namespace basic_block_entry {
44 :
45 : // The basic-block entry counting agent.
46 : // @note: There's a single instance of this class.
47 m : class BasicBlockEntry {
48 m : public:
49 : // This structure describes the contents of the stack above a call to
50 : // BasicBlockEntry::BasicBlockEntryHook. A pointer to this structure will
51 : // be given to the BasicBlockEntryHook by _basic_block_enter.
52 m : struct BasicBlockEntryFrame;
53 :
54 : // This structure describes the contents of the stack above a call to
55 : // BasicBlockEntry::DllMainEntryHook(). A pointer to this structure will
56 : // be given to the BasicBlockEntryHook by _indirect_penter_dllmain.
57 m : struct DllMainEntryFrame;
58 :
59 : // Retrieves the coverage singleton instance.
60 m : static BasicBlockEntry* Instance();
61 :
62 : // Called from _basic_block_enter().
63 m : static void WINAPI BasicBlockEntryHook(BasicBlockEntryFrame* entry_frame);
64 :
65 : // Called from _indirect_penter_dllmain.
66 m : static void WINAPI DllMainEntryHook(DllMainEntryFrame* entry_frame);
67 :
68 m : protected:
69 : // This class defines the per-thread-per-instrumented-module state managed
70 : // by this agent.
71 m : class ThreadState;
72 m : friend class ThreadState;
73 :
74 : // Make sure the LazyInstance can be created.
75 m : friend struct base::DefaultLazyInstanceTraits<BasicBlockEntry>;
76 :
77 m : BasicBlockEntry();
78 m : ~BasicBlockEntry();
79 :
80 : // Handles DLL_PROCESS_ATTACH messages received by DllMainEntryHook().
81 m : void OnProcessAttach(DllMainEntryFrame* entry_frame);
82 :
83 : // Handles DLL_THREAD_DETACH and DLL_PROCESS_DETACH messages received by
84 : // DllMainEntryHook().
85 m : void OnThreadDetach(DllMainEntryFrame* entry_frame);
86 :
87 : // Registers the module containing @p addr with the call_trace_service.
88 m : void RegisterModule(const void* addr);
89 :
90 : // Create the local thread state for the current thread. This should only
91 : // be called if the local thread state has not already been created.
92 m : ThreadState* CreateThreadState(BasicBlockEntryFrame* entry_frame);
93 :
94 : // The RPC session we're logging to/through.
95 m : trace::client::RpcSession session_;
96 :
97 : // A helper to manage the life-cycle of the ThreadState instances allocated
98 : // by this agent.
99 m : agent::common::ThreadStateManager thread_state_manager_;
100 m : };
101 :
102 m : } // namespace coverage
103 m : } // namespace agent
104 :
105 : #endif // SYZYGY_AGENT_BASIC_BLOCK_ENTRY_BASIC_BLOCK_ENTRY_H_
|