| 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 #define XOPEN_SOURCE 500 | 5 #define XOPEN_SOURCE 500 |
| 6 | 6 |
| 7 #include "library.h" | 7 #include "library.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <elf.h> | 10 #include <elf.h> |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 if (is_gs_call || | 474 if (is_gs_call || |
| 475 (code[codeIdx].insn == 0xCD && | 475 (code[codeIdx].insn == 0xCD && |
| 476 code[codeIdx].addr[1] == '\x80' /* INT $0x80 */)) { | 476 code[codeIdx].addr[1] == '\x80' /* INT $0x80 */)) { |
| 477 #else | 477 #else |
| 478 #error Unsupported target platform | 478 #error Unsupported target platform |
| 479 #endif | 479 #endif |
| 480 // Found a system call. Search backwards to figure out how to redirect | 480 // Found a system call. Search backwards to figure out how to redirect |
| 481 // the code. We will need to overwrite a couple of instructions and, | 481 // the code. We will need to overwrite a couple of instructions and, |
| 482 // of course, move these instructions somewhere else. | 482 // of course, move these instructions somewhere else. |
| 483 int startIdx = codeIdx; | 483 int startIdx = codeIdx; |
| 484 int endIdx = codeIdx; | |
| 485 int length = code[codeIdx].len; | 484 int length = code[codeIdx].len; |
| 486 for (int idx = codeIdx; | 485 for (int idx = codeIdx; |
| 487 (idx = (idx + (sizeof(code) / sizeof(struct Code)) - 1) % | 486 (idx = (idx + (sizeof(code) / sizeof(struct Code)) - 1) % |
| 488 (sizeof(code) / sizeof(struct Code))) != codeIdx; ) { | 487 (sizeof(code) / sizeof(struct Code))) != codeIdx; ) { |
| 489 BranchTargets::const_iterator iter = | 488 BranchTargets::const_iterator iter = |
| 490 std::upper_bound(branch_targets.begin(), branch_targets.end(), | 489 std::upper_bound(branch_targets.begin(), branch_targets.end(), |
| 491 code[idx].addr); | 490 code[idx].addr); |
| 492 if (iter != branch_targets.end() && *iter < ptr) { | 491 if (iter != branch_targets.end() && *iter < ptr) { |
| 493 // Found a branch pointing to somewhere past our instruction. This | 492 // Found a branch pointing to somewhere past our instruction. This |
| 494 // instruction cannot be moved safely. Leave it in place. | 493 // instruction cannot be moved safely. Leave it in place. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 522 // Found branch target pointing to our instruction | 521 // Found branch target pointing to our instruction |
| 523 break; | 522 break; |
| 524 } | 523 } |
| 525 char *tmp_rm; | 524 char *tmp_rm; |
| 526 code[i].addr = next; | 525 code[i].addr = next; |
| 527 code[i].insn = next_inst((const char **)&next, __WORDSIZE == 64, | 526 code[i].insn = next_inst((const char **)&next, __WORDSIZE == 64, |
| 528 0, 0, &tmp_rm, 0, 0); | 527 0, 0, &tmp_rm, 0, 0); |
| 529 code[i].len = next - code[i].addr; | 528 code[i].len = next - code[i].addr; |
| 530 code[i].is_ip_relative = tmp_rm && (*tmp_rm & 0xC7) == 0x5; | 529 code[i].is_ip_relative = tmp_rm && (*tmp_rm & 0xC7) == 0x5; |
| 531 if (!code[i].is_ip_relative && isSafeInsn(code[i].insn)) { | 530 if (!code[i].is_ip_relative && isSafeInsn(code[i].insn)) { |
| 532 endIdx = i; | |
| 533 length = next - code[startIdx].addr; | 531 length = next - code[startIdx].addr; |
| 534 } else { | 532 } else { |
| 535 break; | 533 break; |
| 536 } | 534 } |
| 537 } | 535 } |
| 538 // We now know, how many instructions neighboring the system call we | 536 // We now know, how many instructions neighboring the system call we |
| 539 // can safely overwrite. On x86-32 we need six bytes, and on x86-64 | 537 // can safely overwrite. On x86-32 we need six bytes, and on x86-64 |
| 540 // We need five bytes to insert a JMPQ and a 32bit address. We then | 538 // We need five bytes to insert a JMPQ and a 32bit address. We then |
| 541 // jump to a code fragment that safely forwards to our system call | 539 // jump to a code fragment that safely forwards to our system call |
| 542 // entrypoint. | 540 // entrypoint. |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 } | 1246 } |
| 1249 iter = symbols_.find("__kernel_rt_sigreturn"); | 1247 iter = symbols_.find("__kernel_rt_sigreturn"); |
| 1250 if (iter != symbols_.end() && iter->second.st_value) { | 1248 if (iter != symbols_.end() && iter->second.st_value) { |
| 1251 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; | 1249 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; |
| 1252 } | 1250 } |
| 1253 | 1251 |
| 1254 return true; | 1252 return true; |
| 1255 } | 1253 } |
| 1256 | 1254 |
| 1257 } // namespace | 1255 } // namespace |
| OLD | NEW |