| 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_ASSEMBLY_PROGRAM_H_ | 5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_ |
| 6 #define COURGETTE_ASSEMBLY_PROGRAM_H_ | 6 #define COURGETTE_ASSEMBLY_PROGRAM_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include <map> | |
| 12 #include <memory> | 11 #include <memory> |
| 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/callback_forward.h" | 14 #include "base/callback_forward.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/free_deleter.h" | 16 #include "base/memory/free_deleter.h" |
| 17 #include "courgette/courgette.h" | 17 #include "courgette/courgette.h" |
| 18 #include "courgette/image_utils.h" | 18 #include "courgette/image_utils.h" |
| 19 #include "courgette/instruction_utils.h" | 19 #include "courgette/instruction_utils.h" |
| 20 #include "courgette/label_manager.h" | 20 #include "courgette/label_manager.h" |
| 21 #include "courgette/memory_allocator.h" | 21 #include "courgette/memory_allocator.h" |
| 22 | 22 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 // The optional step is to modify the AssemblyProgram. One form of modification | 71 // The optional step is to modify the AssemblyProgram. One form of modification |
| 72 // is to assign indexes in such a way as to make the EncodedProgram for this | 72 // is to assign indexes in such a way as to make the EncodedProgram for this |
| 73 // AssemblyProgram look more like the EncodedProgram for some other | 73 // AssemblyProgram look more like the EncodedProgram for some other |
| 74 // AssemblyProgram. The modification process should call UnassignIndexes, do | 74 // AssemblyProgram. The modification process should call UnassignIndexes, do |
| 75 // its own assignment, and then call AssignRemainingIndexes to ensure all | 75 // its own assignment, and then call AssignRemainingIndexes to ensure all |
| 76 // indexes are assigned. | 76 // indexes are assigned. |
| 77 | 77 |
| 78 class AssemblyProgram { | 78 class AssemblyProgram { |
| 79 public: | 79 public: |
| 80 using LabelHandler = base::Callback<void(Label*)>; | 80 using LabelHandler = base::Callback<void(Label*)>; |
| 81 using LabelHandlerMap = std::map<OP, LabelHandler>; | |
| 82 | 81 |
| 83 AssemblyProgram(ExecutableType kind, uint64_t image_base); | 82 AssemblyProgram(ExecutableType kind, uint64_t image_base); |
| 84 ~AssemblyProgram(); | 83 ~AssemblyProgram(); |
| 85 | 84 |
| 86 ExecutableType kind() const { return kind_; } | 85 ExecutableType kind() const { return kind_; } |
| 86 const std::vector<Label*>& abs32_label_annotations() const { |
| 87 return abs32_label_annotations_; |
| 88 } |
| 89 const std::vector<Label*>& rel32_label_annotations() const { |
| 90 return rel32_label_annotations_; |
| 91 } |
| 92 std::vector<Label*>* mutable_abs32_label_annotations() { |
| 93 return &abs32_label_annotations_; |
| 94 } |
| 95 std::vector<Label*>* mutable_rel32_label_annotations() { |
| 96 return &rel32_label_annotations_; |
| 97 } |
| 87 | 98 |
| 88 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. | 99 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. |
| 89 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); | 100 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); |
| 90 | 101 |
| 91 // Removes underused Labels. Thresholds used (0 = no trimming) is | 102 // Removes underused Labels. Thresholds used (0 = no trimming) is |
| 92 // architecture-dependent. | 103 // architecture-dependent. |
| 93 void TrimLabels(); | 104 void TrimLabels(); |
| 94 | 105 |
| 95 void UnassignIndexes(); | 106 void UnassignIndexes(); |
| 96 void DefaultAssignIndexes(); | 107 void DefaultAssignIndexes(); |
| 97 void AssignRemainingIndexes(); | 108 void AssignRemainingIndexes(); |
| 98 | 109 |
| 99 // Looks up abs32 label. Returns null if none found. | 110 // Looks up abs32 label. Returns null if none found. |
| 100 Label* FindAbs32Label(RVA rva); | 111 Label* FindAbs32Label(RVA rva); |
| 101 | 112 |
| 102 // Looks up rel32 label. Returns null if none found. | 113 // Looks up rel32 label. Returns null if none found. |
| 103 Label* FindRel32Label(RVA rva); | 114 Label* FindRel32Label(RVA rva); |
| 104 | 115 |
| 105 std::unique_ptr<EncodedProgram> Encode() const; | |
| 106 | |
| 107 // For each |instruction| in |instructions_|, looks up its opcode from | |
| 108 // |handler_map| for a handler. If a handler exists, invoke it by passing the | |
| 109 // |instruction|'s label. We assume that |handler_map| has correct keys, i.e., | |
| 110 // opcodes for an instruction that have label. | |
| 111 void HandleInstructionLabels(const LabelHandlerMap& handler_map) const; | |
| 112 | |
| 113 // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a | 116 // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a |
| 114 // receptor to count space requirement. In pass 2 we provide a receptor to | 117 // receptor to count space requirement. In pass 2 we provide a receptor to |
| 115 // store instructions. | 118 // store instructions. If |annotate_labels| is true, then extracts Label |
| 116 CheckBool GenerateInstructions(const InstructionGenerator& gen); | 119 // annotations into |*_label_annotations_|. |
| 120 CheckBool GenerateInstructions(const InstructionGenerator& gen, |
| 121 bool annotate_labels); |
| 122 |
| 123 // Returns an EncodeProgram that converts program to encoded form. |
| 124 std::unique_ptr<EncodedProgram> Encode() const; |
| 117 | 125 |
| 118 // TODO(huangs): Implement these in InstructionStoreReceptor. | 126 // TODO(huangs): Implement these in InstructionStoreReceptor. |
| 119 // Instructions will be assembled in the order they are emitted. | 127 // Instructions will be assembled in the order they are emitted. |
| 120 | 128 |
| 121 // Generates an entire base relocation table. | 129 // Generates an entire base relocation table. |
| 122 CheckBool EmitPeRelocs() WARN_UNUSED_RESULT; | 130 CheckBool EmitPeRelocs() WARN_UNUSED_RESULT; |
| 123 | 131 |
| 124 // Generates an ELF style relocation table for X86. | 132 // Generates an ELF style relocation table for X86. |
| 125 CheckBool EmitElfRelocation() WARN_UNUSED_RESULT; | 133 CheckBool EmitElfRelocation() WARN_UNUSED_RESULT; |
| 126 | 134 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 | 182 |
| 175 std::unique_ptr<Instruction* [], base::FreeDeleter> byte_instruction_cache_; | 183 std::unique_ptr<Instruction* [], base::FreeDeleter> byte_instruction_cache_; |
| 176 | 184 |
| 177 InstructionVector instructions_; // All the instructions in program. | 185 InstructionVector instructions_; // All the instructions in program. |
| 178 | 186 |
| 179 // Storage and lookup of Labels associated with target addresses. We use | 187 // Storage and lookup of Labels associated with target addresses. We use |
| 180 // separate abs32 and rel32 labels. | 188 // separate abs32 and rel32 labels. |
| 181 LabelManager abs32_label_manager_; | 189 LabelManager abs32_label_manager_; |
| 182 LabelManager rel32_label_manager_; | 190 LabelManager rel32_label_manager_; |
| 183 | 191 |
| 192 // Label pointers for each abs32 and rel32 location, sorted by file offset. |
| 193 // These are used by Label adjustment during patch generation. |
| 194 std::vector<Label*> abs32_label_annotations_; |
| 195 std::vector<Label*> rel32_label_annotations_; |
| 196 |
| 184 DISALLOW_COPY_AND_ASSIGN(AssemblyProgram); | 197 DISALLOW_COPY_AND_ASSIGN(AssemblyProgram); |
| 185 }; | 198 }; |
| 186 | 199 |
| 187 // Converts |program| into encoded form, returning it as |*output|. | 200 // Converts |program| into encoded form, returning it as |*output|. |
| 188 // Returns C_OK if succeeded, otherwise returns an error status and sets | 201 // Returns C_OK if succeeded, otherwise returns an error status and sets |
| 189 // |*output| to null. | 202 // |*output| to null. |
| 190 Status Encode(const AssemblyProgram& program, | 203 Status Encode(const AssemblyProgram& program, |
| 191 std::unique_ptr<EncodedProgram>* output); | 204 std::unique_ptr<EncodedProgram>* output); |
| 192 | 205 |
| 193 } // namespace courgette | 206 } // namespace courgette |
| 194 | 207 |
| 195 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ | 208 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ |
| OLD | NEW |