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 |