]> git.saurik.com Git - apple/dyld.git/blob - include/mach-o/dyld_process_info.h
dyld-519.2.2.tar.gz
[apple/dyld.git] / include / mach-o / dyld_process_info.h
1 /*
2 * Copyright (c) 2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 #ifndef _DYLD_PROCESS_INFO_
24 #define _DYLD_PROCESS_INFO_
25
26 #include <stdbool.h>
27 #include <unistd.h>
28 #include <mach/mach.h>
29 #include <dispatch/dispatch.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 //
36 // Beginning in iOS 10.0 and Mac OS X 10.12, this is how lldb figures out mach-o binaries are in a process:
37 //
38 // When attaching to an existing process, lldb uses _dyld_process_info_create() to get the current list of images
39 // in a process, then falls into the start up case.
40 //
41 // When starting a process, lldb starts the process suspended, finds the "_dyld_debugger_notification" symbol in
42 // dyld, sets a break point on it, then resumes the process. Dyld will call _dyld_debugger_notification() with
43 // a list of images that were just added or removed from the process. Dyld calls this function before running
44 // any initializers in the image, so the debugger will have a chance to set break points in the image.
45 //
46 //
47
48 enum dyld_notify_mode { dyld_notify_adding=0, dyld_notify_removing=1, dyld_notify_remove_all=2 };
49 // void _dyld_debugger_notification(enum dyld_notify_mode, unsigned long count, uint64_t machHeaders[]);
50
51
52
53 struct dyld_process_cache_info {
54 uuid_t cacheUUID; // UUID of cache used by process
55 uint64_t cacheBaseAddress; // load address of dyld shared cache
56 bool noCache; // process is running without a dyld cache
57 bool privateCache; // process is using a private copy of its dyld cache
58 };
59 typedef struct dyld_process_cache_info dyld_process_cache_info;
60
61 enum {
62 dyld_process_state_not_started = 0x00, // process is suspended, dyld has not started running yet
63 dyld_process_state_dyld_initialized = 0x10, // dyld has initialzed itself
64 dyld_process_state_terminated_before_inits = 0x20, // process was terminated due missing library or symbol before it got to main()
65 dyld_process_state_libSystem_initialized = 0x30, // dyld has run libSystem's initializer
66 dyld_process_state_running_initializers = 0x40, // dyld is running other initializers
67 dyld_process_state_program_running = 0x50, // dyld has finished and jumped into main()
68 dyld_process_state_dyld_terminated = 0x60 // process was terminated by dyld post-main (e.g. bad lazying binding info)
69 };
70
71 struct dyld_process_state_info {
72 uint64_t timestamp; // mach_absolute_time of last time dyld change to image list
73 uint32_t imageCount; // number of images currently loaded into process
74 uint32_t initialImageCount; // number of images statically loaded into process (before any dlopen() calls)
75 uint8_t dyldState; // one of dyld_process_state_* values
76 };
77 typedef struct dyld_process_state_info dyld_process_state_info;
78
79
80 typedef const struct dyld_process_info_base* dyld_process_info;
81
82 //
83 // Generate a dyld_process_info object for specified task.
84 //
85 // The timestamp parameter is an optimization to not spend the time to gather all the image information
86 // if the process image list has not changed since the last call. If timestamp is zero, this function
87 // always gathers the full process info. If timestamp is non-zero, this function will check if the target
88 // task's image list has changed since that time. If is has not changed, the function returns NULL and
89 // kern_return_t is KERN_SUCCESS. If it has changed, the function gathers the full image info.
90 // The kernelError parameter can be NULL for clients that don't care why it failed.
91 //
92 extern dyld_process_info _dyld_process_info_create(task_t task, uint64_t timestamp, kern_return_t* kernelError);
93
94 // retain/release dyld_process_info for specified task
95 extern void _dyld_process_info_release(dyld_process_info info);
96 extern void _dyld_process_info_retain(dyld_process_info info);
97
98 // fill in struct with basic info about dyld in the process
99 extern void _dyld_process_info_get_state(dyld_process_info info, dyld_process_state_info* stateInfo);
100
101 // fill in struct with info about dyld cache in use by process
102 extern void _dyld_process_info_get_cache(dyld_process_info info, dyld_process_cache_info* cacheInfo);
103
104 // iterate all images in process
105 extern void _dyld_process_info_for_each_image(dyld_process_info info, void (^callback)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path));
106
107 // iterate all segments in an image
108 extern void _dyld_process_info_for_each_segment(dyld_process_info info, uint64_t machHeaderAddress, void (^callback)(uint64_t segmentAddress, uint64_t segmentSize, const char* segmentName));
109
110
111
112
113 typedef const struct dyld_process_info_notify_base* dyld_process_info_notify;
114
115 //
116 // Request notifications if image list changes in target process. Each time a load or unload happens in the target taks,
117 // the notify block will be called in this process. If the process exits, the notifyExit block will be called.
118 // If the notifications cannot be set up, this function will return NULL, and the reason in the kernError parameter.
119 // The kernelError parameter can be NULL for clients that don't care why it failed.
120 // If you want to stop receiving notifications, call _dyld_process_info_notify_release().
121 //
122 extern dyld_process_info_notify _dyld_process_info_notify(task_t task, dispatch_queue_t queue,
123 void (^notify)(bool unload, uint64_t timestamp, uint64_t machHeader, const uuid_t uuid, const char* path),
124 void (^notifyExit)(),
125 kern_return_t* kernelError);
126 // add block to call right before main() is entered.
127 // does nothing if process is already in main().
128 extern void _dyld_process_info_notify_main(dyld_process_info_notify objc, void (^notifyMain)());
129
130
131 // stop notifications and invalid dyld_process_info_notify object
132 extern void _dyld_process_info_notify_release(dyld_process_info_notify object);
133 extern void _dyld_process_info_notify_retain(dyld_process_info_notify object);
134
135
136 #ifdef __cplusplus
137 }
138 #endif
139
140 #endif /* _DYLD_PROCESS_INFO_ */