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

Unified Diff: third_party/mach_override/chromium.patch

Issue 2946753003: Sped up allocateBranchIsland by skipping whole regions of allocated memory. (Closed)
Patch Set: Added overflow and underflow detection. Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: third_party/mach_override/chromium.patch
diff --git a/third_party/mach_override/chromium.patch b/third_party/mach_override/chromium.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ec51843533732644264a4cf7e17518db4b2095c5
--- /dev/null
+++ b/third_party/mach_override/chromium.patch
@@ -0,0 +1,127 @@
+diff --git a/third_party/mach_override/README.chromium b/third_party/mach_override/README.chromium
+index 8a7c3fd79e0b..d83803a2bf63 100644
+--- a/third_party/mach_override/README.chromium
++++ b/third_party/mach_override/README.chromium
+@@ -1,6 +1,7 @@
+ Name: mach_override
+ Short Name: mach_override
+-Version: Newer than 1.2. HEAD from branch semver-1.x.
++Version: 0
++Newer than 1.2. HEAD from branch semver-1.x.
+ URL: https://github.com/rentzsch/mach_override
+ Date: 2014-05-11
+ Revision: 919148f94db54fc04d287eb6a42c0c36b166bbfa
+@@ -16,4 +17,5 @@ mach_override includes a copy of libudis86 1.7.1, available separately from
+ http://udis86.sourceforge.net/ and https://github.com/vmt/udis86 .
+
+
+-Local Modifications: None.
++Local Modifications: Sped up allocation of branch island memory via usage of
++ vm_region to skip already allocated pages.
+diff --git a/third_party/mach_override/chromium.patch b/third_party/mach_override/chromium.patch
+new file mode 100644
+index 000000000000..e69de29bb2d1
+diff --git a/third_party/mach_override/mach_override.c b/third_party/mach_override/mach_override.c
+index 85a75e5c2067..ba2b1de2d598 100644
+--- a/third_party/mach_override/mach_override.c
++++ b/third_party/mach_override/mach_override.c
+@@ -41,7 +41,7 @@ long kIslandTemplate[] = {
+ #define kInstructionHi 10
+ #define kInstructionLo 11
+
+-#elif defined(__i386__)
++#elif defined(__i386__)
+
+ #define kOriginalInstructionsSize 16
+
+@@ -61,6 +61,7 @@ char kIslandTemplate[] = {
+ #define kOriginalInstructionsSize 32
+
+ #define kJumpAddress kOriginalInstructionsSize + 6
++#define kMaxJumpOffset (0x7fffffffUL)
+
+ char kIslandTemplate[] = {
+ // kOriginalInstructionsSize nop instructions so that we
+@@ -267,7 +268,13 @@ mach_override_ptr(
+
+ #if defined(__i386__) || defined(__x86_64__)
+ if (!err) {
+- uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
++ // TODO: On 64-bit, move to opcode FF/4 (jmp 64-bit absolute) instead of
++ // E9 (jmp 32-bit relative to RIP). Then we should update the
++ // allocateBranchIsland to simply allocate any page in the address space.
++ // See the 64-bit version of kIslandTemplate array.
++ int64_t addressOffset64 = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
++ int32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
++ assert(addressOffset64 == addressOffset);
+ addressOffset = OSSwapInt32(addressOffset);
+
+ jumpRelativeInstruction |= 0xE900000000000000LL;
+@@ -385,7 +392,7 @@ allocateBranchIsland(
+ void *originalFunctionAddress)
+ {
+ assert( island );
+-
++
+ mach_error_t err = err_none;
+
+ if( allocateHigh ) {
+@@ -401,23 +408,44 @@ allocateBranchIsland(
+ vm_address_t first = 0xfeffffff;
+ vm_address_t last = 0xfe000000 + PAGE_SIZE;
+ #elif defined(__x86_64__)
+- // 64-bit ASLR is in bits 13-28
+- vm_address_t first = ((uint64_t)originalFunctionAddress & ~( (0xFUL << 28) | (PAGE_SIZE - 1) ) ) | (0x1UL << 31);
+- vm_address_t last = (uint64_t)originalFunctionAddress & ~((0x1UL << 32) - 1);
++ // This logic is more complex due to the 32-bit limit of the jump out
++ // of the original function. Once that limitation is removed, we can
++ // use vm_allocate with VM_FLAGS_ANYWHERE as in the i386 code above.
++ const uint64_t kPageMask = ~(PAGE_SIZE - 1);
++ vm_address_t first = (uint64_t)originalFunctionAddress - kMaxJumpOffset;
++ first = (first & kPageMask) + PAGE_SIZE; // Align up to the next page start
++ if (first > (uint64_t)originalFunctionAddress) first = 0;
++ vm_address_t last = (uint64_t)originalFunctionAddress + kMaxJumpOffset;
++ if (last < (uint64_t)originalFunctionAddress) last = ULONG_MAX;
+ #endif
+
+ page = first;
+ int allocated = 0;
+ vm_map_t task_self = mach_task_self();
+
+- while( !err && !allocated && page != last ) {
++ while( !err && !allocated && page < last ) {
+
+ err = vm_allocate( task_self, &page, PAGE_SIZE, 0 );
+ if( err == err_none )
+ allocated = 1;
+ else if( err == KERN_NO_SPACE ) {
+ #if defined(__x86_64__)
+- page -= PAGE_SIZE;
++ // This memory region is not suitable, skip it:
++ vm_address_t region_start = page;
++ vm_size_t region_size;
++ mach_msg_type_number_t int_count = VM_REGION_BASIC_INFO_COUNT_64;
++ vm_region_basic_info_data_64_t vm_region_info;
++ mach_port_t object_name;
++ kern_return_t region_result =
++ vm_region_64(task_self, &region_start, &region_size,
++ VM_REGION_BASIC_INFO_64, (vm_region_info_t)&vm_region_info,
++ &int_count, &object_name);
++ if (region_result == KERN_SUCCESS) {
++ page = region_start + region_size;
++ } else {
++ err = region_result;
++ break;
++ }
+ #else
+ page += PAGE_SIZE;
+ #endif
+@@ -438,7 +466,7 @@ allocateBranchIsland(
+ }
+ if( !err )
+ (**island).allocatedHigh = allocateHigh;
+-
++
+ return err;
+ }
+

Powered by Google App Engine
This is Rietveld 408576698