| 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 #ifndef COURGETTE_PATCH_GENERATOR_X86_32_H_ | 5 #ifndef COURGETTE_PATCH_GENERATOR_X86_32_H_ |
| 6 #define COURGETTE_PATCH_GENERATOR_X86_32_H_ | 6 #define COURGETTE_PATCH_GENERATOR_X86_32_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "courgette/assembly_program.h" | |
| 13 #include "courgette/courgette_flow.h" | 12 #include "courgette/courgette_flow.h" |
| 14 #include "courgette/ensemble.h" | 13 #include "courgette/ensemble.h" |
| 15 #include "courgette/patcher_x86_32.h" | 14 #include "courgette/patcher_x86_32.h" |
| 16 #include "courgette/program_detector.h" | |
| 17 | 15 |
| 18 namespace courgette { | 16 namespace courgette { |
| 19 | 17 |
| 20 // PatchGeneratorX86_32 is the universal patch generator for all executables, | 18 // PatchGeneratorX86_32 is the universal patch generator for all executables, |
| 21 // performing transformation and adjustment. The executable type is determined | 19 // performing transformation and adjustment. The executable type is determined |
| 22 // by the program detector. | 20 // by the program detector. |
| 23 class PatchGeneratorX86_32 : public TransformationPatchGenerator { | 21 class PatchGeneratorX86_32 : public TransformationPatchGenerator { |
| 24 public: | 22 public: |
| 25 PatchGeneratorX86_32(Element* old_element, | 23 PatchGeneratorX86_32(Element* old_element, |
| 26 Element* new_element, | 24 Element* new_element, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 44 | 42 |
| 45 Status PredictTransformParameters(SinkStreamSet* prediction) { | 43 Status PredictTransformParameters(SinkStreamSet* prediction) { |
| 46 return TransformationPatchGenerator::PredictTransformParameters(prediction); | 44 return TransformationPatchGenerator::PredictTransformParameters(prediction); |
| 47 } | 45 } |
| 48 | 46 |
| 49 Status CorrectedTransformParameters(SinkStreamSet* parameters) { | 47 Status CorrectedTransformParameters(SinkStreamSet* parameters) { |
| 50 // No code needed to write an 'empty' parameter set. | 48 // No code needed to write an 'empty' parameter set. |
| 51 return C_OK; | 49 return C_OK; |
| 52 } | 50 } |
| 53 | 51 |
| 54 // The format of a transformed_element is a serialized EncodedProgram. We | 52 // The format of a transformed_element is a serialized EncodedProgram. Steps: |
| 55 // first disassemble the original old and new Elements into AssemblyPrograms. | 53 // - Form Disassembler for the old and new Elements. |
| 56 // Then we adjust the new AssemblyProgram to make it as much like the old one | 54 // - Extract AssemblyPrograms from old and new Disassemblers. |
| 57 // as possible, before converting the AssemblyPrograms to EncodedPrograms and | 55 // - Adjust the new AssemblyProgram to make it as much like the old one as |
| 58 // serializing them. | 56 // possible. |
| 57 // - Serialize old and new Disassembler to EncodedProgram, using the old |
| 58 // AssemblyProgram and the adjusted new AssemblyProgram. |
| 59 // The steps are performed in an order to reduce peak memory. |
| 59 Status Transform(SourceStreamSet* corrected_parameters, | 60 Status Transform(SourceStreamSet* corrected_parameters, |
| 60 SinkStreamSet* old_transformed_element, | 61 SinkStreamSet* old_transformed_element, |
| 61 SinkStreamSet* new_transformed_element) { | 62 SinkStreamSet* new_transformed_element) { |
| 62 // Don't expect any corrected parameters. | 63 // Don't expect any corrected parameters. |
| 63 if (!corrected_parameters->Empty()) | 64 if (!corrected_parameters->Empty()) |
| 64 return C_GENERAL_ERROR; | 65 return C_GENERAL_ERROR; |
| 65 | 66 |
| 67 // Flow graph and process sequence (DA = Disassembler, AP = AssemblyProgram, |
| 68 // EP = EncodedProgram, Adj = Adjusted): |
| 69 // [1 Old DA] --> [2 Old AP] [6 New AP] <-- [5 New DA] |
| 70 // | | | | | |
| 71 // v | | v (move) v |
| 72 // [3 Old EP] <-----+ +->[7 Adj New AP] --> [8 New EP] |
| 73 // (4 Write) (9 Write) |
| 66 CourgetteFlow flow; | 74 CourgetteFlow flow; |
| 67 RegionBuffer old_buffer(old_element_->region()); | 75 RegionBuffer old_buffer(old_element_->region()); |
| 68 RegionBuffer new_buffer(new_element_->region()); | 76 RegionBuffer new_buffer(new_element_->region()); |
| 69 flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, true); | 77 flow.ReadDisassemblerFromBuffer(flow.OLD, old_buffer); // 1 |
| 70 flow.CreateEncodedProgramFromAssemblyProgram(flow.OLD); | 78 flow.CreateAssemblyProgramFromDisassembler(flow.OLD, true); // 2 |
| 79 flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.OLD); // 3 |
| 80 flow.DestroyDisassembler(flow.OLD); |
| 71 flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD, | 81 flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD, |
| 72 old_transformed_element); | 82 old_transformed_element); // 4 |
| 73 flow.DestroyEncodedProgram(flow.OLD); | 83 flow.DestroyEncodedProgram(flow.OLD); |
| 74 flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, true); | 84 flow.ReadDisassemblerFromBuffer(flow.NEW, new_buffer); // 5 |
| 75 flow.AdjustNewAssemblyProgramToMatchOld(); | 85 flow.CreateAssemblyProgramFromDisassembler(flow.NEW, true); // 6 |
| 86 flow.AdjustNewAssemblyProgramToMatchOld(); // 7 |
| 76 flow.DestroyAssemblyProgram(flow.OLD); | 87 flow.DestroyAssemblyProgram(flow.OLD); |
| 77 flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW); | 88 flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.NEW); // 8 |
| 78 flow.DestroyAssemblyProgram(flow.NEW); | 89 flow.DestroyAssemblyProgram(flow.NEW); |
| 90 flow.DestroyDisassembler(flow.NEW); |
| 79 flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW, | 91 flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW, |
| 80 new_transformed_element); | 92 new_transformed_element); // 9 |
| 81 if (flow.failed()) { | 93 if (flow.failed()) { |
| 82 LOG(ERROR) << flow.message() << " (" << old_element_->Name() << " => " | 94 LOG(ERROR) << flow.message() << " (" << old_element_->Name() << " => " |
| 83 << new_element_->Name() << ")"; | 95 << new_element_->Name() << ")"; |
| 84 } | 96 } |
| 85 return flow.status(); | 97 return flow.status(); |
| 86 } | 98 } |
| 87 | 99 |
| 88 Status Reform(SourceStreamSet* transformed_element, | 100 Status Reform(SourceStreamSet* transformed_element, |
| 89 SinkStream* reformed_element) { | 101 SinkStream* reformed_element) { |
| 90 return TransformationPatchGenerator::Reform(transformed_element, | 102 return TransformationPatchGenerator::Reform(transformed_element, |
| 91 reformed_element); | 103 reformed_element); |
| 92 } | 104 } |
| 93 | 105 |
| 94 private: | 106 private: |
| 95 virtual ~PatchGeneratorX86_32() { } | 107 virtual ~PatchGeneratorX86_32() { } |
| 96 | 108 |
| 97 ExecutableType kind_; | 109 ExecutableType kind_; |
| 98 | 110 |
| 99 DISALLOW_COPY_AND_ASSIGN(PatchGeneratorX86_32); | 111 DISALLOW_COPY_AND_ASSIGN(PatchGeneratorX86_32); |
| 100 }; | 112 }; |
| 101 | 113 |
| 102 } // namespace courgette | 114 } // namespace courgette |
| 103 | 115 |
| 104 #endif // COURGETTE_PATCH_GENERATOR_X86_32_H_ | 116 #endif // COURGETTE_PATCH_GENERATOR_X86_32_H_ |
| OLD | NEW |