Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: courgette/disassembler_win32_x64.cc

Issue 878043002: Add support for RIP relative addresses on x86_64. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix clang build Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « AUTHORS ('k') | courgette/encode_decode_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_x64.h" 5 #include "courgette/disassembler_win32_x64.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 455 }
456 } 456 }
457 457
458 //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) 458 //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva)
459 // ++abs32_pos; 459 // ++abs32_pos;
460 460
461 // Heuristic discovery of rel32 locations in instruction stream: are the 461 // Heuristic discovery of rel32 locations in instruction stream: are the
462 // next few bytes the start of an instruction containing a rel32 462 // next few bytes the start of an instruction containing a rel32
463 // addressing mode? 463 // addressing mode?
464 const uint8* rel32 = NULL; 464 const uint8* rel32 = NULL;
465 bool is_rip_relative = false;
465 466
466 if (p + 5 <= end_pointer) { 467 if (p + 5 <= end_pointer) {
467 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 468 if (*p == 0xE8 || *p == 0xE9) // jmp rel32 and call rel32
468 rel32 = p + 1; 469 rel32 = p + 1;
470 }
471 if (p + 6 <= end_pointer) {
472 if (*p == 0x0F && (*(p + 1) & 0xF0) == 0x80) { // Jcc long form
473 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely
474 rel32 = p + 2;
475 } else if (*p == 0xFF && (*(p + 1) == 0x15 || *(p + 1) == 0x25)) {
476 // rip relative call/jmp
477 rel32 = p + 2;
478 is_rip_relative = true;
469 } 479 }
470 } 480 }
471 if (p + 6 <= end_pointer) { 481 if (p + 7 <= end_pointer) {
472 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form 482 if ((*p & 0xFB) == 0x48 && *(p + 1) == 0x8D &&
473 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely 483 (*(p + 2) & 0xC7) == 0x05) {
474 rel32 = p + 2; 484 // rip relative lea
485 rel32 = p + 3;
486 is_rip_relative = true;
487 } else if ((*p & 0xFB) == 0x48 && *(p + 1) == 0x8B &&
488 (*(p + 2) & 0xC7) == 0x05) {
489 // rip relative mov
490 rel32 = p + 3;
491 is_rip_relative = true;
475 } 492 }
476 } 493 }
494
477 if (rel32) { 495 if (rel32) {
478 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); 496 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva);
479 497
480 // Is there an abs32 reloc overlapping the candidate? 498 // Is there an abs32 reloc overlapping the candidate?
481 while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3) 499 while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3)
482 ++abs32_pos; 500 ++abs32_pos;
483 // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte 501 // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte
484 // region that could overlap rel32_rva. 502 // region that could overlap rel32_rva.
485 if (abs32_pos != abs32_locations_.end()) { 503 if (abs32_pos != abs32_locations_.end()) {
486 if (*abs32_pos < rel32_rva + 4) { 504 if (*abs32_pos < rel32_rva + 4) {
487 // Beginning of abs32 reloc is before end of rel32 reloc so they 505 // Beginning of abs32 reloc is before end of rel32 reloc so they
488 // overlap. Skip four bytes past the abs32 reloc. 506 // overlap. Skip four bytes past the abs32 reloc.
489 p += (*abs32_pos + 4) - current_rva; 507 p += (*abs32_pos + 4) - current_rva;
490 continue; 508 continue;
491 } 509 }
492 } 510 }
493 511
494 RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); 512 RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32);
495 // To be valid, rel32 target must be within image, and within this 513 // To be valid, rel32 target must be within image, and within this
496 // section. 514 // section.
497 if (IsValidRVA(target_rva) && 515 if (IsValidRVA(target_rva) &&
498 start_rva <= target_rva && target_rva < end_rva) { 516 (is_rip_relative ||
517 (start_rva <= target_rva && target_rva < end_rva))) {
499 rel32_locations_.push_back(rel32_rva); 518 rel32_locations_.push_back(rel32_rva);
500 #if COURGETTE_HISTOGRAM_TARGETS 519 #if COURGETTE_HISTOGRAM_TARGETS
501 ++rel32_target_rvas_[target_rva]; 520 ++rel32_target_rvas_[target_rva];
502 #endif 521 #endif
503 p = rel32 + 4; 522 p = rel32 + 4;
504 continue; 523 continue;
505 } 524 }
506 } 525 }
507 p += 1; 526 p += 1;
508 } 527 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 directory->size_ = static_cast<uint32>(size); 739 directory->size_ = static_cast<uint32>(size);
721 return true; 740 return true;
722 } else { 741 } else {
723 directory->address_ = 0; 742 directory->address_ = 0;
724 directory->size_ = 0; 743 directory->size_ = 0;
725 return true; 744 return true;
726 } 745 }
727 } 746 }
728 747
729 } // namespace courgette 748 } // namespace courgette
OLDNEW
« no previous file with comments | « AUTHORS ('k') | courgette/encode_decode_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698