blob: 0faf5d3baba5b8a55957826ac603c42be997aee0 [file] [log] [blame]
// Copyright 2013 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 utilities that are common in the decomposing, transforming,
// ordering, laying out and writing of a PE image file. These utilities
// constitute the core tasks performed by the PERelinker.
#ifndef SYZYGY_PE_PE_RELINKER_UTIL_H_
#define SYZYGY_PE_PE_RELINKER_UTIL_H_
#include "base/files/file_path.h"
#include "syzygy/block_graph/ordered_block_graph.h"
#include "syzygy/pdb/pdb_file.h"
#include "syzygy/pe/image_layout.h"
#include "syzygy/pe/image_source_map.h"
#include "syzygy/pe/pe_transform_policy.h"
namespace pe {
// Validates input and output module paths, and infers/validates input and
// output PDB paths. Logs an error on failure.
// @param input_module The path to the input module.
// @param output_module The path to the output module.
// @param allow_overwrite If true then this won't check to ensure that the
// output paths already exist.
// @param input_pdb The path to the input PDB. This may be empty, in which
// case it will be automatically determined.
// @param output_pdb The path to the output PDB. This may be empty, in
// which case it will be automatically determined.
// @returns true on success, false otherwise.
bool ValidateAndInferPaths(const base::FilePath& input_module,
const base::FilePath& output_module,
bool allow_overwrite,
base::FilePath* input_pdb,
base::FilePath* output_pdb);
// Finalizes a block-graph, preparing it for ordering and laying out. This
// performs the following operations:
// - Adds metadata, if requested to.
// - Update the PDB information to point to the correct PDB file.
// - Finally, run the prepare headers transform. This ensures that the
// header block is properly sized to receive layout information
// post-ordering.
// @param input_module The path to the original input module the block-graph
// was built from.
// @param output_pdb The path to the PDB that will refer to the transformed
// PE file.
// @param pdb_guid The GUID to be used in the PDB file.
// @param add_metadata If true then the block-graph will be augmented with
// metadata describing the transforms and Syzygy toolchain.
// @param policy The policy object to be used in applying any transforms.
// @param block_graph The block-graph to be finalized.
// @param dos_header_block The DOS header block in the block-graph.
// @returns true on success, false otherwise.
bool FinalizeBlockGraph(const base::FilePath& input_module,
const base::FilePath& output_pdb,
const GUID& pdb_guid,
bool add_metadata,
const PETransformPolicy* policy,
block_graph::BlockGraph* block_graph,
block_graph::BlockGraph::Block* dos_header_block);
// Finalizes an ordered block-graph, preparing it for laying out. This simply
// runs the PEOrderer which ensures that PE structures are in the appropriate
// places.
// @param ordered_block_graph The ordered block-graph to be finalized.
// @param dos_header_block The DOS header block in the block-graph.
// @returns true on success, false otherwise.
bool FinalizeOrderedBlockGraph(
block_graph::OrderedBlockGraph* ordered_block_graph,
block_graph::BlockGraph::Block* dos_header_block);
// Builds an image layout for an ordered block-graph.
// @param padding The minimum amount of padding to apply between blocks.
// @param code_alignment The minimum alignment to enforce for code blocks.
// @param ordered_block_graph The image to be laid out.
// @param dos_header_block The DOS header block in the image.
// @param image_layout The image-layout to be populated.
// @returns true on success, false otherwise.
bool BuildImageLayout(size_t padding,
size_t code_alignment,
const block_graph::OrderedBlockGraph& ordered_block_graph,
block_graph::BlockGraph::Block* dos_header_block,
ImageLayout* image_layout);
// Given the sections from an image layout calculates the source range that any
// derived OMAP information must cover. This should be calculated on the
// original untransformed image.
// @param sections The array of sections describing the original image.
// @param range The range to be populated.
void GetOmapRange(const std::vector<ImageLayout::SectionInfo>& sections,
RelativeAddressRange* range);
// Given a transformed PDB file, finalizes it in preparation for writing. This
// performs the following tasks:
// - Sets the new GUID and clears the age count of the PDB to 1.
// - Calculates OMAP information and injects it into the PDB.
// - Adds/updates the Syzygy history stream which contains a record of
// operations performed by the toolchain.
// - If requested, serializes the block-graph to the PDB in an additional
// stream.
// - Finalizes the PDB header.
// - Removes stream 0, the previous PDB directory stream.
// @param input_module The path to the original input module.
// @param output_module The path to the transformed output module.
// @param input_range The input range of the original image, as calculated by
// GetOmapRange.
// @param image_layout The transformed image layout.
// @param guid The guid of the new PDB.
// @param augment_pdb If true then the serialized block-graph will be emitted to
// the PDB.
// @param strip_strings If true then all strings will be stripped from the
// serialized block-graph, to save on space. Has no effect unless
// @p augment_pdb is true.
// @param compress_pdb If true then the serialized block-graph will be
// compressed. Has no effect unless @p augment_pdb is true.
// @param pdb_file The decomposed original PDB file to be updated.
// @returns true on success, false otherwise.
// @pre The transformed PE file must already have been written and finalized
// prior to calling this.
bool FinalizePdbFile(const base::FilePath input_module,
const base::FilePath output_module,
const RelativeAddressRange input_range,
const ImageLayout& image_layout,
const GUID& guid,
bool augment_pdb,
bool strip_strings,
bool compress_pdb,
pdb::PdbFile* pdb_file);
} // namespace pe
#endif // SYZYGY_PE_PE_RELINKER_UTIL_H_