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