diff options
Diffstat (limited to 'xpcom/build')
-rw-r--r-- | xpcom/build/BinaryPath.h | 42 | ||||
-rw-r--r-- | xpcom/build/PoisonIOInterposer.h | 19 | ||||
-rw-r--r-- | xpcom/build/PoisonIOInterposerMac.cpp | 385 | ||||
-rw-r--r-- | xpcom/build/XPCOMInit.cpp | 3 | ||||
-rw-r--r-- | xpcom/build/mach_override.c | 789 | ||||
-rw-r--r-- | xpcom/build/mach_override.h | 121 | ||||
-rw-r--r-- | xpcom/build/moz.build | 7 | ||||
-rw-r--r-- | xpcom/build/nsXPCOMPrivate.h | 7 | ||||
-rw-r--r-- | xpcom/build/nsXULAppAPI.h | 2 |
9 files changed, 4 insertions, 1371 deletions
diff --git a/xpcom/build/BinaryPath.h b/xpcom/build/BinaryPath.h index 6c2622a557..8ad7e8aac2 100644 --- a/xpcom/build/BinaryPath.h +++ b/xpcom/build/BinaryPath.h @@ -9,8 +9,6 @@ #include "nsXPCOMPrivate.h" // for MAXPATHLEN #ifdef XP_WIN #include <windows.h> -#elif defined(XP_MACOSX) -#include <CoreFoundation/CoreFoundation.h> #elif defined(XP_UNIX) #include <sys/stat.h> #include <string.h> @@ -43,46 +41,6 @@ private: return NS_ERROR_FAILURE; } -#elif defined(XP_MACOSX) - static nsresult Get(const char* argv0, char aResult[MAXPATHLEN]) - { - // Works even if we're not bundled. - CFBundleRef appBundle = CFBundleGetMainBundle(); - if (!appBundle) { - return NS_ERROR_FAILURE; - } - - CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle); - if (!executableURL) { - return NS_ERROR_FAILURE; - } - - nsresult rv; - if (CFURLGetFileSystemRepresentation(executableURL, false, (UInt8*)aResult, - MAXPATHLEN)) { - // Sanitize path in case the app was launched from Terminal via - // './firefox' for example. - size_t readPos = 0; - size_t writePos = 0; - while (aResult[readPos] != '\0') { - if (aResult[readPos] == '.' && aResult[readPos + 1] == '/') { - readPos += 2; - } else { - aResult[writePos] = aResult[readPos]; - readPos++; - writePos++; - } - } - aResult[writePos] = '\0'; - rv = NS_OK; - } else { - rv = NS_ERROR_FAILURE; - } - - CFRelease(executableURL); - return rv; - } - #elif defined(XP_UNIX) static nsresult Get(const char* aArgv0, char aResult[MAXPATHLEN]) { diff --git a/xpcom/build/PoisonIOInterposer.h b/xpcom/build/PoisonIOInterposer.h index 20edbd5aa8..6a34e39a0c 100644 --- a/xpcom/build/PoisonIOInterposer.h +++ b/xpcom/build/PoisonIOInterposer.h @@ -35,7 +35,7 @@ void MozillaUnRegisterDebugFILE(FILE* aFile); MOZ_END_EXTERN_C -#if defined(XP_WIN) || defined(XP_MACOSX) +#if defined(XP_WIN) #ifdef __cplusplus namespace mozilla { @@ -53,16 +53,6 @@ bool IsDebugFile(intptr_t aFileID); */ void InitPoisonIOInterposer(); -#ifdef XP_MACOSX -/** - * Check that writes are dirty before reporting I/O (Mac OS X only) - * This is necessary for late-write checks on Mac OS X, but reading the buffer - * from file to see if we're writing dirty bits is expensive, so we don't want - * to do this for everything else that uses - */ -void OnlyReportDirtyWrites(); -#endif /* XP_MACOSX */ - /** * Clear IO poisoning, this is only safe to do on the main-thread when no other * threads are running. @@ -72,19 +62,16 @@ void ClearPoisonIOInterposer(); } // namespace mozilla #endif /* __cplusplus */ -#else /* XP_WIN || XP_MACOSX */ +#else /* XP_WIN */ #ifdef __cplusplus namespace mozilla { inline bool IsDebugFile(intptr_t aFileID) { return true; } inline void InitPoisonIOInterposer() {} inline void ClearPoisonIOInterposer() {} -#ifdef XP_MACOSX -inline void OnlyReportDirtyWrites() {} -#endif /* XP_MACOSX */ } // namespace mozilla #endif /* __cplusplus */ -#endif /* XP_WIN || XP_MACOSX */ +#endif /* XP_WIN */ #endif // mozilla_PoisonIOInterposer_h diff --git a/xpcom/build/PoisonIOInterposerMac.cpp b/xpcom/build/PoisonIOInterposerMac.cpp deleted file mode 100644 index dca9ba0297..0000000000 --- a/xpcom/build/PoisonIOInterposerMac.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PoisonIOInterposer.h" -#include "mach_override.h" - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/IOInterposer.h" -#include "mozilla/Mutex.h" -#include "mozilla/ProcessedStack.h" -#include "mozilla/Telemetry.h" -#include "mozilla/UniquePtrExtensions.h" -#include "nsPrintfCString.h" -#include "mozilla/StackWalk.h" -#include "nsTraceRefcnt.h" -#include "plstr.h" -#include "prio.h" - -#include <algorithm> -#include <vector> - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <aio.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> - -#ifdef MOZ_REPLACE_MALLOC -#include "replace_malloc_bridge.h" -#endif - -namespace { - -using namespace mozilla; - -// Bit tracking if poisoned writes are enabled -static bool sIsEnabled = false; - -// Check if writes are dirty before reporting IO -static bool sOnlyReportDirtyWrites = false; - -// Routines for write validation -bool IsValidWrite(int aFd, const void* aWbuf, size_t aCount); -bool IsIPCWrite(int aFd, const struct stat& aBuf); - -/******************************** IO AutoTimer ********************************/ - -/** - * RAII class for timing the duration of an I/O call and reporting the result - * to the IOInterposeObserver API. - */ -class MacIOAutoObservation : public IOInterposeObserver::Observation -{ -public: - MacIOAutoObservation(IOInterposeObserver::Operation aOp, int aFd) - : IOInterposeObserver::Observation(aOp, sReference, sIsEnabled && - !IsDebugFile(aFd)) - , mFd(aFd) - , mHasQueriedFilename(false) - , mFilename(nullptr) - { - } - - MacIOAutoObservation(IOInterposeObserver::Operation aOp, int aFd, - const void* aBuf, size_t aCount) - : IOInterposeObserver::Observation(aOp, sReference, sIsEnabled && - !IsDebugFile(aFd) && - IsValidWrite(aFd, aBuf, aCount)) - , mFd(aFd) - , mHasQueriedFilename(false) - , mFilename(nullptr) - { - } - - // Custom implementation of IOInterposeObserver::Observation::Filename - const char16_t* Filename() override; - - ~MacIOAutoObservation() - { - Report(); - if (mFilename) { - free(mFilename); - mFilename = nullptr; - } - } - -private: - int mFd; - bool mHasQueriedFilename; - char16_t* mFilename; - static const char* sReference; -}; - -const char* MacIOAutoObservation::sReference = "PoisonIOInterposer"; - -// Get filename for this observation -const char16_t* -MacIOAutoObservation::Filename() -{ - // If mHasQueriedFilename is true, then we already have it - if (mHasQueriedFilename) { - return mFilename; - } - char filename[MAXPATHLEN]; - if (fcntl(mFd, F_GETPATH, filename) != -1) { - mFilename = UTF8ToNewUnicode(nsDependentCString(filename)); - } else { - mFilename = nullptr; - } - mHasQueriedFilename = true; - - // Return filename - return mFilename; -} - -/****************************** Write Validation ******************************/ - -// We want to detect "actual" writes, not IPC. Some IPC mechanisms are -// implemented with file descriptors, so filter them out. -bool -IsIPCWrite(int aFd, const struct stat& aBuf) -{ - if ((aBuf.st_mode & S_IFMT) == S_IFIFO) { - return true; - } - - if ((aBuf.st_mode & S_IFMT) != S_IFSOCK) { - return false; - } - - sockaddr_storage address; - socklen_t len = sizeof(address); - if (getsockname(aFd, (sockaddr*)&address, &len) != 0) { - return true; // Ignore the aFd if we can't find what it is. - } - - return address.ss_family == AF_UNIX; -} - -// We want to report actual disk IO not things that don't move bits on the disk -bool -IsValidWrite(int aFd, const void* aWbuf, size_t aCount) -{ - // Ignore writes of zero bytes, Firefox does some during shutdown. - if (aCount == 0) { - return false; - } - - { - struct stat buf; - int rv = fstat(aFd, &buf); - if (rv != 0) { - return true; - } - - if (IsIPCWrite(aFd, buf)) { - return false; - } - } - - // For writev we pass a nullptr aWbuf. We should only get here from - // dbm, and it uses write, so assert that we have aWbuf. - if (!aWbuf) { - return true; - } - - // Break, here if we're allowed to report non-dirty writes - if (!sOnlyReportDirtyWrites) { - return true; - } - - // As a really bad hack, accept writes that don't change the on disk - // content. This is needed because dbm doesn't keep track of dirty bits - // and can end up writing the same data to disk twice. Once when the - // user (nss) asks it to sync and once when closing the database. - auto wbuf2 = MakeUniqueFallible<char[]>(aCount); - if (!wbuf2) { - return true; - } - off_t pos = lseek(aFd, 0, SEEK_CUR); - if (pos == -1) { - return true; - } - ssize_t r = read(aFd, wbuf2.get(), aCount); - if (r < 0 || (size_t)r != aCount) { - return true; - } - int cmp = memcmp(aWbuf, wbuf2.get(), aCount); - if (cmp != 0) { - return true; - } - off_t pos2 = lseek(aFd, pos, SEEK_SET); - if (pos2 != pos) { - return true; - } - - // Otherwise this is not a valid write - return false; -} - -/*************************** Function Interception ***************************/ - -/** Structure for declaration of function override */ -struct FuncData -{ - const char* Name; // Name of the function for the ones we use dlsym - const void* Wrapper; // The function that we will replace 'Function' with - void* Function; // The function that will be replaced with 'Wrapper' - void* Buffer; // Will point to the jump buffer that lets us call - // 'Function' after it has been replaced. -}; - -// Wrap aio_write. We have not seen it before, so just assert/report it. -typedef ssize_t (*aio_write_t)(struct aiocb* aAioCbp); -ssize_t wrap_aio_write(struct aiocb* aAioCbp); -FuncData aio_write_data = { 0, (void*)wrap_aio_write, (void*)aio_write }; -ssize_t -wrap_aio_write(struct aiocb* aAioCbp) -{ - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, - aAioCbp->aio_fildes); - - aio_write_t old_write = (aio_write_t)aio_write_data.Buffer; - return old_write(aAioCbp); -} - -// Wrap pwrite-like functions. -// We have not seen them before, so just assert/report it. -typedef ssize_t (*pwrite_t)(int aFd, const void* buf, size_t aNumBytes, - off_t aOffset); -template<FuncData& foo> -ssize_t -wrap_pwrite_temp(int aFd, const void* aBuf, size_t aNumBytes, off_t aOffset) -{ - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd); - pwrite_t old_write = (pwrite_t)foo.Buffer; - return old_write(aFd, aBuf, aNumBytes, aOffset); -} - -// Define a FuncData for a pwrite-like functions. -#define DEFINE_PWRITE_DATA(X, NAME) \ -FuncData X ## _data = { NAME, (void*) wrap_pwrite_temp<X ## _data> }; \ - -// This exists everywhere. -DEFINE_PWRITE_DATA(pwrite, "pwrite") -// These exist on 32 bit OS X -DEFINE_PWRITE_DATA(pwrite_NOCANCEL_UNIX2003, "pwrite$NOCANCEL$UNIX2003"); -DEFINE_PWRITE_DATA(pwrite_UNIX2003, "pwrite$UNIX2003"); -// This exists on 64 bit OS X -DEFINE_PWRITE_DATA(pwrite_NOCANCEL, "pwrite$NOCANCEL"); - - -typedef ssize_t (*writev_t)(int aFd, const struct iovec* aIov, int aIovCount); -template<FuncData& foo> -ssize_t -wrap_writev_temp(int aFd, const struct iovec* aIov, int aIovCount) -{ - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, nullptr, - aIovCount); - writev_t old_write = (writev_t)foo.Buffer; - return old_write(aFd, aIov, aIovCount); -} - -// Define a FuncData for a writev-like functions. -#define DEFINE_WRITEV_DATA(X, NAME) \ -FuncData X ## _data = { NAME, (void*) wrap_writev_temp<X ## _data> }; \ - -// This exists everywhere. -DEFINE_WRITEV_DATA(writev, "writev"); -// These exist on 32 bit OS X -DEFINE_WRITEV_DATA(writev_NOCANCEL_UNIX2003, "writev$NOCANCEL$UNIX2003"); -DEFINE_WRITEV_DATA(writev_UNIX2003, "writev$UNIX2003"); -// This exists on 64 bit OS X -DEFINE_WRITEV_DATA(writev_NOCANCEL, "writev$NOCANCEL"); - -typedef ssize_t (*write_t)(int aFd, const void* aBuf, size_t aCount); -template<FuncData& foo> -ssize_t -wrap_write_temp(int aFd, const void* aBuf, size_t aCount) -{ - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, aBuf, aCount); - write_t old_write = (write_t)foo.Buffer; - return old_write(aFd, aBuf, aCount); -} - -// Define a FuncData for a write-like functions. -#define DEFINE_WRITE_DATA(X, NAME) \ -FuncData X ## _data = { NAME, (void*) wrap_write_temp<X ## _data> }; \ - -// This exists everywhere. -DEFINE_WRITE_DATA(write, "write"); -// These exist on 32 bit OS X -DEFINE_WRITE_DATA(write_NOCANCEL_UNIX2003, "write$NOCANCEL$UNIX2003"); -DEFINE_WRITE_DATA(write_UNIX2003, "write$UNIX2003"); -// This exists on 64 bit OS X -DEFINE_WRITE_DATA(write_NOCANCEL, "write$NOCANCEL"); - -FuncData* Functions[] = { - &aio_write_data, - - &pwrite_data, - &pwrite_NOCANCEL_UNIX2003_data, - &pwrite_UNIX2003_data, - &pwrite_NOCANCEL_data, - - &write_data, - &write_NOCANCEL_UNIX2003_data, - &write_UNIX2003_data, - &write_NOCANCEL_data, - - &writev_data, - &writev_NOCANCEL_UNIX2003_data, - &writev_UNIX2003_data, - &writev_NOCANCEL_data -}; - -const int NumFunctions = ArrayLength(Functions); - -} // namespace - -/******************************** IO Poisoning ********************************/ - -namespace mozilla { - -void -InitPoisonIOInterposer() -{ - // Enable reporting from poisoned write methods - sIsEnabled = true; - - // Make sure we only poison writes once! - static bool WritesArePoisoned = false; - if (WritesArePoisoned) { - return; - } - WritesArePoisoned = true; - - // stdout and stderr are OK. - MozillaRegisterDebugFD(1); - MozillaRegisterDebugFD(2); - -#ifdef MOZ_REPLACE_MALLOC - // The contract with InitDebugFd is that the given registry can be used - // at any moment, so the instance needs to persist longer than the scope - // of this functions. - static DebugFdRegistry registry; - ReplaceMalloc::InitDebugFd(registry); -#endif - - for (int i = 0; i < NumFunctions; ++i) { - FuncData* d = Functions[i]; - if (!d->Function) { - d->Function = dlsym(RTLD_DEFAULT, d->Name); - } - if (!d->Function) { - continue; - } - DebugOnly<mach_error_t> t = mach_override_ptr(d->Function, d->Wrapper, - &d->Buffer); - MOZ_ASSERT(t == err_none); - } -} - -void -OnlyReportDirtyWrites() -{ - sOnlyReportDirtyWrites = true; -} - -void -ClearPoisonIOInterposer() -{ - // Not sure how or if we can unpoison the functions. Would be nice, but no - // worries we won't need to do this anyway. - sIsEnabled = false; -} - -} // namespace mozilla diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index 86b4dc6bdf..18aed6528a 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -1015,9 +1015,6 @@ ShutdownXPCOM(nsIServiceManager* aServMgr) PROFILER_MARKER("Shutdown xpcom"); // If we are doing any shutdown checks, poison writes. if (gShutdownChecks != SCM_NOTHING) { -#ifdef XP_MACOSX - mozilla::OnlyReportDirtyWrites(); -#endif /* XP_MACOSX */ mozilla::BeginLateWriteChecks(); } diff --git a/xpcom/build/mach_override.c b/xpcom/build/mach_override.c deleted file mode 100644 index 9e4940d298..0000000000 --- a/xpcom/build/mach_override.c +++ /dev/null @@ -1,789 +0,0 @@ -// Copied from upstream at revision 195c13743fe0ebc658714e2a9567d86529f20443. -// mach_override.c semver:1.2.0 -// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com -// Some rights reserved: http://opensource.org/licenses/mit -// https://github.com/rentzsch/mach_override - -#include "mach_override.h" - -#include <mach-o/dyld.h> -#include <mach/mach_host.h> -#include <mach/mach_init.h> -#include <mach/vm_map.h> -#include <sys/mman.h> - -#include <CoreServices/CoreServices.h> - -/************************** -* -* Constants -* -**************************/ -#pragma mark - -#pragma mark (Constants) - -#define kPageSize 4096 -#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 -// On X86 we migh need to instert an add with a 32 bit immediate after the -// original instructions. -#define kMaxFixupSizeIncrease 5 - -unsigned 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 -// On X86-64 we never need to instert a new instruction. -#define kMaxFixupSizeIncrease 0 - -#define kJumpAddress kOriginalInstructionsSize + 6 - -unsigned 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 - -/************************** -* -* Data Types -* -**************************/ -#pragma mark - -#pragma mark (Data Types) - -typedef struct { - char instructions[sizeof(kIslandTemplate)]; -} BranchIsland; - -/************************** -* -* Funky Protos -* -**************************/ -#pragma mark - -#pragma mark (Funky Protos) - -static mach_error_t -allocateBranchIsland( - BranchIsland **island, - 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, - int *originalInstructionCount, - uint8_t *originalInstructionSizes ); - - static void -fixupInstructions( - uint32_t offset, - void *instructionsToFix, - int instructionCount, - uint8_t *instructionSizes ); -#endif - -/******************************************************************************* -* -* Interface -* -*******************************************************************************/ -#pragma mark - -#pragma mark (Interface) - -#if defined(__i386__) || defined(__x86_64__) -mach_error_t makeIslandExecutable(void *address) { - mach_error_t err = err_none; - uintptr_t page = (uintptr_t)address & ~(uintptr_t)(kPageSize-1); - int e = err_none; - e |= mprotect((void *)page, kPageSize, PROT_EXEC | PROT_READ | PROT_WRITE); - e |= msync((void *)page, kPageSize, 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 ); - - // this addresses overriding such functions as AudioOutputUnitStart() - // test with modified DefaultOutputUnit project -#if defined(__x86_64__) - 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__) - for(;;){ - if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x???????? - originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1); - else break; - } -#endif - - 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; - int originalInstructionCount = 0; - char originalInstructions[kOriginalInstructionsSize]; - uint8_t originalInstructionSizes[kOriginalInstructionsSize]; - uint64_t jumpRelativeInstruction = 0; // JMP - - Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, - &jumpRelativeInstruction, &eatenCount, - originalInstructions, &originalInstructionCount, - originalInstructionSizes ); - if (eatenCount + kMaxFixupSizeIncrease > kOriginalInstructionsSize) { - //printf ("Too many instructions eaten\n"); - overridePossible = false; - } - if (!overridePossible) err = err_cannot_override; - if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); -#endif - - // Make the original function implementation writable. - if( !err ) { - err = vm_protect( mach_task_self(), - (vm_address_t) originalFunctionPtr, 8, false, - (VM_PROT_ALL | VM_PROT_COPY) ); - if( err ) - err = vm_protect( mach_task_self(), - (vm_address_t) originalFunctionPtr, 8, false, - (VM_PROT_DEFAULT | VM_PROT_COPY) ); - } - if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); - - // Allocate and target the escape island to the overriding function. - BranchIsland *escapeIsland = NULL; - if( !err ) - err = allocateBranchIsland( &escapeIsland, originalFunctionAddress ); - if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __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) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); - - if( !err ) - err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 ); - - if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); - // Build the jump relative instruction to the escape island -#endif - - -#if defined(__i386__) || defined(__x86_64__) - if (!err) { - uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5); - addressOffset = OSSwapInt32(addressOffset); - - jumpRelativeInstruction |= 0xE900000000000000LL; - jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24; - jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction); - } -#endif - - // 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, escapeIsland); - 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 ) { - uint32_t offset = (uintptr_t)originalFunctionPtr - (uintptr_t)reentryIsland; - fixupInstructions(offset, originalInstructions, - originalInstructionCount, originalInstructionSizes ); - - if( reentryIsland ) - err = setBranchIslandTarget_i386( reentryIsland, - (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions ); - // try making islands executable before planting the jmp -#if defined(__x86_64__) || defined(__i386__) - if( !err ) - err = makeIslandExecutable(escapeIsland); - if( !err && reentryIsland ) - err = makeIslandExecutable(reentryIsland); -#endif - if ( !err ) - atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction); - } -#endif - - // Clean up on error. - if( err ) { - if( reentryIsland ) - freeBranchIsland( reentryIsland ); - if( escapeIsland ) - freeBranchIsland( escapeIsland ); - } - - return err; -} - -/******************************************************************************* -* -* Implementation -* -*******************************************************************************/ -#pragma mark - -#pragma mark (Implementation) - -static bool jump_in_range(intptr_t from, intptr_t to) { - intptr_t field_value = to - from - 5; - int32_t field_value_32 = field_value; - return field_value == field_value_32; -} - -/******************************************************************************* - Implementation: Allocates memory for a branch island. - - @param island <- The allocated island. - @result <- mach_error_t - - ***************************************************************************/ - -static mach_error_t -allocateBranchIslandAux( - BranchIsland **island, - void *originalFunctionAddress, - bool forward) -{ - assert( island ); - assert( sizeof( BranchIsland ) <= kPageSize ); - - vm_map_t task_self = mach_task_self(); - vm_address_t original_address = (vm_address_t) originalFunctionAddress; - vm_address_t address = original_address; - - for (;;) { - vm_size_t vmsize = 0; - memory_object_name_t object = 0; - kern_return_t kr = 0; - vm_region_flavor_t flavor = VM_REGION_BASIC_INFO; - // Find the region the address is in. -#if __WORDSIZE == 32 - vm_region_basic_info_data_t info; - mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT; - kr = vm_region(task_self, &address, &vmsize, flavor, - (vm_region_info_t)&info, &info_count, &object); -#else - vm_region_basic_info_data_64_t info; - mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64; - kr = vm_region_64(task_self, &address, &vmsize, flavor, - (vm_region_info_t)&info, &info_count, &object); -#endif - if (kr != KERN_SUCCESS) - return kr; - assert((address & (kPageSize - 1)) == 0); - - // Go to the first page before or after this region - vm_address_t new_address = forward ? address + vmsize : address - kPageSize; -#if __WORDSIZE == 64 - if(!jump_in_range(original_address, new_address)) - break; -#endif - address = new_address; - - // Try to allocate this page. - kr = vm_allocate(task_self, &address, kPageSize, 0); - if (kr == KERN_SUCCESS) { - *island = (BranchIsland*) address; - return err_none; - } - if (kr != KERN_NO_SPACE) - return kr; - } - - return KERN_NO_SPACE; -} - -static mach_error_t -allocateBranchIsland( - BranchIsland **island, - void *originalFunctionAddress) -{ - mach_error_t err = - allocateBranchIslandAux(island, originalFunctionAddress, true); - if (!err) - return err; - return allocateBranchIslandAux(island, originalFunctionAddress, false); -} - - -/******************************************************************************* - 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( sizeof( BranchIsland ) <= kPageSize ); - return vm_deallocate( mach_task_self(), (vm_address_t) island, - kPageSize ); -} - -/******************************************************************************* - 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[] = { - { 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 - { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp - { 0x1, {0xFF}, {0x53} }, // push %ebx - { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp - { 0x6, {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, {0x81, 0xEC, 0x00, 0x00, 0x00, 0x00} }, // sub 0x??, %esp with 32bit immediate - { 0x1, {0xFF}, {0x57} }, // push %edi - { 0x1, {0xFF}, {0x56} }, // push %esi - { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax - { 0x3, {0xFF, 0x4F, 0x00}, {0x8B, 0x45, 0x00} }, // mov $imm(%ebp), %reg - { 0x3, {0xFF, 0x4C, 0x00}, {0x8B, 0x40, 0x00} }, // mov $imm(%eax-%edx), %reg - { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x8B, 0x4C, 0x24, 0x00} }, // mov $imm(%esp), %ecx - { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %eax - { 0x6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xE8, 0x00, 0x00, 0x00, 0x00, 0x58} }, // call $imm; pop %eax - { 0x0 } -}; -#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 - { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x48, 0x83, 0xEC, 0x00} }, // sub 0x??, %rsp - { 0x4, {0xFB, 0xFF, 0x00, 0x00}, {0x48, 0x89, 0x00, 0x00} }, // move onto rbp - { 0x4, {0xFF, 0xFF, 0xFF, 0xFF}, {0x40, 0x0f, 0xbe, 0xce} }, // movsbl %sil, %ecx - { 0x2, {0xFF, 0x00}, {0x41, 0x00} }, // push %rXX - { 0x2, {0xFF, 0x00}, {0x85, 0x00} }, // test %rX,%rX - { 0x5, {0xF8, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %reg - { 0x3, {0xFF, 0xFF, 0x00}, {0xFF, 0x77, 0x00} }, // pushq $imm(%rdi) - { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax - { 0x2, {0xFF, 0xFF}, {0x89, 0xF8} }, // mov %edi, %eax - - //leaq offset(%rip),%rax - { 0x7, {0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, {0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00} }, - - { 0x0 } -}; -#endif - -static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction) -{ - Boolean match = true; - - size_t i; - for (i=0; i<instruction->length; 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, - 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; - - // 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; - fprintf(stderr, "mach_override: some instructions unknown! Need to update mach_override.c\n"); - break; - } - - // At this point, we've matched curInstr - int eaten = curInstr->length; - ptr += eaten; - remainsToEat -= eaten; - totalEaten += eaten; - - if (originalInstructionSizes) originalInstructionSizes[instructionIndex] = eaten; - instructionIndex += 1; - if (originalInstructionCount) *originalInstructionCount = instructionIndex; - } - - - 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; -} - - static void -fixupInstructions( - uint32_t offset, - void *instructionsToFix, - int instructionCount, - uint8_t *instructionSizes ) -{ - // The start of "leaq offset(%rip),%rax" - static const uint8_t LeaqHeader[] = {0x48, 0x8d, 0x05}; - - int index; - for (index = 0;index < instructionCount;index += 1) - { - if (*(uint8_t*)instructionsToFix == 0xE9) // 32-bit jump relative - { - uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 1); - *jumpOffsetPtr += offset; - } - - // leaq offset(%rip),%rax - if (memcmp(instructionsToFix, LeaqHeader, 3) == 0) { - uint32_t *LeaqOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 3); - *LeaqOffsetPtr += offset; - } - - // 32-bit call relative to the next addr; pop %eax - if (*(uint8_t*)instructionsToFix == 0xE8) - { - // Just this call is larger than the jump we use, so we - // know this is the last instruction. - assert(index == (instructionCount - 1)); - assert(instructionSizes[index] == 6); - - // Insert "addl $offset, %eax" in the end so that when - // we jump to the rest of the function %eax has the - // value it would have if eip had been pushed by the - // call in its original position. - uint8_t *op = instructionsToFix; - op += 6; - *op = 0x05; // addl - uint32_t *addImmPtr = (uint32_t*)(op + 1); - *addImmPtr = offset; - } - - instructionsToFix = (void*)((uintptr_t)instructionsToFix + instructionSizes[index]); - } -} -#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/xpcom/build/mach_override.h b/xpcom/build/mach_override.h deleted file mode 100644 index d9be988a34..0000000000 --- a/xpcom/build/mach_override.h +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - mach_override.h - Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> - Some rights reserved: <http://opensource.org/licenses/mit-license.php> - - ***************************************************************************/ - -/***************************************************************************//** - @mainpage mach_override - @author Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> - - 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 <sys/types.h> -#include <mach/error.h> - -#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 nullptr. - @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_ diff --git a/xpcom/build/moz.build b/xpcom/build/moz.build index c58b4db3f5..bc20b8aedd 100644 --- a/xpcom/build/moz.build +++ b/xpcom/build/moz.build @@ -32,13 +32,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': 'PoisonIOInterposerBase.cpp', 'PoisonIOInterposerWin.cpp', ] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - UNIFIED_SOURCES += [ - 'PoisonIOInterposerBase.cpp', - 'PoisonIOInterposerMac.cpp', - ] - SOURCES += ['mach_override.c'] - SOURCES['mach_override.c'].flags += ['-Wno-unused-function'] else: SOURCES += ['PoisonIOInterposerStub.cpp'] diff --git a/xpcom/build/nsXPCOMPrivate.h b/xpcom/build/nsXPCOMPrivate.h index c5f6553c03..6c3a2bc0ab 100644 --- a/xpcom/build/nsXPCOMPrivate.h +++ b/xpcom/build/nsXPCOMPrivate.h @@ -254,15 +254,8 @@ void LogTerm(); #define XPCOM_DLL XUL_DLL -// you have to love apple.. -#ifdef XP_MACOSX -#define XPCOM_SEARCH_KEY "DYLD_LIBRARY_PATH" -#define GRE_FRAMEWORK_NAME "XUL.framework" -#define XUL_DLL "XUL" -#else #define XPCOM_SEARCH_KEY "LD_LIBRARY_PATH" #define XUL_DLL "libxul" MOZ_DLL_SUFFIX -#endif #define GRE_CONF_NAME ".gre.config" #define GRE_CONF_PATH "/etc/gre.conf" diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index ffb50565a0..78760f0431 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -106,7 +106,7 @@ */ #define XRE_SYS_SHARE_EXTENSION_PARENT_DIR "XRESysSExtPD" -#if defined(XP_UNIX) || defined(XP_MACOSX) +#if defined(XP_UNIX) /** * Directory service keys for the system-wide and user-specific * directories where host manifests used by the WebExtensions |