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