| 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 <algorithm> | 8 #include <algorithm> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 if (label == NULL) NOTREACHED(); | 79 if (label == NULL) NOTREACHED(); |
| 80 } | 80 } |
| 81 Label* label() const { return label_; } | 81 Label* label() const { return label_; } |
| 82 private: | 82 private: |
| 83 Label* label_; | 83 Label* label_; |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 } // namespace | 86 } // namespace |
| 87 | 87 |
| 88 AssemblyProgram::AssemblyProgram() | 88 AssemblyProgram::AssemblyProgram() |
| 89 : byte_instruction_cache_(NULL), | 89 : image_base_(0) { |
| 90 image_base_(0) { | |
| 91 } | 90 } |
| 92 | 91 |
| 93 static void DeleteContainedLabels(const RVAToLabel& labels) { | 92 static void DeleteContainedLabels(const RVAToLabel& labels) { |
| 94 for (RVAToLabel::const_iterator p = labels.begin(); p != labels.end(); ++p) | 93 for (RVAToLabel::const_iterator p = labels.begin(); p != labels.end(); ++p) |
| 95 delete p->second; | 94 delete p->second; |
| 96 } | 95 } |
| 97 | 96 |
| 98 AssemblyProgram::~AssemblyProgram() { | 97 AssemblyProgram::~AssemblyProgram() { |
| 99 for (size_t i = 0; i < instructions_.size(); ++i) { | 98 for (size_t i = 0; i < instructions_.size(); ++i) { |
| 100 Instruction* instruction = instructions_[i]; | 99 Instruction* instruction = instructions_[i]; |
| 101 if (instruction->op() != DEFBYTE) // Will be in byte_instruction_cache_. | 100 if (instruction->op() != DEFBYTE) // Will be in byte_instruction_cache_. |
| 102 delete instruction; | 101 delete instruction; |
| 103 } | 102 } |
| 104 if (byte_instruction_cache_) { | 103 if (byte_instruction_cache_.get()) { |
| 105 for (size_t i = 0; i < 256; ++i) | 104 for (size_t i = 0; i < 256; ++i) |
| 106 delete byte_instruction_cache_[i]; | 105 delete byte_instruction_cache_[i]; |
| 107 delete[] byte_instruction_cache_; | |
| 108 } | 106 } |
| 109 DeleteContainedLabels(rel32_labels_); | 107 DeleteContainedLabels(rel32_labels_); |
| 110 DeleteContainedLabels(abs32_labels_); | 108 DeleteContainedLabels(abs32_labels_); |
| 111 } | 109 } |
| 112 | 110 |
| 113 void AssemblyProgram::EmitMakeRelocsInstruction() { | 111 CheckBool AssemblyProgram::EmitMakeRelocsInstruction() { |
| 114 Emit(new MakeRelocsInstruction()); | 112 return Emit(new(std::nothrow) MakeRelocsInstruction()); |
| 115 } | 113 } |
| 116 | 114 |
| 117 void AssemblyProgram::EmitOriginInstruction(RVA rva) { | 115 CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) { |
| 118 Emit(new OriginInstruction(rva)); | 116 return Emit(new(std::nothrow) OriginInstruction(rva)); |
| 119 } | 117 } |
| 120 | 118 |
| 121 void AssemblyProgram::EmitByteInstruction(uint8 byte) { | 119 CheckBool AssemblyProgram::EmitByteInstruction(uint8 byte) { |
| 122 Emit(GetByteInstruction(byte)); | 120 return Emit(GetByteInstruction(byte)); |
| 123 } | 121 } |
| 124 | 122 |
| 125 void AssemblyProgram::EmitRel32(Label* label) { | 123 CheckBool AssemblyProgram::EmitRel32(Label* label) { |
| 126 Emit(new InstructionWithLabel(REL32, label)); | 124 return Emit(new(std::nothrow) InstructionWithLabel(REL32, label)); |
| 127 } | 125 } |
| 128 | 126 |
| 129 void AssemblyProgram::EmitAbs32(Label* label) { | 127 CheckBool AssemblyProgram::EmitAbs32(Label* label) { |
| 130 Emit(new InstructionWithLabel(ABS32, label)); | 128 return Emit(new(std::nothrow) InstructionWithLabel(ABS32, label)); |
| 131 } | 129 } |
| 132 | 130 |
| 133 Label* AssemblyProgram::FindOrMakeAbs32Label(RVA rva) { | 131 Label* AssemblyProgram::FindOrMakeAbs32Label(RVA rva) { |
| 134 return FindLabel(rva, &abs32_labels_); | 132 return FindLabel(rva, &abs32_labels_); |
| 135 } | 133 } |
| 136 | 134 |
| 137 Label* AssemblyProgram::FindOrMakeRel32Label(RVA rva) { | 135 Label* AssemblyProgram::FindOrMakeRel32Label(RVA rva) { |
| 138 return FindLabel(rva, &rel32_labels_); | 136 return FindLabel(rva, &rel32_labels_); |
| 139 } | 137 } |
| 140 | 138 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 160 return NULL; | 158 return NULL; |
| 161 } | 159 } |
| 162 | 160 |
| 163 Label* AssemblyProgram::InstructionRel32Label( | 161 Label* AssemblyProgram::InstructionRel32Label( |
| 164 const Instruction* instruction) const { | 162 const Instruction* instruction) const { |
| 165 if (instruction->op() == REL32) | 163 if (instruction->op() == REL32) |
| 166 return static_cast<const InstructionWithLabel*>(instruction)->label(); | 164 return static_cast<const InstructionWithLabel*>(instruction)->label(); |
| 167 return NULL; | 165 return NULL; |
| 168 } | 166 } |
| 169 | 167 |
| 168 CheckBool AssemblyProgram::Emit(Instruction* instruction) { |
| 169 if (!instruction) |
| 170 return false; |
| 171 bool ok = instructions_.push_back(instruction); |
| 172 if (!ok) |
| 173 delete instruction; |
| 174 return ok; |
| 175 } |
| 176 |
| 170 Label* AssemblyProgram::FindLabel(RVA rva, RVAToLabel* labels) { | 177 Label* AssemblyProgram::FindLabel(RVA rva, RVAToLabel* labels) { |
| 171 Label*& slot = (*labels)[rva]; | 178 Label*& slot = (*labels)[rva]; |
| 172 if (slot == 0) { | 179 if (slot == NULL) { |
| 173 slot = new Label(rva); | 180 slot = new(std::nothrow) Label(rva); |
| 174 } | 181 } |
| 175 return slot; | 182 return slot; |
| 176 } | 183 } |
| 177 | 184 |
| 178 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { | 185 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { |
| 179 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | 186 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { |
| 180 Label* current = p->second; | 187 Label* current = p->second; |
| 181 current->index_ = Label::kNoIndex; | 188 current->index_ = Label::kNoIndex; |
| 182 } | 189 } |
| 183 } | 190 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 for (RVAToLabel::const_iterator p = labels.begin(); | 307 for (RVAToLabel::const_iterator p = labels.begin(); |
| 301 ok && p != labels.end(); | 308 ok && p != labels.end(); |
| 302 ++p) { | 309 ++p) { |
| 303 Label* label = p->second; | 310 Label* label = p->second; |
| 304 ok = (encoded_format->*define_label)(label->index_, label->rva_); | 311 ok = (encoded_format->*define_label)(label->index_, label->rva_); |
| 305 } | 312 } |
| 306 return ok; | 313 return ok; |
| 307 } | 314 } |
| 308 | 315 |
| 309 EncodedProgram* AssemblyProgram::Encode() const { | 316 EncodedProgram* AssemblyProgram::Encode() const { |
| 310 scoped_ptr<EncodedProgram> encoded(new EncodedProgram()); | 317 scoped_ptr<EncodedProgram> encoded(new(std::nothrow) EncodedProgram()); |
| 318 if (!encoded.get()) |
| 319 return NULL; |
| 320 |
| 311 encoded->set_image_base(image_base_); | 321 encoded->set_image_base(image_base_); |
| 312 | 322 |
| 313 if (!DefineLabels(abs32_labels_, encoded.get(), | 323 if (!DefineLabels(abs32_labels_, encoded.get(), |
| 314 &EncodedProgram::DefineAbs32Label) || | 324 &EncodedProgram::DefineAbs32Label) || |
| 315 !DefineLabels(rel32_labels_, encoded.get(), | 325 !DefineLabels(rel32_labels_, encoded.get(), |
| 316 &EncodedProgram::DefineRel32Label)) { | 326 &EncodedProgram::DefineRel32Label)) { |
| 317 return NULL; | 327 return NULL; |
| 318 } | 328 } |
| 319 | 329 |
| 320 encoded->EndLabels(); | 330 encoded->EndLabels(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 default: { | 365 default: { |
| 356 NOTREACHED() << "Unknown Insn OP kind"; | 366 NOTREACHED() << "Unknown Insn OP kind"; |
| 357 } | 367 } |
| 358 } | 368 } |
| 359 } | 369 } |
| 360 | 370 |
| 361 return encoded.release(); | 371 return encoded.release(); |
| 362 } | 372 } |
| 363 | 373 |
| 364 Instruction* AssemblyProgram::GetByteInstruction(uint8 byte) { | 374 Instruction* AssemblyProgram::GetByteInstruction(uint8 byte) { |
| 365 if (!byte_instruction_cache_) { | 375 if (!byte_instruction_cache_.get()) { |
| 366 byte_instruction_cache_ = new Instruction*[256]; | 376 byte_instruction_cache_.reset(new(std::nothrow) Instruction*[256]); |
| 377 if (!byte_instruction_cache_.get()) |
| 378 return NULL; |
| 379 |
| 367 for (int i = 0; i < 256; ++i) { | 380 for (int i = 0; i < 256; ++i) { |
| 368 byte_instruction_cache_[i] = new ByteInstruction(static_cast<uint8>(i)); | 381 byte_instruction_cache_[i] = |
| 382 new(std::nothrow) ByteInstruction(static_cast<uint8>(i)); |
| 383 if (!byte_instruction_cache_[i]) { |
| 384 for (int j = 0; j < i; ++j) |
| 385 delete byte_instruction_cache_[j]; |
| 386 byte_instruction_cache_.reset(); |
| 387 return NULL; |
| 388 } |
| 369 } | 389 } |
| 370 } | 390 } |
| 371 | 391 |
| 372 return byte_instruction_cache_[byte]; | 392 return byte_instruction_cache_[byte]; |
| 373 } | 393 } |
| 374 | 394 |
| 375 //////////////////////////////////////////////////////////////////////////////// | 395 //////////////////////////////////////////////////////////////////////////////// |
| 376 | 396 |
| 377 Status Encode(AssemblyProgram* program, EncodedProgram** output) { | 397 Status Encode(AssemblyProgram* program, EncodedProgram** output) { |
| 378 *output = NULL; | 398 *output = NULL; |
| 379 EncodedProgram *encoded = program->Encode(); | 399 EncodedProgram *encoded = program->Encode(); |
| 380 if (encoded) { | 400 if (encoded) { |
| 381 *output = encoded; | 401 *output = encoded; |
| 382 return C_OK; | 402 return C_OK; |
| 383 } else { | 403 } else { |
| 384 return C_GENERAL_ERROR; | 404 return C_GENERAL_ERROR; |
| 385 } | 405 } |
| 386 } | 406 } |
| 387 | 407 |
| 388 } // namespace courgette | 408 } // namespace courgette |
| OLD | NEW |