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