1 : // Copyright 2012 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 : // Utilities for dealing with block-graphs and blocks.
16 :
17 : #ifndef SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_
18 : #define SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_
19 :
20 : #include "syzygy/block_graph/basic_block.h"
21 : #include "syzygy/block_graph/basic_block_subgraph.h"
22 : #include "syzygy/block_graph/block_graph.h"
23 :
24 m : namespace block_graph {
25 :
26 : // Determines whether @p bb's instructions and successors comprise a contiguous
27 : // source range, and return it if so.
28 : // @param bb the basic block to inspect.
29 : // @param source_range returns @p bb's source range on success.
30 : // @returns true iff @p bb's instructions and successors comprise a contiguous
31 : // source range.
32 : // @note @p bb's source range is deemed contiguous if at least one instruction
33 : // or successor has a source range, and if all the source ranges constitute
34 : // a single contiguous range, irrespective order. This means that this
35 : // function may succeed even if instructions in @p bb have been added,
36 : // reordered or mutated.
37 m : bool GetBasicBlockSourceRange(const BasicCodeBlock& bb,
38 m : BlockGraph::Block::SourceRange* source_range);
39 :
40 : // Returns true if the given references @p ref from @p referrer may not safely
41 : // be redirected. If both the referrer and the referenced blocks are irregular
42 : // in any way (i.e., inline assembly, not generated by cl.exe, etc) we cannot
43 : // safely assume that @p ref has call semantics, i.e., where a return address
44 : // is at the top of stack at entry. Ideally we would decide this on the basis
45 : // of a full stack analysis, but beggars can't be choosers; plus, for
46 : // hand-coded assembly that's the halting problem :).
47 : // For any instrumentation or manipulation that uses return address swizzling,
48 : // instrumenting an unsafe reference generally leads to crashes.
49 m : bool IsUnsafeReference(const BlockGraph::Block* referrer,
50 m : const BlockGraph::Reference& ref);
51 :
52 : // Returns true if there are any instructions manipulating the stack frame
53 : // pointer in an unexpected way. We expect the compiler to produce a standard
54 : // stack frame with two pointers (base EBP, top ESP). Any writes to EBP inside
55 : // this scope is reported as unexpected by this function.
56 : // @param subgraph The subgraph to inspect.
57 m : bool HasUnexpectedStackFrameManipulation(BasicBlockSubGraph* subgraph);
58 :
59 : // Calculates the number of entries in a given jump table. A jump table is a run
60 : // of contiguous 32-bit references terminating when there is no next reference,
61 : // at the next data label or the end of the block, whichever comes first.
62 : // @param block The block containing this jump table.
63 : // @param jump_table_label An iterator to the jump table label in this block.
64 : // @param table_size Will receive the size of the jump table.
65 : // @returns true on success, false otherwise.
66 m : bool GetJumpTableSize(const block_graph::BlockGraph::Block* block,
67 m : block_graph::BlockGraph::Block::LabelMap::const_iterator jump_table_label,
68 m : size_t* table_size);
69 :
70 m : } // namespace block_graph
71 :
72 : #endif // SYZYGY_BLOCK_GRAPH_BLOCK_UTIL_H_
|