blob: 3a6074af607a0a528cf408fc4b7fcb846a034bbe [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// The runtime portion of a code coverage client. This is responsible for
// starting the RPC connection and initializing an array where the baked-in
// instrumentation will dump its code coverage results. The instrumentation
// injects a run-time dependency on this library and adds appropriate
// initialization hooks.
#ifndef SYZYGY_AGENT_COVERAGE_COVERAGE_H_
#define SYZYGY_AGENT_COVERAGE_COVERAGE_H_
#include <windows.h>
#include <winnt.h>
#include <vector>
#include "base/lazy_instance.h"
#include "base/win/pe_image.h"
#include "syzygy/agent/common/entry_frame.h"
#include "syzygy/common/indexed_frequency_data.h"
#include "syzygy/trace/client/rpc_session.h"
// Instrumentation stubs to handle the loading of the library.
extern "C" void _cdecl _indirect_penter_dllmain();
namespace agent {
namespace coverage {
// There's a single instance of this class.
class Coverage {
public:
// This is overlaid on a hand-crafted ASM generated stack frame. See
// syzygy/agent/coverage/coverage.cc for details.
struct EntryHookFrame {
void* func_addr;
common::IndexedFrequencyData* coverage_data;
};
// The thunks _indirect_penter_dllmain and _indirect_exe_entry are redirected
// here.
static void WINAPI EntryHook(EntryHookFrame* entry_frame);
// Retrieves the coverage singleton instance.
static Coverage* Instance();
private:
// Make sure the LazyInstance can be created.
friend struct base::DefaultLazyInstanceTraits<Coverage>;
Coverage();
~Coverage();
// Initializes the given coverage data element.
bool InitializeCoverageData(void* module_base,
::common::IndexedFrequencyData* coverage_data);
// The RPC session we're logging to/through.
trace::client::RpcSession session_;
// The trace file segment we're writing module events to. The coverage data
// goes to specially allocated segments that we don't explicitly keep track
// of, but rather that we let live until the client gets torn down.
trace::client::TraceFileSegment segment_;
};
} // namespace coverage
} // namespace agent
#endif // SYZYGY_AGENT_COVERAGE_COVERAGE_H_