| // 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_ |