| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "courgette/third_party/bsdiff.h" | 17 #include "courgette/third_party/bsdiff.h" |
| 18 #include "courgette/courgette.h" | 18 #include "courgette/courgette.h" |
| 19 #include "courgette/streams.h" | 19 #include "courgette/streams.h" |
| 20 | 20 |
| 21 | 21 |
| 22 void PrintHelp() { | 22 void PrintHelp() { |
| 23 fprintf(stderr, | 23 fprintf(stderr, |
| 24 "Usage:\n" | 24 "Usage:\n" |
| 25 " courgette -supported <executable_file>\n" |
| 25 " courgette -dis <executable_file> <binary_assembly_file>\n" | 26 " courgette -dis <executable_file> <binary_assembly_file>\n" |
| 26 " courgette -asm <binary_assembly_file> <executable_file>\n" | 27 " courgette -asm <binary_assembly_file> <executable_file>\n" |
| 27 " courgette -disadj <executable_file> <reference> <binary_assembly_file>\n" | 28 " courgette -disadj <executable_file> <reference> <binary_assembly_file>\n" |
| 28 " courgette -gen <v1> <v2> <patch>\n" | 29 " courgette -gen <v1> <v2> <patch>\n" |
| 29 " courgette -apply <v1> <patch> <v2>\n" | 30 " courgette -apply <v1> <patch> <v2>\n" |
| 30 "\n"); | 31 "\n"); |
| 31 } | 32 } |
| 32 | 33 |
| 33 void UsageProblem(const char* message) { | 34 void UsageProblem(const char* message) { |
| 34 fprintf(stderr, "%s", message); | 35 fprintf(stderr, "%s", message); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 99 |
| 99 courgette::DeleteEncodedProgram(encoded); | 100 courgette::DeleteEncodedProgram(encoded); |
| 100 | 101 |
| 101 courgette::SinkStream sink; | 102 courgette::SinkStream sink; |
| 102 if (!sinks.CopyTo(&sink)) | 103 if (!sinks.CopyTo(&sink)) |
| 103 Problem("Can't combine serialized encoded program streams."); | 104 Problem("Can't combine serialized encoded program streams."); |
| 104 | 105 |
| 105 WriteSinkToFile(&sink, output_file); | 106 WriteSinkToFile(&sink, output_file); |
| 106 } | 107 } |
| 107 | 108 |
| 109 bool Supported(const FilePath& input_file) { |
| 110 bool result = false; |
| 111 |
| 112 std::string buffer = ReadOrFail(input_file, "input"); |
| 113 |
| 114 courgette::ExecutableType type; |
| 115 size_t detected_length; |
| 116 |
| 117 DetectExecutableType(buffer.c_str(), buffer.length(), |
| 118 &type, |
| 119 &detected_length); |
| 120 |
| 121 // If the detection fails, we just fall back on UNKNOWN |
| 122 std::string format = "Unsupported"; |
| 123 |
| 124 switch (type) |
| 125 { |
| 126 case courgette::EXE_UNKNOWN: |
| 127 break; |
| 128 |
| 129 case courgette::EXE_WIN_32_X86: |
| 130 format = "Windows 32 PE"; |
| 131 result = true; |
| 132 break; |
| 133 |
| 134 case courgette::EXE_ELF_32_X86: |
| 135 format = "ELF 32 X86"; |
| 136 result = true; |
| 137 break; |
| 138 } |
| 139 |
| 140 printf("%s Executable\n", format.c_str()); |
| 141 return result; |
| 142 } |
| 143 |
| 108 void DisassembleAndAdjust(const FilePath& program_file, | 144 void DisassembleAndAdjust(const FilePath& program_file, |
| 109 const FilePath& model_file, | 145 const FilePath& model_file, |
| 110 const FilePath& output_file) { | 146 const FilePath& output_file) { |
| 111 std::string program_buffer = ReadOrFail(program_file, "program"); | 147 std::string program_buffer = ReadOrFail(program_file, "program"); |
| 112 std::string model_buffer = ReadOrFail(model_file, "reference"); | 148 std::string model_buffer = ReadOrFail(model_file, "reference"); |
| 113 | 149 |
| 114 courgette::AssemblyProgram* program = NULL; | 150 courgette::AssemblyProgram* program = NULL; |
| 115 const courgette::Status parse_program_status = | 151 const courgette::Status parse_program_status = |
| 116 courgette::ParseDetectedExecutable(program_buffer.c_str(), | 152 courgette::ParseDetectedExecutable(program_buffer.c_str(), |
| 117 program_buffer.length(), | 153 program_buffer.length(), |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 420 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 385 | 421 |
| 386 (void)logging::InitLogging( | 422 (void)logging::InitLogging( |
| 387 FILE_PATH_LITERAL("courgette.log"), | 423 FILE_PATH_LITERAL("courgette.log"), |
| 388 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, | 424 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, |
| 389 logging::LOCK_LOG_FILE, | 425 logging::LOCK_LOG_FILE, |
| 390 logging::APPEND_TO_OLD_LOG_FILE, | 426 logging::APPEND_TO_OLD_LOG_FILE, |
| 391 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); | 427 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); |
| 392 logging::SetMinLogLevel(logging::LOG_VERBOSE); | 428 logging::SetMinLogLevel(logging::LOG_VERBOSE); |
| 393 | 429 |
| 430 bool cmd_sup = command_line.HasSwitch("supported"); |
| 394 bool cmd_dis = command_line.HasSwitch("dis"); | 431 bool cmd_dis = command_line.HasSwitch("dis"); |
| 395 bool cmd_asm = command_line.HasSwitch("asm"); | 432 bool cmd_asm = command_line.HasSwitch("asm"); |
| 396 bool cmd_disadj = command_line.HasSwitch("disadj"); | 433 bool cmd_disadj = command_line.HasSwitch("disadj"); |
| 397 bool cmd_make_patch = command_line.HasSwitch("gen"); | 434 bool cmd_make_patch = command_line.HasSwitch("gen"); |
| 398 bool cmd_apply_patch = command_line.HasSwitch("apply"); | 435 bool cmd_apply_patch = command_line.HasSwitch("apply"); |
| 399 bool cmd_make_bsdiff_patch = command_line.HasSwitch("genbsdiff"); | 436 bool cmd_make_bsdiff_patch = command_line.HasSwitch("genbsdiff"); |
| 400 bool cmd_apply_bsdiff_patch = command_line.HasSwitch("applybsdiff"); | 437 bool cmd_apply_bsdiff_patch = command_line.HasSwitch("applybsdiff"); |
| 401 bool cmd_spread_1_adjusted = command_line.HasSwitch("gen1a"); | 438 bool cmd_spread_1_adjusted = command_line.HasSwitch("gen1a"); |
| 402 bool cmd_spread_1_unadjusted = command_line.HasSwitch("gen1u"); | 439 bool cmd_spread_1_unadjusted = command_line.HasSwitch("gen1u"); |
| 403 | 440 |
| 404 std::vector<FilePath> values; | 441 std::vector<FilePath> values; |
| 405 const CommandLine::StringVector& args = command_line.GetArgs(); | 442 const CommandLine::StringVector& args = command_line.GetArgs(); |
| 406 for (size_t i = 0; i < args.size(); ++i) { | 443 for (size_t i = 0; i < args.size(); ++i) { |
| 407 values.push_back(FilePath(args[i])); | 444 values.push_back(FilePath(args[i])); |
| 408 } | 445 } |
| 409 | 446 |
| 410 // '-repeat=N' is for debugging. Running many iterations can reveal leaks and | 447 // '-repeat=N' is for debugging. Running many iterations can reveal leaks and |
| 411 // bugs in cleanup. | 448 // bugs in cleanup. |
| 412 int repeat_count = 1; | 449 int repeat_count = 1; |
| 413 std::string repeat_switch = command_line.GetSwitchValueASCII("repeat"); | 450 std::string repeat_switch = command_line.GetSwitchValueASCII("repeat"); |
| 414 if (!repeat_switch.empty()) | 451 if (!repeat_switch.empty()) |
| 415 if (!base::StringToInt(repeat_switch, &repeat_count)) | 452 if (!base::StringToInt(repeat_switch, &repeat_count)) |
| 416 repeat_count = 1; | 453 repeat_count = 1; |
| 417 | 454 |
| 418 if (cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch + cmd_apply_patch + | 455 if (cmd_sup + cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch + |
| 419 cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch + | 456 cmd_apply_patch + cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch + |
| 420 cmd_spread_1_adjusted + cmd_spread_1_unadjusted | 457 cmd_spread_1_adjusted + cmd_spread_1_unadjusted |
| 421 != 1) | 458 != 1) |
| 422 UsageProblem( | 459 UsageProblem( |
| 423 "Must have exactly one of:\n" | 460 "Must have exactly one of:\n" |
| 424 " -asm, -dis, -disadj, -gen or -apply, -genbsdiff or -applybsdiff."); | 461 " -supported -asm, -dis, -disadj, -gen or -apply, -genbsdiff" |
| 462 " or -applybsdiff."); |
| 425 | 463 |
| 426 while (repeat_count-- > 0) { | 464 while (repeat_count-- > 0) { |
| 427 if (cmd_dis) { | 465 if (cmd_sup) { |
| 428 if (values.size() != 2) | 466 if (values.size() != 1) |
| 429 UsageProblem("-dis <executable_file> <courgette_file>"); | 467 UsageProblem("-supported <executable_file>"); |
| 430 Disassemble(values[0], values[1]); | 468 return !Supported(values[0]); |
| 469 } else if (cmd_dis) { |
| 470 if (values.size() != 2) |
| 471 UsageProblem("-dis <executable_file> <courgette_file>"); |
| 472 Disassemble(values[0], values[1]); |
| 431 } else if (cmd_asm) { | 473 } else if (cmd_asm) { |
| 432 if (values.size() != 2) | 474 if (values.size() != 2) |
| 433 UsageProblem("-asm <courgette_file_input> <executable_file_output>"); | 475 UsageProblem("-asm <courgette_file_input> <executable_file_output>"); |
| 434 Assemble(values[0], values[1]); | 476 Assemble(values[0], values[1]); |
| 435 } else if (cmd_disadj) { | 477 } else if (cmd_disadj) { |
| 436 if (values.size() != 3) | 478 if (values.size() != 3) |
| 437 UsageProblem("-disadj <executable_file> <model> <courgette_file>"); | 479 UsageProblem("-disadj <executable_file> <model> <courgette_file>"); |
| 438 DisassembleAndAdjust(values[0], values[1], values[2]); | 480 DisassembleAndAdjust(values[0], values[1], values[2]); |
| 439 } else if (cmd_make_patch) { | 481 } else if (cmd_make_patch) { |
| 440 if (values.size() != 3) | 482 if (values.size() != 3) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 454 ApplyBSDiffPatch(values[0], values[1], values[2]); | 496 ApplyBSDiffPatch(values[0], values[1], values[2]); |
| 455 } else if (cmd_spread_1_adjusted || cmd_spread_1_unadjusted) { | 497 } else if (cmd_spread_1_adjusted || cmd_spread_1_unadjusted) { |
| 456 if (values.size() != 3) | 498 if (values.size() != 3) |
| 457 UsageProblem("-gen1[au] <old_file> <new_file> <patch_files_root>"); | 499 UsageProblem("-gen1[au] <old_file> <new_file> <patch_files_root>"); |
| 458 DisassembleAdjustDiff(values[0], values[1], values[2], | 500 DisassembleAdjustDiff(values[0], values[1], values[2], |
| 459 cmd_spread_1_adjusted); | 501 cmd_spread_1_adjusted); |
| 460 } else { | 502 } else { |
| 461 UsageProblem("No operation specified"); | 503 UsageProblem("No operation specified"); |
| 462 } | 504 } |
| 463 } | 505 } |
| 506 |
| 507 return 0; |
| 464 } | 508 } |
| OLD | NEW |