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