]> git.saurik.com Git - apple/dyld.git/blob - src/ImageLoader.h
587a339d2b83612eb64b00d105ddcb0011b7a49b
[apple/dyld.git] / src / ImageLoader.h
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26 #ifndef __IMAGELOADER__
27 #define __IMAGELOADER__
28
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <mach/mach_time.h> // struct mach_timebase_info
32 #include <mach/mach_init.h> // struct mach_thread_self
33 #include <mach/shared_region.h>
34 #include <mach-o/loader.h>
35 #include <mach-o/nlist.h>
36 #include <stdint.h>
37 #include <vector>
38 #include <set>
39 #include <new>
40
41 #include "mach-o/dyld_images.h"
42 #include "mach-o/dyld_priv.h"
43
44 #if __i386__
45 #define SHARED_REGION_BASE SHARED_REGION_BASE_I386
46 #define SHARED_REGION_SIZE SHARED_REGION_SIZE_I386
47 #elif __x86_64__
48 #define SHARED_REGION_BASE SHARED_REGION_BASE_X86_64
49 #define SHARED_REGION_SIZE SHARED_REGION_SIZE_X86_64
50 #elif __ppc__
51 #define SHARED_REGION_BASE SHARED_REGION_BASE_PPC
52 #define SHARED_REGION_SIZE SHARED_REGION_SIZE_PPC
53 #elif __ppc64__
54 #define SHARED_REGION_BASE SHARED_REGION_BASE_PPC64
55 #define SHARED_REGION_SIZE SHARED_REGION_SIZE_PPC64
56 #elif __arm__
57 #define SHARED_REGION_BASE SHARED_REGION_BASE_ARM
58 #define SHARED_REGION_SIZE SHARED_REGION_SIZE_ARM
59 #endif
60
61
62
63 #define SPLIT_SEG_SHARED_REGION_SUPPORT __arm__
64 #define SPLIT_SEG_DYLIB_SUPPORT (__ppc__ || __i386__ || __arm__)
65 #define PREBOUND_IMAGE_SUPPORT (__ppc__ || __i386__ || __arm__)
66 #define TEXT_RELOC_SUPPORT (__ppc__ || __i386__)
67 #define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __i386__ || __ppc64__ || __x86_64__)
68 #define SUPPORT_OLD_CRT_INITIALIZATION (__ppc__ || __i386__)
69 #define COMPRESSED_DYLD_INFO_SUPPORT (__i386__ || __x86_64__)
70 #define CORESYMBOLICATION_SUPPORT (__i386__ || __x86_64__)
71 #if __arm__
72 #define INITIAL_IMAGE_COUNT 100
73 #else
74 #define INITIAL_IMAGE_COUNT 200
75 #endif
76
77 #define CODESIGNING_SUPPORT __arm__
78
79 // utilities
80 namespace dyld {
81 extern __attribute__((noreturn)) void throwf(const char* format, ...) __attribute__((format(printf, 1, 2)));
82 extern void log(const char* format, ...) __attribute__((format(printf, 1, 2)));
83 extern void warn(const char* format, ...) __attribute__((format(printf, 1, 2)));
84 extern const char* mkstringf(const char* format, ...) __attribute__((format(printf, 1, 2)));
85 };
86
87
88 #if __LP64__
89 struct macho_header : public mach_header_64 {};
90 struct macho_nlist : public nlist_64 {};
91 #else
92 struct macho_header : public mach_header {};
93 struct macho_nlist : public nlist {};
94 #endif
95
96
97 struct ProgramVars
98 {
99 const void* mh;
100 int* NXArgcPtr;
101 const char*** NXArgvPtr;
102 const char*** environPtr;
103 const char** __prognamePtr;
104 };
105
106
107
108 //
109 // ImageLoader is an abstract base class. To support loading a particular executable
110 // file format, you make a concrete subclass of ImageLoader.
111 //
112 // For each executable file (dynamic shared object) in use, an ImageLoader is instantiated.
113 //
114 // The ImageLoader base class does the work of linking together images, but it knows nothing
115 // about any particular file format.
116 //
117 //
118 class ImageLoader {
119 public:
120
121 typedef uint32_t DefinitionFlags;
122 static const DefinitionFlags kNoDefinitionOptions = 0;
123 static const DefinitionFlags kWeakDefinition = 1;
124
125 typedef uint32_t ReferenceFlags;
126 static const ReferenceFlags kNoReferenceOptions = 0;
127 static const ReferenceFlags kWeakReference = 1;
128 static const ReferenceFlags kTentativeDefinition = 2;
129
130 enum PrebindMode { kUseAllPrebinding, kUseSplitSegPrebinding, kUseAllButAppPredbinding, kUseNoPrebinding };
131 enum BindingOptions { kBindingNone, kBindingLazyPointers, kBindingNeverSetLazyPointers };
132 enum SharedRegionMode { kUseSharedRegion, kUsePrivateSharedRegion, kDontUseSharedRegion, kSharedRegionIsSharedCache };
133
134 struct Symbol; // abstact symbol
135
136 struct MappedRegion {
137 uintptr_t address;
138 size_t size;
139 };
140
141 struct RPathChain {
142 RPathChain(const RPathChain* n, std::vector<const char*>* p) : next(n), paths(p) {};
143 const RPathChain* next;
144 std::vector<const char*>* paths;
145 };
146
147 struct DOFInfo {
148 void* dof;
149 const mach_header* imageHeader;
150 const char* imageShortName;
151 };
152
153 struct LinkContext {
154 ImageLoader* (*loadLibrary)(const char* libraryName, bool search, const char* origin, const RPathChain* rpaths);
155 void (*terminationRecorder)(ImageLoader* image);
156 bool (*flatExportFinder)(const char* name, const Symbol** sym, const ImageLoader** image);
157 bool (*coalescedExportFinder)(const char* name, const Symbol** sym, const ImageLoader** image);
158 unsigned int (*getCoalescedImages)(ImageLoader* images[]);
159 void (*undefinedHandler)(const char* name);
160 MappedRegion* (*getAllMappedRegions)(MappedRegion*);
161 void * (*bindingHandler)(const char *, const char *, void *);
162 void (*notifySingle)(dyld_image_states, const ImageLoader* image);
163 void (*notifyBatch)(dyld_image_states state);
164 void (*removeImage)(ImageLoader* image);
165 void (*registerDOFs)(const std::vector<DOFInfo>& dofs);
166 void (*clearAllDepths)();
167 unsigned int (*imageCount)();
168 void (*setNewProgramVars)(const ProgramVars&);
169 bool (*inSharedCache)(const char* path);
170 #if SUPPORT_OLD_CRT_INITIALIZATION
171 void (*setRunInitialzersOldWay)();
172 #endif
173 BindingOptions bindingOptions;
174 int argc;
175 const char** argv;
176 const char** envp;
177 const char** apple;
178 const char* progname;
179 ProgramVars programVars;
180 ImageLoader* mainExecutable;
181 const char* imageSuffix;
182 const char** rootPaths;
183 PrebindMode prebindUsage;
184 SharedRegionMode sharedRegionMode;
185 bool dyldLoadedAtSameAddressNeededBySharedCache;
186 bool preFetchDisabled;
187 bool prebinding;
188 bool bindFlat;
189 bool linkingMainExecutable;
190 bool startedInitializingMainExecutable;
191 bool noPIE;
192 bool processIsRestricted;
193 bool verboseOpts;
194 bool verboseEnv;
195 bool verboseMapping;
196 bool verboseRebase;
197 bool verboseBind;
198 bool verboseWeakBind;
199 bool verboseInit;
200 bool verboseDOF;
201 bool verbosePrebinding;
202 bool verboseWarnings;
203 };
204
205 struct CoalIterator
206 {
207 ImageLoader* image;
208 const char* symbolName;
209 unsigned int loadOrder;
210 bool weakSymbol;
211 bool symbolMatches;
212 bool done;
213 // the following are private to the ImageLoader subclass
214 uintptr_t curIndex;
215 uintptr_t endIndex;
216 uintptr_t address;
217 uintptr_t type;
218 uintptr_t addend;
219 };
220
221 virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder) = 0;
222 virtual bool incrementCoalIterator(CoalIterator&) = 0;
223 virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& context) = 0;
224 virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, const LinkContext& context) = 0;
225
226
227
228 // constructor is protected, but anyone can delete an image
229 virtual ~ImageLoader();
230
231 // link() takes a newly instantiated ImageLoader and does all
232 // fixups needed to make it usable by the process
233 void link(const LinkContext& context, bool forceLazysBound, bool preflight, const RPathChain& loaderRPaths);
234
235 // runInitializers() is normally called in link() but the main executable must
236 // run crt code before initializers
237 void runInitializers(const LinkContext& context);
238
239 // called after link() forces all lazy pointers to be bound
240 void bindAllLazyPointers(const LinkContext& context, bool recursive);
241
242 // used by dyld to see if a requested library is already loaded (might be symlink)
243 bool statMatch(const struct stat& stat_buf) const;
244
245 // get short name of this image
246 const char* getShortName() const;
247
248 // get path used to load this image, not necessarily the "real" path
249 const char* getPath() const { return fPath; }
250
251 uint32_t getPathHash() const { return fPathHash; }
252
253 // get path this image is intended to be placed on disk or NULL if no preferred install location
254 virtual const char* getInstallPath() const = 0;
255
256 // image was loaded with NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME and all clients are looking for install path
257 bool matchInstallPath() const;
258 void setMatchInstallPath(bool);
259
260 // mark that this image's exported symbols should be ignored when linking other images (e.g. RTLD_LOCAL)
261 void setHideExports(bool hide = true);
262
263 // check if this image's exported symbols should be ignored when linking other images
264 bool hasHiddenExports() const;
265
266 // checks if this image is already linked into the process
267 bool isLinked() const;
268
269 // even if image is deleted, leave segments mapped in
270 void setLeaveMapped();
271
272 // even if image is deleted, leave segments mapped in
273 bool leaveMapped() { return fLeaveMapped; }
274
275 // checks if the specifed address is within one of this image's segments
276 virtual bool containsAddress(const void* addr) const;
277
278 // checks if the specifed symbol is within this image's symbol table
279 virtual bool containsSymbol(const void* addr) const = 0;
280
281 // checks if the specifed address range overlaps any of this image's segments
282 virtual bool overlapsWithAddressRange(const void* start, const void* end) const;
283
284 // adds to list of ranges of memory mapped in
285 void getMappedRegions(MappedRegion*& region) const;
286
287 // st_mtime from stat() on file
288 time_t lastModified() const;
289
290 // only valid for main executables, returns a pointer its entry point
291 virtual void* getMain() const = 0;
292
293 // dyld API's require each image to have an associated mach_header
294 virtual const struct mach_header* machHeader() const = 0;
295
296 // dyld API's require each image to have a slide (actual load address minus preferred load address)
297 virtual uintptr_t getSlide() const = 0;
298
299 // last address mapped by image
300 virtual const void* getEnd() const = 0;
301
302 // image has exports that participate in runtime coalescing
303 virtual bool hasCoalescedExports() const = 0;
304
305 // search symbol table of definitions in this image for requested name
306 virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const ImageLoader** foundIn) const = 0;
307
308 // gets address of implementation (code) of the specified exported symbol
309 virtual uintptr_t getExportedSymbolAddress(const Symbol* sym, const LinkContext& context, const ImageLoader* requestor=NULL) const = 0;
310
311 // gets attributes of the specified exported symbol
312 virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const = 0;
313
314 // gets name of the specified exported symbol
315 virtual const char* getExportedSymbolName(const Symbol* sym) const = 0;
316
317 // gets how many symbols are exported by this image
318 virtual uint32_t getExportedSymbolCount() const = 0;
319
320 // gets the i'th exported symbol
321 virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const = 0;
322
323 // find exported symbol as if imported by this image
324 // used by RTLD_NEXT
325 virtual const Symbol* findExportedSymbolInDependentImages(const char* name, const LinkContext& context, const ImageLoader** foundIn) const;
326
327 // find exported symbol as if imported by this image
328 // used by RTLD_SELF
329 virtual const Symbol* findExportedSymbolInImageOrDependentImages(const char* name, const LinkContext& context, const ImageLoader** foundIn) const;
330
331 // gets how many symbols are imported by this image
332 virtual uint32_t getImportedSymbolCount() const = 0;
333
334 // gets the i'th imported symbol
335 virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const = 0;
336
337 // gets attributes of the specified imported symbol
338 virtual ReferenceFlags getImportedSymbolInfo(const Symbol* sym) const = 0;
339
340 // gets name of the specified imported symbol
341 virtual const char* getImportedSymbolName(const Symbol* sym) const = 0;
342
343 // find the closest symbol before addr
344 virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const = 0;
345
346 // checks if this image is a bundle and can be loaded but not linked
347 virtual bool isBundle() const = 0;
348
349 // checks if this image is a dylib
350 virtual bool isDylib() const = 0;
351
352 // checks if this image is a main executable
353 virtual bool isExecutable() const = 0;
354
355 // checks if this image is a main executable
356 virtual bool isPositionIndependentExecutable() const = 0;
357
358 // only for main executable
359 virtual bool forceFlat() const = 0;
360
361 // called at runtime when a lazily bound function is first called
362 virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) = 0;
363
364 // called at runtime when a fast lazily bound function is first called
365 virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context) = 0;
366
367 // calls termination routines (e.g. C++ static destructors for image)
368 virtual void doTermination(const LinkContext& context) = 0;
369
370 // return if this image has initialization routines
371 virtual bool needsInitialization() = 0;
372
373 // return if this image has specified section and set start and length
374 virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length) = 0;
375
376 // fills in info about __eh_frame and __unwind_info sections
377 virtual void getUnwindInfo(dyld_unwind_sections* info) = 0;
378
379 // given a pointer into an image, find which segment and section it is in
380 virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset) = 0;
381
382 // the image supports being prebound
383 virtual bool isPrebindable() const = 0;
384
385 // the image is prebindable and its prebinding is valid
386 virtual bool usablePrebinding(const LinkContext& context) const = 0;
387
388 // add all RPATH paths this image contains
389 virtual void getRPaths(const LinkContext& context, std::vector<const char*>&) const = 0;
390
391 // image has or uses weak definitions that need runtime coalescing
392 virtual bool participatesInCoalescing() const = 0;
393
394 // if image has a UUID, copy into parameter and return true
395 virtual bool getUUID(uuid_t) const = 0;
396
397
398 //
399 // A segment is a chunk of an executable file that is mapped into memory.
400 //
401 virtual unsigned int segmentCount() const = 0;
402 virtual const char* segName(unsigned int) const = 0;
403 virtual uintptr_t segSize(unsigned int) const = 0;
404 virtual uintptr_t segFileSize(unsigned int) const = 0;
405 virtual bool segHasTrailingZeroFill(unsigned int) = 0;
406 virtual uintptr_t segFileOffset(unsigned int) const = 0;
407 virtual bool segReadable(unsigned int) const = 0;
408 virtual bool segWriteable(unsigned int) const = 0;
409 virtual bool segExecutable(unsigned int) const = 0;
410 virtual bool segUnaccessible(unsigned int) const = 0;
411 virtual bool segHasPreferredLoadAddress(unsigned int) const = 0;
412 virtual uintptr_t segPreferredLoadAddress(unsigned int) const = 0;
413 virtual uintptr_t segActualLoadAddress(unsigned int) const = 0;
414 virtual uintptr_t segActualEndAddress(unsigned int) const = 0;
415
416
417
418 dyld_image_states getState() { return (dyld_image_states)fState; }
419
420 // used to sort images bottom-up
421 int compare(const ImageLoader* right) const;
422
423 void incrementDlopenReferenceCount() { ++fDlopenReferenceCount; }
424
425 bool decrementDlopenReferenceCount();
426
427 void printReferenceCounts();
428
429 uint32_t referenceCount() const { return fDlopenReferenceCount + fStaticReferenceCount + fDynamicReferenceCount; }
430
431 bool neverUnload() const { return fNeverUnload; }
432
433 void setNeverUnload() { fNeverUnload = true; fLeaveMapped = true; }
434
435 // triggered by DYLD_PRINT_STATISTICS to write info on work done and how fast
436 static void printStatistics(unsigned int imageCount);
437
438 // used with DYLD_IMAGE_SUFFIX
439 static void addSuffix(const char* path, const char* suffix, char* result);
440
441 static uint32_t hash(const char*);
442
443 // used instead of directly deleting image
444 static void deleteImage(ImageLoader*);
445
446 void setPath(const char* path); // only called for images created from memory
447 void setPathUnowned(const char* path);
448
449 void clearDepth() { fDepth = 0; }
450
451 void setBeingRemoved() { fBeingRemoved = true; }
452 bool isBeingRemoved() const { return fBeingRemoved; }
453
454 void setAddFuncNotified() { fAddFuncNotified = true; }
455 bool addFuncNotified() const { return fAddFuncNotified; }
456
457 protected:
458 // abstract base class so all constructors protected
459 ImageLoader(const char* path, unsigned int libCount);
460 ImageLoader(const ImageLoader&);
461 void operator=(const ImageLoader&);
462 void operator delete(void* image) throw() { free(image); }
463
464
465 struct LibraryInfo {
466 uint32_t checksum;
467 uint32_t minVersion;
468 uint32_t maxVersion;
469 };
470
471 struct DependentLibrary {
472 ImageLoader* image;
473 uint32_t required : 1,
474 checksumMatches : 1,
475 isReExported : 1,
476 isSubFramework : 1;
477 };
478
479 struct DependentLibraryInfo {
480 const char* name;
481 LibraryInfo info;
482 bool required;
483 bool reExported;
484 };
485
486
487 typedef void (*Initializer)(int argc, const char* argv[], const char* envp[], const char* apple[], const ProgramVars* vars);
488 typedef void (*Terminator)(void);
489
490
491
492 unsigned int libraryCount() const { return fLibraryCount; }
493 virtual ImageLoader* libImage(unsigned int) const = 0;
494 virtual bool libReExported(unsigned int) const = 0;
495 virtual void setLibImage(unsigned int, ImageLoader*, bool) = 0;
496
497
498 // To link() an image, its dependent libraries are loaded, it is rebased, bound, and initialized.
499 // These methods do the above, exactly once, and it the right order
500 void recursiveLoadLibraries(const LinkContext& context, bool preflightOnly, const RPathChain& loaderRPaths);
501 void recursiveUnLoadMappedLibraries(const LinkContext& context);
502 unsigned int recursiveUpdateDepth(unsigned int maxDepth);
503 void recursiveValidate(const LinkContext& context);
504 void recursiveRebase(const LinkContext& context);
505 void recursiveBind(const LinkContext& context, bool forceLazysBound);
506 void weakBind(const LinkContext& context);
507 void recursiveGetDOFSections(const LinkContext& context, std::vector<DOFInfo>& dofs);
508 void recursiveInitialization(const LinkContext& context, mach_port_t this_thread);
509
510 // fill in information about dependent libraries (array length is fLibraryCount)
511 virtual void doGetDependentLibraries(DependentLibraryInfo libs[]) = 0;
512
513 // called on images that are libraries, returns info about itself
514 virtual LibraryInfo doGetLibraryInfo() = 0;
515
516 // do any fix ups in this image that depend only on the load address of the image
517 virtual void doRebase(const LinkContext& context) = 0;
518
519 // do any symbolic fix ups in this image
520 virtual void doBind(const LinkContext& context, bool forceLazysBound) = 0;
521
522 // called later via API to force all lazy pointer to be bound
523 virtual void doBindJustLazies(const LinkContext& context) = 0;
524
525 // if image has any dtrace DOF sections, append them to list to be registered
526 virtual void doGetDOFSections(const LinkContext& context, std::vector<DOFInfo>& dofs) = 0;
527
528 // run any initialization routines in this image
529 virtual void doInitialization(const LinkContext& context) = 0;
530
531 // return if this image has termination routines
532 virtual bool needsTermination() = 0;
533
534 // support for runtimes in which segments don't have to maintain their relative positions
535 virtual bool segmentsMustSlideTogether() const = 0;
536
537 // built with PIC code and can load at any address
538 virtual bool segmentsCanSlide() const = 0;
539
540 // set how much all segments slide
541 virtual void setSlide(intptr_t slide) = 0;
542
543 // returns if all dependent libraries checksum's were as expected and none slide
544 bool allDependentLibrariesAsWhenPreBound() const;
545
546 // in mach-o a child tells it parent to re-export, instead of the other way around...
547 virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const = 0;
548
549 // in mach-o a parent library knows name of sub libraries it re-exports..
550 virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const = 0;
551
552 // set fState to dyld_image_state_memory_mapped
553 void setMapped(const LinkContext& context);
554
555 // mark that target should not be unloaded unless this is also unloaded
556 void addDynamicReference(const ImageLoader* target);
557
558 void setFileInfo(dev_t device, ino_t inode, time_t modDate);
559
560 static uintptr_t fgNextPIEDylibAddress;
561 static uint32_t fgImagesWithUsedPrebinding;
562 static uint32_t fgImagesUsedFromSharedCache;
563 static uint32_t fgImagesRequiringNoFixups;
564 static uint32_t fgImagesHasWeakDefinitions;
565 static uint32_t fgImagesRequiringCoalescing;
566 static uint32_t fgTotalRebaseFixups;
567 static uint32_t fgTotalBindFixups;
568 static uint32_t fgTotalBindSymbolsResolved;
569 static uint32_t fgTotalBindImageSearches;
570 static uint32_t fgTotalLazyBindFixups;
571 static uint32_t fgTotalPossibleLazyBindFixups;
572 static uint32_t fgTotalSegmentsMapped;
573 static uint64_t fgTotalBytesMapped;
574 static uint64_t fgTotalBytesPreFetched;
575 static uint64_t fgTotalLoadLibrariesTime;
576 static uint64_t fgTotalRebaseTime;
577 static uint64_t fgTotalBindTime;
578 static uint64_t fgTotalWeakBindTime;
579 static uint64_t fgTotalDOF;
580 static uint64_t fgTotalInitTime;
581 const char* fPath;
582 dev_t fDevice;
583 ino_t fInode;
584 time_t fLastModified;
585 uint32_t fPathHash;
586 uint32_t fDlopenReferenceCount; // count of how many dlopens have been done on this image
587 uint32_t fStaticReferenceCount; // count of images that have a fLibraries entry pointing to this image
588 uint32_t fDynamicReferenceCount; // count of images that have a fDynamicReferences entry pointer to this image
589 std::set<const ImageLoader*>* fDynamicReferences; // list of all images this image used because of a flat/coalesced lookup
590
591 private:
592 struct recursive_lock {
593 recursive_lock(mach_port_t t) : thread(t), count(0) {}
594 mach_port_t thread;
595 int count;
596 };
597 void recursiveSpinLock(recursive_lock&);
598 void recursiveSpinUnLock();
599
600 const ImageLoader::Symbol* findExportedSymbolInDependentImagesExcept(const char* name, const ImageLoader** dsiStart,
601 const ImageLoader**& dsiCur, const ImageLoader** dsiEnd, const ImageLoader** foundIn) const;
602
603
604
605 recursive_lock* fInitializerRecursiveLock;
606 uint16_t fDepth;
607 uint16_t fLoadOrder;
608 uint32_t fState : 8,
609 fLibraryCount : 10,
610 fAllLibraryChecksumsAndLoadAddressesMatch : 1,
611 fLeaveMapped : 1, // when unloaded, leave image mapped in cause some other code may have pointers into it
612 fNeverUnload : 1, // image was statically loaded by main executable
613 fHideSymbols : 1, // ignore this image's exported symbols when linking other images
614 fMatchByInstallName : 1,// look at image's install-path not its load path
615 fRegisteredDOF : 1,
616 fAllLazyPointersBound : 1,
617 fBeingRemoved : 1,
618 fAddFuncNotified : 1,
619 fPathOwnedByImage : 1,
620 fWeakSymbolsBound : 1;
621
622 static uint16_t fgLoadOrdinal;
623 };
624
625
626
627
628 #endif
629