├── README.md ├── demo ├── PGOATest.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── rhythmzhang.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── rhythmzhang.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── PGOATest │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── PGOAnalyzer.framework │ ├── Headers │ │ ├── CPPHook.h │ │ ├── PGOAnalyzer.h │ │ └── modinit.h │ ├── Info.plist │ ├── Modules │ │ └── module.modulemap │ └── PGOAnalyzer │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── release └── PGOAnalyzer.framework ├── Headers ├── CPPHook.h ├── PGOAnalyzer.h └── modinit.h ├── Info.plist ├── Modules └── module.modulemap └── PGOAnalyzer /README.md: -------------------------------------------------------------------------------- 1 | # PGOAnalyzer 2 | support for iOS objc application's binary layout.二进制重排trace生成order_file以及order_string 3 | 4 | PGOAnalyzer 5 | 6 | #### 一、关于 7 | 8 | Analyzer目标是实现对objc程序的动态trace并顺序记录启动过程中的所有符号调用,以达到二进制(代码段)重排目的。 9 | 10 | 重排的trace过程主要有2种方式,编译插桩和运行时trace。从代码覆盖率上来说编译插桩是最佳方式,但编译插桩无法解决工程中引入的二进制库的重排问题。所以本项目采取了运行时trace的动态方式来插桩而实现trace过程,最终完成重排。 11 | 12 | > 实际使用,可以考虑编译插桩与动态trace结合,合并生成order file符号信息,以达到更优。 13 | 14 | 关于原理见本文: [简谈二进制重排](http://www.cocoachina.com/articles/52793) 15 | 16 | 17 | #### 二、使用方式 18 | 19 | 使用方式如下: 20 | 21 | 1. 将release目录下的PGOAnalyzer.framework拖到当前app内,由于是动态库需要特殊设置,且尽量使得当前动态库排在第一位,以避免工程中接入了其它动态库而无法及时trace该动态库的问题,设置如下图: 22 | 23 | 或参考 [Embedding Frameworks In An App](https://developer.apple.com/library/archive/technotes/tn2435/_index.html) 24 | 25 | 2. 在主app,自定义一个新的类,重写其load方法,如,添加如下代码,即可: 26 | 27 | ``` 28 | #if defined(__arm64__) || defined(__aarch64__) 29 | #import 30 | 31 | void my_cpp_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const pgoa_program_vars_t* vars) 32 | { 33 | pgoa_stub_initializer(argc,argv,envp,apple,vars); 34 | } 35 | 36 | @interface PGOALTest : NSObject 37 | @end 38 | 39 | @implementation PGOALTest 40 | 41 | + (void)load 42 | { 43 | pgoa_hook_mod_init((intptr_t)my_cpp_initializer); 44 | } 45 | 46 | @end 47 | 48 | #endif 49 | 50 | ``` 51 | 52 | 3. 在启动结束时间点,如主viewcontroller的viewDidAppear等回调里加入如下代码: 53 | 54 | ``` 55 | #if defined(__arm64__) || defined(__aarch64__) 56 | #import 57 | pgoa_end(true,^(NSString *str){ 58 | NSLog(@"%@",str); 59 | }); 60 | /* 61 | NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; 62 | NSString *file = [doc stringByAppendingPathComponent:@"order.txt"]; 63 | pgoa_endwithfile(true,file,^(NSString *path){ 64 | NSLog(@"path=%@",path); 65 | }); 66 | */ 67 | /* 68 | //如下函数调用会生成order_file,和order_string.且返回的是一个文件路径 69 | //需要自己拷贝出来使用. 70 | pgoa_endp(^(NSString *path_orderfile, NSString *path_string) { 71 | 72 | }); 73 | */ 74 | #endif 75 | ``` 76 | 77 | 4. 以上新加的代码,必须处于如下宏定义内.使用arm64,arm64e设备真机测试运行即可. 78 | 79 | ``` 80 | #if defined(__arm64__) || defined(__aarch64__) 81 | //..代码块 82 | #endif 83 | 84 | //需要引入头文件: 85 | #import 86 | ``` 87 | 88 | 5. 如果选择默认配置,则需要开启符号表(在工程配置Build Settings里找到并关闭strip linked product),否则无法自动翻译符号表,Strip Linked Product = NO; 89 | 90 | 91 | 6. 按照如上接入后,构建打包,建议Release下构建打包并运行。 92 | 93 | > 备注:如果是DEBUG下构建打包则不需要设置5中的Strip Linked Product = NO; 94 | 95 | 7. 运行后得到的翻译后的文件名为order_file.txt,且默认在Documents目录下,可自行完成选择导出; 96 | 97 | 8. 将7中导出的文件,配置到正式仓库工程中,设置order_file,如: 98 | 将order_file.txt文件放到工程根目录,然后在Build Settings里设置order file,添加值为$(SRCROOT)/order_file.txt 99 | 100 | ![image](http://cdn.rhythmkay.com/img/09122040.png) 101 | 102 | 9. 再次重新构建打包,即得到重排后的二进制。 103 | 104 | 如需要重排字符串,请将生成的PGOAOrderString.m文件拖进工程里,且在Build Phases里找到Compile Sources并将PGOAOrderString.m拖到最顶部即可。 105 | 106 | #### 三、其它 107 | 建议结合编译插桩来生成多份order_file来拼凑起一个更完善的order file;工程里不要再hook objc_msgSend,block,initialize,load,dispatch_sync,UIViewController等逻辑,不然可能会有异常情况。 108 | -------------------------------------------------------------------------------- /demo/PGOATest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B76D9046232A7666007F2586 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B76D9045232A7666007F2586 /* AppDelegate.m */; }; 11 | B76D9049232A7666007F2586 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B76D9048232A7666007F2586 /* ViewController.m */; }; 12 | B76D904C232A7666007F2586 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B76D904A232A7666007F2586 /* Main.storyboard */; }; 13 | B76D904E232A7667007F2586 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B76D904D232A7667007F2586 /* Assets.xcassets */; }; 14 | B76D9051232A7667007F2586 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B76D904F232A7667007F2586 /* LaunchScreen.storyboard */; }; 15 | B76D9054232A7667007F2586 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B76D9053232A7667007F2586 /* main.m */; }; 16 | B76D905E232A7728007F2586 /* PGOAnalyzer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B76D905D232A7728007F2586 /* PGOAnalyzer.framework */; }; 17 | B76D9061232A77B3007F2586 /* PGOAnalyzer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = B76D905D232A7728007F2586 /* PGOAnalyzer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | B76D9060232A77AD007F2586 /* CopyFiles */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | B76D9061232A77B3007F2586 /* PGOAnalyzer.framework in CopyFiles */, 28 | ); 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | B76D9041232A7666007F2586 /* PGOATest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PGOATest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | B76D9044232A7666007F2586 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | B76D9045232A7666007F2586 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | B76D9047232A7666007F2586 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 38 | B76D9048232A7666007F2586 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 39 | B76D904B232A7666007F2586 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 40 | B76D904D232A7667007F2586 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 41 | B76D9050232A7667007F2586 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 42 | B76D9052232A7667007F2586 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | B76D9053232A7667007F2586 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | B76D905D232A7728007F2586 /* PGOAnalyzer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PGOAnalyzer.framework; path = PGOATest/PGOAnalyzer.framework; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | B76D903E232A7666007F2586 /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | B76D905E232A7728007F2586 /* PGOAnalyzer.framework in Frameworks */, 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | B76D9038232A7666007F2586 = { 60 | isa = PBXGroup; 61 | children = ( 62 | B76D9043232A7666007F2586 /* PGOATest */, 63 | B76D9042232A7666007F2586 /* Products */, 64 | B76D905C232A7728007F2586 /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | B76D9042232A7666007F2586 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | B76D9041232A7666007F2586 /* PGOATest.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | B76D9043232A7666007F2586 /* PGOATest */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | B76D9044232A7666007F2586 /* AppDelegate.h */, 80 | B76D9045232A7666007F2586 /* AppDelegate.m */, 81 | B76D9047232A7666007F2586 /* ViewController.h */, 82 | B76D9048232A7666007F2586 /* ViewController.m */, 83 | B76D904A232A7666007F2586 /* Main.storyboard */, 84 | B76D904D232A7667007F2586 /* Assets.xcassets */, 85 | B76D904F232A7667007F2586 /* LaunchScreen.storyboard */, 86 | B76D9052232A7667007F2586 /* Info.plist */, 87 | B76D9053232A7667007F2586 /* main.m */, 88 | ); 89 | path = PGOATest; 90 | sourceTree = ""; 91 | }; 92 | B76D905C232A7728007F2586 /* Frameworks */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | B76D905D232A7728007F2586 /* PGOAnalyzer.framework */, 96 | ); 97 | name = Frameworks; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | B76D9040232A7666007F2586 /* PGOATest */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = B76D9057232A7667007F2586 /* Build configuration list for PBXNativeTarget "PGOATest" */; 106 | buildPhases = ( 107 | B76D903D232A7666007F2586 /* Sources */, 108 | B76D903E232A7666007F2586 /* Frameworks */, 109 | B76D903F232A7666007F2586 /* Resources */, 110 | B76D9060232A77AD007F2586 /* CopyFiles */, 111 | ); 112 | buildRules = ( 113 | ); 114 | dependencies = ( 115 | ); 116 | name = PGOATest; 117 | productName = PGOATest; 118 | productReference = B76D9041232A7666007F2586 /* PGOATest.app */; 119 | productType = "com.apple.product-type.application"; 120 | }; 121 | /* End PBXNativeTarget section */ 122 | 123 | /* Begin PBXProject section */ 124 | B76D9039232A7666007F2586 /* Project object */ = { 125 | isa = PBXProject; 126 | attributes = { 127 | LastUpgradeCheck = 1020; 128 | ORGANIZATIONNAME = rhythmzhang; 129 | TargetAttributes = { 130 | B76D9040232A7666007F2586 = { 131 | CreatedOnToolsVersion = 10.2.1; 132 | }; 133 | }; 134 | }; 135 | buildConfigurationList = B76D903C232A7666007F2586 /* Build configuration list for PBXProject "PGOATest" */; 136 | compatibilityVersion = "Xcode 9.3"; 137 | developmentRegion = en; 138 | hasScannedForEncodings = 0; 139 | knownRegions = ( 140 | en, 141 | Base, 142 | ); 143 | mainGroup = B76D9038232A7666007F2586; 144 | productRefGroup = B76D9042232A7666007F2586 /* Products */; 145 | projectDirPath = ""; 146 | projectRoot = ""; 147 | targets = ( 148 | B76D9040232A7666007F2586 /* PGOATest */, 149 | ); 150 | }; 151 | /* End PBXProject section */ 152 | 153 | /* Begin PBXResourcesBuildPhase section */ 154 | B76D903F232A7666007F2586 /* Resources */ = { 155 | isa = PBXResourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | B76D9051232A7667007F2586 /* LaunchScreen.storyboard in Resources */, 159 | B76D904E232A7667007F2586 /* Assets.xcassets in Resources */, 160 | B76D904C232A7666007F2586 /* Main.storyboard in Resources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXResourcesBuildPhase section */ 165 | 166 | /* Begin PBXSourcesBuildPhase section */ 167 | B76D903D232A7666007F2586 /* Sources */ = { 168 | isa = PBXSourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | B76D9049232A7666007F2586 /* ViewController.m in Sources */, 172 | B76D9054232A7667007F2586 /* main.m in Sources */, 173 | B76D9046232A7666007F2586 /* AppDelegate.m in Sources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXSourcesBuildPhase section */ 178 | 179 | /* Begin PBXVariantGroup section */ 180 | B76D904A232A7666007F2586 /* Main.storyboard */ = { 181 | isa = PBXVariantGroup; 182 | children = ( 183 | B76D904B232A7666007F2586 /* Base */, 184 | ); 185 | name = Main.storyboard; 186 | sourceTree = ""; 187 | }; 188 | B76D904F232A7667007F2586 /* LaunchScreen.storyboard */ = { 189 | isa = PBXVariantGroup; 190 | children = ( 191 | B76D9050232A7667007F2586 /* Base */, 192 | ); 193 | name = LaunchScreen.storyboard; 194 | sourceTree = ""; 195 | }; 196 | /* End PBXVariantGroup section */ 197 | 198 | /* Begin XCBuildConfiguration section */ 199 | B76D9055232A7667007F2586 /* Debug */ = { 200 | isa = XCBuildConfiguration; 201 | buildSettings = { 202 | ALWAYS_SEARCH_USER_PATHS = NO; 203 | CLANG_ANALYZER_NONNULL = YES; 204 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 205 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 206 | CLANG_CXX_LIBRARY = "libc++"; 207 | CLANG_ENABLE_MODULES = YES; 208 | CLANG_ENABLE_OBJC_ARC = YES; 209 | CLANG_ENABLE_OBJC_WEAK = YES; 210 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 211 | CLANG_WARN_BOOL_CONVERSION = YES; 212 | CLANG_WARN_COMMA = YES; 213 | CLANG_WARN_CONSTANT_CONVERSION = YES; 214 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 215 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 216 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 217 | CLANG_WARN_EMPTY_BODY = YES; 218 | CLANG_WARN_ENUM_CONVERSION = YES; 219 | CLANG_WARN_INFINITE_RECURSION = YES; 220 | CLANG_WARN_INT_CONVERSION = YES; 221 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 222 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 223 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 224 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 225 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 226 | CLANG_WARN_STRICT_PROTOTYPES = YES; 227 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 228 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 229 | CLANG_WARN_UNREACHABLE_CODE = YES; 230 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 231 | CODE_SIGN_IDENTITY = "iPhone Developer"; 232 | COPY_PHASE_STRIP = NO; 233 | DEBUG_INFORMATION_FORMAT = dwarf; 234 | ENABLE_STRICT_OBJC_MSGSEND = YES; 235 | ENABLE_TESTABILITY = YES; 236 | GCC_C_LANGUAGE_STANDARD = gnu11; 237 | GCC_DYNAMIC_NO_PIC = NO; 238 | GCC_NO_COMMON_BLOCKS = YES; 239 | GCC_OPTIMIZATION_LEVEL = 0; 240 | GCC_PREPROCESSOR_DEFINITIONS = ( 241 | "DEBUG=1", 242 | "$(inherited)", 243 | ); 244 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 245 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 246 | GCC_WARN_UNDECLARED_SELECTOR = YES; 247 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 248 | GCC_WARN_UNUSED_FUNCTION = YES; 249 | GCC_WARN_UNUSED_VARIABLE = YES; 250 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 251 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 252 | MTL_FAST_MATH = YES; 253 | ONLY_ACTIVE_ARCH = YES; 254 | SDKROOT = iphoneos; 255 | }; 256 | name = Debug; 257 | }; 258 | B76D9056232A7667007F2586 /* Release */ = { 259 | isa = XCBuildConfiguration; 260 | buildSettings = { 261 | ALWAYS_SEARCH_USER_PATHS = NO; 262 | CLANG_ANALYZER_NONNULL = YES; 263 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 264 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 265 | CLANG_CXX_LIBRARY = "libc++"; 266 | CLANG_ENABLE_MODULES = YES; 267 | CLANG_ENABLE_OBJC_ARC = YES; 268 | CLANG_ENABLE_OBJC_WEAK = YES; 269 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 270 | CLANG_WARN_BOOL_CONVERSION = YES; 271 | CLANG_WARN_COMMA = YES; 272 | CLANG_WARN_CONSTANT_CONVERSION = YES; 273 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 275 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 276 | CLANG_WARN_EMPTY_BODY = YES; 277 | CLANG_WARN_ENUM_CONVERSION = YES; 278 | CLANG_WARN_INFINITE_RECURSION = YES; 279 | CLANG_WARN_INT_CONVERSION = YES; 280 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 281 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 282 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 283 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 284 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 285 | CLANG_WARN_STRICT_PROTOTYPES = YES; 286 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 287 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 288 | CLANG_WARN_UNREACHABLE_CODE = YES; 289 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 290 | CODE_SIGN_IDENTITY = "iPhone Developer"; 291 | COPY_PHASE_STRIP = NO; 292 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 293 | ENABLE_NS_ASSERTIONS = NO; 294 | ENABLE_STRICT_OBJC_MSGSEND = YES; 295 | GCC_C_LANGUAGE_STANDARD = gnu11; 296 | GCC_NO_COMMON_BLOCKS = YES; 297 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 298 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 299 | GCC_WARN_UNDECLARED_SELECTOR = YES; 300 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 301 | GCC_WARN_UNUSED_FUNCTION = YES; 302 | GCC_WARN_UNUSED_VARIABLE = YES; 303 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 304 | MTL_ENABLE_DEBUG_INFO = NO; 305 | MTL_FAST_MATH = YES; 306 | SDKROOT = iphoneos; 307 | VALIDATE_PRODUCT = YES; 308 | }; 309 | name = Release; 310 | }; 311 | B76D9058232A7667007F2586 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 315 | CODE_SIGN_STYLE = Manual; 316 | DEVELOPMENT_TEAM = GD4XA3P5ZN; 317 | FRAMEWORK_SEARCH_PATHS = ( 318 | "$(inherited)", 319 | "$(PROJECT_DIR)/PGOATest", 320 | ); 321 | INFOPLIST_FILE = PGOATest/Info.plist; 322 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 323 | LD_RUNPATH_SEARCH_PATHS = ( 324 | "$(inherited)", 325 | "@executable_path/Frameworks", 326 | ); 327 | PRODUCT_BUNDLE_IDENTIFIER = com.tt.PGOATest; 328 | PRODUCT_NAME = "$(TARGET_NAME)"; 329 | PROVISIONING_PROFILE_SPECIFIER = QQBrowseriPhoneDev; 330 | TARGETED_DEVICE_FAMILY = "1,2"; 331 | }; 332 | name = Debug; 333 | }; 334 | B76D9059232A7667007F2586 /* Release */ = { 335 | isa = XCBuildConfiguration; 336 | buildSettings = { 337 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 338 | CODE_SIGN_STYLE = Manual; 339 | DEVELOPMENT_TEAM = ""; 340 | FRAMEWORK_SEARCH_PATHS = ( 341 | "$(inherited)", 342 | "$(PROJECT_DIR)/PGOATest", 343 | ); 344 | INFOPLIST_FILE = PGOATest/Info.plist; 345 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 346 | LD_RUNPATH_SEARCH_PATHS = ( 347 | "$(inherited)", 348 | "@executable_path/Frameworks", 349 | ); 350 | PRODUCT_BUNDLE_IDENTIFIER = com.tt.PGOATest; 351 | PRODUCT_NAME = "$(TARGET_NAME)"; 352 | PROVISIONING_PROFILE_SPECIFIER = ""; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Release; 356 | }; 357 | /* End XCBuildConfiguration section */ 358 | 359 | /* Begin XCConfigurationList section */ 360 | B76D903C232A7666007F2586 /* Build configuration list for PBXProject "PGOATest" */ = { 361 | isa = XCConfigurationList; 362 | buildConfigurations = ( 363 | B76D9055232A7667007F2586 /* Debug */, 364 | B76D9056232A7667007F2586 /* Release */, 365 | ); 366 | defaultConfigurationIsVisible = 0; 367 | defaultConfigurationName = Release; 368 | }; 369 | B76D9057232A7667007F2586 /* Build configuration list for PBXNativeTarget "PGOATest" */ = { 370 | isa = XCConfigurationList; 371 | buildConfigurations = ( 372 | B76D9058232A7667007F2586 /* Debug */, 373 | B76D9059232A7667007F2586 /* Release */, 374 | ); 375 | defaultConfigurationIsVisible = 0; 376 | defaultConfigurationName = Release; 377 | }; 378 | /* End XCConfigurationList section */ 379 | }; 380 | rootObject = B76D9039232A7666007F2586 /* Project object */; 381 | } 382 | -------------------------------------------------------------------------------- /demo/PGOATest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo/PGOATest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /demo/PGOATest.xcodeproj/project.xcworkspace/xcuserdata/rhythmzhang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhythmkay/PGOAnalyzer/b4a894d868e8485fe10175aca9f56d774f2ff423/demo/PGOATest.xcodeproj/project.xcworkspace/xcuserdata/rhythmzhang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /demo/PGOATest.xcodeproj/xcuserdata/rhythmzhang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PGOATest.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/PGOATest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PGOATest 4 | // 5 | // Created by rhythmkay on 2019/9/12. 6 | // Copyright © 2019 rhythmkay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /demo/PGOATest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PGOATest 4 | // 5 | // Created by rhythmkay on 2019/9/12. 6 | // Copyright © 2019 rhythmkay. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 23 | 24 | 25 | 26 | pgoa_end(true,^(NSString *str){ 27 | NSLog(@"%@",str); 28 | }); 29 | 30 | 31 | /* 32 | //如下函数调用会生成order_file,和order_string.且返回的是一个文件路径 33 | //需要自己拷贝出来使用. 34 | pgoa_endp(^(NSString *path_orderfile, NSString *path_string) { 35 | 36 | }); 37 | */ 38 | 39 | /* 40 | NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; 41 | NSString *file = [doc stringByAppendingPathComponent:@"order.txt"]; 42 | pgoa_endwithfile(true,file,^(NSString *path){ 43 | NSLog(@"path=%@",path); 44 | }); 45 | */ 46 | 47 | // pgoa_logall(false,nil); 48 | }); 49 | return YES; 50 | } 51 | 52 | 53 | - (void)applicationWillResignActive:(UIApplication *)application { 54 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 55 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 56 | } 57 | 58 | 59 | - (void)applicationDidEnterBackground:(UIApplication *)application { 60 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 61 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 62 | } 63 | 64 | 65 | - (void)applicationWillEnterForeground:(UIApplication *)application { 66 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 67 | } 68 | 69 | 70 | - (void)applicationDidBecomeActive:(UIApplication *)application { 71 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 72 | } 73 | 74 | 75 | - (void)applicationWillTerminate:(UIApplication *)application { 76 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 77 | } 78 | 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /demo/PGOATest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /demo/PGOATest/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /demo/PGOATest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /demo/PGOATest/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /demo/PGOATest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/Headers/CPPHook.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPHook.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(__arm64__) || defined(__aarch64__) 12 | 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif // __cplusplus 17 | 18 | /*! 19 | * @function pgoa_endp 20 | * 21 | * @param completion 22 | * block传入并异步返回排列好的order symbol,和order_string的文件路径; 23 | 注意:path_string返回的是一个.m文件,可以直接拖进工程Compile Source里设置,或导出为.m拖进Compile Source设置 24 | */ 25 | void pgoa_endp(void(^completion)(NSString* path_orderfile,NSString *path_string)); 26 | 27 | 28 | /*! 29 | * @function pgoa_end 30 | * 31 | * @abstract 32 | * 得到trace的order_file字符串 33 | * 34 | * @param symbolicate 35 | * 是否需要自动翻译符号表,建议传入true,否则需要自行结合dwarf翻译符号表 36 | * 37 | * @param completion 38 | * block传入并异步返回排列好的order symbol,由order_txt变量返回. 39 | */ 40 | void pgoa_end(bool symbolicate, void(^completion)(NSString* order_txt)); 41 | 42 | 43 | /*! 44 | * @function pgoa_endwithfile 45 | * 46 | * @abstract 47 | * 得到trace的order_file保存的文件路径 48 | * 49 | * @param symbolicate 50 | * 是否需要自动翻译符号表,建议传入true,否则需要自行结合dwarf翻译符号表 51 | * 52 | * @param path 53 | * 指定order_file的路径或文件名,绝对路径.如/xxx/xx/abc.txt 54 | * 55 | * @param completion 56 | * block传入并异步返回实际写成功的order_file文件路径,由path变量返回. 57 | */ 58 | void pgoa_endwithfile(bool symbolicate, NSString *path, void(^completion)(NSString *path)); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/Headers/PGOAnalyzer.h: -------------------------------------------------------------------------------- 1 | // 2 | // PGOAnalyzer.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/Headers/modinit.h: -------------------------------------------------------------------------------- 1 | // 2 | // mod_init_hook.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #if defined(__arm64__) || defined(__aarch64__) 10 | #import 11 | 12 | //copy from dyld ImageLoader.h 13 | typedef struct 14 | { 15 | const void* mh; 16 | int* NXArgcPtr; 17 | const char*** NXArgvPtr; 18 | const char*** environPtr; 19 | const char** __prognamePtr; 20 | } pgoa_program_vars_t; 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif // __cplusplus 25 | 26 | void pgoa_stub_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const pgoa_program_vars_t* vars); 27 | void pgoa_hook_mod_init(intptr_t func); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif // __cplusplus 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhythmkay/PGOAnalyzer/b4a894d868e8485fe10175aca9f56d774f2ff423/demo/PGOATest/PGOAnalyzer.framework/Info.plist -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module PGOAnalyzer { 2 | umbrella header "PGOAnalyzer.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /demo/PGOATest/PGOAnalyzer.framework/PGOAnalyzer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhythmkay/PGOAnalyzer/b4a894d868e8485fe10175aca9f56d774f2ff423/demo/PGOATest/PGOAnalyzer.framework/PGOAnalyzer -------------------------------------------------------------------------------- /demo/PGOATest/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PGOATest 4 | // 5 | // Created by rhythmkay on 2019/9/12. 6 | // Copyright © 2019 rhythmkay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /demo/PGOATest/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PGOATest 4 | // 5 | // Created by rhythmkay on 2019/9/12. 6 | // Copyright © 2019 rhythmkay. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)viewDidAppear:(BOOL)animated 23 | { 24 | 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /demo/PGOATest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PGOATest 4 | // 5 | // Created by rhythmkay on 2019/9/12. 6 | // Copyright © 2019 rhythmkay. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/Headers/CPPHook.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPHook.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(__arm64__) || defined(__aarch64__) 12 | 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif // __cplusplus 17 | 18 | /*! 19 | * @function pgoa_endp 20 | * 21 | * @param completion 22 | * block传入并异步返回排列好的order symbol,和order_string的文件路径; 23 | 注意:path_string返回的是一个.m文件,可以直接拖进工程Compile Source里设置,或导出为.m拖进Compile Source设置 24 | */ 25 | void pgoa_endp(void(^completion)(NSString* path_orderfile,NSString *path_string)); 26 | 27 | 28 | /*! 29 | * @function pgoa_end 30 | * 31 | * @abstract 32 | * 得到trace的order_file字符串 33 | * 34 | * @param symbolicate 35 | * 是否需要自动翻译符号表,建议传入true,否则需要自行结合dwarf翻译符号表 36 | * 37 | * @param completion 38 | * block传入并异步返回排列好的order symbol,由order_txt变量返回. 39 | */ 40 | void pgoa_end(bool symbolicate, void(^completion)(NSString* order_txt)); 41 | 42 | 43 | /*! 44 | * @function pgoa_endwithfile 45 | * 46 | * @abstract 47 | * 得到trace的order_file保存的文件路径 48 | * 49 | * @param symbolicate 50 | * 是否需要自动翻译符号表,建议传入true,否则需要自行结合dwarf翻译符号表 51 | * 52 | * @param path 53 | * 指定order_file的路径或文件名,绝对路径.如/xxx/xx/abc.txt 54 | * 55 | * @param completion 56 | * block传入并异步返回实际写成功的order_file文件路径,由path变量返回. 57 | */ 58 | void pgoa_endwithfile(bool symbolicate, NSString *path, void(^completion)(NSString *path)); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/Headers/PGOAnalyzer.h: -------------------------------------------------------------------------------- 1 | // 2 | // PGOAnalyzer.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/Headers/modinit.h: -------------------------------------------------------------------------------- 1 | // 2 | // mod_init_hook.h 3 | // PGOAnalyzer 4 | // 5 | // Created by rhythmzhang on 2019/8/13. 6 | // Copyright © 2019 rhythmzhang. All rights reserved. 7 | // 8 | 9 | #if defined(__arm64__) || defined(__aarch64__) 10 | #import 11 | 12 | //copy from dyld ImageLoader.h 13 | typedef struct 14 | { 15 | const void* mh; 16 | int* NXArgcPtr; 17 | const char*** NXArgvPtr; 18 | const char*** environPtr; 19 | const char** __prognamePtr; 20 | } pgoa_program_vars_t; 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif // __cplusplus 25 | 26 | void pgoa_stub_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const pgoa_program_vars_t* vars); 27 | void pgoa_hook_mod_init(intptr_t func); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif // __cplusplus 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhythmkay/PGOAnalyzer/b4a894d868e8485fe10175aca9f56d774f2ff423/release/PGOAnalyzer.framework/Info.plist -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module PGOAnalyzer { 2 | umbrella header "PGOAnalyzer.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /release/PGOAnalyzer.framework/PGOAnalyzer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhythmkay/PGOAnalyzer/b4a894d868e8485fe10175aca9f56d774f2ff423/release/PGOAnalyzer.framework/PGOAnalyzer --------------------------------------------------------------------------------