| 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/disassembler_elf_32_x86.h" | 5 #include "courgette/disassembler_elf_32_x86.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 // Find the rel32 relocations. | 560 // Find the rel32 relocations. |
| 561 const uint8* p = start_pointer; | 561 const uint8* p = start_pointer; |
| 562 while (p < end_pointer) { | 562 while (p < end_pointer) { |
| 563 //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); | 563 //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); |
| 564 | 564 |
| 565 // Heuristic discovery of rel32 locations in instruction stream: are the | 565 // Heuristic discovery of rel32 locations in instruction stream: are the |
| 566 // next few bytes the start of an instruction containing a rel32 | 566 // next few bytes the start of an instruction containing a rel32 |
| 567 // addressing mode? | 567 // addressing mode? |
| 568 const uint8* rel32 = NULL; | 568 const uint8* rel32 = NULL; |
| 569 | 569 |
| 570 if (p + 5 < end_pointer) { | 570 if (p + 5 <= end_pointer) { |
| 571 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 | 571 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 |
| 572 rel32 = p + 1; | 572 rel32 = p + 1; |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 if (p + 6 < end_pointer) { | 575 if (p + 6 <= end_pointer) { |
| 576 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form | 576 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form |
| 577 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely | 577 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely |
| 578 rel32 = p + 2; | 578 rel32 = p + 2; |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 if (rel32) { | 581 if (rel32) { |
| 582 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); | 582 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); |
| 583 | 583 |
| 584 RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); | 584 RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); |
| 585 // To be valid, rel32 target must be within image, and within this | 585 // To be valid, rel32 target must be within image, and within this |
| 586 // section. | 586 // section. |
| 587 if (IsValidRVA(target_rva)) { | 587 if (IsValidRVA(target_rva)) { |
| 588 rel32_locations_.push_back(rel32_rva); | 588 rel32_locations_.push_back(rel32_rva); |
| 589 #if COURGETTE_HISTOGRAM_TARGETS | 589 #if COURGETTE_HISTOGRAM_TARGETS |
| 590 ++rel32_target_rvas_[target_rva]; | 590 ++rel32_target_rvas_[target_rva]; |
| 591 #endif | 591 #endif |
| 592 p += 4; | 592 p = rel32 + 4; |
| 593 continue; | 593 continue; |
| 594 } | 594 } |
| 595 } | 595 } |
| 596 p += 1; | 596 p += 1; |
| 597 } | 597 } |
| 598 | 598 |
| 599 return true; | 599 return true; |
| 600 } | 600 } |
| 601 | 601 |
| 602 } // namespace courgette | 602 } // namespace courgette |
| OLD | NEW |