dyld-655.1.tar.gz
[apple/dyld.git] / dyld3 / Loading.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
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>
33
34 #include "Closure.h"
35 #include "MachOLoaded.h"
36
37 namespace dyld3 {
38
39
40 //
41 // Tuple of info about a loaded image. Contains the loaded address, Image*, and state.
42 //
43 class VIS_HIDDEN LoadedImage {
44 public:
45 enum class State { unmapped=0, mapped=1, fixedUp=2, beingInited=3, inited=4 };
46
47 static LoadedImage make(const closure::Image* img) { LoadedImage result; result._image = img; return result; }
48 static LoadedImage make(const closure::Image* img, const MachOLoaded* mh)
49 { LoadedImage result; result._image = img; result.setLoadedAddress(mh); return result; }
50
51 const closure::Image* image() const { return _image; }
52 const MachOLoaded* loadedAddress() const { return (MachOLoaded*)(_loadAddr & (-4096)); }
53 void setLoadedAddress(const MachOLoaded* a) { _loadAddr |= ((uintptr_t)a & (-4096)); }
54 State state() const { return (State)(asBits().state); }
55 void setState(State s) { asBits().state = (int)s; }
56 bool hideFromFlatSearch() const { return asBits().hide; }
57 void setHideFromFlatSearch(bool h) { asBits().hide = h; }
58 bool leaveMapped() const { return asBits().leaveMapped; }
59 void markLeaveMapped() { asBits().leaveMapped = true; }
60
61 private:
62 // since loaded MachO files are always page aligned, that means at least low 12-bits are always zero
63 // so we don't need to record the low 12 bits, instead those bits hold various flags in the _loadeAddr field
64 struct AddrBits {
65 uintptr_t state : 3,
66 hide : 1,
67 leaveMapped : 1,
68 extra : 7,
69 #if __LP64__
70 addr : 52;
71 #else
72 addr : 20;
73 #endif
74 };
75 AddrBits& asBits() { return *((AddrBits*)&_loadAddr); }
76 const AddrBits& asBits() const { return *((AddrBits*)&_loadAddr); }
77
78 // Note: this must be statically initializable so as to not cause static initializers
79 const closure::Image* _image = nullptr;
80 uintptr_t _loadAddr = 0; // really AddrBits
81 };
82
83
84 //
85 // Utility class to recursively load dependents
86 //
87 class VIS_HIDDEN Loader {
88 public:
89 typedef bool (*LogFunc)(const char*, ...) __attribute__((format(printf, 1, 2)));
90
91 Loader(Array<LoadedImage>& storage, const void* cacheAddress, const Array<const dyld3::closure::ImageArray*>& imagesArrays,
92 LogFunc log_loads, LogFunc log_segments, LogFunc log_fixups, LogFunc log_dofs);
93
94 void addImage(const LoadedImage&);
95 void completeAllDependents(Diagnostics& diag, uintptr_t topIndex=0);
96 void mapAndFixupAllImages(Diagnostics& diag, bool processDOFs, bool fromOFI=false, uintptr_t topIndex=0);
97 uintptr_t resolveTarget(closure::Image::ResolvedSymbolTarget target);
98 LoadedImage* findImage(closure::ImageNum targetImageNum);
99
100 static void unmapImage(LoadedImage& info);
101 static bool dtraceUserProbesEnabled();
102 static void vmAccountingSetSuspended(bool suspend, LogFunc);
103
104 private:
105
106 struct ImageOverride
107 {
108 closure::ImageNum inCache;
109 closure::ImageNum replacement;
110 };
111
112 struct DOFInfo {
113 const void* dof;
114 const mach_header* imageHeader;
115 const char* imageShortName;
116 };
117
118 void mapImage(Diagnostics& diag, LoadedImage& info, bool fromOFI);
119 void applyFixupsToImage(Diagnostics& diag, LoadedImage& info);
120 void registerDOFs(const Array<DOFInfo>& dofs);
121 void setSegmentProtects(const LoadedImage& info, bool write);
122 bool sandboxBlockedMmap(const char* path);
123 bool sandboxBlockedOpen(const char* path);
124 bool sandboxBlockedStat(const char* path);
125 bool sandboxBlocked(const char* path, const char* kind);
126
127 Array<LoadedImage>& _allImages;
128 const Array<const closure::ImageArray*>& _imagesArrays;
129 const void* _dyldCacheAddress;
130 LogFunc _logLoads;
131 LogFunc _logSegments;
132 LogFunc _logFixups;
133 LogFunc _logDofs;
134 };
135
136
137
138 #if BUILDING_DYLD
139 bool bootArgsContains(const char* arg) VIS_HIDDEN;
140 bool internalInstall();
141 void forEachLineInFile(const char* path, void (^lineHandler)(const char* line, bool& stop));
142 void forEachLineInFile(const char* buffer, size_t bufferLen, void (^lineHandler)(const char* line, bool& stop));
143 #endif
144
145
146 } // namespace dyld3
147
148
149 #endif // __DYLD_LOADING_H__
150
151