Coverage for /Syzygy/reorder/reorder_main.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00131.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   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    :  // Parses a module and ETW trace files, generating an ordering of the
  16    :  // blocks in the decomposed image.
  17    :  
  18    :  #include <objbase.h>
  19    :  #include <iostream>
  20    :  
  21    :  #include "base/at_exit.h"
  22    :  #include "base/command_line.h"
  23    :  #include "base/file_path.h"
  24    :  #include "base/string_number_conversions.h"
  25    :  #include "base/string_split.h"
  26    :  #include "base/stringprintf.h"
  27    :  #include "syzygy/reorder/dead_code_finder.h"
  28    :  #include "syzygy/reorder/linear_order_generator.h"
  29    :  #include "syzygy/reorder/random_order_generator.h"
  30    :  
  31  m :  using reorder::DeadCodeFinder;
  32  m :  using reorder::LinearOrderGenerator;
  33  m :  using reorder::RandomOrderGenerator;
  34  m :  using reorder::Reorderer;
  35    :  
  36  m :  static const char kUsage[] =
  37  m :      "Usage: reorder [options] [ETW log files ...]\n"
  38  m :      "  Required Options:\n"
  39  m :      "    --instrumented-dll=<path> the path to the instrumented DLL.\n"
  40  m :      "    --output-file=<path> the output file.\n"
  41  m :      "  Optional Options:\n"
  42  m :      "    --input-dll=<path> the input DLL to reorder. If this is not\n"
  43  m :      "        specified it will be inferred from the instrumented DLL\n"
  44  m :      "        metadata.\n"
  45  m :      "    --seed=INT generates a random ordering; don't specify ETW log files.\n"
  46  m :      "    --list-dead-code instead of an ordering, output the set of functions\n"
  47  m :      "        not visited during the trace.\n"
  48  m :      "    --pretty-print enables pretty printing of the JSON output file.\n"
  49  m :      "    --reorderer-flags=<comma separated reorderer flags>\n"
  50  m :      "  Reorderer Flags:\n"
  51  m :      "    no-code: Do not reorder code sections.\n"
  52  m :      "    no-data: Do not reorder data sections.\n";
  53    :  
  54  m :  const char kFlags[] = "reorderer-flags";
  55    :  
  56  m :  static int Usage(const char* message) {
  57  m :    std::cerr << message << std::endl << kUsage;
  58    :  
  59  m :    return 1;
  60  m :  }
  61    :  
  62    :  // Parses reorderer flags. Returns true on success, false otherwise. On
  63    :  // failure, also outputs Usage with an error message.
  64  m :  static bool ParseReordererFlags(CommandLine* cmd_line,
  65  m :                                  Reorderer::Flags* flags) {
  66  m :    DCHECK(cmd_line != NULL);
  67  m :    DCHECK(flags != NULL);
  68    :  
  69  m :    Reorderer::Flags out_flags = (Reorderer::kFlagReorderData |
  70  m :                                  Reorderer::kFlagReorderCode);
  71    :  
  72  m :    if (cmd_line->HasSwitch(kFlags)) {
  73  m :      typedef std::vector<std::string> TextFlags;
  74  m :      TextFlags text_flags;
  75  m :      base::SplitString(cmd_line->GetSwitchValueASCII(kFlags), ',', &text_flags);
  76  m :      TextFlags::const_iterator flag_iter = text_flags.begin();
  77  m :      for (; flag_iter != text_flags.end(); ++flag_iter) {
  78  m :        if (*flag_iter == "no-data") {
  79  m :          out_flags &= ~Reorderer::kFlagReorderData;
  80  m :        } else if (*flag_iter == "no-code") {
  81  m :          out_flags &= ~Reorderer::kFlagReorderCode;
  82  m :        } else if (!flag_iter->empty()) {
  83  m :          std::string message = base::StringPrintf("Unknown reorderer flag: %s.",
  84  m :                                                   flag_iter->c_str());
  85  m :          Usage(message.c_str());
  86  m :          return false;
  87  m :        }
  88  m :      }
  89  m :    }
  90  m :    *flags = out_flags;
  91    :  
  92  m :    return true;
  93  m :  }
  94    :  
  95  m :  int main(int argc, char** argv) {
  96  m :    base::AtExitManager at_exit_manager;
  97  m :    CommandLine::Init(argc, argv);
  98    :  
  99  m :    if (!logging::InitLogging(L"", logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
 100  m :        logging::DONT_LOCK_LOG_FILE, logging::APPEND_TO_OLD_LOG_FILE,
 101  m :        logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS)) {
 102  m :      return 1;
 103  m :    }
 104    :  
 105  m :    CommandLine* cmd_line = CommandLine::ForCurrentProcess();
 106  m :    DCHECK(cmd_line != NULL);
 107    :  
 108    :    // Parse the command line.
 109  m :    typedef CommandLine::StringType StringType;
 110  m :    FilePath instrumented_dll_path =
 111  m :        cmd_line->GetSwitchValuePath("instrumented-dll");
 112  m :    FilePath input_dll_path = cmd_line->GetSwitchValuePath("input-dll");
 113  m :    FilePath output_file = cmd_line->GetSwitchValuePath("output-file");
 114    :  
 115  m :    int seed = 0;
 116  m :    StringType seed_str(cmd_line->GetSwitchValueNative("seed"));
 117  m :    if (!seed_str.empty() && !base::StringToInt(seed_str, &seed)) {
 118  m :      return Usage("Invalid seed value.");
 119  m :    }
 120    :  
 121  m :    std::vector<FilePath> trace_paths;
 122  m :    for (size_t i = 0; i < cmd_line->GetArgs().size(); ++i)
 123  m :      trace_paths.push_back(FilePath(cmd_line->GetArgs()[i]));
 124  m :    bool pretty_print = cmd_line->HasSwitch("pretty-print");
 125  m :    bool list_dead_code = cmd_line->HasSwitch("list-dead-code");
 126    :  
 127  m :    if (instrumented_dll_path.empty() || output_file.empty()) {
 128  m :      return Usage(
 129  m :          "You must specify instrumented-dll and output-file.");
 130  m :    }
 131    :  
 132  m :    if (seed_str.empty()) {
 133  m :      if (trace_paths.size() < 1) {
 134  m :        return Usage("You must specify at least one trace file "
 135  m :            "if you are not generating a random ordering.");
 136  m :      }
 137  m :    } else {
 138  m :      if (list_dead_code || trace_paths.size()) {
 139  m :        return Usage("Do not specify list-dead-code or ETW trace files when "
 140  m :            "generating a random ordering.");
 141  m :      }
 142  m :    }
 143    :  
 144  m :    Reorderer::Flags reorderer_flags = 0;
 145  m :    if (!ParseReordererFlags(cmd_line, &reorderer_flags)) {
 146  m :      return 1;
 147  m :    }
 148    :  
 149    :    // Initialize COM, as it is used by Decomposer, ComdatOrder and Reorderer.
 150  m :    if (FAILED(CoInitialize(NULL))) {
 151  m :      LOG(ERROR) << "Failed to initialize COM.";
 152  m :      return 1;
 153  m :    }
 154    :  
 155  m :    scoped_ptr<Reorderer::OrderGenerator> order_generator;
 156  m :    if (!seed_str.empty()) {
 157  m :      order_generator.reset(new RandomOrderGenerator(seed));
 158  m :    } else if (list_dead_code) {
 159  m :      order_generator.reset(new DeadCodeFinder());
 160  m :    } else {
 161  m :      order_generator.reset(new LinearOrderGenerator());
 162  m :    }
 163    :  
 164  m :    pe::PEFile input_dll;
 165  m :    block_graph::BlockGraph block_graph;
 166  m :    pe::ImageLayout image_layout(&block_graph);
 167  m :    reorder::Reorderer::Order order;
 168  m :    Reorderer reorderer(input_dll_path,
 169  m :                        instrumented_dll_path,
 170  m :                        trace_paths,
 171  m :                        reorderer_flags);
 172  m :    if (!reorderer.Reorder(order_generator.get(),
 173  m :                           &order,
 174  m :                           &input_dll,
 175  m :                           &image_layout)) {
 176  m :      LOG(ERROR) << "Reorder failed.";
 177  m :      return 1;
 178  m :    }
 179    :  
 180  m :    if (!order.SerializeToJSON(input_dll, output_file, pretty_print)) {
 181  m :      LOG(ERROR) << "Unable to output order.";
 182  m :      return 1;
 183  m :    }
 184    :  
 185  m :    CoUninitialize();
 186    :  
 187  m :    return 0;
 188  m :  }

Coverage information generated Thu Sep 06 11:30:46 2012.