dyld-655.1.tar.gz
[apple/dyld.git] / dyld3 / AllImages.h
1 /*
2 * Copyright (c) 2017 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
24
25 #ifndef __ALL_IMAGES_H__
26 #define __ALL_IMAGES_H__
27
28 #include <mach-o/loader.h>
29 #include <pthread.h>
30 #include <os/lock_private.h>
31
32 #include "dyld_priv.h"
33
34 #include "Closure.h"
35 #include "Loading.h"
36 #include "MachOLoaded.h"
37 #include "DyldSharedCache.h"
38
39
40 #if __MAC_OS_X_VERSION_MIN_REQUIRED
41 // only in macOS and deprecated
42 struct VIS_HIDDEN OFIInfo
43 {
44 const char* path; // = nullptr;
45 const void* memSource; // = nullptr;
46 size_t memLength; // = 0;
47 const dyld3::MachOLoaded* loadAddress; // = nullptr;
48 uint64_t imageNum; // = 0;
49 };
50 #endif
51
52 namespace dyld3 {
53
54 class VIS_HIDDEN AllImages
55 {
56 public:
57 typedef void (*NotifyFunc)(const mach_header* mh, intptr_t slide);
58 typedef void (*LoadNotifyFunc)(const mach_header* mh, const char* path, bool unloadable);
59
60 void init(const closure::LaunchClosure* closure, const DyldSharedCache* dyldCacheLoadAddress, const char* dyldCachePath,
61 const Array<LoadedImage>& initialImages);
62 void setRestrictions(bool allowAtPaths, bool allowEnvPaths);
63 void setMainPath(const char* path);
64 void applyInitialImages();
65
66 void addImages(const Array<LoadedImage>& newImages);
67 void removeImages(const Array<LoadedImage>& unloadImages);
68 void runImageNotifiers(const Array<LoadedImage>& newImages);
69 void applyInterposingToDyldCache(const closure::Closure* closure);
70 void runStartupInitialzers();
71 void runInitialzersBottomUp(const closure::Image* topImage);
72 void runLibSystemInitializer(const LoadedImage& libSystem);
73
74 uint32_t count() const;
75
76 void forEachImage(void (^handler)(const LoadedImage& loadedImage, bool& stop)) const;
77 const MachOLoaded* findDependent(const MachOLoaded* mh, uint32_t depIndex);
78 void visitDependentsTopDown(const LoadedImage& start, void (^handler)(const LoadedImage& aLoadedImage, bool& stop)) const;
79 void infoForImageMappedAt(const void* addr, void (^handler)(const LoadedImage& foundImage, uint8_t permissions)) const;
80 bool infoForImageMappedAt(const void* addr, const MachOLoaded** ml, uint64_t* textSize, const char** path) const;
81 void infoForNonCachedImageMappedAt(const void* addr, void (^handler)(const LoadedImage& foundImage, uint8_t permissions)) const;
82 void infoForImageWithLoadAddress(const MachOLoaded*, void (^handler)(const LoadedImage& foundImage)) const;
83 const char* pathForImageMappedAt(const void* addr) const;
84 const char* imagePathByIndex(uint32_t index) const;
85 const mach_header* imageLoadAddressByIndex(uint32_t index) const;
86 bool immutableMemory(const void* addr, size_t length) const;
87
88 bool isRestricted() const;
89 const MachOLoaded* mainExecutable() const;
90 const closure::Image* mainExecutableImage() const;
91 const void* cacheLoadAddress() const { return _dyldCacheAddress; }
92 const char* dyldCachePath() const { return _dyldCachePath; }
93 bool dyldCacheHasPath(const char* path) const;
94 const char* imagePath(const closure::Image*) const;
95 dyld_platform_t platform() const;
96
97 const Array<const closure::ImageArray*>& imagesArrays();
98
99 void incRefCount(const mach_header* loadAddress);
100 void decRefCount(const mach_header* loadAddress);
101
102 void addLoadNotifier(NotifyFunc);
103 void addUnloadNotifier(NotifyFunc);
104 void setObjCNotifiers(_dyld_objc_notify_mapped, _dyld_objc_notify_init, _dyld_objc_notify_unmapped);
105 void notifyObjCUnmap(const char* path, const struct mach_header* mh);
106 void addLoadNotifier(LoadNotifyFunc);
107
108
109 void setOldAllImageInfo(dyld_all_image_infos* old) { _oldAllImageInfos = old; }
110 dyld_all_image_infos* oldAllImageInfo() const { return _oldAllImageInfos;}
111 void notifyMonitorMain();
112 void notifyMonitorLoads(const Array<LoadedImage>& newImages);
113 void notifyMonitorUnloads(const Array<LoadedImage>& unloadingImages);
114
115 #if __MAC_OS_X_VERSION_MIN_REQUIRED
116 NSObjectFileImage addNSObjectFileImage(const OFIInfo&);
117 void removeNSObjectFileImage(NSObjectFileImage);
118 bool forNSObjectFileImage(NSObjectFileImage imageHandle,
119 void (^handler)(OFIInfo& image));
120 #endif
121
122 const MachOLoaded* dlopen(Diagnostics& diag, const char* path, bool rtldNoLoad, bool rtldLocal, bool rtldNoDelete, bool fromOFI, const void* callerAddress);
123
124 struct ProgramVars
125 {
126 const void* mh;
127 int* NXArgcPtr;
128 const char*** NXArgvPtr;
129 const char*** environPtr;
130 const char** __prognamePtr;
131 };
132 void setProgramVars(ProgramVars* vars);
133
134 private:
135 friend class Reaper;
136
137 struct DlopenCount {
138 const mach_header* loadAddress;
139 uintptr_t refCount;
140 };
141
142
143 typedef void (*Initializer)(int argc, const char* argv[], char* envp[], const char* apple[], const ProgramVars* vars);
144 typedef const Array<LoadedImage> StartImageArray;
145
146 void runInitialzersInImage(const mach_header* imageLoadAddress, const closure::Image* image);
147 void mirrorToOldAllImageInfos();
148 void garbageCollectImages();
149 void breadthFirstRecurseDependents(Array<closure::ImageNum>& visited, const LoadedImage& nodeLi, bool& stop, void (^handler)(const LoadedImage& aLoadedImage, bool& stop)) const;
150 void appendToImagesArray(const closure::ImageArray* newArray);
151 void withReadLock(void (^work)()) const;
152 void withWriteLock(void (^work)());
153 void withNotifiersLock(void (^work)()) const;
154 bool findImage(const mach_header* loadAddress, LoadedImage& foundImage) const;
155 bool findImageNum(closure::ImageNum imageNum, LoadedImage& foundImage) const;
156 LoadedImage findImageNum(closure::ImageNum num, uint32_t& indexHint);
157 bool swapImageState(closure::ImageNum num, uint32_t& indexHint, LoadedImage::State expectedCurrentState, LoadedImage::State newState);
158 void runAllInitializersInImage(const closure::Image* image, const MachOLoaded* ml);
159 void recomputeBounds();
160
161 void constructMachPorts(int slot);
162 void teardownMachPorts(int slot);
163 void forEachPortSlot(void (^callback)(int slot));
164 void sendMachMessage(int slot, mach_msg_id_t msg_id, mach_msg_header_t* msg_buffer, mach_msg_size_t msg_size);
165 void notifyMonitoringDyld(bool unloading, const Array<LoadedImage>& images);
166
167 typedef closure::ImageArray ImageArray;
168
169 const closure::LaunchClosure* _mainClosure = nullptr;
170 const DyldSharedCache* _dyldCacheAddress = nullptr;
171 const char* _dyldCachePath = nullptr;
172 uint64_t _dyldCacheSlide = 0;
173 StartImageArray* _initialImages = nullptr;
174 const char* _mainExeOverridePath = nullptr;
175 _dyld_objc_notify_mapped _objcNotifyMapped = nullptr;
176 _dyld_objc_notify_init _objcNotifyInit = nullptr;
177 _dyld_objc_notify_unmapped _objcNotifyUnmapped = nullptr;
178 ProgramVars* _programVars = nullptr;
179 dyld_all_image_infos* _oldAllImageInfos = nullptr;
180 dyld_image_info* _oldAllImageArray = nullptr;
181 dyld_uuid_info* _oldUUIDArray = nullptr;
182 dyld_platform_t _platform = 0;
183 uint32_t _oldArrayAllocCount = 0;
184 uint32_t _oldUUIDAllocCount = 0;
185 closure::ImageNum _nextImageNum = 0;
186 int32_t _gcCount = 0;
187 bool _processDOFs = false;
188 bool _allowAtPaths = false;
189 bool _allowEnvPaths = false;
190 uintptr_t _lowestNonCached = 0;
191 uintptr_t _highestNonCached = UINTPTR_MAX;
192 #ifdef OS_UNFAIR_RECURSIVE_LOCK_INIT
193 mutable os_unfair_recursive_lock _loadImagesLock = OS_UNFAIR_RECURSIVE_LOCK_INIT;
194 mutable os_unfair_recursive_lock _notifiersLock = OS_UNFAIR_RECURSIVE_LOCK_INIT;
195 #else
196 mutable pthread_mutex_t _loadImagesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
197 mutable pthread_mutex_t _notifiersLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
198 #endif
199 GrowableArray<const ImageArray*, 4, 4> _imagesArrays;
200 GrowableArray<NotifyFunc, 4, 4> _loadNotifiers;
201 GrowableArray<NotifyFunc, 4, 4> _unloadNotifiers;
202 GrowableArray<LoadNotifyFunc, 4, 4> _loadNotifiers2;
203 GrowableArray<DlopenCount, 4, 4> _dlopenRefCounts;
204 GrowableArray<LoadedImage, 16> _loadedImages;
205 #if __MAC_OS_X_VERSION_MIN_REQUIRED
206 uint64_t _nextObjectFileImageNum = 0;
207 GrowableArray<OFIInfo, 4, 1> _objectFileImages;
208 #endif
209 };
210
211 extern AllImages gAllImages;
212
213
214 } // dyld3
215
216
217 #endif // __ALL_IMAGES_H__