From cda3f562a282c8adab5adbb16a90ad9532b8d021 Mon Sep 17 00:00:00 2001 From: "thakis@chromium.org" Date: Tue, 12 Apr 2011 22:10:23 +0000 Subject: =?UTF-8?q?Revert=2081308=20(broke=2010.5)-=20Mac:=20Let=20chrome?= =?UTF-8?q?=20coexist=20with=20the=20Chinese=20Handwriting=20IME.The=20ren?= =?UTF-8?q?derer=20sandbox=20breaks=20the=20Chinese=20Handwriting=20shortc?= =?UTF-8?q?ut=20while=20Chromeis=20running,=20even=20when=20Chrome=20is=20?= =?UTF-8?q?not=20active:=20In=20a=20nutshell,=20Carbon=20tries=20to=20load?= =?UTF-8?q?the=20IME=20in=20every=20process,=20and=20if=20that=20fails,=20?= =?UTF-8?q?it=20uninstalls=20the=20toggle=20shorcut.=20Itfails=20in=20the?= =?UTF-8?q?=20renderer=20process=20due=20to=20the=20sandbox.=20See=20the?= =?UTF-8?q?=20bug=20for=20details.Prewarming=20(patch=20set=201)=20doesn't?= =?UTF-8?q?=20work=20because=20that=20opens=20up=20clipboardaccess=20to=20?= =?UTF-8?q?the=20renderer=20=E2=80=93=20the=20IME=20doesn't=20load=20corre?= =?UTF-8?q?ctly=20if=20it=20doesn't=20haveclipboard=20access.dyld=20=5F=5F?= =?UTF-8?q?interpose=20based=20interposing=20(patch=20set=202)=20doesn't?= =?UTF-8?q?=20work=20becauseTISCreateInputSourceList=20and=20its=20broken?= =?UTF-8?q?=20caller=20are=20in=20the=20sameframework=20(HIToolbox).Hence,?= =?UTF-8?q?=20use=20binary=20rewriting=20to=20return=20an=20arbitrary=20ar?= =?UTF-8?q?ray=20with=20size=20>=200=20to=20makeHIToolbox=20believe=20that?= =?UTF-8?q?=20the=20IME=20loads=20correctly,=20so=20that=20it=20doesn't=20?= =?UTF-8?q?uninstall=20theglobal=20handwriting=20keyboard=20shortcut.BUG?= =?UTF-8?q?=3D31225TEST=3DEnable=20Chinese=20in=20the=20input=20menu.=20Ma?= =?UTF-8?q?ke=20sure=20Chrome's=20not=20running.Note=20that=20ctrl-shift-s?= =?UTF-8?q?pace=20opens=20and=20dismisses=20the=20Handwriting=20IME(you=20?= =?UTF-8?q?need=20a=20multitouch=20trackpad=20for=20that).=20Open=20Chrome?= =?UTF-8?q?,=20note=20that=20theIME=20still=20works.(If=20you=20run=20Chro?= =?UTF-8?q?me=20without=20this=20patch,=20the=20IME=20will=20be=20broken?= =?UTF-8?q?=20until=20you=20do=20=20ps=20aux=20|=20grep=20Chineseand=20the?= =?UTF-8?q?n=20=20kill=20$CHINESE=5FHANDWRITING=5FPIDand=20then=20toggle?= =?UTF-8?q?=20the=20IME=20once=20through=20the=20Menu=20Extra=20menu.)It?= =?UTF-8?q?=20is=20a=20good=20idea=20to=20have=20a=20Terminal=20open=20dur?= =?UTF-8?q?ing=20testing,=20because=20killingthe=20task=20is=20the=20only?= =?UTF-8?q?=20way=20to=20dismiss=20the=20IME=20with=20the=20keyboard=20wit?= =?UTF-8?q?hout=20thisCL.Review=20URL:=20http://codereview.chromium.org/68?= =?UTF-8?q?01056=20TBR=3Dthakis@chromium.org=20Review=20URL:=20http://code?= =?UTF-8?q?review.chromium.org/6839001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81318 0039d316-1c4b-4281-b951-d872f2087c98 --- third_party/mach_override/LICENSE | 2 - third_party/mach_override/README.chromium | 29 -- third_party/mach_override/chromium.diff | 136 ------ third_party/mach_override/mach_override.c | 681 ---------------------------- third_party/mach_override/mach_override.gyp | 28 -- third_party/mach_override/mach_override.h | 121 ----- 6 files changed, 997 deletions(-) delete mode 100644 third_party/mach_override/LICENSE delete mode 100644 third_party/mach_override/README.chromium delete mode 100644 third_party/mach_override/chromium.diff delete mode 100644 third_party/mach_override/mach_override.c delete mode 100644 third_party/mach_override/mach_override.gyp delete mode 100644 third_party/mach_override/mach_override.h (limited to 'third_party/mach_override') diff --git a/third_party/mach_override/LICENSE b/third_party/mach_override/LICENSE deleted file mode 100644 index 5f6ba7e..0000000 --- a/third_party/mach_override/LICENSE +++ /dev/null @@ -1,2 +0,0 @@ -Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: -Some rights reserved: diff --git a/third_party/mach_override/README.chromium b/third_party/mach_override/README.chromium deleted file mode 100644 index 385ba92..0000000 --- a/third_party/mach_override/README.chromium +++ /dev/null @@ -1,29 +0,0 @@ -Name: mach_override -Short Name: Part of the mach_star project -Version: Unknown -URL: https://github.com/rentzsch/mach_star -Date: 04/11/2011 -Revision: 2cd209e090640220b48e5f97e7a366165f9de3f9 -License: MIT -Security Critical: Yes. - - -Description: -This is the mach_override part of the lastest (as of 04/11/2011) revision of -mach_star, namely: - - https://github.com/rentzsch/mach_star/tree/2cd209e090640220b48e5f97e7a366165f9de3f9 - -This package is used to replace framework functions with different -implementations at run time. - - -Local Modifications: - -* Minor fixes to make the file buildable with -std=c99 -Wall -Werror -* Support for |sub %esp| with a 32bit immediate -* atomic_mov64 is no longer .globl -* Removed function mach_override() because it used deprecated functions -* Added a gyp file - -See chromium.diff for details. diff --git a/third_party/mach_override/chromium.diff b/third_party/mach_override/chromium.diff deleted file mode 100644 index 650c2b8..0000000 --- a/third_party/mach_override/chromium.diff +++ /dev/null @@ -1,136 +0,0 @@ ---- ../../mach_star/mach_override/mach_override.c 2011-04-11 09:35:25.000000000 -0700 -+++ third_party/mach_override/mach_override.c 2011-04-11 16:09:56.000000000 -0700 -@@ -145,36 +145,6 @@ - #pragma mark - - #pragma mark (Interface) - -- mach_error_t --mach_override( -- char *originalFunctionSymbolName, -- const char *originalFunctionLibraryNameHint, -- const void *overrideFunctionAddress, -- void **originalFunctionReentryIsland ) --{ -- assert( originalFunctionSymbolName ); -- assert( strlen( originalFunctionSymbolName ) ); -- assert( overrideFunctionAddress ); -- -- // Lookup the original function's code pointer. -- long *originalFunctionPtr; -- if( originalFunctionLibraryNameHint ) -- _dyld_lookup_and_bind_with_hint( -- originalFunctionSymbolName, -- originalFunctionLibraryNameHint, -- (void*) &originalFunctionPtr, -- NULL ); -- else -- _dyld_lookup_and_bind( -- originalFunctionSymbolName, -- (void*) &originalFunctionPtr, -- NULL ); -- -- //printf ("In mach_override\n"); -- return mach_override_ptr( originalFunctionPtr, overrideFunctionAddress, -- originalFunctionReentryIsland ); --} -- - #if defined(__x86_64__) - mach_error_t makeIslandExecutable(void *address) { - mach_error_t err = err_none; -@@ -563,6 +533,7 @@ - { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp - { 0x1, {0xFF}, {0x53} }, // push %ebx - { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp -+ { 0x3, {0xFF, 0xFF, 0x00}, {0x81, 0xEC, 0x00} }, // sub 0x??, %esp with 32bit immediate - { 0x1, {0xFF}, {0x57} }, // push %edi - { 0x1, {0xFF}, {0x56} }, // push %esi - { 0x0 } -@@ -584,7 +555,7 @@ - { - Boolean match = true; - -- int i; -+ size_t i; - for (i=0; ilength; i++) { - unsigned char mask = instruction->mask[i]; - unsigned char constraint = instruction->constraint[i]; -@@ -617,7 +588,7 @@ - // See if instruction matches one we know - AsmInstructionMatch* curInstr = possibleInstructions; - do { -- if (curInstructionKnown = codeMatchesInstruction(ptr, curInstr)) break; -+ if ((curInstructionKnown = codeMatchesInstruction(ptr, curInstr))) break; - curInstr++; - } while (curInstr->length > 0); - -@@ -665,10 +636,9 @@ - #endif - - #if defined(__i386__) --asm( -+__asm( - ".text;" - ".align 2, 0x90;" -- ".globl _atomic_mov64;" - "_atomic_mov64:;" - " pushl %ebp;" - " movl %esp, %ebp;" -@@ -708,4 +678,4 @@ - *targetAddress = value; - } - #endif --#endif -\ No newline at end of file -+#endif ---- ../../mach_star/mach_override/mach_override.h 2011-04-11 09:35:25.000000000 -0700 -+++ third_party/mach_override/mach_override.h 2011-04-11 15:43:33.000000000 -0700 -@@ -57,42 +57,6 @@ - */ - #define err_cannot_override (err_local|1) - --/***************************************************************************//** -- Dynamically overrides the function implementation referenced by -- originalFunctionSymbolName with the implentation pointed to by -- overrideFunctionAddress. Optionally returns a pointer to a "reentry island" -- which, if jumped to, will resume the original implementation. -- -- @param originalFunctionSymbolName -> Required symbol name of the -- function to override (with -- overrideFunctionAddress). -- Remember, C function name -- symbols are prepended with an -- underscore. -- @param originalFunctionLibraryNameHint -> Optional name of the library -- which contains -- originalFunctionSymbolName. Can -- be NULL, but this may result in -- the wrong function being -- overridden and/or a crash. -- @param overrideFunctionAddress -> Required address to the -- overriding function. -- @param originalFunctionReentryIsland <- Optional pointer to pointer to -- the reentry island. Can be NULL. -- @result <- err_cannot_override if the -- original function's -- implementation begins with the -- 'mfctr' instruction. -- -- ***************************************************************************/ -- -- mach_error_t --mach_override( -- char *originalFunctionSymbolName, -- const char *originalFunctionLibraryNameHint, -- const void *overrideFunctionAddress, -- void **originalFunctionReentryIsland ); -- - /************************************************************************************//** - Dynamically overrides the function implementation referenced by - originalFunctionAddress with the implentation pointed to by overrideFunctionAddress. -@@ -154,4 +118,4 @@ - #ifdef __cplusplus - } - #endif --#endif // _mach_override_ -\ No newline at end of file -+#endif // _mach_override_ diff --git a/third_party/mach_override/mach_override.c b/third_party/mach_override/mach_override.c deleted file mode 100644 index 2af0f14..0000000 --- a/third_party/mach_override/mach_override.c +++ /dev/null @@ -1,681 +0,0 @@ -/******************************************************************************* - mach_override.c - Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: - Some rights reserved: - - ***************************************************************************/ - -#include "mach_override.h" - -#include -#include -#include -#include -#include - -#include - -/************************** -* -* Constants -* -**************************/ -#pragma mark - -#pragma mark (Constants) - -#if defined(__ppc__) || defined(__POWERPC__) - -long kIslandTemplate[] = { - 0x9001FFFC, // stw r0,-4(SP) - 0x3C00DEAD, // lis r0,0xDEAD - 0x6000BEEF, // ori r0,r0,0xBEEF - 0x7C0903A6, // mtctr r0 - 0x8001FFFC, // lwz r0,-4(SP) - 0x60000000, // nop ; optionally replaced - 0x4E800420 // bctr -}; - -#define kAddressHi 3 -#define kAddressLo 5 -#define kInstructionHi 10 -#define kInstructionLo 11 - -#elif defined(__i386__) - -#define kOriginalInstructionsSize 16 - -char kIslandTemplate[] = { - // kOriginalInstructionsSize nop instructions so that we - // should have enough space to host original instructions - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - // Now the real jump instruction - 0xE9, 0xEF, 0xBE, 0xAD, 0xDE -}; - -#define kInstructions 0 -#define kJumpAddress kInstructions + kOriginalInstructionsSize + 1 -#elif defined(__x86_64__) - -#define kOriginalInstructionsSize 32 - -#define kJumpAddress kOriginalInstructionsSize + 6 - -char kIslandTemplate[] = { - // kOriginalInstructionsSize nop instructions so that we - // should have enough space to host original instructions - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - // Now the real jump instruction - 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif - -#define kAllocateHigh 1 -#define kAllocateNormal 0 - -/************************** -* -* Data Types -* -**************************/ -#pragma mark - -#pragma mark (Data Types) - -typedef struct { - char instructions[sizeof(kIslandTemplate)]; - int allocatedHigh; -} BranchIsland; - -/************************** -* -* Funky Protos -* -**************************/ -#pragma mark - -#pragma mark (Funky Protos) - - mach_error_t -allocateBranchIsland( - BranchIsland **island, - int allocateHigh, - void *originalFunctionAddress); - - mach_error_t -freeBranchIsland( - BranchIsland *island ); - -#if defined(__ppc__) || defined(__POWERPC__) - mach_error_t -setBranchIslandTarget( - BranchIsland *island, - const void *branchTo, - long instruction ); -#endif - -#if defined(__i386__) || defined(__x86_64__) -mach_error_t -setBranchIslandTarget_i386( - BranchIsland *island, - const void *branchTo, - char* instructions ); -void -atomic_mov64( - uint64_t *targetAddress, - uint64_t value ); - - static Boolean -eatKnownInstructions( - unsigned char *code, - uint64_t *newInstruction, - int *howManyEaten, - char *originalInstructions ); -#endif - -/******************************************************************************* -* -* Interface -* -*******************************************************************************/ -#pragma mark - -#pragma mark (Interface) - -#if defined(__x86_64__) -mach_error_t makeIslandExecutable(void *address) { - mach_error_t err = err_none; - vm_size_t pageSize; - host_page_size( mach_host_self(), &pageSize ); - uint64_t page = (uint64_t)address & ~(uint64_t)(pageSize-1); - int e = err_none; - e |= mprotect((void *)page, pageSize, PROT_EXEC | PROT_READ | PROT_WRITE); - e |= msync((void *)page, pageSize, MS_INVALIDATE ); - if (e) { - err = err_cannot_override; - } - return err; -} -#endif - - mach_error_t -mach_override_ptr( - void *originalFunctionAddress, - const void *overrideFunctionAddress, - void **originalFunctionReentryIsland ) -{ - assert( originalFunctionAddress ); - assert( overrideFunctionAddress ); - - long *originalFunctionPtr = (long*) originalFunctionAddress; - mach_error_t err = err_none; - -#if defined(__ppc__) || defined(__POWERPC__) - // Ensure first instruction isn't 'mfctr'. - #define kMFCTRMask 0xfc1fffff - #define kMFCTRInstruction 0x7c0903a6 - - long originalInstruction = *originalFunctionPtr; - if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) ) - err = err_cannot_override; -#elif defined(__i386__) || defined(__x86_64__) - int eatenCount = 0; - char originalInstructions[kOriginalInstructionsSize]; - uint64_t jumpRelativeInstruction = 0; // JMP - - Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, - &jumpRelativeInstruction, &eatenCount, originalInstructions); - if (eatenCount > kOriginalInstructionsSize) { - //printf ("Too many instructions eaten\n"); - overridePossible = false; - } - if (!overridePossible) err = err_cannot_override; - if (err) printf("err = %x %d\n", err, __LINE__); -#endif - - // Make the original function implementation writable. - if( !err ) { - err = vm_protect( mach_task_self(), - (vm_address_t) originalFunctionPtr, - sizeof(long), false, (VM_PROT_ALL | VM_PROT_COPY) ); - if( err ) - err = vm_protect( mach_task_self(), - (vm_address_t) originalFunctionPtr, sizeof(long), false, - (VM_PROT_DEFAULT | VM_PROT_COPY) ); - } - if (err) printf("err = %x %d\n", err, __LINE__); - - // Allocate and target the escape island to the overriding function. - BranchIsland *escapeIsland = NULL; - if( !err ) - err = allocateBranchIsland( &escapeIsland, kAllocateHigh, originalFunctionAddress ); - if (err) printf("err = %x %d\n", err, __LINE__); - - -#if defined(__ppc__) || defined(__POWERPC__) - if( !err ) - err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 ); - - // Build the branch absolute instruction to the escape island. - long branchAbsoluteInstruction = 0; // Set to 0 just to silence warning. - if( !err ) { - long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF; - branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress; - } -#elif defined(__i386__) || defined(__x86_64__) - if (err) printf("err = %x %d\n", err, __LINE__); - - if( !err ) - err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 ); - - if (err) printf("err = %x %d\n", err, __LINE__); - // Build the jump relative instruction to the escape island -#endif - - -#if defined(__i386__) || defined(__x86_64__) - if (!err) { - uint32_t addressOffset = ((void*)escapeIsland - (void*)originalFunctionPtr - 5); - addressOffset = OSSwapInt32(addressOffset); - - jumpRelativeInstruction |= 0xE900000000000000LL; - jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24; - jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction); - } -#endif - - // Optionally allocate & return the reentry island. - BranchIsland *reentryIsland = NULL; - if( !err && originalFunctionReentryIsland ) { - err = allocateBranchIsland( &reentryIsland, kAllocateNormal, NULL); - if( !err ) - *originalFunctionReentryIsland = reentryIsland; - } - -#if defined(__ppc__) || defined(__POWERPC__) - // Atomically: - // o If the reentry island was allocated: - // o Insert the original instruction into the reentry island. - // o Target the reentry island at the 2nd instruction of the - // original function. - // o Replace the original instruction with the branch absolute. - if( !err ) { - int escapeIslandEngaged = false; - do { - if( reentryIsland ) - err = setBranchIslandTarget( reentryIsland, - (void*) (originalFunctionPtr+1), originalInstruction ); - if( !err ) { - escapeIslandEngaged = CompareAndSwap( originalInstruction, - branchAbsoluteInstruction, - (UInt32*)originalFunctionPtr ); - if( !escapeIslandEngaged ) { - // Someone replaced the instruction out from under us, - // re-read the instruction, make sure it's still not - // 'mfctr' and try again. - originalInstruction = *originalFunctionPtr; - if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction) - err = err_cannot_override; - } - } - } while( !err && !escapeIslandEngaged ); - } -#elif defined(__i386__) || defined(__x86_64__) - // Atomically: - // o If the reentry island was allocated: - // o Insert the original instructions into the reentry island. - // o Target the reentry island at the first non-replaced - // instruction of the original function. - // o Replace the original first instructions with the jump relative. - // - // Note that on i386, we do not support someone else changing the code under our feet - if ( !err ) { - if( reentryIsland ) - err = setBranchIslandTarget_i386( reentryIsland, - (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions ); - if ( !err ) - atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction); - } -#endif - - // Clean up on error. - if( err ) { - if( reentryIsland ) - freeBranchIsland( reentryIsland ); - if( escapeIsland ) - freeBranchIsland( escapeIsland ); - } - -#if defined(__x86_64__) - err = makeIslandExecutable(escapeIsland); - err = makeIslandExecutable(reentryIsland); -#endif - - return err; -} - -/******************************************************************************* -* -* Implementation -* -*******************************************************************************/ -#pragma mark - -#pragma mark (Implementation) - -/***************************************************************************//** - Implementation: Allocates memory for a branch island. - - @param island <- The allocated island. - @param allocateHigh -> Whether to allocate the island at the end of the - address space (for use with the branch absolute - instruction). - @result <- mach_error_t - - ***************************************************************************/ - - mach_error_t -allocateBranchIsland( - BranchIsland **island, - int allocateHigh, - void *originalFunctionAddress) -{ - assert( island ); - - mach_error_t err = err_none; - - if( allocateHigh ) { - vm_size_t pageSize; - err = host_page_size( mach_host_self(), &pageSize ); - if( !err ) { - assert( sizeof( BranchIsland ) <= pageSize ); -#if defined(__x86_64__) - vm_address_t first = (uint64_t)originalFunctionAddress & ~(uint64_t)(((uint64_t)1 << 31) - 1) | ((uint64_t)1 << 31); // start in the middle of the page? - vm_address_t last = 0x0; -#else - vm_address_t first = 0xfeffffff; - vm_address_t last = 0xfe000000 + pageSize; -#endif - - vm_address_t page = first; - int allocated = 0; - vm_map_t task_self = mach_task_self(); - - while( !err && !allocated && page != last ) { - - err = vm_allocate( task_self, &page, pageSize, 0 ); - if( err == err_none ) - allocated = 1; - else if( err == KERN_NO_SPACE ) { -#if defined(__x86_64__) - page -= pageSize; -#else - page += pageSize; -#endif - err = err_none; - } - } - if( allocated ) - *island = (void*) page; - else if( !allocated && !err ) - err = KERN_NO_SPACE; - } - } else { - void *block = malloc( sizeof( BranchIsland ) ); - if( block ) - *island = block; - else - err = KERN_NO_SPACE; - } - if( !err ) - (**island).allocatedHigh = allocateHigh; - - return err; -} - -/***************************************************************************//** - Implementation: Deallocates memory for a branch island. - - @param island -> The island to deallocate. - @result <- mach_error_t - - ***************************************************************************/ - - mach_error_t -freeBranchIsland( - BranchIsland *island ) -{ - assert( island ); - assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] ); - assert( island->allocatedHigh ); - - mach_error_t err = err_none; - - if( island->allocatedHigh ) { - vm_size_t pageSize; - err = host_page_size( mach_host_self(), &pageSize ); - if( !err ) { - assert( sizeof( BranchIsland ) <= pageSize ); - err = vm_deallocate( - mach_task_self(), - (vm_address_t) island, pageSize ); - } - } else { - free( island ); - } - - return err; -} - -/***************************************************************************//** - Implementation: Sets the branch island's target, with an optional - instruction. - - @param island -> The branch island to insert target into. - @param branchTo -> The address of the target. - @param instruction -> Optional instruction to execute prior to branch. Set - to zero for nop. - @result <- mach_error_t - - ***************************************************************************/ -#if defined(__ppc__) || defined(__POWERPC__) - mach_error_t -setBranchIslandTarget( - BranchIsland *island, - const void *branchTo, - long instruction ) -{ - // Copy over the template code. - bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); - - // Fill in the address. - ((short*)island->instructions)[kAddressLo] = ((long) branchTo) & 0x0000FFFF; - ((short*)island->instructions)[kAddressHi] - = (((long) branchTo) >> 16) & 0x0000FFFF; - - // Fill in the (optional) instuction. - if( instruction != 0 ) { - ((short*)island->instructions)[kInstructionLo] - = instruction & 0x0000FFFF; - ((short*)island->instructions)[kInstructionHi] - = (instruction >> 16) & 0x0000FFFF; - } - - //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) ); - msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); - - return err_none; -} -#endif - -#if defined(__i386__) - mach_error_t -setBranchIslandTarget_i386( - BranchIsland *island, - const void *branchTo, - char* instructions ) -{ - - // Copy over the template code. - bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); - - // copy original instructions - if (instructions) { - bcopy (instructions, island->instructions + kInstructions, kOriginalInstructionsSize); - } - - // Fill in the address. - int32_t addressOffset = (char *)branchTo - (island->instructions + kJumpAddress + 4); - *((int32_t *)(island->instructions + kJumpAddress)) = addressOffset; - - msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); - return err_none; -} - -#elif defined(__x86_64__) -mach_error_t -setBranchIslandTarget_i386( - BranchIsland *island, - const void *branchTo, - char* instructions ) -{ - // Copy over the template code. - bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); - - // Copy original instructions. - if (instructions) { - bcopy (instructions, island->instructions, kOriginalInstructionsSize); - } - - // Fill in the address. - *((uint64_t *)(island->instructions + kJumpAddress)) = (uint64_t)branchTo; - msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); - - return err_none; -} -#endif - - -#if defined(__i386__) || defined(__x86_64__) -// simplistic instruction matching -typedef struct { - unsigned int length; // max 15 - unsigned char mask[15]; // sequence of bytes in memory order - unsigned char constraint[15]; // sequence of bytes in memory order -} AsmInstructionMatch; - -#if defined(__i386__) -static AsmInstructionMatch possibleInstructions[] = { - { 0x1, {0xFF}, {0x90} }, // nop - { 0x1, {0xFF}, {0x55} }, // push %esp - { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp - { 0x1, {0xFF}, {0x53} }, // push %ebx - { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp - { 0x3, {0xFF, 0xFF, 0x00}, {0x81, 0xEC, 0x00} }, // sub 0x??, %esp with 32bit immediate - { 0x1, {0xFF}, {0x57} }, // push %edi - { 0x1, {0xFF}, {0x56} }, // push %esi - { 0x0 } -}; -#elif defined(__x86_64__) -static AsmInstructionMatch possibleInstructions[] = { - { 0x1, {0xFF}, {0x90} }, // nop - { 0x1, {0xF8}, {0x50} }, // push %rX - { 0x3, {0xFF, 0xFF, 0xFF}, {0x48, 0x89, 0xE5} }, // mov %rsp,%rbp - { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x48, 0x83, 0xEC, 0x00} }, // sub 0x??, %rsp - { 0x4, {0xFB, 0xFF, 0x00, 0x00}, {0x48, 0x89, 0x00, 0x00} }, // move onto rbp - { 0x2, {0xFF, 0x00}, {0x41, 0x00} }, // push %rXX - { 0x2, {0xFF, 0x00}, {0x85, 0x00} }, // test %rX,%rX - { 0x0 } -}; -#endif - -static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction) -{ - Boolean match = true; - - size_t i; - for (i=0; ilength; i++) { - unsigned char mask = instruction->mask[i]; - unsigned char constraint = instruction->constraint[i]; - unsigned char codeValue = code[i]; - - match = ((codeValue & mask) == constraint); - if (!match) break; - } - - return match; -} - -#if defined(__i386__) || defined(__x86_64__) - static Boolean -eatKnownInstructions( - unsigned char *code, - uint64_t* newInstruction, - int* howManyEaten, - char* originalInstructions ) -{ - Boolean allInstructionsKnown = true; - int totalEaten = 0; - unsigned char* ptr = code; - int remainsToEat = 5; // a JMP instruction takes 5 bytes - - if (howManyEaten) *howManyEaten = 0; - while (remainsToEat > 0) { - Boolean curInstructionKnown = false; - - // See if instruction matches one we know - AsmInstructionMatch* curInstr = possibleInstructions; - do { - if ((curInstructionKnown = codeMatchesInstruction(ptr, curInstr))) break; - curInstr++; - } while (curInstr->length > 0); - - // if all instruction matches failed, we don't know current instruction then, stop here - if (!curInstructionKnown) { - allInstructionsKnown = false; - break; - } - - // At this point, we've matched curInstr - int eaten = curInstr->length; - ptr += eaten; - remainsToEat -= eaten; - totalEaten += eaten; - } - - - if (howManyEaten) *howManyEaten = totalEaten; - - if (originalInstructions) { - Boolean enoughSpaceForOriginalInstructions = (totalEaten < kOriginalInstructionsSize); - - if (enoughSpaceForOriginalInstructions) { - memset(originalInstructions, 0x90 /* NOP */, kOriginalInstructionsSize); // fill instructions with NOP - bcopy(code, originalInstructions, totalEaten); - } else { - // printf ("Not enough space in island to store original instructions. Adapt the island definition and kOriginalInstructionsSize\n"); - return false; - } - } - - if (allInstructionsKnown) { - // save last 3 bytes of first 64bits of codre we'll replace - uint64_t currentFirst64BitsOfCode = *((uint64_t *)code); - currentFirst64BitsOfCode = OSSwapInt64(currentFirst64BitsOfCode); // back to memory representation - currentFirst64BitsOfCode &= 0x0000000000FFFFFFLL; - - // keep only last 3 instructions bytes, first 5 will be replaced by JMP instr - *newInstruction &= 0xFFFFFFFFFF000000LL; // clear last 3 bytes - *newInstruction |= (currentFirst64BitsOfCode & 0x0000000000FFFFFFLL); // set last 3 bytes - } - - return allInstructionsKnown; -} -#endif - -#if defined(__i386__) -__asm( - ".text;" - ".align 2, 0x90;" - "_atomic_mov64:;" - " pushl %ebp;" - " movl %esp, %ebp;" - " pushl %esi;" - " pushl %ebx;" - " pushl %ecx;" - " pushl %eax;" - " pushl %edx;" - - // atomic push of value to an address - // we use cmpxchg8b, which compares content of an address with - // edx:eax. If they are equal, it atomically puts 64bit value - // ecx:ebx in address. - // We thus put contents of address in edx:eax to force ecx:ebx - // in address - " mov 8(%ebp), %esi;" // esi contains target address - " mov 12(%ebp), %ebx;" - " mov 16(%ebp), %ecx;" // ecx:ebx now contains value to put in target address - " mov (%esi), %eax;" - " mov 4(%esi), %edx;" // edx:eax now contains value currently contained in target address - " lock; cmpxchg8b (%esi);" // atomic move. - - // restore registers - " popl %edx;" - " popl %eax;" - " popl %ecx;" - " popl %ebx;" - " popl %esi;" - " popl %ebp;" - " ret" -); -#elif defined(__x86_64__) -void atomic_mov64( - uint64_t *targetAddress, - uint64_t value ) -{ - *targetAddress = value; -} -#endif -#endif diff --git a/third_party/mach_override/mach_override.gyp b/third_party/mach_override/mach_override.gyp deleted file mode 100644 index 3dbb1d1..0000000 --- a/third_party/mach_override/mach_override.gyp +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'targets': [ - ], - 'conditions': [ - ['OS=="mac"', { - 'targets' : [ - { - 'target_name' : 'mach_override', - 'type': '<(library)', - 'sources': [ - 'mach_override.c', - 'mach_override.h', - ], - }, - ], - }], - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/third_party/mach_override/mach_override.h b/third_party/mach_override/mach_override.h deleted file mode 100644 index 76fdb1b..0000000 --- a/third_party/mach_override/mach_override.h +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - mach_override.h - Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: - Some rights reserved: - - ***************************************************************************/ - -/***************************************************************************//** - @mainpage mach_override - @author Jonathan 'Wolf' Rentzsch: - - This package, coded in C to the Mach API, allows you to override ("patch") - program- and system-supplied functions at runtime. You can fully replace - functions with your implementations, or merely head- or tail-patch the - original implementations. - - Use it by #include'ing mach_override.h from your .c, .m or .mm file(s). - - @todo Discontinue use of Carbon's MakeDataExecutable() and - CompareAndSwap() calls and start using the Mach equivalents, if they - exist. If they don't, write them and roll them in. That way, this - code will be pure Mach, which will make it easier to use everywhere. - Update: MakeDataExecutable() has been replaced by - msync(MS_INVALIDATE). There is an OSCompareAndSwap in libkern, but - I'm currently unsure if I can link against it. May have to roll in - my own version... - @todo Stop using an entire 4K high-allocated VM page per 28-byte escape - branch island. Done right, this will dramatically speed up escape - island allocations when they number over 250. Then again, if you're - overriding more than 250 functions, maybe speed isn't your main - concern... - @todo Add detection of: b, bl, bla, bc, bcl, bcla, bcctrl, bclrl - first-instructions. Initially, we should refuse to override - functions beginning with these instructions. Eventually, we should - dynamically rewrite them to make them position-independent. - @todo Write mach_unoverride(), which would remove an override placed on a - function. Must be multiple-override aware, which means an almost - complete rewrite under the covers, because the target address can't - be spread across two load instructions like it is now since it will - need to be atomically updatable. - @todo Add non-rentry variants of overrides to test_mach_override. - - ***************************************************************************/ - -#ifndef _mach_override_ -#define _mach_override_ - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -/** - Returned if the function to be overrided begins with a 'mfctr' instruction. -*/ -#define err_cannot_override (err_local|1) - -/************************************************************************************//** - Dynamically overrides the function implementation referenced by - originalFunctionAddress with the implentation pointed to by overrideFunctionAddress. - Optionally returns a pointer to a "reentry island" which, if jumped to, will resume - the original implementation. - - @param originalFunctionAddress -> Required address of the function to - override (with overrideFunctionAddress). - @param overrideFunctionAddress -> Required address to the overriding - function. - @param originalFunctionReentryIsland <- Optional pointer to pointer to the - reentry island. Can be NULL. - @result <- err_cannot_override if the original - function's implementation begins with - the 'mfctr' instruction. - - ************************************************************************************/ - - mach_error_t -mach_override_ptr( - void *originalFunctionAddress, - const void *overrideFunctionAddress, - void **originalFunctionReentryIsland ); - -/************************************************************************************//** - - - ************************************************************************************/ - -#ifdef __cplusplus - -#define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \ - { \ - static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \ - static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \ - class mach_override_class__##ORIGINAL_FUNCTION_NAME { \ - public: \ - static kern_return_t override(void *originalFunctionPtr) { \ - kern_return_t result = err_none; \ - if (!ORIGINAL_FUNCTION_NAME##_overriden) { \ - ORIGINAL_FUNCTION_NAME##_overriden = true; \ - result = mach_override_ptr( (void*)originalFunctionPtr, \ - (void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \ - (void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \ - } \ - return result; \ - } \ - static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS { - -#define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \ - } \ - }; \ - \ - err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \ - } - -#endif - -#ifdef __cplusplus - } -#endif -#endif // _mach_override_ -- cgit v1.1