| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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> |
| 11 #include <sstream> | 11 #include <sstream> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/scoped_ptr.h" |
| 15 | 16 |
| 16 #include "courgette/courgette.h" | 17 #include "courgette/courgette.h" |
| 17 #include "courgette/encoded_program.h" | 18 #include "courgette/encoded_program.h" |
| 18 | 19 |
| 19 namespace courgette { | 20 namespace courgette { |
| 20 | 21 |
| 21 // Opcodes of simple assembly language | 22 // Opcodes of simple assembly language |
| 22 enum OP { | 23 enum OP { |
| 23 ORIGIN, // ORIGIN <rva> - set current address for assembly. | 24 ORIGIN, // ORIGIN <rva> - set current address for assembly. |
| 24 MAKERELOCS, // Generates a base relocation table. | 25 MAKERELOCS, // Generates a base relocation table. |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 ++index; | 281 ++index; |
| 281 ++fill_infill_count; | 282 ++fill_infill_count; |
| 282 } | 283 } |
| 283 } | 284 } |
| 284 | 285 |
| 285 VLOG(1) << " fill forward " << fill_forward_count | 286 VLOG(1) << " fill forward " << fill_forward_count |
| 286 << " backward " << fill_backward_count | 287 << " backward " << fill_backward_count |
| 287 << " infill " << fill_infill_count; | 288 << " infill " << fill_infill_count; |
| 288 } | 289 } |
| 289 | 290 |
| 290 typedef void (EncodedProgram::*DefineLabelMethod)(int index, RVA value); | 291 typedef CheckBool (EncodedProgram::*DefineLabelMethod)(int index, RVA value); |
| 291 | 292 |
| 292 #if defined(OS_WIN) | 293 #if defined(OS_WIN) |
| 293 __declspec(noinline) | 294 __declspec(noinline) |
| 294 #endif | 295 #endif |
| 295 static void DefineLabels(const RVAToLabel& labels, | 296 static CheckBool DefineLabels(const RVAToLabel& labels, |
| 296 EncodedProgram* encoded_format, | 297 EncodedProgram* encoded_format, |
| 297 DefineLabelMethod define_label) { | 298 DefineLabelMethod define_label) { |
| 298 for (RVAToLabel::const_iterator p = labels.begin(); p != labels.end(); ++p) { | 299 bool ok = true; |
| 300 for (RVAToLabel::const_iterator p = labels.begin(); |
| 301 ok && p != labels.end(); |
| 302 ++p) { |
| 299 Label* label = p->second; | 303 Label* label = p->second; |
| 300 (encoded_format->*define_label)(label->index_, label->rva_); | 304 ok = (encoded_format->*define_label)(label->index_, label->rva_); |
| 301 } | 305 } |
| 306 return ok; |
| 302 } | 307 } |
| 303 | 308 |
| 304 EncodedProgram* AssemblyProgram::Encode() const { | 309 EncodedProgram* AssemblyProgram::Encode() const { |
| 305 EncodedProgram* encoded = new EncodedProgram(); | 310 scoped_ptr<EncodedProgram> encoded(new EncodedProgram()); |
| 311 encoded->set_image_base(image_base_); |
| 306 | 312 |
| 307 encoded->set_image_base(image_base_); | 313 if (!DefineLabels(abs32_labels_, encoded.get(), |
| 308 DefineLabels(abs32_labels_, encoded, &EncodedProgram::DefineAbs32Label); | 314 &EncodedProgram::DefineAbs32Label) || |
| 309 DefineLabels(rel32_labels_, encoded, &EncodedProgram::DefineRel32Label); | 315 !DefineLabels(rel32_labels_, encoded.get(), |
| 316 &EncodedProgram::DefineRel32Label)) { |
| 317 return NULL; |
| 318 } |
| 319 |
| 310 encoded->EndLabels(); | 320 encoded->EndLabels(); |
| 311 | 321 |
| 312 for (size_t i = 0; i < instructions_.size(); ++i) { | 322 for (size_t i = 0; i < instructions_.size(); ++i) { |
| 313 Instruction* instruction = instructions_[i]; | 323 Instruction* instruction = instructions_[i]; |
| 314 | 324 |
| 315 switch (instruction->op()) { | 325 switch (instruction->op()) { |
| 316 case ORIGIN: { | 326 case ORIGIN: { |
| 317 OriginInstruction* org = static_cast<OriginInstruction*>(instruction); | 327 OriginInstruction* org = static_cast<OriginInstruction*>(instruction); |
| 318 encoded->AddOrigin(org->origin_rva()); | 328 if (!encoded->AddOrigin(org->origin_rva())) |
| 329 return NULL; |
| 319 break; | 330 break; |
| 320 } | 331 } |
| 321 case DEFBYTE: { | 332 case DEFBYTE: { |
| 322 uint8 b = static_cast<ByteInstruction*>(instruction)->byte_value(); | 333 uint8 b = static_cast<ByteInstruction*>(instruction)->byte_value(); |
| 323 encoded->AddCopy(1, &b); | 334 if (!encoded->AddCopy(1, &b)) |
| 335 return NULL; |
| 324 break; | 336 break; |
| 325 } | 337 } |
| 326 case REL32: { | 338 case REL32: { |
| 327 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); | 339 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); |
| 328 encoded->AddRel32(label->index_); | 340 if (!encoded->AddRel32(label->index_)) |
| 341 return NULL; |
| 329 break; | 342 break; |
| 330 } | 343 } |
| 331 case ABS32: { | 344 case ABS32: { |
| 332 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); | 345 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); |
| 333 encoded->AddAbs32(label->index_); | 346 if (!encoded->AddAbs32(label->index_)) |
| 347 return NULL; |
| 334 break; | 348 break; |
| 335 } | 349 } |
| 336 case MAKERELOCS: { | 350 case MAKERELOCS: { |
| 337 encoded->AddMakeRelocs(); | 351 if (!encoded->AddMakeRelocs()) |
| 352 return NULL; |
| 338 break; | 353 break; |
| 339 } | 354 } |
| 340 default: { | 355 default: { |
| 341 NOTREACHED() << "Unknown Insn OP kind"; | 356 NOTREACHED() << "Unknown Insn OP kind"; |
| 342 } | 357 } |
| 343 } | 358 } |
| 344 } | 359 } |
| 345 | 360 |
| 346 return encoded; | 361 return encoded.release(); |
| 347 } | 362 } |
| 348 | 363 |
| 349 Instruction* AssemblyProgram::GetByteInstruction(uint8 byte) { | 364 Instruction* AssemblyProgram::GetByteInstruction(uint8 byte) { |
| 350 if (!byte_instruction_cache_) { | 365 if (!byte_instruction_cache_) { |
| 351 byte_instruction_cache_ = new Instruction*[256]; | 366 byte_instruction_cache_ = new Instruction*[256]; |
| 352 for (int i = 0; i < 256; ++i) { | 367 for (int i = 0; i < 256; ++i) { |
| 353 byte_instruction_cache_[i] = new ByteInstruction(static_cast<uint8>(i)); | 368 byte_instruction_cache_[i] = new ByteInstruction(static_cast<uint8>(i)); |
| 354 } | 369 } |
| 355 } | 370 } |
| 356 | 371 |
| 357 return byte_instruction_cache_[byte]; | 372 return byte_instruction_cache_[byte]; |
| 358 } | 373 } |
| 359 | 374 |
| 360 //////////////////////////////////////////////////////////////////////////////// | 375 //////////////////////////////////////////////////////////////////////////////// |
| 361 | 376 |
| 362 Status Encode(AssemblyProgram* program, EncodedProgram** output) { | 377 Status Encode(AssemblyProgram* program, EncodedProgram** output) { |
| 363 *output = NULL; | 378 *output = NULL; |
| 364 EncodedProgram *encoded = program->Encode(); | 379 EncodedProgram *encoded = program->Encode(); |
| 365 if (encoded) { | 380 if (encoded) { |
| 366 *output = encoded; | 381 *output = encoded; |
| 367 return C_OK; | 382 return C_OK; |
| 368 } else { | 383 } else { |
| 369 return C_GENERAL_ERROR; | 384 return C_GENERAL_ERROR; |
| 370 } | 385 } |
| 371 } | 386 } |
| 372 | 387 |
| 373 } // namespace courgette | 388 } // namespace courgette |
| OLD | NEW |