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 #include <algorithm> | 6 #include <algorithm> |
7 #include <elf.h> | 7 #include <elf.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 *__kernel_vsyscall = '\xE9'; | 828 *__kernel_vsyscall = '\xE9'; |
829 *reinterpret_cast<long *>(__kernel_vsyscall + 1) = | 829 *reinterpret_cast<long *>(__kernel_vsyscall + 1) = |
830 reinterpret_cast<char *>(&syscallWrapper) - | 830 reinterpret_cast<char *>(&syscallWrapper) - |
831 reinterpret_cast<char *>(__kernel_vsyscall + 5); | 831 reinterpret_cast<char *>(__kernel_vsyscall + 5); |
832 } | 832 } |
833 if (__kernel_sigreturn) { | 833 if (__kernel_sigreturn) { |
834 // Replace the sigreturn() system call with a jump to code that does: | 834 // Replace the sigreturn() system call with a jump to code that does: |
835 // | 835 // |
836 // 58 POP %eax | 836 // 58 POP %eax |
837 // B8 77 00 00 00 MOV $0x77, %eax | 837 // B8 77 00 00 00 MOV $0x77, %eax |
838 // E9 .. .. .. .. JMP syscallWrapper | 838 // E8 .. .. .. .. CALL syscallWrapper |
839 char* dest = getScratchSpace(maps_, __kernel_sigreturn, 11, extraSpace, | 839 char* dest = getScratchSpace(maps_, __kernel_sigreturn, 11, extraSpace, |
840 extraLength); | 840 extraLength); |
841 memcpy(dest, "\x58\xB8\x77\x00\x00\x00\xE9", 7); | 841 memcpy(dest, "\x58\xB8\x77\x00\x00\x00\xE8", 7); |
842 *reinterpret_cast<char *>(dest + 7) = | 842 *reinterpret_cast<long *>(dest + 7) = |
843 reinterpret_cast<char *>(&syscallWrapper) - | 843 reinterpret_cast<char *>(&syscallWrapper) - dest - 11;; |
844 reinterpret_cast<char *>(dest + 11); | |
845 *__kernel_sigreturn = '\xE9'; | 844 *__kernel_sigreturn = '\xE9'; |
846 *reinterpret_cast<char *>(__kernel_sigreturn + 1) = | 845 *reinterpret_cast<long *>(__kernel_sigreturn + 1) = |
847 dest - reinterpret_cast<char *>(__kernel_sigreturn + 5); | 846 dest - reinterpret_cast<char *>(__kernel_sigreturn) - 5; |
848 } | 847 } |
849 if (__kernel_rt_sigreturn) { | 848 if (__kernel_rt_sigreturn) { |
850 // Replace the rt_sigreturn() system call with a jump to code that does: | 849 // Replace the rt_sigreturn() system call with a jump to code that does: |
851 // | 850 // |
852 // B8 AD 00 00 00 MOV $0xAD, %eax | 851 // B8 AD 00 00 00 MOV $0xAD, %eax |
853 // E9 .. .. .. .. JMP syscallWrapper | 852 // E8 .. .. .. .. CALL syscallWrapper |
854 char* dest = getScratchSpace(maps_, __kernel_rt_sigreturn, 10, extraSpace, | 853 char* dest = getScratchSpace(maps_, __kernel_rt_sigreturn, 10, extraSpace, |
855 extraLength); | 854 extraLength); |
856 memcpy(dest, "\xB8\xAD\x00\x00\x00\xE9", 6); | 855 memcpy(dest, "\xB8\xAD\x00\x00\x00\xE8", 6); |
857 *reinterpret_cast<char *>(dest + 6) = | 856 *reinterpret_cast<long *>(dest + 6) = |
858 reinterpret_cast<char *>(&syscallWrapper) - | 857 reinterpret_cast<char *>(&syscallWrapper) - dest - 10; |
859 reinterpret_cast<char *>(dest + 10); | |
860 *__kernel_rt_sigreturn = '\xE9'; | 858 *__kernel_rt_sigreturn = '\xE9'; |
861 *reinterpret_cast<char *>(__kernel_rt_sigreturn + 1) = | 859 *reinterpret_cast<long *>(__kernel_rt_sigreturn + 1) = |
862 dest - reinterpret_cast<char *>(__kernel_rt_sigreturn + 5); | 860 dest - reinterpret_cast<char *>(__kernel_rt_sigreturn) - 5; |
863 } | 861 } |
864 #endif | 862 #endif |
865 } | 863 } |
866 | 864 |
867 int Library::patchVSystemCalls() { | 865 int Library::patchVSystemCalls() { |
868 #if defined(__x86_64__) | 866 #if defined(__x86_64__) |
869 // VSyscalls live in a shared 4kB page at the top of the address space. This | 867 // VSyscalls live in a shared 4kB page at the top of the address space. This |
870 // page cannot be unmapped nor remapped. We have to create a copy within | 868 // page cannot be unmapped nor remapped. We have to create a copy within |
871 // 2GB of the page, and rewrite all IP-relative accesses to shared variables. | 869 // 2GB of the page, and rewrite all IP-relative accesses to shared variables. |
872 // As the top of the address space is not accessible by mmap(), this means | 870 // As the top of the address space is not accessible by mmap(), this means |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 } | 1200 } |
1203 iter = symbols_.find("__kernel_rt_sigreturn"); | 1201 iter = symbols_.find("__kernel_rt_sigreturn"); |
1204 if (iter != symbols_.end() && iter->second.st_value) { | 1202 if (iter != symbols_.end() && iter->second.st_value) { |
1205 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; | 1203 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; |
1206 } | 1204 } |
1207 | 1205 |
1208 return true; | 1206 return true; |
1209 } | 1207 } |
1210 | 1208 |
1211 } // namespace | 1209 } // namespace |
OLD | NEW |