| 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 |