blob: 4cb901938f323614e8224117a977157439a12194 [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.
//
// Utilities for dealing with block-graphs and blocks.
#ifndef SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_
#define SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_
#include "syzygy/block_graph/basic_block.h"
#include "syzygy/block_graph/basic_block_subgraph.h"
#include "syzygy/block_graph/block_graph.h"
namespace block_graph {
// Determines whether @p bb's instructions and successors comprise a contiguous
// source range, and return it if so.
// @param bb the basic block to inspect.
// @param source_range returns @p bb's source range on success.
// @returns true iff @p bb's instructions and successors comprise a contiguous
// source range.
// @note @p bb's source range is deemed contiguous if at least one instruction
// or successor has a source range, and if all the source ranges constitute
// a single contiguous range, irrespective order. This means that this
// function may succeed even if instructions in @p bb have been added,
// reordered or mutated.
bool GetBasicBlockSourceRange(const BasicCodeBlock& bb,
BlockGraph::Block::SourceRange* source_range);
// Returns true if the given references @p ref from @p referrer may not safely
// be redirected. If both the referrer and the referenced blocks are irregular
// in any way (i.e., inline assembly, not generated by cl.exe, etc) we cannot
// safely assume that @p ref has call semantics, i.e., where a return address
// is at the top of stack at entry. Ideally we would decide this on the basis
// of a full stack analysis, but beggars can't be choosers; plus, for
// hand-coded assembly that's the halting problem :).
// For any instrumentation or manipulation that uses return address swizzling,
// instrumenting an unsafe reference generally leads to crashes.
bool IsUnsafeReference(const BlockGraph::Block* referrer,
const BlockGraph::Reference& ref);
// Returns true if there are any instructions manipulating the stack frame
// pointer in an unexpected way. We expect the compiler to produce a standard
// stack frame with two pointers (base EBP, top ESP). Any writes to EBP inside
// this scope is reported as unexpected by this function.
// @param subgraph The subgraph to inspect.
bool HasUnexpectedStackFrameManipulation(BasicBlockSubGraph* subgraph);
// Calculates the number of entries in a given jump table. A jump table is a run
// of contiguous 32-bit references terminating when there is no next reference,
// at the next data label or the end of the block, whichever comes first.
// @param block The block containing this jump table.
// @param jump_table_label An iterator to the jump table label in this block.
// @param table_size Will receive the size of the jump table.
// @returns true on success, false otherwise.
bool GetJumpTableSize(const block_graph::BlockGraph::Block* block,
block_graph::BlockGraph::Block::LabelMap::const_iterator jump_table_label,
size_t* table_size);
} // namespace block_graph
#endif // SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_