]> git.saurik.com Git - apple/dyld.git/blame - dyld3/Loading.h
dyld-851.27.tar.gz
[apple/dyld.git] / dyld3 / Loading.h
CommitLineData
10b92d3b
A
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
26#ifndef __DYLD_LOADING_H__
27#define __DYLD_LOADING_H__
28
29#include <string.h>
30#include <stdint.h>
31#include <mach/mach.h>
32#include <_simple.h>
10b92d3b 33
6cae9b63
A
34#include "Closure.h"
35#include "MachOLoaded.h"
bc3b7c8c 36#include "MachOAnalyzerSet.h"
10b92d3b 37
cf998323
A
38namespace objc_opt {
39struct objc_clsopt_t;
40struct objc_selopt_t;
41}
42
10b92d3b
A
43namespace dyld3 {
44
bc3b7c8c
A
45class RootsChecker;
46
47struct LaunchErrorInfo
48{
49 uintptr_t kind;
50 const char* clientOfDylibPath;
51 const char* targetDylibPath;
52 const char* symbol;
53};
10b92d3b 54
6cae9b63
A
55//
56// Tuple of info about a loaded image. Contains the loaded address, Image*, and state.
57//
58class VIS_HIDDEN LoadedImage {
59public:
60 enum class State { unmapped=0, mapped=1, fixedUp=2, beingInited=3, inited=4 };
61
62 static LoadedImage make(const closure::Image* img) { LoadedImage result; result._image = img; return result; }
63 static LoadedImage make(const closure::Image* img, const MachOLoaded* mh)
64 { LoadedImage result; result._image = img; result.setLoadedAddress(mh); return result; }
65
66 const closure::Image* image() const { return _image; }
67 const MachOLoaded* loadedAddress() const { return (MachOLoaded*)(_loadAddr & (-4096)); }
68 void setLoadedAddress(const MachOLoaded* a) { _loadAddr |= ((uintptr_t)a & (-4096)); }
69 State state() const { return (State)(asBits().state); }
70 void setState(State s) { asBits().state = (int)s; }
71 bool hideFromFlatSearch() const { return asBits().hide; }
72 void setHideFromFlatSearch(bool h) { asBits().hide = h; }
73 bool leaveMapped() const { return asBits().leaveMapped; }
74 void markLeaveMapped() { asBits().leaveMapped = true; }
75
76private:
77 // since loaded MachO files are always page aligned, that means at least low 12-bits are always zero
78 // so we don't need to record the low 12 bits, instead those bits hold various flags in the _loadeAddr field
79 struct AddrBits {
80 uintptr_t state : 3,
81 hide : 1,
82 leaveMapped : 1,
83 extra : 7,
84 #if __LP64__
85 addr : 52;
86 #else
87 addr : 20;
88 #endif
89 };
90 AddrBits& asBits() { return *((AddrBits*)&_loadAddr); }
91 const AddrBits& asBits() const { return *((AddrBits*)&_loadAddr); }
92
93 // Note: this must be statically initializable so as to not cause static initializers
94 const closure::Image* _image = nullptr;
95 uintptr_t _loadAddr = 0; // really AddrBits
10b92d3b
A
96};
97
98
6cae9b63
A
99//
100// Utility class to recursively load dependents
101//
bc3b7c8c 102class VIS_HIDDEN Loader : public MachOAnalyzerSet {
6cae9b63
A
103public:
104 typedef bool (*LogFunc)(const char*, ...) __attribute__((format(printf, 1, 2)));
105
cf998323
A
106 Loader(const Array<LoadedImage>& existingImages, Array<LoadedImage>& newImagesStorage,
107 const void* cacheAddress, const Array<const dyld3::closure::ImageArray*>& imagesArrays,
108 const closure::ObjCSelectorOpt* selOpt, const Array<closure::Image::ObjCSelectorImage>& selImages,
bc3b7c8c
A
109 const RootsChecker& rootsChecker, dyld3::Platform platform,
110 LogFunc log_loads, LogFunc log_segments, LogFunc log_fixups, LogFunc log_dofs,
111 bool allowMissingLazies=false, dyld3::LaunchErrorInfo* launchErrorInfo=nullptr);
6cae9b63
A
112
113 void addImage(const LoadedImage&);
cf998323 114 void completeAllDependents(Diagnostics& diag, bool& someCacheImageOverridden);
bc3b7c8c 115 void mapAndFixupAllImages(Diagnostics& diag, bool processDOFs, bool fromOFI, bool* closureOutOfDate, bool* recoverable);
6cae9b63 116 uintptr_t resolveTarget(closure::Image::ResolvedSymbolTarget target);
bc3b7c8c
A
117 LoadedImage* findImage(closure::ImageNum targetImageNum) const;
118 void forEachImage(void (^handler)(const LoadedImage& li, bool& stop)) const;
6cae9b63
A
119
120 static void unmapImage(LoadedImage& info);
121 static bool dtraceUserProbesEnabled();
122 static void vmAccountingSetSuspended(bool suspend, LogFunc);
123
124private:
125
126 struct ImageOverride
127 {
128 closure::ImageNum inCache;
129 closure::ImageNum replacement;
130 };
131
132 struct DOFInfo {
133 const void* dof;
134 const mach_header* imageHeader;
135 const char* imageShortName;
136 };
137
cf998323
A
138#if BUILDING_DYLD
139 struct LaunchImagesCache {
140 LoadedImage* findImage(closure::ImageNum targetImageNum,
141 Array<LoadedImage>& images) const;
bc3b7c8c 142 void tryAddImage(closure::ImageNum targetImageNum, uint64_t allImagesIndex) const;
cf998323
A
143
144 static const uint64_t _cacheSize = 128;
145 static const closure::ImageNum _firstImageNum = closure::kFirstLaunchClosureImageNum;
146 static const closure::ImageNum _lastImageNum = closure::kFirstLaunchClosureImageNum + _cacheSize;
147
148 // Note, the cache stores "indices + 1" into the _allImages array.
149 // 0 means we haven't cached an entry yet
150 uint32_t _cacheStorage[_cacheSize] = { 0 };
bc3b7c8c 151 mutable Array<uint32_t> _imageIndices = { &_cacheStorage[0], _cacheSize, _cacheSize };
cf998323
A
152 };
153#endif
154
bc3b7c8c 155 void mapImage(Diagnostics& diag, LoadedImage& info, bool fromOFI, bool* closureOutOfDate);
6cae9b63
A
156 void applyFixupsToImage(Diagnostics& diag, LoadedImage& info);
157 void registerDOFs(const Array<DOFInfo>& dofs);
158 void setSegmentProtects(const LoadedImage& info, bool write);
159 bool sandboxBlockedMmap(const char* path);
160 bool sandboxBlockedOpen(const char* path);
161 bool sandboxBlockedStat(const char* path);
162 bool sandboxBlocked(const char* path, const char* kind);
bc3b7c8c
A
163 void unmapAllImages();
164
165 // MachOAnalyzerSet support
166 void mas_forEachImage(void (^handler)(const WrappedMachO& anImage, bool hidden, bool& stop)) const override;
167 void mas_mainExecutable(WrappedMachO& anImage) const override;
168 void* mas_dyldCache() const override;
169 bool wmo_dependent(const WrappedMachO* image, uint32_t depIndex, WrappedMachO& childObj, bool& missingWeakDylib) const override;
170 const char* wmo_path(const WrappedMachO* image) const override;
171 bool wmo_missingSymbolResolver(const WrappedMachO* fromWmo, bool weakImport, bool lazyBind, const char* symbolName, const char* expectedInDylibPath, const char* clientPath, FixupTarget& target) const override;
172
6cae9b63 173
cf998323
A
174 const Array<LoadedImage>& _existingImages;
175 Array<LoadedImage>& _newImages;
176 const Array<const closure::ImageArray*>& _imagesArrays;
177 const void* _dyldCacheAddress;
178 const objc_opt::objc_selopt_t* _dyldCacheSelectorOpt;
179 const closure::ObjCSelectorOpt* _closureSelectorOpt;
180 const Array<closure::Image::ObjCSelectorImage>& _closureSelectorImages;
bc3b7c8c 181 const RootsChecker& _rootsChecker;
cf998323
A
182#if BUILDING_DYLD
183 LaunchImagesCache _launchImagesCache;
184#endif
bc3b7c8c
A
185 bool _allowMissingLazies;
186 dyld3::Platform _platform;
cf998323
A
187 LogFunc _logLoads;
188 LogFunc _logSegments;
189 LogFunc _logFixups;
190 LogFunc _logDofs;
bc3b7c8c 191 dyld3::LaunchErrorInfo* _launchErrorInfo;
6cae9b63 192};
10b92d3b
A
193
194
10b92d3b 195
cf998323 196#if (BUILDING_LIBDYLD || BUILDING_DYLD)
10b92d3b 197bool internalInstall();
cf998323
A
198#endif
199#if BUILDING_DYLD
10b92d3b 200void forEachLineInFile(const char* path, void (^lineHandler)(const char* line, bool& stop));
6cae9b63 201void forEachLineInFile(const char* buffer, size_t bufferLen, void (^lineHandler)(const char* line, bool& stop));
10b92d3b 202#endif
10b92d3b 203
10b92d3b
A
204} // namespace dyld3
205
10b92d3b
A
206#endif // __DYLD_LOADING_H__
207
208