Prevent RCTProfileTrampoline from getting stripped
Summary: public I was using `dlsym` as a more elegant way of checking if the function was defined to prevent crashes if running on an unsupported architecture, but Xcode might strip the symbol, even with `.no_dead_strip`, if there's no references to the compilation unit at all. Replace it with an ugly `#if` that checks if it's any of the supported targets and extern the function prototype. Reviewed By: jspahrsummers Differential Revision: D2581143 fb-gh-sync-id: b004ed351de97f96c04b4a6c914ce55cfcbbbcbb
This commit is contained in:
parent
0e4dec930b
commit
0f92639a96
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#define _CONCAT(A, B) A##B
|
||||
#define CONCAT(A, B) _CONCAT(A, B)
|
||||
|
||||
#define SYMBOL_NAME(S) CONCAT(__USER_LABEL_PREFIX__, S)
|
|
@ -190,16 +190,15 @@ IMP RCTProfileGetImplementation(id obj, SEL cmd)
|
|||
* The implementation can be found in RCTProfileTrampoline-<arch>.s where arch
|
||||
* is one of: x86, x86_64, arm, arm64.
|
||||
*/
|
||||
static IMP RCTProfileGetTrampoline(void)
|
||||
{
|
||||
static void (*RCTProfileTrampoline)(void);
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
RCTProfileTrampoline = dlsym(RTLD_DEFAULT, "RCTProfileTrampoline");
|
||||
});
|
||||
#if defined(__x86__) || \
|
||||
defined(__x86_64__) || \
|
||||
defined(__arm__) || \
|
||||
defined(__arm64__)
|
||||
|
||||
return (IMP)RCTProfileTrampoline;
|
||||
}
|
||||
RCT_EXTERN void RCTProfileTrampoline(void);
|
||||
#else
|
||||
static void *RCTProfileTrampoline = NULL;
|
||||
#endif
|
||||
|
||||
RCT_EXTERN void RCTProfileTrampolineStart(id, SEL);
|
||||
void RCTProfileTrampolineStart(id self, SEL cmd)
|
||||
|
@ -216,9 +215,12 @@ void RCTProfileTrampolineEnd(void)
|
|||
|
||||
void RCTProfileHookModules(RCTBridge *bridge)
|
||||
{
|
||||
if (RCTProfileGetTrampoline() == NULL) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
|
||||
if (RCTProfileTrampoline == NULL) {
|
||||
return;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"moduleDataByID"]) {
|
||||
[moduleData dispatchBlock:^{
|
||||
|
@ -239,7 +241,7 @@ void RCTProfileHookModules(RCTBridge *bridge)
|
|||
}
|
||||
const char *types = method_getTypeEncoding(method);
|
||||
|
||||
class_addMethod(proxyClass, selector, RCTProfileGetTrampoline(), types);
|
||||
class_addMethod(proxyClass, selector, RCTProfileTrampoline, types);
|
||||
}
|
||||
free(methods);
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "RCTDefines.h"
|
||||
#include "RCTMacros.h"
|
||||
|
||||
#if RCT_DEV && defined(__arm__)
|
||||
|
||||
.align 5
|
||||
.globl _RCTProfileTrampoline
|
||||
_RCTProfileTrampoline:
|
||||
.globl SYMBOL_NAME(RCTProfileTrampoline)
|
||||
SYMBOL_NAME(RCTProfileTrampoline):
|
||||
/**
|
||||
* The explanation here is shorter, refer to the x86_64 implementation to a
|
||||
* richer explanation
|
||||
|
@ -24,7 +25,7 @@ _RCTProfileTrampoline:
|
|||
* profile
|
||||
*/
|
||||
mov r0, #0xc
|
||||
bl _malloc
|
||||
bl SYMBOL_NAME(malloc)
|
||||
/**
|
||||
* r4 is the callee saved register we'll use to refer to the allocated memory,
|
||||
* store its initial value, so we can restore it later
|
||||
|
@ -40,7 +41,7 @@ _RCTProfileTrampoline:
|
|||
*/
|
||||
ldr r0, [sp]
|
||||
ldr r1, [sp, #0x4]
|
||||
bl _RCTProfileGetImplementation
|
||||
bl SYMBOL_NAME(RCTProfileGetImplementation)
|
||||
// store the actual function address in the allocated memory
|
||||
str r0, [r4, #0x4]
|
||||
|
||||
|
@ -51,7 +52,7 @@ _RCTProfileTrampoline:
|
|||
*/
|
||||
ldr r0, [sp]
|
||||
ldr r1, [sp, #0x4]
|
||||
bl _RCTProfileTrampolineStart
|
||||
bl SYMBOL_NAME(RCTProfileTrampolineStart)
|
||||
|
||||
/**
|
||||
* Restore the state to call the actual function we want to profile: pop
|
||||
|
@ -66,7 +67,7 @@ _RCTProfileTrampoline:
|
|||
push {r0} // save return value
|
||||
|
||||
// void RCTProfileTrampolineEnd(void) in RCTProfile.m - just ends this profile
|
||||
bl _RCTProfileTrampolineEnd
|
||||
bl SYMBOL_NAME(RCTProfileTrampolineEnd)
|
||||
|
||||
/**
|
||||
* Save the value we still need from the allocated memory (caller address),
|
||||
|
@ -76,7 +77,7 @@ _RCTProfileTrampoline:
|
|||
ldr r1, [r4, #0x8]
|
||||
ldr r4, [r4]
|
||||
push {r1} // save the caller on the stack
|
||||
bl _free
|
||||
bl SYMBOL_NAME(free)
|
||||
|
||||
pop {lr} // pop the caller
|
||||
pop {r0} // pop the return value
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "RCTDefines.h"
|
||||
#include "RCTMacros.h"
|
||||
|
||||
#if RCT_DEV && defined(__arm64__)
|
||||
|
||||
.align 5
|
||||
.globl _RCTProfileTrampoline
|
||||
_RCTProfileTrampoline:
|
||||
.globl SYMBOL_NAME(RCTProfileTrampoline)
|
||||
SYMBOL_NAME(RCTProfileTrampoline):
|
||||
/**
|
||||
* The explanation here is shorter, refer to the x86_64 implementation to a
|
||||
* richer explanation
|
||||
|
@ -38,7 +39,7 @@ _RCTProfileTrampoline:
|
|||
* the implementation and the caller address.
|
||||
*/
|
||||
mov x0, #0x10
|
||||
bl _malloc
|
||||
bl SYMBOL_NAME(malloc)
|
||||
// store the initial value of r19, the callee saved register we'll use
|
||||
str x19, [x0]
|
||||
mov x19, x0
|
||||
|
@ -50,7 +51,7 @@ _RCTProfileTrampoline:
|
|||
* this function
|
||||
*/
|
||||
ldp x0, x1, [sp, #(8*16+0*8)]
|
||||
bl _RCTProfileGetImplementation
|
||||
bl SYMBOL_NAME(RCTProfileGetImplementation)
|
||||
str x0, [x19, #0x8] // store the actual function address
|
||||
|
||||
/**
|
||||
|
@ -59,7 +60,7 @@ _RCTProfileTrampoline:
|
|||
* start the profile, it takes the same first 2 arguments as above.
|
||||
*/
|
||||
ldp x0, x1, [sp, #(8*16+0*8)]
|
||||
bl _RCTProfileTrampolineStart
|
||||
bl SYMBOL_NAME(RCTProfileTrampolineStart)
|
||||
|
||||
// Restore all the parameter registers to the initial state.
|
||||
ldp q0, q1, [sp, #(0*16)]
|
||||
|
@ -91,7 +92,7 @@ _RCTProfileTrampoline:
|
|||
str x0, [sp, #0x10] // 8-byte return value
|
||||
|
||||
// void RCTProfileTrampolineEnd(void) in RCTProfile.m - just ends this profile
|
||||
bl _RCTProfileTrampolineEnd
|
||||
bl SYMBOL_NAME(RCTProfileTrampolineEnd)
|
||||
|
||||
/**
|
||||
* restore the callee saved registers, move the values we still need to the
|
||||
|
@ -101,7 +102,7 @@ _RCTProfileTrampoline:
|
|||
ldr x10, [x19, #0x8] // load the caller address
|
||||
ldr x19, [x19] // restore x19
|
||||
str x10, [sp, #0x18] // store x10 on the stack space allocated above
|
||||
bl _free
|
||||
bl SYMBOL_NAME(free)
|
||||
|
||||
// Load both return values and link register from the stack
|
||||
ldr q0, [sp, #0x0]
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "RCTDefines.h"
|
||||
#include "RCTMacros.h"
|
||||
|
||||
#if RCT_DEV && defined(__i386__)
|
||||
|
||||
.globl _RCTProfileTrampoline
|
||||
_RCTProfileTrampoline:
|
||||
.globl SYMBOL_NAME(RCTProfileTrampoline)
|
||||
SYMBOL_NAME(RCTProfileTrampoline):
|
||||
/**
|
||||
* The x86 version is much simpler, since all the arguments are passed in the
|
||||
* stack, so we just have to preserve the stack pointer (%esp) and the callee
|
||||
|
@ -20,7 +21,7 @@ _RCTProfileTrampoline:
|
|||
*/
|
||||
subl $0x8, %esp // stack padding (16-byte alignment for function calls)
|
||||
pushl $0xc // allocate 12-bytes
|
||||
calll _malloc
|
||||
calll SYMBOL_NAME(malloc)
|
||||
addl $0xc, %esp // restore stack (8-byte padding + 4-byte argument)
|
||||
|
||||
/**
|
||||
|
@ -37,7 +38,7 @@ _RCTProfileTrampoline:
|
|||
*
|
||||
* Get the address of the actual C function we have to profile
|
||||
*/
|
||||
calll _RCTProfileGetImplementation
|
||||
calll SYMBOL_NAME(RCTProfileGetImplementation)
|
||||
movl %eax, 0x8(%edi) // Save it in the allocated memory
|
||||
|
||||
/**
|
||||
|
@ -47,7 +48,7 @@ _RCTProfileTrampoline:
|
|||
* stack since it takes the same first 2 arguments as the any ObjC function -
|
||||
* "self" and "_cmd"
|
||||
*/
|
||||
calll _RCTProfileTrampolineStart
|
||||
calll SYMBOL_NAME(RCTProfileTrampolineStart)
|
||||
|
||||
/**
|
||||
* Call the actual function and save it's return value, since it should be the
|
||||
|
@ -58,7 +59,7 @@ _RCTProfileTrampoline:
|
|||
|
||||
// Align stack and end profile
|
||||
subl $0xc, %esp
|
||||
calll _RCTProfileTrampolineEnd
|
||||
calll SYMBOL_NAME(RCTProfileTrampolineEnd)
|
||||
addl $0xc, %esp // restore the stack
|
||||
|
||||
/**
|
||||
|
@ -75,7 +76,7 @@ _RCTProfileTrampoline:
|
|||
* the stack has already been padded and the first and only argument, the
|
||||
* memory address, is already in the bottom of the stack.
|
||||
*/
|
||||
calll _free
|
||||
calll SYMBOL_NAME(free)
|
||||
addl $0x8, %esp
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#include "RCTDefines.h"
|
||||
#include "RCTMacros.h"
|
||||
|
||||
#if RCT_DEV && defined(__x86_64__)
|
||||
|
||||
.globl _RCTProfileTrampoline
|
||||
_RCTProfileTrampoline:
|
||||
/**
|
||||
* Define both symbols for compatibility with other assemblers
|
||||
*/
|
||||
.globl SYMBOL_NAME(RCTProfileTrampoline)
|
||||
SYMBOL_NAME(RCTProfileTrampoline):
|
||||
|
||||
/**
|
||||
* Saves all the state so we can restore it before calling the functions being
|
||||
|
@ -40,7 +44,7 @@ _RCTProfileTrampoline:
|
|||
* This is a C function defined in `RCTProfile.m`, the object and the selector
|
||||
* already have to be on %rdi and %rsi respectively, as in any ObjC call.
|
||||
*/
|
||||
callq _RCTProfileGetImplementation
|
||||
callq SYMBOL_NAME(RCTProfileGetImplementation)
|
||||
|
||||
// Restore/unalign the stack pointer, so we can access the registers we stored
|
||||
movq %r12, %rsp
|
||||
|
@ -71,7 +75,7 @@ _RCTProfileTrampoline:
|
|||
|
||||
// allocate 16 bytes
|
||||
movq $0x10, %rdi
|
||||
callq _malloc
|
||||
callq SYMBOL_NAME(malloc)
|
||||
|
||||
// store the initial value of calle saved registers %r13 and %r14
|
||||
movq %r13, 0x0(%rax)
|
||||
|
@ -89,7 +93,7 @@ _RCTProfileTrampoline:
|
|||
movq 0x38(%r12), %rsi // selector
|
||||
|
||||
// void RCTProfileTrampolineStart(id, SEL) in RCTProfile.m
|
||||
callq _RCTProfileTrampolineStart
|
||||
callq SYMBOL_NAME(RCTProfileTrampolineStart)
|
||||
|
||||
// unalign the stack and restore %r12
|
||||
movq %r12, %rsp
|
||||
|
@ -121,7 +125,7 @@ _RCTProfileTrampoline:
|
|||
andq $-0x10, %rsp
|
||||
|
||||
// void RCTProfileTrampolineEnd(void) in RCTProfile.m - just ends this profile
|
||||
callq _RCTProfileTrampolineEnd
|
||||
callq SYMBOL_NAME(RCTProfileTrampolineEnd)
|
||||
|
||||
// unalign stack and restore %r12
|
||||
movq %r12, %rsp
|
||||
|
@ -151,7 +155,7 @@ _RCTProfileTrampoline:
|
|||
|
||||
// Free the memory allocated to stash callee saved registers
|
||||
movq %rdx, %rdi
|
||||
callq _free
|
||||
callq SYMBOL_NAME(free)
|
||||
|
||||
// unalign stack and restore %r12
|
||||
movq %r12, %rsp
|
||||
|
|
Loading…
Reference in New Issue