1 : // Copyright 2013 Google Inc. All Rights Reserved.
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 : // Declares the data structure that will be used by various pieces of the
16 : // instrumentation and trace agent's to collect data at runtime.
17 :
18 : #ifndef SYZYGY_COMMON_INDEXED_FREQUENCY_DATA_H_
19 : #define SYZYGY_COMMON_INDEXED_FREQUENCY_DATA_H_
20 :
21 : #include <windows.h>
22 :
23 : #include "base/basictypes.h"
24 : #include "base/strings/string_piece.h"
25 : #include "syzygy/common/assertions.h"
26 :
27 m : namespace common {
28 :
29 : #pragma pack(push, 1)
30 :
31 : // This data structure is injected into an instrumented image in a read-write
32 : // section of its own. It will be initialized by the runtime client library
33 : // and is referred to by all of the instrumentation code.
34 m : struct IndexedFrequencyData {
35 :
36 : // Describe the kind of data contained in frequency_data;
37 : // IndexedFrequencyDataTypeName must be maintained if this is changed.
38 m : enum DataType {
39 m : INVALID_DATA_TYPE = 0,
40 m : BASIC_BLOCK_ENTRY = 1,
41 m : BRANCH = 2,
42 m : COVERAGE = 3,
43 m : JUMP_TABLE = 4,
44 m : MAX_DATA_TYPE = 5,
45 m : };
46 :
47 : // An identifier denoting the agent with which this frequency data
48 : // instrumentation is intended to work.
49 m : uint32 agent_id;
50 :
51 : // The version of the data structure and agent of the toolchain that
52 : // instrumented the binary. If this doesn't match the running client
53 : // library then the whole process should be aborted. This just a simple
54 : // counter which should be updated whenever a non-backwards compatible
55 : // change is made to the data structure or its usage.
56 m : uint32 version;
57 :
58 : // This points to an array of length 'num_entries' counter elements. At
59 : // link time it is initialized to point to statically allocated array that is
60 : // in the .data section of the image (this is done so that if capture is not
61 : // enabled the binary can still run without crashing). If a single process-
62 : // wide frequency table is needed, the agent may allocate a call-trace buffer
63 : // and redirect this pointer to point into it. Alternatively, it may allocate
64 : // any thread-specific context it requires and refer to this pointer as a
65 : // fall-back measure if tracing is disabled.
66 : //
67 : // The total size (in bytes) of the buffer pointed to is
68 : // num_entries * num_columns * frequency_size.
69 m : void* frequency_data;
70 :
71 : // The number of entries in the frequency table. This is required by the
72 : // runtime client library so it knows how big an array to allocate.
73 m : uint32 num_entries;
74 :
75 : // The number of columns for each entry.
76 m : uint32 num_columns;
77 :
78 : // The number of bytes used for each element of frequency_data: 1, 4, or 8.
79 m : uint8 frequency_size;
80 :
81 : // Each module only needs to be registered once with the call-trace service.
82 : // Our hooks grab various entry points (e.g. TLS initializers and the image
83 : // entry points), so the initialization routine may be called repeatedly. We
84 : // use this to determine whether or not we should try initializing things.
85 : // Upon first entry this is protected by the loader lock and afterwards it
86 : // is only read, so synchronization is not an issue.
87 m : uint8 initialization_attempted;
88 :
89 : // The type of data associated with this module.
90 m : uint8 data_type;
91 m : };
92 m : COMPILE_ASSERT_IS_POD(IndexedFrequencyData);
93 :
94 : // Indexed frequency data that is managed as a thread local. Used by the basic
95 : // block entry instrumentation and agent, and variants.
96 m : struct ThreadLocalIndexedFrequencyData {
97 : // The indexed frequency data information common for all agents.
98 m : ::common::IndexedFrequencyData module_data;
99 :
100 : // The TLS slot associated with this module (if any). This allows for the
101 : // frequency trace data to be managed on a per-thread basis, if desired by the
102 : // agent. The TLS index is initialized to TLS_OUT_OF_INDEXES by the
103 : // instrumenter.
104 m : DWORD tls_index;
105 :
106 : // The FS slot associated with this module (if any). This allows for the
107 : // frequency trace data to be managed on a per-thread basis, if desired by the
108 : // agent. An unused slot is initialized to zero by the instrumenter, otherwise
109 : // it is initialized to a slot index between 1 and 4.
110 m : DWORD fs_slot;
111 m : };
112 :
113 : #pragma pack(pop)
114 :
115 : // The basic-block coverage agent ID.
116 m : extern const uint32 kBasicBlockCoverageAgentId;
117 :
118 : // The basic-block entry counting agent ID.
119 m : extern const uint32 kBasicBlockEntryAgentId;
120 :
121 : // The jump table counting agent ID.
122 m : extern const uint32 kJumpTableCountAgentId;
123 :
124 : // The basic-block trace agent version.
125 m : extern const uint32 kBasicBlockFrequencyDataVersion;
126 :
127 : // The branch trace agent version.
128 m : extern const uint32 kBranchFrequencyDataVersion;
129 :
130 : // The jump table trace agent version.
131 m : extern const uint32 kJumpTableFrequencyDataVersion;
132 :
133 : // The name of the basic-block ranges stream added to the PDB by
134 : // any instrumentation employing basic-block trace data.
135 m : extern const char kBasicBlockRangesStreamName[];
136 :
137 : // A string table mapping from DataType to text representation.
138 : // This array must be maintained if enum DataType is changed.
139 m : extern const char* IndexedFrequencyDataTypeName[];
140 :
141 : // Produce a human readable name for the IndexedFrequencyData::DataType.
142 : // @param type type to convert in string.
143 : // @param result on success, receives the textual representation of @p type.
144 m : bool IndexedFrequencyDataTypeToString(IndexedFrequencyData::DataType type,
145 m : std::string* result);
146 :
147 : // Parse a string to get the IndexedFrequencyData::DataType.
148 : // @param str the string to convert.
149 : // @param result on success, receives the DataType value of @p str.
150 m : bool ParseFrequencyDataType(const base::StringPiece& str,
151 m : IndexedFrequencyData::DataType* type);
152 :
153 m : } // namespace common
154 :
155 : #endif // SYZYGY_COMMON_INDEXED_FREQUENCY_DATA_H_
|