blob: f7f836617be382476a8a3f0de594cc081c35c0c8 [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.
//
// Declares a simple API for transforming BlockGraphs in situ.
#ifndef SYZYGY_BLOCK_GRAPH_TRANSFORM_H_
#define SYZYGY_BLOCK_GRAPH_TRANSFORM_H_
#include "syzygy/block_graph/basic_block_subgraph.h"
#include "syzygy/block_graph/block_graph.h"
#include "syzygy/block_graph/ordered_block_graph.h"
#include "syzygy/block_graph/transform_policy.h"
#include "syzygy/pe/image_layout.h"
namespace block_graph {
// A BlockGraphTransform is a pure virtual base class defining the transform
// API.
class BlockGraphTransformInterface {
public:
virtual ~BlockGraphTransformInterface() { }
// Gets the name of this transform.
//
// @returns the name of this transform.
virtual const char* name() const = 0;
// Applies this transform to the provided block graph.
//
// @param policy The policy object restricting how the transform is applied.
// @param block_graph The block graph to transform.
// @param header_block The header block of the block graph to transform.
// @returns true on success, false otherwise.
virtual bool TransformBlockGraph(const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* header_block) = 0;
};
// This applies the provided BlockGraphTransform and checks that invariant has
// been satisfied; namely, that the header block has not been deleted from the
// block graph.
//
// @param transform The transform to apply.
// @param policy The policy object restricting how the transform is applied.
// @param block_graph The block graph to transform.
// @param header_block The header block from block_graph.
// @returns true on success, false otherwise.
bool ApplyBlockGraphTransform(BlockGraphTransformInterface* transform,
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* header_block);
// This applies the provided BlockGraphTransforms in series and checks that
// the invariant has been satisfied; namely, that the header block has not been
// deleted from the block graph.
//
// @param transforms The transforms to apply.
// @param policy The policy object restricting how the transform is applied.
// @param block_graph The block graph to transform.
// @param header_block The header block from block_graph.
// @returns true on success, false otherwise.
bool ApplyBlockGraphTransforms(
const std::vector<BlockGraphTransformInterface*>& transforms,
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* header_block);
// A BasicBlockSubGraphTransform is a pure virtual base class defining the
// basic-block transform API.
class BasicBlockSubGraphTransformInterface {
public:
virtual ~BasicBlockSubGraphTransformInterface() { }
// Gets the name of this transform.
//
// @returns the name of this transform.
virtual const char* name() const = 0;
// Applies this transform to the provided block.
//
// @param policy The policy object restricting how the transform is applied.
// @param block_graph the block-graph of which the basic block subgraph
// is a part.
// @param basic_block_subgraph the basic block subgraph to be transformed.
// @returns true on success, false otherwise.
virtual bool TransformBasicBlockSubGraph(
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BasicBlockSubGraph* basic_block_subgraph) = 0;
};
// Applies the provided BasicBlockSubGraphTransform to a single block. Takes
// care of basic-block decomposing the block, passes it to the transform, and
// recomposes the block.
//
// @param transform the transform to apply.
// @param policy The policy object restricting how the transform is applied.
// @param block_graph the block containing the block to be transformed.
// @param block the block to be transformed.
// @param new_blocks On success, any newly created blocks will be returned
// here. Note that this parameter may be NULL if you are not interested
// in retrieving the set of new blocks.
// @pre block must be a code block.
// @returns true on success, false otherwise.
bool ApplyBasicBlockSubGraphTransform(
BasicBlockSubGraphTransformInterface* transform,
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* block,
BlockVector* new_blocks);
// Applies a series of BasicBlockSubGraphTransform to a single block. Takes
// care of basic-block decomposing the block, passes it to the transform, and
// recomposes the block.
//
// @param transforms the series of transform to apply.
// @param policy The policy object restricting how the transform is applied.
// @param block_graph the block containing the block to be transformed.
// @param block the block to be transformed.
// @param new_blocks On success, any newly created blocks will be returned
// here. Note that this parameter may be NULL if you are not interested
// in retrieving the set of new blocks.
// @pre block must be a code block.
// @returns true on success, false otherwise.
bool ApplyBasicBlockSubGraphTransforms(
const std::vector<BasicBlockSubGraphTransformInterface*>& transforms,
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* block,
BlockVector* new_blocks);
// An ImageLayoutTransformInterface is a pure virtual base class defining the
// PE image layout transform API
class ImageLayoutTransformInterface {
public:
virtual ~ImageLayoutTransformInterface() { }
// Gets the name of this transform.
//
// @returns the name of this transform
virtual const char* name() const = 0;
// Applies this layout transform to the provided PE image. Contents of block
// data can be changed in-place, and references may be deleted, created and
// modified. However one cannot add, delete or reorder blocks and/or sections
// nor can the size of blocks or sections be changed by adding / deleting
// data bytes.
//
// @param policy The policy object restricting how the transform is applied.
// @param image_layout The PE image on which to apply the transform.
// @param ordered_block_graph A block graph view of the PE image
// @return true if successful, false otherwise
virtual bool TransformImageLayout(
const TransformPolicyInterface* policy,
const pe::ImageLayout* image_layout,
const OrderedBlockGraph* ordered_block_graph) = 0;
};
// Applies a single layout transform to a PE image. Checks if the transform
// preserves the number of blocks, the size and order of all blocks in the
// PE image.
//
// @param transform The transform to apply.
// @param policy The policy object restricting how the transform is applied.
// @param image_layout The PE image on which the transform is applied.
// @param ordered_block_graph A block graph view of the PE image.
// @return true if successful, false otherwise.
bool ApplyImageLayoutTransform(
ImageLayoutTransformInterface* transform,
const TransformPolicyInterface* policy,
const pe::ImageLayout* image_layout,
const OrderedBlockGraph* ordered_block_graph);
// Applies a series of layout transform to a PE image. Checks if the transforms
// preserve the number of blocks, the size and order of all blocks in the
// PE image.
//
// @param transforms The series of transforms to apply.
// @param policy The policy object restricting how the transform is applied.
// @param image_layout The PE image on which the transform is applied.
// @param ordered_block_graph A block graph view of the PE image.
// @return true if successful, false otherwise.
bool ApplyImageLayoutTransforms(
const std::vector<ImageLayoutTransformInterface*>& transforms,
const TransformPolicyInterface* policy,
const pe::ImageLayout* image_layout,
const OrderedBlockGraph* ordered_block_graph);
} // namespace block_graph
#endif // SYZYGY_BLOCK_GRAPH_TRANSFORM_H_