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(), |
amit
2011/03/22 17:43:36
nice! could this be the cause of http://crbug.com/
tommi (sloooow) - chröme
2011/03/22 18:37:49
I don't think so, but it's possible. Bug 76262 lo
| |
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 |