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