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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 if (is_gs_call || | 465 if (is_gs_call || |
466 (code[codeIdx].insn == 0xCD && | 466 (code[codeIdx].insn == 0xCD && |
467 code[codeIdx].addr[1] == '\x80' /* INT $0x80 */)) { | 467 code[codeIdx].addr[1] == '\x80' /* INT $0x80 */)) { |
468 #else | 468 #else |
469 #error Unsupported target platform | 469 #error Unsupported target platform |
470 #endif | 470 #endif |
471 // Found a system call. Search backwards to figure out how to redirect | 471 // Found a system call. Search backwards to figure out how to redirect |
472 // the code. We will need to overwrite a couple of instructions and, | 472 // the code. We will need to overwrite a couple of instructions and, |
473 // of course, move these instructions somewhere else. | 473 // of course, move these instructions somewhere else. |
474 int startIdx = codeIdx; | 474 int startIdx = codeIdx; |
475 int endIdx = codeIdx; | |
476 int length = code[codeIdx].len; | 475 int length = code[codeIdx].len; |
477 for (int idx = codeIdx; | 476 for (int idx = codeIdx; |
478 (idx = (idx + (sizeof(code) / sizeof(struct Code)) - 1) % | 477 (idx = (idx + (sizeof(code) / sizeof(struct Code)) - 1) % |
479 (sizeof(code) / sizeof(struct Code))) != codeIdx; ) { | 478 (sizeof(code) / sizeof(struct Code))) != codeIdx; ) { |
480 BranchTargets::const_iterator iter = | 479 BranchTargets::const_iterator iter = |
481 std::upper_bound(branch_targets.begin(), branch_targets.end(), | 480 std::upper_bound(branch_targets.begin(), branch_targets.end(), |
482 code[idx].addr); | 481 code[idx].addr); |
483 if (iter != branch_targets.end() && *iter < ptr) { | 482 if (iter != branch_targets.end() && *iter < ptr) { |
484 // Found a branch pointing to somewhere past our instruction. This | 483 // Found a branch pointing to somewhere past our instruction. This |
485 // instruction cannot be moved safely. Leave it in place. | 484 // instruction cannot be moved safely. Leave it in place. |
(...skipping 27 matching lines...) Expand all Loading... |
513 // Found branch target pointing to our instruction | 512 // Found branch target pointing to our instruction |
514 break; | 513 break; |
515 } | 514 } |
516 char *tmp_rm; | 515 char *tmp_rm; |
517 code[i].addr = next; | 516 code[i].addr = next; |
518 code[i].insn = next_inst((const char **)&next, __WORDSIZE == 64, | 517 code[i].insn = next_inst((const char **)&next, __WORDSIZE == 64, |
519 0, 0, &tmp_rm, 0, 0); | 518 0, 0, &tmp_rm, 0, 0); |
520 code[i].len = next - code[i].addr; | 519 code[i].len = next - code[i].addr; |
521 code[i].is_ip_relative = tmp_rm && (*tmp_rm & 0xC7) == 0x5; | 520 code[i].is_ip_relative = tmp_rm && (*tmp_rm & 0xC7) == 0x5; |
522 if (!code[i].is_ip_relative && isSafeInsn(code[i].insn)) { | 521 if (!code[i].is_ip_relative && isSafeInsn(code[i].insn)) { |
523 endIdx = i; | |
524 length = next - code[startIdx].addr; | 522 length = next - code[startIdx].addr; |
525 } else { | 523 } else { |
526 break; | 524 break; |
527 } | 525 } |
528 } | 526 } |
529 // We now know, how many instructions neighboring the system call we | 527 // We now know, how many instructions neighboring the system call we |
530 // can safely overwrite. On x86-32 we need six bytes, and on x86-64 | 528 // can safely overwrite. On x86-32 we need six bytes, and on x86-64 |
531 // We need five bytes to insert a JMPQ and a 32bit address. We then | 529 // We need five bytes to insert a JMPQ and a 32bit address. We then |
532 // jump to a code fragment that safely forwards to our system call | 530 // jump to a code fragment that safely forwards to our system call |
533 // entrypoint. | 531 // entrypoint. |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 } | 1237 } |
1240 iter = symbols_.find("__kernel_rt_sigreturn"); | 1238 iter = symbols_.find("__kernel_rt_sigreturn"); |
1241 if (iter != symbols_.end() && iter->second.st_value) { | 1239 if (iter != symbols_.end() && iter->second.st_value) { |
1242 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; | 1240 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; |
1243 } | 1241 } |
1244 | 1242 |
1245 return true; | 1243 return true; |
1246 } | 1244 } |
1247 | 1245 |
1248 } // namespace | 1246 } // namespace |
OLD | NEW |