/
dyld_priv.h
757 lines (609 loc) · 30.3 KB
/
dyld_priv.h
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
* Copyright (c) 2003-2010 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACH_O_DYLD_PRIV_H_
#define _MACH_O_DYLD_PRIV_H_
#include <assert.h>
#include <stdbool.h>
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif
#include <Availability.h>
#include <TargetConditionals.h>
#include <mach-o/dyld.h>
#include <uuid/uuid.h>
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
//
// private interface between libSystem.dylib and dyld
//
extern void _dyld_atfork_prepare(void);
extern void _dyld_atfork_parent(void);
extern void _dyld_fork_child(void);
extern void _dyld_dlopen_atfork_prepare(void);
extern void _dyld_dlopen_atfork_parent(void);
extern void _dyld_dlopen_atfork_child(void);
typedef void (*_dyld_objc_notify_mapped)(unsigned count, const char* const paths[], const struct mach_header* const mh[]);
typedef void (*_dyld_objc_notify_init)(const char* path, const struct mach_header* mh);
typedef void (*_dyld_objc_notify_unmapped)(const char* path, const struct mach_header* mh);
typedef void (*_dyld_objc_notify_patch_class)(const struct mach_header* originalMH, void* originalClass,
const struct mach_header* replacementMH, const void* replacementClass);
struct _dyld_objc_notify_mapped_info {
const struct mach_header* mh;
const char* path;
uint32_t dyldOptimized : 1,
flags : 31;
};
typedef void (*_dyld_objc_notify_mapped2)(unsigned count, const struct _dyld_objc_notify_mapped_info infos[]);
//
// Note: only for use by objc runtime
// Register handlers to be called when objc images are mapped, unmapped, and initialized.
// Dyld will call back the "mapped" function with an array of images that contain an objc-image-info section.
// Those images that are dylibs will have the ref-counts automatically bumped, so objc will no longer need to
// call dlopen() on them to keep them from being unloaded. During the call to _dyld_objc_notify_register(),
// dyld will call the "mapped" function with already loaded objc images. During any later dlopen() call,
// dyld will also call the "mapped" function. Dyld will call the "init" function when dyld would be called
// initializers in that image. This is when objc calls any +load methods in that image.
//
void _dyld_objc_notify_register(_dyld_objc_notify_mapped mapped,
_dyld_objc_notify_init init,
_dyld_objc_notify_unmapped unmapped);
struct _dyld_objc_callbacks
{
uintptr_t version;
};
struct _dyld_objc_callbacks_v1
{
uintptr_t version; // == 1
_dyld_objc_notify_mapped mapped;
_dyld_objc_notify_init init;
_dyld_objc_notify_unmapped unmapped;
_dyld_objc_notify_patch_class patches;
};
struct _dyld_objc_callbacks_v2
{
uintptr_t version; // == 2
_dyld_objc_notify_mapped2 mapped;
_dyld_objc_notify_init init;
_dyld_objc_notify_unmapped unmapped;
_dyld_objc_notify_patch_class patches;
};
// Exists in Mac OS X 13.0 and later
// Exists in iOS 16.0 and later
// Exists in watchOS 9.0 and later
// Exists in tvOS 16.0 and later.
void _dyld_objc_register_callbacks(const struct _dyld_objc_callbacks*);
//
// get slide for a given loaded mach_header
// Mac OS X 10.6 and later
//
extern intptr_t _dyld_get_image_slide(const struct mach_header* mh);
struct dyld_unwind_sections
{
const struct mach_header* mh;
const void* dwarf_section;
uintptr_t dwarf_section_length;
const void* compact_unwind_section;
uintptr_t compact_unwind_section_length;
};
//
// Returns true iff some loaded mach-o image contains "addr".
// info->mh mach header of image containing addr
// info->dwarf_section pointer to start of __TEXT/__eh_frame section
// info->dwarf_section_length length of __TEXT/__eh_frame section
// info->compact_unwind_section pointer to start of __TEXT/__unwind_info section
// info->compact_unwind_section_length length of __TEXT/__unwind_info section
//
// Exists in Mac OS X 10.6 and later
#if !__USING_SJLJ_EXCEPTIONS__
extern bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info);
#endif
//
// This is an optimized form of dladdr() that only returns the dli_fname field.
//
// Exists in Mac OS X 10.6 and later
extern const char* dyld_image_path_containing_address(const void* addr);
//
// This is an optimized form of dladdr() that only returns the dli_fbase field.
// Return NULL, if address is not in any image tracked by dyld.
//
// Exists in Mac OS X 10.11 and later
extern const struct mach_header* dyld_image_header_containing_address(const void* addr);
//
// Return the mach header of the process
//
// Exists in Mac OS X 10.16 and later
extern const struct mach_header* _dyld_get_prog_image_header(void);
//
// Return the mach header of the binary returned by dlopen
//
// Exists in Mac OS X 13.0 and later
extern const struct mach_header* _dyld_get_dlopen_image_header(void* handle);
typedef uint32_t dyld_platform_t;
typedef struct {
dyld_platform_t platform;
uint32_t version;
} dyld_build_version_t;
// Returns the active platform of the process
extern dyld_platform_t dyld_get_active_platform(void) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Base platforms are platforms that have version numbers (macOS, iOS, watchos, tvOS, bridgeOS)
// All other platforms are mapped to a base platform for version checks
// It is intended that most code in the OS will use the version set constants, which will correctly deal with secret and future
// platforms. For example:
// if (dyld_program_sdk_at_least(dyld_fall_2018_os_versions)) {
// New behaviour for programs built against the iOS 12, tvOS 12, watchOS 5, macOS 10.14, or bridgeOS 3 (or newer) SDKs
// } else {
// Old behaviour
// }
// In cases where more precise control is required (such as APIs that were added to varions platforms in different years)
// the os specific values may be used instead. Unlike the version set constants, the platform specific ones will only ever
// return true if the running binary is the platform being testsed, allowing conditions to be built for specific platforms
// and releases that came out at different times. For example:
// if (dyld_program_sdk_at_least(dyld_platform_version_iOS_12_0)
// || dyld_program_sdk_at_least(dyld_platform_version_watchOS_6_0)) {
// New behaviour for programs built against the iOS 12 (fall 2018), watchOS 6 (fall 2019) (or newer) SDKs
// } else {
// Old behaviour all other platforms, as well as older iOSes and watchOSes
// }
extern dyld_platform_t dyld_get_base_platform(dyld_platform_t platform) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// SPI to ask if a platform is a simulation platform
extern bool dyld_is_simulator_platform(dyld_platform_t platform) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Takes a version and returns if the image was built againt that SDK or newer
// In the case of multi_plaform mach-o's it tests against the active platform
extern bool dyld_sdk_at_least(const struct mach_header* mh, dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Takes a version and returns if the image was built with that minos version or newer
// In the case of multi_plaform mach-o's it tests against the active platform
extern bool dyld_minos_at_least(const struct mach_header* mh, dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Convenience versions of the previous two functions that run against the the main executable
extern bool dyld_program_sdk_at_least(dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
extern bool dyld_program_minos_at_least(dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Function that walks through the load commands and calls the internal block for every version found
// Intended as a fallback for very complex (and rare) version checks, or for tools that need to
// print our everything for diagnostic reasons
extern void dyld_get_image_versions(const struct mach_header* mh, void (^callback)(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version)) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
// Convienence constants for dyld version SPIs.
// Because we now have so many different OSes with different versions these version set values are intended to
// to provide a more convenient way to version check. They may be used instead of platform specific version in
// dyld_sdk_at_least(), dyld_minos_at_least(), dyld_program_sdk_at_least(), and dyld_program_minos_at_least().
// Since they are references into a lookup table they MUST NOT be used by any code that does not ship as part of
// the OS, as the values may change and the tables in older OSes may not have the necessary values for back
// deployed binaries. These values are future proof against new platforms being added, and any checks against
// platforms that did not exist at the epoch of a version set will return true since all versions of that platform
// are inherently newer.
//@VERSION_DEFS@
//
// This finds the SDK version a binary was built against.
// Returns zero on error, or if SDK version could not be determined.
//
// Exists in Mac OS X 10.8 and later
// Exists in iOS 6.0 and later
extern uint32_t dyld_get_sdk_version(const struct mach_header* mh);
//
// This finds the SDK version that the main executable was built against.
// Returns zero on error, or if SDK version could not be determined.
//
// Note on watchOS, this returns the equivalent iOS SDK version number
// (i.e an app built against watchOS 2.0 SDK returne 9.0). To see the
// platform specific sdk version use dyld_get_program_sdk_watch_os_version().
//
// Exists in Mac OS X 10.8 and later
// Exists in iOS 6.0 and later
extern uint32_t dyld_get_program_sdk_version(void);
#if TARGET_OS_WATCH
// watchOS only.
// This finds the Watch OS SDK version that the main executable was built against.
// Exists in Watch OS 2.0 and later
extern uint32_t dyld_get_program_sdk_watch_os_version(void) __API_AVAILABLE(watchos(2.0));
// watchOS only.
// This finds the Watch min OS version that the main executable was built to run on.
// Note: dyld_get_program_min_os_version() returns the iOS equivalent (e.g. 9.0)
// whereas this returns the raw watchOS version (e.g. 2.0).
// Exists in Watch OS 3.0 and later
extern uint32_t dyld_get_program_min_watch_os_version(void) __API_AVAILABLE(watchos(3.0));
#endif
#if TARGET_OS_BRIDGE
// bridgeOS only.
// This finds the bridgeOS SDK version that the main executable was built against.
// Exists in bridgeOSOS 2.0 and later
extern uint32_t dyld_get_program_sdk_bridge_os_version(void) __API_AVAILABLE(bridgeos(2.0));
// bridgeOS only.
// This finds the Watch min OS version that the main executable was built to run on.
// Note: dyld_get_program_min_os_version() returns the iOS equivalent (e.g. 9.0)
// whereas this returns the raw bridgeOS version (e.g. 2.0).
// Exists in bridgeOS 2.0 and later
extern uint32_t dyld_get_program_min_bridge_os_version(void) __API_AVAILABLE(bridgeos(2.0));
#endif
//
// This finds the min OS version a binary was built to run on.
// Returns zero on error, or if no min OS recorded in binary.
//
// Exists in Mac OS X 10.8 and later
// Exists in iOS 6.0 and later
extern uint32_t dyld_get_min_os_version(const struct mach_header* mh);
//
// This finds the min OS version the main executable was built to run on.
// Returns zero on error, or if no min OS recorded in binary.
//
// Exists in Mac OS X 10.8 and later
// Exists in iOS 6.0 and later
extern uint32_t dyld_get_program_min_os_version(void);
//
// Returns true if any OS dylib has overridden its copy in the shared cache
// Returns false for iOS unzippered twins in the shared cache overriding
// their macOS counterpart in catalyst mode.
//
// Exists in iPhoneOS 3.1 and later
// Exists in Mac OS X 10.10 and later
extern bool dyld_shared_cache_some_image_overridden(void);
//
// Returns if the process is setuid or is code signed with entitlements.
// NOTE: It is safe to call this prior to malloc being initialized. This function
// is guaranteed to not call malloc, or depend on its state.
//
// Exists in Mac OS X 10.9 and later
extern bool dyld_process_is_restricted(void);
//
// Returns path used by dyld for standard dyld shared cache file for the current arch.
//
// Exists in Mac OS X 10.11 and later
extern const char* dyld_shared_cache_file_path(void);
//
// Returns if there are any inserted (via DYLD_INSERT_LIBRARIES) or interposing libraries.
//
// Exists in Mac OS X 10.15 and later
extern bool dyld_has_inserted_or_interposing_libraries(void);
//
// Return true if dyld contains a fix for a specific identifier. Intended for staging breaking SPI
// changes
//
// Exists in macOS 10.16, iOS 14, tvOS14, watchOS 7 and later
extern bool _dyld_has_fix_for_radar(const char *rdar);
//
// <rdar://problem/13820686> for OpenGL to tell dyld it is ok to deallocate a memory based image when done.
//
// Exists in Mac OS X 10.9 and later
#define NSLINKMODULE_OPTION_CAN_UNLOAD 0x20
//
// Update all bindings on specified image.
// Looks for uses of 'replacement' and changes it to 'replacee'.
// NOTE: this is less safe than using static interposing via DYLD_INSERT_LIBRARIES
// because the running program may have already copy the pointer values to other
// locations that dyld does not know about.
//
struct dyld_interpose_tuple {
const void* replacement;
const void* replacee;
};
extern void dyld_dynamic_interpose(const struct mach_header* mh, const struct dyld_interpose_tuple array[], size_t count);
struct dyld_shared_cache_dylib_text_info {
uint64_t version; // current version 2
// following fields all exist in version 1
uint64_t loadAddressUnslid;
uint64_t textSegmentSize;
uuid_t dylibUuid;
const char* path; // pointer invalid at end of iterations
// following fields all exist in version 2
uint64_t textSegmentOffset; // offset from start of cache
};
typedef struct dyld_shared_cache_dylib_text_info dyld_shared_cache_dylib_text_info;
#ifdef __BLOCKS__
//
// Given the UUID of a dyld shared cache file, this function will attempt to locate the cache
// file and if found iterate all images, returning info about each one. Returns 0 on success.
//
// Exists in Mac OS X 10.11 and later
// iOS 9.0 and later
extern int dyld_shared_cache_iterate_text(const uuid_t cacheUuid, void (^callback)(const dyld_shared_cache_dylib_text_info* info));
//
// Given the UUID of a dyld shared cache file, and a NULL terminated array of extra directory paths to search,
// this function will scan the standard and extra directories looking for a cache file that matches the UUID
// and if found iterate all images, returning info about each one. Returns 0 on success.
//
// Exists in Mac OS X 10.12 and later
// iOS 10.0 and later
extern int dyld_shared_cache_find_iterate_text(const uuid_t cacheUuid, const char* extraSearchDirs[], void (^callback)(const dyld_shared_cache_dylib_text_info* info));
#endif /* __BLOCKS */
//
// Returns if the specified address range is in a dyld owned memory
// that is mapped read-only and will never be unloaded.
//
// Exists in Mac OS X 10.12 and later
// iOS 10.0 and later
extern bool _dyld_is_memory_immutable(const void* addr, size_t length);
//
// Finds the UUID (from LC_UUID load command) of given image.
// Returns false if LC_UUID is missing or mach_header is malformed.
//
// Exists in Mac OS X 10.12 and later
// Exists in iOS 10.0 and later
extern bool _dyld_get_image_uuid(const struct mach_header* mh, uuid_t uuid);
//
// Gets the UUID of the dyld shared cache in the current process.
// Returns false if there is no dyld shared cache in use by the processes.
//
// Exists in Mac OS X 10.12 and later
// Exists in iOS 10.0 and later
extern bool _dyld_get_shared_cache_uuid(uuid_t uuid);
//
// Returns the start address of the dyld cache in the process and sets length to the size of the cache.
// Returns NULL if the process is not using a dyld shared cache
//
// Exists in Mac OS X 10.13 and later
// Exists in iOS 11.0 and later
extern const void* _dyld_get_shared_cache_range(size_t* length);
//
// Returns if the currently active dyld shared cache is optimized.
// Note: macOS does not use optimized caches and will always return false.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern bool _dyld_shared_cache_optimized(void);
//
// Returns if the currently active dyld shared cache was built locally.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern bool _dyld_shared_cache_is_locally_built(void);
//
// Returns if the given app needs a closure built.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern bool dyld_need_closure(const char* execPath, const char* dataContainerRootDir);
struct dyld_image_uuid_offset {
uuid_t uuid;
uint64_t offsetInImage;
const struct mach_header* image;
};
//
// Given an array of addresses, returns info about each address.
// Common usage is the array or addresses was produced by a stack backtrace.
// For each address, returns the where that image was loaded, the offset
// of the address in the image, and the image's uuid. If a specified
// address is unknown to dyld, all fields will be returned a zeros.
//
// Exists in macOS 10.14 and later
// Exists in iOS 12.0 and later
extern void _dyld_images_for_addresses(unsigned count, const void* addresses[], struct dyld_image_uuid_offset infos[]);
//
// Lets you register a callback which is called each time an image is loaded and provides the mach_header*, path, and
// whether the image may be unloaded later. During the call to _dyld_register_for_image_loads(), the callback is called
// once for each image currently loaded.
//
// Exists in macOS 10.14 and later
// Exists in iOS 12.0 and later
extern void _dyld_register_for_image_loads(void (*func)(const struct mach_header* mh, const char* path, bool unloadable));
//
// Lets you register a callback which is called for bulk notifications of images loaded. During the call to
// _dyld_register_for_bulk_image_loads(), the callback is called once with all images currently loaded.
// Then later during dlopen() the callback is called once with all newly images.
//
// Exists in macOS 10.15 and later
// Exists in iOS 13.0 and later
extern void _dyld_register_for_bulk_image_loads(void (*func)(unsigned imageCount, const struct mach_header* mhs[], const char* paths[]));
//
// DriverKit main executables do not have an LC_MAIN. Instead DriverKit.framework's initializer calls
// _dyld_register_driverkit_main() with a function pointer that dyld should call into instead
// of using LC_MAIN.
//
extern void _dyld_register_driverkit_main(void (*mainFunc)(void));
//
// This is similar to _dyld_shared_cache_contains_path(), except that it returns the canonical
// shared cache path for the given path.
//
// Exists in macOS 10.16 and later
// Exists in iOS 14.0 and later
extern const char* _dyld_shared_cache_real_path(const char* path);
//
// Dyld has a number of modes. This function returns the mode for the current process.
// dyld2 is the classic "interpreter" way to run.
// dyld3 runs by compiling down and caching what dyld needs to do into a "closure".
//
// Exists in macOS 10.16 and later
// Exists in iOS 14.0 and later
//
#define DYLD_LAUNCH_MODE_USING_CLOSURE 0x00000001 // dyld4: 0 => main is JITLoader, 1=> main is PrebuiltLoader
#define DYLD_LAUNCH_MODE_BUILT_CLOSURE_AT_LAUNCH 0x00000002 // dyld4: currently unused
#define DYLD_LAUNCH_MODE_CLOSURE_SAVED_TO_FILE 0x00000004 // dyld4: built and wrote PrebuiltLoaderSet to disk
#define DYLD_LAUNCH_MODE_CLOSURE_FROM_OS 0x00000008 // dyld4: PrebuiltLoaderSet used was built into dyld cache
#define DYLD_LAUNCH_MODE_MINIMAL_CLOSURE 0x00000010 // dyld4: unused
#define DYLD_LAUNCH_MODE_HAS_INTERPOSING 0x00000020 // dyld4: process has interposed symbols
#define DYLD_LAUNCH_MODE_OPTIMIZED_DYLD_CACHE 0x00000040 // dyld4: dyld shared cache is optimized (stubs eliminated)
extern uint32_t _dyld_launch_mode(void);
//
// When dyld must terminate a process because of a required dependent dylib
// could not be loaded or a symbol is missing, dyld calls abort_with_reason()
// using one of the following error codes.
//
#define DYLD_EXIT_REASON_DYLIB_MISSING 1
#define DYLD_EXIT_REASON_DYLIB_WRONG_ARCH 2
#define DYLD_EXIT_REASON_DYLIB_WRONG_VERSION 3
#define DYLD_EXIT_REASON_SYMBOL_MISSING 4
#define DYLD_EXIT_REASON_CODE_SIGNATURE 5
#define DYLD_EXIT_REASON_FILE_SYSTEM_SANDBOX 6
#define DYLD_EXIT_REASON_MALFORMED_MACHO 7
#define DYLD_EXIT_REASON_OTHER 9
//
// When it has more information about the termination, dyld will use abort_with_payload().
// The payload is a dyld_abort_payload structure. The fixed fields are offsets into the
// payload for the corresponding string. If the offset is zero, that string is not available.
//
struct dyld_abort_payload {
uint32_t version; // first version is 1
uint32_t flags; // 0x00000001 means dyld terminated at launch, backtrace not useful
uint32_t targetDylibPathOffset; // offset in payload of path string to dylib that could not be loaded
uint32_t clientPathOffset; // offset in payload of path string to image requesting dylib
uint32_t symbolOffset; // offset in payload of symbol string that could not be found
// string data
};
typedef struct dyld_abort_payload dyld_abort_payload;
// These global variables are implemented in libdyld.dylib
// Old programs that used crt1.o also defined these globals.
// The ones in dyld are not used when an old program is run.
extern int NXArgc;
extern const char** NXArgv;
extern char** environ; // POSIX says this not const, because it pre-dates const
extern const char* __progname;
// called by libSystem_initializer only
extern void _dyld_initializer(void);
// never called from source code. Used by static linker to implement lazy binding
extern void dyld_stub_binder(void) __asm__("dyld_stub_binder");
// never call from source code. Used by closure builder to bind missing lazy symbols to
extern void _dyld_missing_symbol_abort(void);
// Called only by objc to see if dyld has uniqued this selector.
// Returns the value if dyld has uniqued it, or nullptr if it has not.
// Note, this function must be called after _dyld_objc_notify_register.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern const char* _dyld_get_objc_selector(const char* selName);
// Called only by objc to see if dyld has pre-optimized classes with this name.
// The callback will be called once for each class with the given name where
// isLoaded is true if that class is in a binary which has been previously passed
// to the objc load notifier.
// Note you can set stop to true to stop iterating.
// Also note, this function must be called after _dyld_objc_notify_register.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern void _dyld_for_each_objc_class(const char* className,
void (^callback)(void* classPtr, bool isLoaded, bool* stop));
// Called only by objc to see if dyld has pre-optimized protocols with this name.
// The callback will be called once for each protocol with the given name where
// isLoaded is true if that protocol is in a binary which has been previously passed
// to the objc load notifier.
// Note you can set stop to true to stop iterating.
// Also note, this function must be called after _dyld_objc_notify_register.
//
// Exists in Mac OS X 10.15 and later
// Exists in iOS 13.0 and later
extern void _dyld_for_each_objc_protocol(const char* protocolName,
void (^callback)(void* protocolPtr, bool isLoaded, bool* stop));
// Called only by lldb to visit every objc Class in the shared cache hash table
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
extern void _dyld_visit_objc_classes(void (^callback)(const void* classPtr));
// Called only by libobjc to get the number of classes in the shared cache hash table
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
extern uint32_t _dyld_objc_class_count(void);
// Called only by libobjc to check if relative method lists are the new large caches format
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
extern bool _dyld_objc_uses_large_shared_cache(void);
enum _dyld_protocol_conformance_result_kind {
_dyld_protocol_conformance_result_kind_found_descriptor,
_dyld_protocol_conformance_result_kind_found_witness_table,
_dyld_protocol_conformance_result_kind_not_found,
_dyld_protocol_conformance_result_kind_definitive_failure
// Unknown values will be considered to be a non-definitive failure, so we can
// add more response kinds later if needed without a synchronized submission.
};
struct _dyld_protocol_conformance_result {
// Note this is really a _dyld_protocol_conformance_result_kind in disguise
uintptr_t kind;
// Contains a ProtocolConformanceDescriptor iff `kind` is _dyld_protocol_conformance_result_kind_found_descriptor
// Contains a WitnessTable iff `kind` is _dyld_protocol_conformance_result_kind_found_witness_table
const void *value;
};
// Called only by Swift to see if dyld has pre-optimized protocol conformances for the given
// protocolDescriptor/metadataType and typeDescriptor.
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
extern struct _dyld_protocol_conformance_result
_dyld_find_protocol_conformance(const void *protocolDescriptor,
const void *metadataType,
const void *typeDescriptor);
// Called only by Swift to see if dyld has pre-optimized protocol conformances for the given
// foreign type descriptor name and protocol
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
extern struct _dyld_protocol_conformance_result
_dyld_find_foreign_type_protocol_conformance(const void *protocol,
const char *foreignTypeIdentityStart,
size_t foreignTypeIdentityLength);
// Called only by Swift to check what version of the optimizations are available.
//
// Exists in Mac OS X 12.0 and later
// Exists in iOS 15.0 and later
// Exists in watchOS 8.0 and later
// Exists in tvOS 15.0 and later.
extern uint32_t _dyld_swift_optimizations_version(void) __API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));
// Swift uses this define to guard for the above symbol being available at build time
#define DYLD_FIND_PROTOCOL_CONFORMANCE_DEFINED 1
// Called only by Swift to check if dyld has pre-optimized protocol conformances in the closure
// for the given on-disk mach_header containing a __swift5_proto section
//
// Exists in Mac OS X 13.0 and later
// Exists in iOS 16.0 and later
extern bool _dyld_has_preoptimized_swift_protocol_conformances(const struct mach_header* mh);
// Called only by Swift to see if dyld has pre-optimized protocol conformances for the given
// protocolDescriptor/metadataType and typeDescriptor in the closure on disk.
//
// Exists in Mac OS X 13.0 and later
// Exists in iOS 16.0 and later
extern struct _dyld_protocol_conformance_result
_dyld_find_protocol_conformance_on_disk(const void *protocolDescriptor,
const void *metadataType,
const void *typeDescriptor,
uint32_t flags);
// Called only by Swift to see if dyld has pre-optimized protocol conformances for the given
// foreign type descriptor name and protocol in the closure on disk.
//
// Exists in Mac OS X 13.0 and later
// Exists in iOS 16.0 and later
extern struct _dyld_protocol_conformance_result
_dyld_find_foreign_type_protocol_conformance_on_disk(const void *protocol,
const char *foreignTypeIdentityStart,
size_t foreignTypeIdentityLength,
uint32_t flags);
// Swift uses this define to guard for the above symbols being available at build time
#define DYLD_FIND_PROTOCOL_ON_DISK_CONFORMANCE_DEFINED 1
// called by exit() before it calls cxa_finalize() so that thread_local
// objects are destroyed before global objects.
extern void _tlv_exit(void);
typedef enum {
dyld_objc_string_kind
} DyldObjCConstantKind;
// CF constants such as CFString's can be moved in to a contiguous range of
// shared cache memory. This returns true if the given pointer is to an object of
// the given kind.
//
// Exists in Mac OS X 10.16 and later
// Exists in iOS 14.0 and later
extern bool _dyld_is_objc_constant(DyldObjCConstantKind kind, const void* addr);
// temp exports to keep tapi happy, until ASan stops using dyldVersionNumber
extern double dyldVersionNumber;
extern const char* dyldVersionString;
// True if dyld told objc to patch classes
extern uint8_t dyld_process_has_objc_patches;
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* _MACH_O_DYLD_PRIV_H_ */