(一) objc4-818.2源码 编译

1,299 阅读4分钟

一、当前环境

  • macOS Monterey 版本:12.0.1
  • Xcode Version 13.1
  • objc4-818.2

二、获取源码

objc4-818.2 最新的在 macOS Big Sur -> macOS 11.2 -> objc4-818.2

WechatIMG613.png

可以先找到以下文件备用(这都是我照 macOS 11.2 下载的版本 其中有几个文件没有 在Libc-825.40.1中可以找到):

WechatIMG618 1.png

文件名查找位置
sys/reason.hxnu-7195.81.3/bsd/sys/reason.h
mach-o/dyld_priv.hdyld-832.7.3/include/mach-o/dyld_priv.h
os/lock_private.hlibplatform-254.80.2/private/os/lock_private.h
os/base_privatexnu-7195.81.3/libkern/os/base_private.h
pthread/tsd_private.hlibpthread-454.80.2/private/pthread/tsd_private.h
System/machine/cpu_capabilities.hxnu-7195.81.3/osfmk/machine/cpu_capabilities.h
os/tsd.hxnu-7195.81.3/libsyscall/os/tsd.h
pthread/spinlock_private.hlibpthread-454.80.2/private/pthread/spinlock_private.h
System/pthread_machdep.hLibc-825.40.1/pthreads/pthread_machdep.h
CrashReporterClient.hLibc-825.40.1/include/CrashReporterClient.h
objc-shared-cache.hdyld-832.7.3/include/objc-shared-cache.h
_simple.hlibplatform-254.80.2/private/_simple.h
Block_private.hlibdispatch-1271.40.12/src/BlocksRuntime/Block_private.h
kern/restartable.hxnu-7195.81.3/osfmk/kern/restartable.h
os/linker_set.hLibc-1439.40.11/os/linker_set.h
os/reason_private.hxnu-7195.81.3/libkern/os/reason_private.h
os/variant_private.hLibc-1439.40.11/os/variant_private.h
os/feature_private.h注释
objc-bp-assist.h注释
Cambria/Traps.h注释
Cambria/Cambria.h注释

三、系统超过11.2的报错信息

  • 解压objc4-818.2
  • 打开工程
  • 因为最新系统的objc4还没开源 如果你和我一样的系统超过11.2配置到中间部分会报错 ⚠️错误信息 Cannot combine with previous 'static' declaration specifier Expected unqualified-id

WechatIMG620.png

解决办法: 打开工程以后 直接将 TARGET -> objc -> Deployment Target 设置为 11.0 WechatIMG621.png

四、开始配置

1.scheme设置为objc

WechatIMG614.png

2.unable to find sdk 'macosx.internal'

  • PROJECT -> objc -> Base SDK 改为macOS
  • TARGETS -> objc -> Base SDK 改为macOS WechatIMG616.png

3.头文件缺失

3.01'sys/reason.h' file not found

这就可以用上我们上面找的文件了

  • 先创建一个文件夹名字可以随意 我这里叫include放到跟目录下
  • reason.h文件放在include/sys/路径下
  • include添加到头文件搜索路径 WechatIMG617.png
3.02.mach-o/dyld_priv.h' file not found

找到头文件添加到include/mach-o/

3.03.'os/lock_private.h' file not found

找到头文件添加到include/os/

3.04.'os/base_private.h' file not found

找到头文件添加到include/os/

3.05.'pthread/tsd_private.h' file not found

找到头文件添加到include/pthread/

3.06.'System/machine/cpu_capabilities.h' file not found

找到头文件添加到include/System/machine/

3.07.'os/tsd.h' file not found

找到头文件添加到include/os/

3.08.'pthread/spinlock_private.h' file not found

找到头文件添加到include/pthread/

3.09.'System/pthread_machdep.h' file not found

找到头文件添加到include/System/

3.10.'CrashReporterClient.h' file not found

找到头文件添加到include/,然后在 TARGET -> objc -> build setting -> Preprocessor Macros 添加 LIBC_NO_LIBCRASHREPORTERCLIENT WechatIMG439.jpeg

3.11.'objc-shared-cache.h' file not found

找到头文件添加到include/

3.12.'_simple.h' file not found

找到头文件添加到include/

3.13.'Block_private.h' file not found

找到头文件添加到include/

3.14.'kern/restartable.h' file not found

找到头文件添加到include/kern

3.15.'os/linker_set.h' file not found

找到头文件添加到include/os

3.16.'os/reason_private' file not found

找到头文件添加到include/os

3.17.'os/variant_private.h' file not found

找到头文件添加到include/os

一共17个.h文件 添加后如下图

WechatIMG438.jpeg

4.头文件缺失注释(4个头文件)

4.1.'os/feature_private.h' file not found

注释掉

//#include <os/feature_private.h> // os_feature_enabled_simple()
4.2.'objc-bp-assist.h' file not found
4.3.'Cambria/Traps.h' file not found
4.4.'Cambria/Cambria.h' file not found

5.API_AVAILABLE(macosx(10.16)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos)

去掉最后一个参数

API_AVAILABLE(macosx(10.16)) API_UNAVAILABLE(ios, tvos, watchos)

__API_AVAILABLE参数中, bridgeos(XX)都删除

6.pthread_machdep.h文件中报错的都注释掉

//typedef int pthread_lock_t;
//
//__inline__ static int
//_pthread_has_direct_tsd(void)
//{
//#if TARGET_IPHONE_SIMULATOR
//	/* Simulator will use the host implementation, so bypass the macro that is in the target code */
//	return 0;
//#elif defined(__ppc__)
//	int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES;
//	if (*caps & kFastThreadLocalStorage) {
//		return 1;
//	} else {
//		return 0;
//	}
//#else
//	return 1;
//#endif
//}
/* To be used with static constant keys only */
//__inline__ static void *
//_pthread_getspecific_direct(unsigned long slot)
//{
//	void *ret;
//#if defined(__i386__) || defined(__x86_64__)
//	__asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *))));
//#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
//	void **__pthread_tsd;
//#if defined(__arm__) && defined(_ARM_ARCH_6)
//	uintptr_t __pthread_tpid;
//	__asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
//	__pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
//#elif defined(__arm__) && defined(_ARM_ARCH_5)
//	register uintptr_t __pthread_tpid asm ("r9");
//	__pthread_tsd = (void**)__pthread_tpid;
//#endif
//	ret = __pthread_tsd[slot];
//#else
//#error no _pthread_getspecific_direct implementation for this arch
//#endif
//	return ret;
//}

/* To be used with static constant keys only */
//__inline__ static int
//_pthread_setspecific_direct(unsigned long slot, void * val)
//{
//#if defined(__i386__)
//#if defined(__PIC__)
//	__asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
//#else
//	__asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val));
//#endif
//#elif defined(__x86_64__)
//	/* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
//	__asm__("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
//#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
//	void **__pthread_tsd;
//#if defined(__arm__) && defined(_ARM_ARCH_6)
//	uintptr_t __pthread_tpid;
//	__asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
//	__pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
//#elif defined(__arm__) && defined(_ARM_ARCH_5)
//	register uintptr_t __pthread_tpid asm ("r9");
//	__pthread_tsd = (void**)__pthread_tpid;
//#endif
//	__pthread_tsd[slot] = val;
//#else
//#error no _pthread_setspecific_direct implementation for this arch
//#endif
//	return 0;
//}

7.Use of undeclared identifier 'dyld_platform_version_macOS_10_13'

//        if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_13)) {
//            DisableInitializeForkSafety = true;
//            if (PrintInitializing) {
//                _objc_inform("INITIALIZE: disabling +initialize fork "
//                             "safety enforcement because the app is "
//                             "too old.)");
//            }
//        }

8.Use of undeclared identifier 'dyld_fall_2020_os_versions'

//    if (!dyld_program_sdk_at_least(dyld_fall_2020_os_versions))
//        DisableAutoreleaseCoalescingLRU = true;

9.Use of undeclared identifier 'objc4' Use of undeclared identifier 'preoptimizedCaches'

//    if (!os_feature_enabled_simple(objc4, preoptimizedCaches, true)) {
//        DisablePreoptCaches = true;
//    }

10.Mismatch in debug-ness macros

//#error mismatch in debug-ness macros

11.Use of undeclared identifier 'oah_is_current_process_translated'

//#if TARGET_OS_OSX
//        if (oah_is_current_process_translated()) {
//            kern_return_t ret = objc_thread_get_rip(threads[count], (uint64_t*)&pc);
//            if (ret != KERN_SUCCESS) {
//                pc = PC_SENTINEL;
//            }
//        } else {
//            pc = _get_pc_for_thread (threads[count]);
//        }
//#else
        pc = _get_pc_for_thread (threads[count]);//留下
//#endif

12.Use of undeclared identifier 'dyld_platform_version_macOS_10_11'

//        if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_11)) {
//            DisableNonpointerIsa = true;
//            if (PrintRawIsa) {
//                _objc_inform("RAW ISA: disabling non-pointer isa because "
//                             "the app is too old.");
//            }
//        }

13.Use of undeclared identifier 'dyld_fall_2018_os_versions'

static void
initializeTaggedPointerObfuscator(void)
{ //&& dyld_program_sdk_at_least(dyld_fall_2018_os_versions)
    if (!DisableTaggedPointerObfuscation) {
        ...
#if OBJC_SPLIT_TAGGED_POINTERS
        ...
#endif
    } else {
        ...
    }
}

14.Use of undeclared identifier 'dyld_platform_version_bridgeOS_2_0'

// || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0, 2_0) 拿出来注释掉
if (DebugPoolAllocation) {
    // OBJC_DEBUG_POOL_ALLOCATION or new SDK. Bad pop is fatal.
    _objc_fatal
        ("Invalid or prematurely-freed autorelease pool %p.", token);
}

15.'_static_assert' declared as an array with a negative size

//STATIC_ASSERT((~ISA_MASK & MACH_VM_MAX_ADDRESS) == 0  ||
//              ISA_MASK + sizeof(void*) == MACH_VM_MAX_ADDRESS);

16. can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/AppleInternal/OrderFiles/libobjc.order

TARGET -> objc -> Order File 改为 $(SRCROOT)/libobjc.order WeChatc5d5a7f1b8d0c901c7c7a4db7245bef1.png

17.library not found for -lCrashReporterClient

TARGET -> objc -> Other Linker Flags 删除 -lCrashReporterClient WeChat89b08810433f358aac221d313de196e2.png

18.library not found for -loah

TARGET -> objc -> Other Linker Flags 删除 -loah

19.SDK "macosx.internal" cannot be located.

TARGET -> objc -> Build Phases 中的脚本 删除.internal WechatIMG626.png

20.编译成功

WechatIMG627.png

五、源码调试

1.创建一个终端命令行

File -> New -> Target... -> macOS -> Application -> Command Line Tool

Product name MMTest(自定义)

2.添加依赖

TARGET -> MMTest -> Dependcies -> objc(objc)

TARGET -> MMTest -> Link Binary With Libraries -> libobjc.A/dylib

WechatIMG630.png

3.创建文件

  • MMTest下创建一个继承NSObject命名为MMObject的类
  • main函数导入MMObject并实例化一个对象
  • 在main中打上断点
#import <Foundation/Foundation.h>
#import "MMObject.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        MMObject *objc = [MMObject alloc];
    }
    return 0;
}

4.如果进不了断点

TARGET -> MMTest -> Build Phases -> Compile Sources

main.m放在最上面 WechatIMG452.png

5.进不去底层源码

target -> objc -> Build Settings -> Enable Hardened Runtime -> NO WechatIMG633.png

6.如果是12的系统会直接崩在这里,这里我也没有很好的解决办法

ASSERT(sel_registerName(sel_getName(meth.name())) == meth.name());

7. 12以下的版本就可以进入源码调试了

WechatIMG453.png 然后我们就可以愉快的调试了😄