OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/disassembler_win32.h" | 5 #include "courgette/disassembler_win32.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 const uint8_t* optional_header = pe_header + 4 + kSizeOfCoffHeader; | 358 const uint8_t* optional_header = pe_header + 4 + kSizeOfCoffHeader; |
359 // Check we can read the magic. | 359 // Check we can read the magic. |
360 if (optional_header + 2 >= start + length) | 360 if (optional_header + 2 >= start + length) |
361 return false; | 361 return false; |
362 if (magic != ReadU16(optional_header, 0)) | 362 if (magic != ReadU16(optional_header, 0)) |
363 return false; | 363 return false; |
364 | 364 |
365 return true; | 365 return true; |
366 } | 366 } |
367 | 367 |
| 368 bool DisassemblerWin32::ParseAbs32Relocs() { |
| 369 abs32_locations_.clear(); |
| 370 if (!ParseRelocs(&abs32_locations_)) |
| 371 return false; |
| 372 |
| 373 #if COURGETTE_HISTOGRAM_TARGETS |
| 374 for (size_t i = 0; i < abs32_locations_.size(); ++i) { |
| 375 RVA rva = abs32_locations_[i]; |
| 376 // The 4 bytes at the relocation are a reference to some address. |
| 377 ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))]; |
| 378 } |
| 379 #endif |
| 380 return true; |
| 381 } |
| 382 |
| 383 void DisassemblerWin32::ParseRel32RelocsFromSections() { |
| 384 FileOffset file_offset = 0; |
| 385 while (file_offset < length()) { |
| 386 const Section* section = FindNextSection(file_offset); |
| 387 if (section == nullptr) |
| 388 break; |
| 389 if (file_offset < section->file_offset_of_raw_data) |
| 390 file_offset = section->file_offset_of_raw_data; |
| 391 ParseRel32RelocsFromSection(section); |
| 392 file_offset += section->size_of_raw_data; |
| 393 } |
| 394 std::sort(rel32_locations_.begin(), rel32_locations_.end()); |
| 395 DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA); |
| 396 |
| 397 #if COURGETTE_HISTOGRAM_TARGETS |
| 398 VLOG(1) << "abs32_locations_ " << abs32_locations_.size() |
| 399 << "\nrel32_locations_ " << rel32_locations_.size() |
| 400 << "\nabs32_target_rvas_ " << abs32_target_rvas_.size() |
| 401 << "\nrel32_target_rvas_ " << rel32_target_rvas_.size(); |
| 402 |
| 403 int common = 0; |
| 404 std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin(); |
| 405 std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin(); |
| 406 while (abs32_iter != abs32_target_rvas_.end() && |
| 407 rel32_iter != rel32_target_rvas_.end()) { |
| 408 if (abs32_iter->first < rel32_iter->first) { |
| 409 ++abs32_iter; |
| 410 } else if (rel32_iter->first < abs32_iter->first) { |
| 411 ++rel32_iter; |
| 412 } else { |
| 413 ++common; |
| 414 ++abs32_iter; |
| 415 ++rel32_iter; |
| 416 } |
| 417 } |
| 418 VLOG(1) << "common " << common; |
| 419 #endif |
| 420 } |
| 421 |
368 RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() { | 422 RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() { |
369 return new RvaVisitor_Abs32(abs32_locations_, *this); | 423 return new RvaVisitor_Abs32(abs32_locations_, *this); |
370 } | 424 } |
371 | 425 |
372 RvaVisitor* DisassemblerWin32::CreateRel32TargetRvaVisitor() { | 426 RvaVisitor* DisassemblerWin32::CreateRel32TargetRvaVisitor() { |
373 return new RvaVisitor_Rel32(rel32_locations_, *this); | 427 return new RvaVisitor_Rel32(rel32_locations_, *this); |
374 } | 428 } |
375 | 429 |
376 void DisassemblerWin32::RemoveUnusedRel32Locations( | 430 void DisassemblerWin32::RemoveUnusedRel32Locations( |
377 AssemblyProgram* program) { | 431 AssemblyProgram* program) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 } | 467 } |
414 | 468 |
415 #if COURGETTE_HISTOGRAM_TARGETS | 469 #if COURGETTE_HISTOGRAM_TARGETS |
416 HistogramTargets("abs32 relocs", abs32_target_rvas_); | 470 HistogramTargets("abs32 relocs", abs32_target_rvas_); |
417 HistogramTargets("rel32 relocs", rel32_target_rvas_); | 471 HistogramTargets("rel32 relocs", rel32_target_rvas_); |
418 #endif | 472 #endif |
419 | 473 |
420 return true; | 474 return true; |
421 } | 475 } |
422 | 476 |
423 bool DisassemblerWin32::ParseAbs32Relocs() { | |
424 abs32_locations_.clear(); | |
425 if (!ParseRelocs(&abs32_locations_)) | |
426 return false; | |
427 | |
428 #if COURGETTE_HISTOGRAM_TARGETS | |
429 for (size_t i = 0; i < abs32_locations_.size(); ++i) { | |
430 RVA rva = abs32_locations_[i]; | |
431 // The 4 bytes at the relocation are a reference to some address. | |
432 ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))]; | |
433 } | |
434 #endif | |
435 return true; | |
436 } | |
437 | |
438 void DisassemblerWin32::ParseRel32RelocsFromSections() { | |
439 FileOffset file_offset = 0; | |
440 while (file_offset < length()) { | |
441 const Section* section = FindNextSection(file_offset); | |
442 if (section == nullptr) | |
443 break; | |
444 if (file_offset < section->file_offset_of_raw_data) | |
445 file_offset = section->file_offset_of_raw_data; | |
446 ParseRel32RelocsFromSection(section); | |
447 file_offset += section->size_of_raw_data; | |
448 } | |
449 std::sort(rel32_locations_.begin(), rel32_locations_.end()); | |
450 DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA); | |
451 | |
452 #if COURGETTE_HISTOGRAM_TARGETS | |
453 VLOG(1) << "abs32_locations_ " << abs32_locations_.size() | |
454 << "\nrel32_locations_ " << rel32_locations_.size() | |
455 << "\nabs32_target_rvas_ " << abs32_target_rvas_.size() | |
456 << "\nrel32_target_rvas_ " << rel32_target_rvas_.size(); | |
457 | |
458 int common = 0; | |
459 std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin(); | |
460 std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin(); | |
461 while (abs32_iter != abs32_target_rvas_.end() && | |
462 rel32_iter != rel32_target_rvas_.end()) { | |
463 if (abs32_iter->first < rel32_iter->first) { | |
464 ++abs32_iter; | |
465 } else if (rel32_iter->first < abs32_iter->first) { | |
466 ++rel32_iter; | |
467 } else { | |
468 ++common; | |
469 ++abs32_iter; | |
470 ++rel32_iter; | |
471 } | |
472 } | |
473 VLOG(1) << "common " << common; | |
474 #endif | |
475 } | |
476 | |
477 CheckBool DisassemblerWin32::ParseNonSectionFileRegion( | 477 CheckBool DisassemblerWin32::ParseNonSectionFileRegion( |
478 FileOffset start_file_offset, | 478 FileOffset start_file_offset, |
479 FileOffset end_file_offset, | 479 FileOffset end_file_offset, |
480 InstructionReceptor* receptor) const { | 480 InstructionReceptor* receptor) const { |
481 if (incomplete_disassembly_) | 481 if (incomplete_disassembly_) |
482 return true; | 482 return true; |
483 | 483 |
484 if (end_file_offset > start_file_offset) { | 484 if (end_file_offset > start_file_offset) { |
485 if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset), | 485 if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset), |
486 end_file_offset - start_file_offset)) { | 486 end_file_offset - start_file_offset)) { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 directory->size_ = static_cast<uint32_t>(size); | 677 directory->size_ = static_cast<uint32_t>(size); |
678 return true; | 678 return true; |
679 } else { | 679 } else { |
680 directory->address_ = 0; | 680 directory->address_ = 0; |
681 directory->size_ = 0; | 681 directory->size_ = 0; |
682 return true; | 682 return true; |
683 } | 683 } |
684 } | 684 } |
685 | 685 |
686 } // namespace courgette | 686 } // namespace courgette |
OLD | NEW |