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 "courgette/assembly_program.h" | 5 #include "courgette/assembly_program.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "courgette/courgette.h" | 9 #include "courgette/courgette.h" |
| 10 #include "courgette/disassembler.h" |
10 #include "courgette/encoded_program.h" | 11 #include "courgette/encoded_program.h" |
11 | 12 |
12 namespace courgette { | 13 namespace courgette { |
13 | 14 |
14 namespace { | 15 namespace { |
15 | 16 |
16 // Sets the current address for the emitting instructions. | 17 // Sets the current address for the emitting instructions. |
17 class OriginInstruction : public Instruction { | 18 class OriginInstruction : public Instruction { |
18 public: | 19 public: |
19 explicit OriginInstruction(RVA rva) : Instruction(ORIGIN, 0), rva_(rva) {} | 20 explicit OriginInstruction(RVA rva) : Instruction(ORIGIN, 0), rva_(rva) {} |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 uint16_t op_size_; | 98 uint16_t op_size_; |
98 }; | 99 }; |
99 | 100 |
100 /******** InstructionCountReceptor ********/ | 101 /******** InstructionCountReceptor ********/ |
101 | 102 |
102 // An InstructionReceptor that counts space occupied by emitted instructions. | 103 // An InstructionReceptor that counts space occupied by emitted instructions. |
103 class InstructionCountReceptor : public InstructionReceptor { | 104 class InstructionCountReceptor : public InstructionReceptor { |
104 public: | 105 public: |
105 InstructionCountReceptor() = default; | 106 InstructionCountReceptor() = default; |
106 | 107 |
107 size_t size() const { return size_; } | 108 size_t abs_count() const { return abs_count_; } |
| 109 size_t rel_count() const { return rel_count_; } |
108 | 110 |
109 // InstructionReceptor: | 111 // InstructionReceptor: |
110 // TODO(huangs): 2016/11: Populate these with size_ += ... | |
111 CheckBool EmitPeRelocs() override { return true; } | 112 CheckBool EmitPeRelocs() override { return true; } |
112 CheckBool EmitElfRelocation() override { return true; } | 113 CheckBool EmitElfRelocation() override { return true; } |
113 CheckBool EmitElfARMRelocation() override { return true; } | 114 CheckBool EmitElfARMRelocation() override { return true; } |
114 CheckBool EmitOrigin(RVA rva) override { return true; } | 115 CheckBool EmitOrigin(RVA rva) override { return true; } |
115 CheckBool EmitSingleByte(uint8_t byte) override { return true; } | 116 CheckBool EmitSingleByte(uint8_t byte) override { return true; } |
116 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { | 117 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { |
117 return true; | 118 return true; |
118 } | 119 } |
119 CheckBool EmitRel32(Label* label) override { return true; } | 120 CheckBool EmitRel32(Label* label) override { |
| 121 ++rel_count_; |
| 122 return true; |
| 123 } |
120 CheckBool EmitRel32ARM(uint16_t op, | 124 CheckBool EmitRel32ARM(uint16_t op, |
121 Label* label, | 125 Label* label, |
122 const uint8_t* arm_op, | 126 const uint8_t* arm_op, |
123 uint16_t op_size) override { | 127 uint16_t op_size) override { |
| 128 ++rel_count_; |
124 return true; | 129 return true; |
125 } | 130 } |
126 CheckBool EmitAbs32(Label* label) override { return true; } | 131 CheckBool EmitAbs32(Label* label) override { |
127 CheckBool EmitAbs64(Label* label) override { return true; } | 132 ++abs_count_; |
| 133 return true; |
| 134 } |
| 135 CheckBool EmitAbs64(Label* label) override { |
| 136 ++abs_count_; |
| 137 return true; |
| 138 } |
128 | 139 |
129 private: | 140 private: |
130 size_t size_ = 0; | 141 size_t abs_count_ = 0; |
| 142 size_t rel_count_ = 0; |
131 | 143 |
132 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); | 144 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); |
133 }; | 145 }; |
134 | 146 |
135 /******** InstructionStoreReceptor ********/ | 147 /******** InstructionStoreReceptor ********/ |
136 | 148 |
137 // An InstructionReceptor that stores emitted instructions. | 149 // An InstructionReceptor that stores emitted instructions. |
138 class InstructionStoreReceptor : public InstructionReceptor { | 150 class InstructionStoreReceptor : public InstructionReceptor { |
139 public: | 151 public: |
140 explicit InstructionStoreReceptor(AssemblyProgram* program) | 152 InstructionStoreReceptor(AssemblyProgram* program, bool annotate_labels) |
141 : program_(program) { | 153 : program_(program), annotate_labels_(annotate_labels) { |
142 CHECK(program_); | 154 CHECK(program_); |
143 } | 155 } |
144 | 156 |
145 // TODO(huangs): 2016/11: Add Reserve(). | 157 // TODO(huangs): 2017/04: Add Reserve(). |
146 | 158 |
147 // InstructionReceptor: | 159 // InstructionReceptor: |
148 // TODO(huangs): 2016/11: Replace stub with implementation. | 160 // TODO(huangs): 2017/04: Move implementations here. |
149 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); } | 161 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); } |
150 CheckBool EmitElfRelocation() override { | 162 CheckBool EmitElfRelocation() override { |
151 return program_->EmitElfRelocation(); | 163 return program_->EmitElfRelocation(); |
152 } | 164 } |
153 CheckBool EmitElfARMRelocation() override { | 165 CheckBool EmitElfARMRelocation() override { |
154 return program_->EmitElfARMRelocation(); | 166 return program_->EmitElfARMRelocation(); |
155 } | 167 } |
156 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); } | 168 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); } |
157 CheckBool EmitSingleByte(uint8_t byte) override { | 169 CheckBool EmitSingleByte(uint8_t byte) override { |
158 return program_->EmitSingleByte(byte); | 170 return program_->EmitSingleByte(byte); |
159 } | 171 } |
160 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { | 172 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { |
161 return program_->EmitMultipleBytes(bytes, len); | 173 return program_->EmitMultipleBytes(bytes, len); |
162 } | 174 } |
163 CheckBool EmitRel32(Label* label) override { | 175 CheckBool EmitRel32(Label* label) override { |
| 176 if (annotate_labels_) |
| 177 program_->mutable_rel32_label_annotations()->push_back(label); |
164 return program_->EmitRel32(label); | 178 return program_->EmitRel32(label); |
165 } | 179 } |
166 CheckBool EmitRel32ARM(uint16_t op, | 180 CheckBool EmitRel32ARM(uint16_t op, |
167 Label* label, | 181 Label* label, |
168 const uint8_t* arm_op, | 182 const uint8_t* arm_op, |
169 uint16_t op_size) override { | 183 uint16_t op_size) override { |
| 184 if (annotate_labels_) |
| 185 program_->mutable_rel32_label_annotations()->push_back(label); |
170 return program_->EmitRel32ARM(op, label, arm_op, op_size); | 186 return program_->EmitRel32ARM(op, label, arm_op, op_size); |
171 } | 187 } |
172 CheckBool EmitAbs32(Label* label) override { | 188 CheckBool EmitAbs32(Label* label) override { |
| 189 if (annotate_labels_) |
| 190 program_->mutable_abs32_label_annotations()->push_back(label); |
173 return program_->EmitAbs32(label); | 191 return program_->EmitAbs32(label); |
174 } | 192 } |
175 CheckBool EmitAbs64(Label* label) override { | 193 CheckBool EmitAbs64(Label* label) override { |
| 194 if (annotate_labels_) |
| 195 program_->mutable_abs32_label_annotations()->push_back(label); |
176 return program_->EmitAbs64(label); | 196 return program_->EmitAbs64(label); |
177 } | 197 } |
178 | 198 |
179 private: | 199 private: |
180 AssemblyProgram* program_; | 200 AssemblyProgram* program_; |
| 201 const bool annotate_labels_; |
181 | 202 |
182 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); | 203 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); |
183 }; | 204 }; |
184 | 205 |
185 } // namespace | 206 } // namespace |
186 | 207 |
187 /******** AssemblyProgram ********/ | 208 /******** AssemblyProgram ********/ |
188 | 209 |
189 AssemblyProgram::AssemblyProgram(ExecutableType kind, uint64_t image_base) | 210 AssemblyProgram::AssemblyProgram(ExecutableType kind, uint64_t image_base) |
190 : kind_(kind), image_base_(image_base) {} | 211 : kind_(kind), image_base_(image_base) {} |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 } | 308 } |
288 | 309 |
289 Label* AssemblyProgram::FindAbs32Label(RVA rva) { | 310 Label* AssemblyProgram::FindAbs32Label(RVA rva) { |
290 return abs32_label_manager_.Find(rva); | 311 return abs32_label_manager_.Find(rva); |
291 } | 312 } |
292 | 313 |
293 Label* AssemblyProgram::FindRel32Label(RVA rva) { | 314 Label* AssemblyProgram::FindRel32Label(RVA rva) { |
294 return rel32_label_manager_.Find(rva); | 315 return rel32_label_manager_.Find(rva); |
295 } | 316 } |
296 | 317 |
297 void AssemblyProgram::HandleInstructionLabels( | 318 CheckBool AssemblyProgram::GenerateInstructions(const InstructionGenerator& gen, |
298 const AssemblyProgram::LabelHandlerMap& handler_map) const { | 319 bool annotate_labels) { |
299 for (const Instruction* instruction : instructions_) { | 320 // Pass 1: Count storage space required and reserve in advance. |
300 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); | |
301 if (it != handler_map.end()) { | |
302 it->second.Run( | |
303 static_cast<const InstructionWithLabel*>(instruction)->label()); | |
304 } | |
305 } | |
306 } | |
307 | |
308 CheckBool AssemblyProgram::GenerateInstructions( | |
309 const InstructionGenerator& gen) { | |
310 // Pass 1: Count the space needed to store instructions. | |
311 InstructionCountReceptor count_receptor; | 321 InstructionCountReceptor count_receptor; |
312 if (!gen.Run(&count_receptor)) | 322 if (!gen.Run(&count_receptor)) |
313 return false; | 323 return false; |
314 | 324 |
315 // Pass 2: Emit all instructions to preallocated buffer (uses Phase 1 count). | 325 if (annotate_labels) { |
316 InstructionStoreReceptor store_receptor(this); | 326 DCHECK(abs32_label_annotations_.empty()); |
317 // TODO(huangs): 2017/03: Pass |count_receptor->size()| to |store_receptor_| | 327 abs32_label_annotations_.reserve(count_receptor.abs_count()); |
318 // to reserve space for raw data. | 328 DCHECK(rel32_label_annotations_.empty()); |
| 329 rel32_label_annotations_.reserve(count_receptor.rel_count()); |
| 330 } |
| 331 |
| 332 // Pass 2: Emit all instructions to reserved buffer (uses Phase 1 count). |
| 333 // Populates |abs32_label_annotations_| and |re32_label_annotations_| if |
| 334 // |annotate_labels| is true. |
| 335 InstructionStoreReceptor store_receptor(this, annotate_labels); |
319 return gen.Run(&store_receptor); | 336 return gen.Run(&store_receptor); |
320 } | 337 } |
321 | 338 |
322 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { | 339 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { |
323 if (!instruction || !instructions_.push_back(instruction.get())) | 340 if (!instruction || !instructions_.push_back(instruction.get())) |
324 return false; | 341 return false; |
325 // Ownership successfully passed to instructions_. | 342 // Ownership successfully passed to instructions_. |
326 ignore_result(instruction.release()); | 343 ignore_result(instruction.release()); |
327 return true; | 344 return true; |
328 } | 345 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 Status Encode(const AssemblyProgram& program, | 462 Status Encode(const AssemblyProgram& program, |
446 std::unique_ptr<EncodedProgram>* output) { | 463 std::unique_ptr<EncodedProgram>* output) { |
447 // Explicitly release any memory associated with the output before encoding. | 464 // Explicitly release any memory associated with the output before encoding. |
448 output->reset(); | 465 output->reset(); |
449 | 466 |
450 *output = program.Encode(); | 467 *output = program.Encode(); |
451 return (*output) ? C_OK : C_GENERAL_ERROR; | 468 return (*output) ? C_OK : C_GENERAL_ERROR; |
452 } | 469 } |
453 | 470 |
454 } // namespace courgette | 471 } // namespace courgette |
OLD | NEW |