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 |