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 <memory.h> | 7 #include <memory.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 uint16_t compressed_op() const { return compressed_op_; } | 98 uint16_t compressed_op() const { return compressed_op_; } |
99 const uint8_t* arm_op() const { return arm_op_; } | 99 const uint8_t* arm_op() const { return arm_op_; } |
100 uint16_t op_size() const { return op_size_; } | 100 uint16_t op_size() const { return op_size_; } |
101 | 101 |
102 private: | 102 private: |
103 uint16_t compressed_op_; | 103 uint16_t compressed_op_; |
104 const uint8_t* arm_op_; | 104 const uint8_t* arm_op_; |
105 uint16_t op_size_; | 105 uint16_t op_size_; |
106 }; | 106 }; |
107 | 107 |
| 108 /******** InstructionCountReceptor ********/ |
| 109 |
| 110 // An InstructionReceptor that counts space occupied by emitted instructions. |
| 111 class InstructionCountReceptor : public InstructionReceptor { |
| 112 public: |
| 113 InstructionCountReceptor() = default; |
| 114 |
| 115 size_t size() const { return size_; } |
| 116 |
| 117 // InstructionReceptor: |
| 118 // TODO(huangs): 2016/11: Populate these with size_ += ... |
| 119 CheckBool EmitPeRelocs() override { return true; } |
| 120 CheckBool EmitElfRelocation() override { return true; } |
| 121 CheckBool EmitElfARMRelocation() override { return true; } |
| 122 CheckBool EmitOrigin(RVA rva) override { return true; } |
| 123 CheckBool EmitSingleByte(uint8_t byte) override { return true; } |
| 124 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { |
| 125 return true; |
| 126 } |
| 127 CheckBool EmitRel32(Label* label) override { return true; } |
| 128 CheckBool EmitRel32ARM(uint16_t op, |
| 129 Label* label, |
| 130 const uint8_t* arm_op, |
| 131 uint16_t op_size) override { |
| 132 return true; |
| 133 } |
| 134 CheckBool EmitAbs32(Label* label) override { return true; } |
| 135 CheckBool EmitAbs64(Label* label) override { return true; } |
| 136 |
| 137 private: |
| 138 size_t size_ = 0; |
| 139 |
| 140 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); |
| 141 }; |
| 142 |
| 143 /******** InstructionStoreReceptor ********/ |
| 144 |
| 145 // An InstructionReceptor that stores emitted instructions. |
| 146 class InstructionStoreReceptor : public InstructionReceptor { |
| 147 public: |
| 148 explicit InstructionStoreReceptor(AssemblyProgram* program) |
| 149 : program_(program) { |
| 150 CHECK(program_); |
| 151 } |
| 152 |
| 153 // TODO(huangs): 2016/11: Add Reserve(). |
| 154 |
| 155 // InstructionReceptor: |
| 156 // TODO(huangs): 2016/11: Replace stub with implementation. |
| 157 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); } |
| 158 CheckBool EmitElfRelocation() override { |
| 159 return program_->EmitElfRelocation(); |
| 160 } |
| 161 CheckBool EmitElfARMRelocation() override { |
| 162 return program_->EmitElfARMRelocation(); |
| 163 } |
| 164 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); } |
| 165 CheckBool EmitSingleByte(uint8_t byte) override { |
| 166 return program_->EmitSingleByte(byte); |
| 167 } |
| 168 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { |
| 169 return program_->EmitMultipleBytes(bytes, len); |
| 170 } |
| 171 CheckBool EmitRel32(Label* label) override { |
| 172 return program_->EmitRel32(label); |
| 173 } |
| 174 CheckBool EmitRel32ARM(uint16_t op, |
| 175 Label* label, |
| 176 const uint8_t* arm_op, |
| 177 uint16_t op_size) override { |
| 178 return program_->EmitRel32ARM(op, label, arm_op, op_size); |
| 179 } |
| 180 CheckBool EmitAbs32(Label* label) override { |
| 181 return program_->EmitAbs32(label); |
| 182 } |
| 183 CheckBool EmitAbs64(Label* label) override { |
| 184 return program_->EmitAbs64(label); |
| 185 } |
| 186 |
| 187 private: |
| 188 AssemblyProgram* program_; |
| 189 |
| 190 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); |
| 191 }; |
| 192 |
108 } // namespace | 193 } // namespace |
109 | 194 |
| 195 /******** AssemblyProgram ********/ |
| 196 |
110 AssemblyProgram::AssemblyProgram(ExecutableType kind) | 197 AssemblyProgram::AssemblyProgram(ExecutableType kind) |
111 : kind_(kind), image_base_(0) { | 198 : kind_(kind), image_base_(0) { |
112 } | 199 } |
113 | 200 |
114 AssemblyProgram::~AssemblyProgram() { | 201 AssemblyProgram::~AssemblyProgram() { |
115 for (size_t i = 0; i < instructions_.size(); ++i) { | 202 for (size_t i = 0; i < instructions_.size(); ++i) { |
116 Instruction* instruction = instructions_[i]; | 203 Instruction* instruction = instructions_[i]; |
117 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. | 204 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. |
118 UncheckedDelete(instruction); | 205 UncheckedDelete(instruction); |
119 } | 206 } |
120 if (byte_instruction_cache_.get()) { | 207 if (byte_instruction_cache_.get()) { |
121 for (size_t i = 0; i < 256; ++i) | 208 for (size_t i = 0; i < 256; ++i) |
122 UncheckedDelete(byte_instruction_cache_[i]); | 209 UncheckedDelete(byte_instruction_cache_[i]); |
123 } | 210 } |
124 } | 211 } |
125 | 212 |
126 CheckBool AssemblyProgram::EmitPeRelocsInstruction() { | 213 CheckBool AssemblyProgram::EmitPeRelocs() { |
127 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>())); | 214 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>())); |
128 } | 215 } |
129 | 216 |
130 CheckBool AssemblyProgram::EmitElfRelocationInstruction() { | 217 CheckBool AssemblyProgram::EmitElfRelocation() { |
131 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>())); | 218 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>())); |
132 } | 219 } |
133 | 220 |
134 CheckBool AssemblyProgram::EmitElfARMRelocationInstruction() { | 221 CheckBool AssemblyProgram::EmitElfARMRelocation() { |
135 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>())); | 222 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>())); |
136 } | 223 } |
137 | 224 |
138 CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) { | 225 CheckBool AssemblyProgram::EmitOrigin(RVA rva) { |
139 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva))); | 226 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva))); |
140 } | 227 } |
141 | 228 |
142 CheckBool AssemblyProgram::EmitByteInstruction(uint8_t byte) { | 229 CheckBool AssemblyProgram::EmitSingleByte(uint8_t byte) { |
143 return EmitShared(GetByteInstruction(byte)); | 230 return EmitShared(GetByteInstruction(byte)); |
144 } | 231 } |
145 | 232 |
146 CheckBool AssemblyProgram::EmitBytesInstruction(const uint8_t* values, | 233 CheckBool AssemblyProgram::EmitMultipleBytes(const uint8_t* bytes, size_t len) { |
147 size_t len) { | 234 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(bytes, len))); |
148 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(values, len))); | |
149 } | 235 } |
150 | 236 |
151 CheckBool AssemblyProgram::EmitRel32(Label* label) { | 237 CheckBool AssemblyProgram::EmitRel32(Label* label) { |
152 return Emit( | 238 return Emit( |
153 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label))); | 239 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label))); |
154 } | 240 } |
155 | 241 |
156 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op, | 242 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op, |
157 Label* label, | 243 Label* label, |
158 const uint8_t* arm_op, | 244 const uint8_t* arm_op, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 const AssemblyProgram::LabelHandlerMap& handler_map) const { | 307 const AssemblyProgram::LabelHandlerMap& handler_map) const { |
222 for (const Instruction* instruction : instructions_) { | 308 for (const Instruction* instruction : instructions_) { |
223 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); | 309 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); |
224 if (it != handler_map.end()) { | 310 if (it != handler_map.end()) { |
225 it->second.Run( | 311 it->second.Run( |
226 static_cast<const InstructionWithLabel*>(instruction)->label()); | 312 static_cast<const InstructionWithLabel*>(instruction)->label()); |
227 } | 313 } |
228 } | 314 } |
229 } | 315 } |
230 | 316 |
| 317 CheckBool AssemblyProgram::GenerateInstructions( |
| 318 const InstructionGenerator& gen) { |
| 319 // Pass 1: Count the space needed to store instructions. |
| 320 InstructionCountReceptor count_receptor; |
| 321 if (!gen.Run(this, &count_receptor)) |
| 322 return false; |
| 323 |
| 324 // Pass 2: Emit all instructions to preallocated buffer (uses Phase 1 count). |
| 325 InstructionStoreReceptor store_receptor(this); |
| 326 // TODO(huangs): 2016/11: Pass |count_receptor_->size()| to |store_receptor_| |
| 327 // to reserve space for raw data. |
| 328 return gen.Run(this, &store_receptor); |
| 329 } |
| 330 |
231 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { | 331 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { |
232 if (!instruction || !instructions_.push_back(instruction.get())) | 332 if (!instruction || !instructions_.push_back(instruction.get())) |
233 return false; | 333 return false; |
234 // Ownership successfully passed to instructions_. | 334 // Ownership successfully passed to instructions_. |
235 ignore_result(instruction.release()); | 335 ignore_result(instruction.release()); |
236 return true; | 336 return true; |
237 } | 337 } |
238 | 338 |
239 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { | 339 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { |
240 DCHECK(!instruction || instruction->op() == DEFBYTE); | 340 DCHECK(!instruction || instruction->op() == DEFBYTE); |
241 return instruction && instructions_.push_back(instruction); | 341 return instruction && instructions_.push_back(instruction); |
242 } | 342 } |
243 | 343 |
244 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { | 344 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { |
245 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | 345 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { |
246 Label* current = p->second; | 346 Label* current = p->second; |
247 current->index_ = Label::kNoIndex; | 347 current->index_ = Label::kNoIndex; |
248 } | 348 } |
249 } | 349 } |
250 | 350 |
251 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing | 351 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing |
252 // address order. | 352 // address order. |
253 // | |
254 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) { | 353 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) { |
255 int index = 0; | 354 int index = 0; |
256 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | 355 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { |
257 Label* current = p->second; | 356 Label* current = p->second; |
258 if (current->index_ != Label::kNoIndex) | 357 if (current->index_ != Label::kNoIndex) |
259 NOTREACHED(); | 358 NOTREACHED(); |
260 current->index_ = index; | 359 current->index_ = index; |
261 ++index; | 360 ++index; |
262 } | 361 } |
263 } | 362 } |
264 | 363 |
265 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not | 364 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not |
266 // yet assigned an index. | 365 // yet assigned an index. |
267 // | |
268 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) { | 366 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) { |
269 // An address table compresses best when each index is associated with an | 367 // An address table compresses best when each index is associated with an |
270 // address that is slight larger than the previous index. | 368 // address that is slight larger than the previous index. |
271 | 369 |
272 // First see which indexes have not been used. The 'available' vector could | 370 // First see which indexes have not been used. The 'available' vector could |
273 // grow even bigger, but the number of addresses is a better starting size | 371 // grow even bigger, but the number of addresses is a better starting size |
274 // than empty. | 372 // than empty. |
275 std::vector<bool> available(labels->size(), true); | 373 std::vector<bool> available(labels->size(), true); |
276 int used = 0; | 374 int used = 0; |
277 | 375 |
278 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | 376 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { |
279 int index = p->second->index_; | 377 int index = p->second->index_; |
280 if (index != Label::kNoIndex) { | 378 if (index != Label::kNoIndex) { |
281 while (static_cast<size_t>(index) >= available.size()) | 379 while (static_cast<size_t>(index) >= available.size()) |
282 available.push_back(true); | 380 available.push_back(true); |
283 available.at(index) = false; | 381 available.at(index) = false; |
284 ++used; | 382 ++used; |
285 } | 383 } |
286 } | 384 } |
287 | 385 |
288 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned"; | 386 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned"; |
289 | 387 |
290 // Are there any unused labels that happen to be adjacent following a used | 388 // Are there any unused labels that happen to be adjacent following a used |
291 // label? | 389 // label? |
292 // | |
293 int fill_forward_count = 0; | 390 int fill_forward_count = 0; |
294 Label* prev = 0; | 391 Label* prev = 0; |
295 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | 392 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { |
296 Label* current = p->second; | 393 Label* current = p->second; |
297 if (current->index_ == Label::kNoIndex) { | 394 if (current->index_ == Label::kNoIndex) { |
298 int index = 0; | 395 int index = 0; |
299 if (prev && prev->index_ != Label::kNoIndex) | 396 if (prev && prev->index_ != Label::kNoIndex) |
300 index = prev->index_ + 1; | 397 index = prev->index_ + 1; |
301 if (index < static_cast<int>(available.size()) && available.at(index)) { | 398 if (index < static_cast<int>(available.size()) && available.at(index)) { |
302 current->index_ = index; | 399 current->index_ = index; |
303 available.at(index) = false; | 400 available.at(index) = false; |
304 ++fill_forward_count; | 401 ++fill_forward_count; |
305 } | 402 } |
306 } | 403 } |
307 prev = current; | 404 prev = current; |
308 } | 405 } |
309 | 406 |
310 // Are there any unused labels that happen to be adjacent preceeding a used | 407 // Are there any unused labels that happen to be adjacent preceeding a used |
311 // label? | 408 // label? |
312 // | |
313 int fill_backward_count = 0; | 409 int fill_backward_count = 0; |
314 prev = 0; | 410 prev = 0; |
315 for (RVAToLabel::reverse_iterator p = labels->rbegin(); | 411 for (RVAToLabel::reverse_iterator p = labels->rbegin(); |
316 p != labels->rend(); | 412 p != labels->rend(); |
317 ++p) { | 413 ++p) { |
318 Label* current = p->second; | 414 Label* current = p->second; |
319 if (current->index_ == Label::kNoIndex) { | 415 if (current->index_ == Label::kNoIndex) { |
320 int prev_index; | 416 int prev_index; |
321 if (prev) | 417 if (prev) |
322 prev_index = prev->index_; | 418 prev_index = prev->index_; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 Status Encode(const AssemblyProgram& program, | 563 Status Encode(const AssemblyProgram& program, |
468 std::unique_ptr<EncodedProgram>* output) { | 564 std::unique_ptr<EncodedProgram>* output) { |
469 // Explicitly release any memory associated with the output before encoding. | 565 // Explicitly release any memory associated with the output before encoding. |
470 output->reset(); | 566 output->reset(); |
471 | 567 |
472 *output = program.Encode(); | 568 *output = program.Encode(); |
473 return (*output) ? C_OK : C_GENERAL_ERROR; | 569 return (*output) ? C_OK : C_GENERAL_ERROR; |
474 } | 570 } |
475 | 571 |
476 } // namespace courgette | 572 } // namespace courgette |
OLD | NEW |