]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/dyldcache.h
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / dyldcache.h
1 /*
2 * Copyright (c) 2009,2011-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 //
25 // dyldcache - access layer to the DYLD Shared Library Cache file
26 //
27 #ifndef _H_DYLDCACHE
28 #define _H_DYLDCACHE
29
30 #include <security_utilities/unix++.h>
31 #include <security_utilities/memutils.h>
32 #include <security_utilities/macho++.h>
33 #include <security_utilities/endian.h>
34 #include "dyld_cache_format.h"
35
36
37 //
38 // One (architecture of the) Shared Library Cache.
39 // We mmap the file rather than reading a copy, since its format is rather scattered, and we're not
40 // interested in the vast majority of it.
41 // This is a read-only view of the cache file. It will not allow modifications, though it may
42 // tell you where in the file they should go.
43 //
44 class DYLDCache : public UnixPlusPlus::AutoFileDesc {
45 public:
46 DYLDCache(const std::string &path);
47 virtual ~DYLDCache();
48
49 std::string magic() const { return mHeader->magic; }
50 uint64_t baseAddress() const { return flip(mHeader->dyldBaseAddress); }
51 Architecture architecture() const { return mArch->architecture(); }
52 size_t mapSize() const { return mSigStart; } // size of all the mappings
53 size_t signatureLength() const { return mSigLength; } // size of all the mappings
54 size_t totalSize() const { return mLength; } // size of entire file (>= mapSize(), we hope)
55
56 template <class Int> Int flip(Int x) const { return mFlip ? Security::flip(x) : x; }
57
58 public:
59 static std::string pathFor(const Architecture &arch); // file path for given architecture
60 static bool validate(UnixPlusPlus::FileDesc &fd); // does this look like a shared library cache?
61
62 protected:
63 template <class SubStruct>
64 class Item {
65 public:
66 Item(const DYLDCache &c, uint32_t off)
67 : cache(c), mStruct(c.at<SubStruct>(off)) { }
68 const DYLDCache &cache;
69
70 protected:
71 const SubStruct *mStruct;
72 template <class Int> Int flip(Int x) const { return cache.flip(x); }
73 };
74
75 public:
76 //
77 // A contiguous mapping established by the cache builder
78 //
79 struct Mapping : public Item<shared_file_mapping_np> {
80 mach_vm_address_t address() const { return flip(mStruct->sfm_address); }
81 mach_vm_size_t size() const { return flip(mStruct->sfm_size); }
82 mach_vm_address_t limit() const { return address() + size(); }
83 mach_vm_offset_t offset() const { return flip(mStruct->sfm_file_offset); }
84 vm_prot_t maxProt() const { return flip(mStruct->sfm_max_prot); }
85 vm_prot_t initProt() const { return flip(mStruct->sfm_init_prot); }
86
87 bool contains(uint64_t address) const
88 { return address >= this->address() && address < this->limit(); }
89
90 Mapping(const DYLDCache &c, uint32_t off) : Item<shared_file_mapping_np>(c, off) { }
91 };
92
93 uint32_t mappingCount() const { return flip(mHeader->mappingCount); }
94 Mapping mapping(unsigned ix) const;
95
96 Mapping findMap(uint64_t address) const;
97 uint64_t mapAddress(uint64_t address) const;
98
99 public:
100 //
101 // One original binary ("image") as embedded in the cache.
102 //
103 struct Image : public Item<dyld_cache_image_info> {
104 Image(const DYLDCache &c, uint32_t off) : Item<dyld_cache_image_info>(c, off) { }
105
106 uint64_t address() const { return flip(mStruct->address); }
107 uint64_t modTime() const { return flip(mStruct->modTime); }
108 uint64_t inode() const { return flip(mStruct->inode); }
109 uint32_t pad() const { return flip(mStruct->pad); }
110 std::string path() const { return cache.at<char>(flip(mStruct->pathFileOffset)); }
111 };
112
113 uint32_t imageCount() const { return flip(mHeader->imagesCount); }
114 Image image(unsigned ix) const;
115
116 public:
117 template <class T>
118 const T *at(uint32_t offset) const
119 {
120 size_t end = offset + sizeof(T);
121 if (offset > end || end > mLength)
122 UnixError::throwMe(ENOEXEC);
123 return LowLevelMemoryUtilities::increment<const T>(mBase, offset);
124 }
125
126 private:
127 //
128 // A private table correlating cache "magic strings" to information we need about the cache
129 // (This should be in the cache files themselves)
130 //
131 struct ArchType {
132 cpu_type_t cpu; // main architecture
133 cpu_subtype_t sub; // subarchitecture
134 char magic[16]; // cache file magic string
135 char filename[10]; // conventional file name (off cacheFileBase)
136 uint16_t order; // byte order marker
137
138 std::string path() const
139 { return std::string(DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME) + filename; }
140
141 Architecture architecture() const { return Architecture(cpu, sub); }
142 };
143 static const ArchType architectures[];
144 static const ArchType defaultArchitecture;
145
146 static const ArchType *matchArchitecture(const dyld_cache_header &header);
147
148 private:
149 const void *mBase;
150 size_t mLength;
151
152 const dyld_cache_header *mHeader; // cache file header (NOT byte order corrected)
153 const ArchType *mArch; // ArchType entry that describes this file
154 bool mFlip; // need to flip all integers?
155 size_t mSigStart; // end of all file mappings (start of signature)
156 size_t mSigLength; // indicated length of signature
157 };
158
159
160 #endif //_H_DYLDCACHE