summaryrefslogtreecommitdiffstats
path: root/third_party/mach_override
diff options
context:
space:
mode:
authorbadea@adobe.com <badea@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-22 16:44:47 +0000
committerbadea@adobe.com <badea@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-22 16:44:47 +0000
commita288635bbfff0682103ac2753c06f028c4bb59ce (patch)
tree2e88427362030a3c81820b93727d78ad67b01c02 /third_party/mach_override
parenta5578850f830bf8e852debf559957348a66ec858 (diff)
downloadchromium_src-a288635bbfff0682103ac2753c06f028c4bb59ce.zip
chromium_src-a288635bbfff0682103ac2753c06f028c4bb59ce.tar.gz
chromium_src-a288635bbfff0682103ac2753c06f028c4bb59ce.tar.bz2
Roll mach_override to newer versions in small increments.
See https://code.google.com/p/chromium/issues/detail?id=138535#c5 Review URL: https://chromiumcodereview.appspot.com/11186020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163308 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/mach_override')
-rw-r--r--third_party/mach_override/README.chromium17
-rw-r--r--third_party/mach_override/mach_override.c88
2 files changed, 76 insertions, 29 deletions
diff --git a/third_party/mach_override/README.chromium b/third_party/mach_override/README.chromium
index 96b0cf7..1ad35e3 100644
--- a/third_party/mach_override/README.chromium
+++ b/third_party/mach_override/README.chromium
@@ -2,27 +2,18 @@ Name: mach_override
Short Name: Part of the mach_star project
Version: Unknown
URL: https://github.com/rentzsch/mach_star
-Date: 08/19/2011
-Revision: 87f491f8acef924d2ba90dd55fc23ad64f9d5bbd
+Date: 10/16/2012
+Revision: f8e0c424b5be5cb641ded67c265e616157ae4bcf
License: MIT
Security Critical: Yes
Description:
This is the mach_override part of mach_star, namely:
-
- https://github.com/rentzsch/mach_star/tree/87f491f8acef924d2ba90dd55fc23ad64f9d5bbd
+https://github.com/rentzsch/mach_star/tree/f8e0c424b5be5cb641ded67c265e616157ae4bcf
This package is used to replace framework functions with different
implementations at run time.
-Local Modifications:
-
-reentryIsland is allocated in high memory with vm_allocate rather than the
-heap with malloc by changing the allocation policy to kAllocateHigh. It
-appears probable that putting the reentry island in the heap causes its page
-to lose execute permission at some point under some circumstances, which
-results in a crash on Lion. This modification is temoprary to simply test
-out the theory. If proven, the code will be improved somewhat.
-http://crbug.com/93736.
+Local Modifications: None
diff --git a/third_party/mach_override/mach_override.c b/third_party/mach_override/mach_override.c
index 4768a57..db59620 100644
--- a/third_party/mach_override/mach_override.c
+++ b/third_party/mach_override/mach_override.c
@@ -134,7 +134,17 @@ eatKnownInstructions(
unsigned char *code,
uint64_t *newInstruction,
int *howManyEaten,
- char *originalInstructions );
+ char *originalInstructions,
+ int *originalInstructionCount,
+ uint8_t *originalInstructionSizes );
+
+ static void
+fixupInstructions(
+ void *originalFunction,
+ void *escapeIsland,
+ void *instructionsToFix,
+ int instructionCount,
+ uint8_t *instructionSizes );
#endif
/*******************************************************************************
@@ -172,17 +182,16 @@ mach_override_ptr(
// this addresses overriding such functions as AudioOutputUnitStart()
// test with modified DefaultOutputUnit project
-#if defined(__x86_64__) || defined(__i386__)
- for(;;){
- if(*(unsigned char*)originalFunctionAddress==0xE9) // jmp .+0x????????
- originalFunctionAddress=(void*)((char*)originalFunctionAddress+5+*(int32_t *)((char*)originalFunctionAddress+1));
#if defined(__x86_64__)
- else if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp qword near [rip+0x????????]
+ for(;;){
+ if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp qword near [rip+0x????????]
originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1));
+ else break;
+ }
#elif defined(__i386__)
- else if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x????????
+ for(;;){
+ if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x????????
originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1);
-#endif
else break;
}
#endif
@@ -200,11 +209,15 @@ mach_override_ptr(
err = err_cannot_override;
#elif defined(__i386__) || defined(__x86_64__)
int eatenCount = 0;
+ int originalInstructionCount = 0;
char originalInstructions[kOriginalInstructionsSize];
+ uint8_t originalInstructionSizes[kOriginalInstructionsSize];
uint64_t jumpRelativeInstruction = 0; // JMP
Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr,
- &jumpRelativeInstruction, &eatenCount, originalInstructions);
+ &jumpRelativeInstruction, &eatenCount,
+ originalInstructions, &originalInstructionCount,
+ originalInstructionSizes );
if (eatenCount > kOriginalInstructionsSize) {
//printf ("Too many instructions eaten\n");
overridePossible = false;
@@ -264,10 +277,13 @@ mach_override_ptr(
}
#endif
- // Optionally allocate & return the reentry island.
+ // Optionally allocate & return the reentry island. This may contain relocated
+ // jmp instructions and so has all the same addressing reachability requirements
+ // the escape island has to the original function, except the escape island is
+ // technically our original function.
BranchIsland *reentryIsland = NULL;
if( !err && originalFunctionReentryIsland ) {
- err = allocateBranchIsland( &reentryIsland, kAllocateHigh, NULL);
+ err = allocateBranchIsland( &reentryIsland, kAllocateHigh, escapeIsland);
if( !err )
*originalFunctionReentryIsland = reentryIsland;
}
@@ -310,6 +326,9 @@ mach_override_ptr(
//
// Note that on i386, we do not support someone else changing the code under our feet
if ( !err ) {
+ fixupInstructions(originalFunctionPtr, reentryIsland, originalInstructions,
+ originalInstructionCount, originalInstructionSizes );
+
if( reentryIsland )
err = setBranchIslandTarget_i386( reentryIsland,
(void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
@@ -370,7 +389,10 @@ allocateBranchIsland(
err = host_page_size( mach_host_self(), &pageSize );
if( !err ) {
assert( sizeof( BranchIsland ) <= pageSize );
-#if defined(__x86_64__)
+#if defined(__ppc__) || defined(__POWERPC__)
+ vm_address_t first = 0xfeffffff;
+ vm_address_t last = 0xfe000000 + pageSize;
+#elif 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
@@ -547,6 +569,7 @@ typedef struct {
#if defined(__i386__)
static AsmInstructionMatch possibleInstructions[] = {
+ { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x????????
{ 0x5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0x55, 0x89, 0xe5, 0xc9, 0xc3} }, // push %ebp; mov %esp,%ebp; leave; ret
{ 0x1, {0xFF}, {0x90} }, // nop
{ 0x1, {0xFF}, {0x55} }, // push %esp
@@ -564,6 +587,7 @@ static AsmInstructionMatch possibleInstructions[] = {
};
#elif defined(__x86_64__)
static AsmInstructionMatch possibleInstructions[] = {
+ { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x????????
{ 0x1, {0xFF}, {0x90} }, // nop
{ 0x1, {0xF8}, {0x50} }, // push %rX
{ 0x3, {0xFF, 0xFF, 0xFF}, {0x48, 0x89, 0xE5} }, // mov %rsp,%rbp
@@ -597,17 +621,21 @@ static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch*
#if defined(__i386__) || defined(__x86_64__)
static Boolean
eatKnownInstructions(
- unsigned char *code,
- uint64_t* newInstruction,
- int* howManyEaten,
- char* originalInstructions )
+ unsigned char *code,
+ uint64_t *newInstruction,
+ int *howManyEaten,
+ char *originalInstructions,
+ int *originalInstructionCount,
+ uint8_t *originalInstructionSizes )
{
Boolean allInstructionsKnown = true;
int totalEaten = 0;
unsigned char* ptr = code;
int remainsToEat = 5; // a JMP instruction takes 5 bytes
+ int instructionIndex = 0;
if (howManyEaten) *howManyEaten = 0;
+ if (originalInstructionCount) *originalInstructionCount = 0;
while (remainsToEat > 0) {
Boolean curInstructionKnown = false;
@@ -630,6 +658,10 @@ eatKnownInstructions(
ptr += eaten;
remainsToEat -= eaten;
totalEaten += eaten;
+
+ if (originalInstructionSizes) originalInstructionSizes[instructionIndex] = eaten;
+ instructionIndex += 1;
+ if (originalInstructionCount) *originalInstructionCount = instructionIndex;
}
@@ -660,6 +692,30 @@ eatKnownInstructions(
return allInstructionsKnown;
}
+
+ static void
+fixupInstructions(
+ void *originalFunction,
+ void *escapeIsland,
+ void *instructionsToFix,
+ int instructionCount,
+ uint8_t *instructionSizes )
+{
+ int index;
+ for (index = 0;index < instructionCount;index += 1)
+ {
+ if (*(uint8_t*)instructionsToFix == 0xE9) // 32-bit jump relative
+ {
+ uint32_t offset = (uintptr_t)originalFunction - (uintptr_t)escapeIsland;
+ uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 1);
+ *jumpOffsetPtr += offset;
+ }
+
+ originalFunction = (void*)((uintptr_t)originalFunction + instructionSizes[index]);
+ escapeIsland = (void*)((uintptr_t)escapeIsland + instructionSizes[index]);
+ instructionsToFix = (void*)((uintptr_t)instructionsToFix + instructionSizes[index]);
+ }
+}
#endif
#if defined(__i386__)